internal EmittingContext(LLVMModuleRef pModule, LLVMPassManagerRef pPass, bool pEmitDebug)
        {
            CurrentModule       = pModule;
            _passManager        = pPass;
            _context            = LLVM.GetGlobalContext();
            _deferredStatements = new Stack <List <Syntax.SyntaxNode> >();
            Builder             = LLVM.CreateBuilder();
            _emitDebug          = pEmitDebug;
            Locals         = new ScopeCache <LocalDefinition>();
            AccessStack    = new AccessStack <MemberAccess>();
            BreakLocations = new AccessStack <LLVMValueRef>(1);

            if (_emitDebug)
            {
                _debugLocations = new Stack <LLVMMetadataRef>();
                _debugInfo      = Utils.LlvmPInvokes.LLVMCreateDIBuilder(CurrentModule);
                _debugFile      = Utils.LlvmPInvokes.LLVMDIBuilderCreateFile(_debugInfo, "debug", 5, ".", 1);

                //Set debug version
                var version = LLVM.MDNode(new LLVMValueRef[] { GetInt(1),                               //Error on mismatch
                                                               LLVM.MDString("Debug Info Version", 18), //Constant string. Cannot change.
                                                               GetInt(3) });                            //Debug version
                LLVM.AddNamedMetadataOperand(CurrentModule, "llvm.module.flags", version);
            }
        }
        private void EmitDebugMetadata()
        {
            var dwarfVersion = LLVM.MDNode(new[]
            {
                LLVM.ConstInt(LLVM.Int32Type(), 2, false),
                LLVM.MDString("Dwarf Version", 13),
                LLVM.ConstInt(LLVM.Int32Type(), 4, false)
            });
            var dwarfSchemaVersion = LLVM.MDNode(new[]
            {
                LLVM.ConstInt(LLVM.Int32Type(), 2, false),
                LLVM.MDString("Debug Info Version", 18),
                LLVM.ConstInt(LLVM.Int32Type(), 3, false)
            });

            LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", dwarfVersion);
            LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", dwarfSchemaVersion);
            LLVM.DIBuilderFinalize(DIBuilder);
        }
Beispiel #3
0
        public CodeGenerator(string targetPlatform, string dataLayout, int optimisation, string moduleName)
        {
            TargetPlatform    = targetPlatform;
            DataLayout        = dataLayout;
            OptimisationLevel = optimisation;

            if (optimisation != -1)
            {
                LLVMPassManagerBuilderRef passManagerBuilderRef = LLVM.PassManagerBuilderCreate();
                LLVM.PassManagerBuilderSetOptLevel(passManagerBuilderRef, (uint)optimisation);
                PassManager = LLVM.CreatePassManager();
                LLVM.PassManagerBuilderPopulateModulePassManager(passManagerBuilderRef, PassManager.Value);
            }

            Module  = LLVM.ModuleCreateWithName(moduleName);
            Context = LLVM.GetModuleContext(Module);
            Builder = LLVM.CreateBuilder();
            LLVM.SetTarget(Module, TargetPlatform);
            LLVM.SetDataLayout(Module, dataLayout);

            LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", LLVM.MDNode(new[]
            {
                LLVM.ConstInt(LLVM.Int32Type(), 2, false),
                LLVM.MDString("Dwarf Version", (uint)"Dwarf Version".Length),
                LLVM.ConstInt(LLVM.Int32Type(), 4, false)
            }));
            LLVM.AddNamedMetadataOperand(Module, "llvm.module.flags", LLVM.MDNode(new[]
            {
                LLVM.ConstInt(LLVM.Int32Type(), 2, false),
                LLVM.MDString("Debug Info Version", (uint)"Debug Info Version".Length),
                LLVM.ConstInt(LLVM.Int32Type(), 3, false)
            }));

            _globals       = new Dictionary <string, LLVMValueRef>();
            _structCache   = new Dictionary <string, LLVMTypeRef>();
            _functionCache = new Dictionary <string, LLVMValueRef>();
        }
Beispiel #4
0
        public void TestPTX()
        {
            LLVM.InitializeAllTargets();
            LLVM.InitializeAllTargetMCs();
            LLVM.InitializeAllTargetInfos();
            LLVM.InitializeAllAsmPrinters();
            ModuleRef mod = LLVM.ModuleCreateWithName("llvmptx");
            var       pt  = LLVM.PointerType(LLVM.Int64Type(), 1);

            TypeRef[]     param_types = { pt };
            TypeRef       ret_type    = LLVM.FunctionType(LLVM.VoidType(), param_types, false);
            ValueRef      sum         = LLVM.AddFunction(mod, "sum", ret_type);
            BasicBlockRef entry       = LLVM.AppendBasicBlock(sum, "entry");
            BuilderRef    builder     = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder, entry);
            var      v   = LLVM.BuildLoad(builder, LLVM.GetParam(sum, 0), "");
            ValueRef tmp = LLVM.BuildAdd(builder, v, LLVM.ConstInt(LLVM.Int64Type(), 1, false), "tmp");

            LLVM.BuildStore(builder, tmp, LLVM.GetParam(sum, 0));
            LLVM.BuildRetVoid(builder);
            MyString the_error = new MyString();

            LLVM.VerifyModule(mod, VerifierFailureAction.PrintMessageAction, the_error);

            string    triple = "nvptx64-nvidia-cuda";
            TargetRef t2;
            var       b = LLVM.GetTargetFromTriple(triple, out t2, the_error);

            string cpu      = "";
            string features = "";

            TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, triple, cpu, features,
                                                            CodeGenOptLevel.CodeGenLevelDefault,
                                                            RelocMode.RelocDefault,
                                                            CodeModel.CodeModelKernel);
            ContextRef context_ref = LLVM.ContextCreate();
            ValueRef   kernelMd    = LLVM.MDNodeInContext(context_ref, new ValueRef[3]
            {
                sum,
                LLVM.MDStringInContext(context_ref, "kernel", 6),
                LLVM.ConstInt(LLVM.Int32TypeInContext(context_ref), 1, false)
            });

            LLVM.AddNamedMetadataOperand(mod, "nvvm.annotations", kernelMd);
            var y1 = LLVM.TargetMachineEmitToMemoryBuffer(
                tmr,
                mod,
                Swigged.LLVM.CodeGenFileType.AssemblyFile,
                the_error,
                out MemoryBufferRef buffer);
            string ptx = null;

            try
            {
                ptx = LLVM.GetBufferStart(buffer);
                uint length = LLVM.GetBufferSize(buffer);
                // Output the PTX assembly code. We can run this using the CUDA Driver API
                System.Console.WriteLine(ptx);
            }
            finally
            {
                LLVM.DisposeMemoryBuffer(buffer);
            }


            // RUN THE MF.

            Int64[]     h_C             = new Int64[100];
            CudaContext ctx             = new CudaContext(CudaContext.GetMaxGflopsDeviceId());
            CudaKernel  kernel          = ctx.LoadKernelPTX(Encoding.ASCII.GetBytes(ptx), "sum");
            var         d_C             = new CudaDeviceVariable <Int64>(100);
            int         N               = 1;
            int         threadsPerBlock = 256;

            kernel.BlockDimensions = threadsPerBlock;
            kernel.GridDimensions  = (N + threadsPerBlock - 1) / threadsPerBlock;
            kernel.Run(d_C.DevicePointer);
            h_C = d_C;
            System.Console.WriteLine("Result " + h_C[0]);
            if (h_C[0] != 1)
            {
                throw new Exception("Failed.");
            }
            LLVM.DumpModule(mod);
            LLVM.DisposeBuilder(builder);
        }
Beispiel #5
0
        private static async Task <CudaModule> CompileAsync(
            IMethod method,
            IEnumerable <ITypeMember> memberRoots,
            IEnumerable <IType> typeRoots,
            int threadIdParamIndex,
            ClrAssembly assembly,
            CudaContext context)
        {
            // Figure out which members we need to compile.
            var desc = await CreateContentDescriptionAsync(method, memberRoots, typeRoots, assembly);

            // Compile those members to LLVM IR. Use an Itanium name mangling scheme.
            var mangler       = new ItaniumMangler(assembly.Resolver.TypeEnvironment);
            var moduleBuilder = LlvmBackend.Compile(desc, assembly.Resolver.TypeEnvironment);
            var module        = moduleBuilder.Module;

            // Generate type metadata for all type roots.
            foreach (var type in typeRoots)
            {
                moduleBuilder.Metadata.GetMetadata(type, moduleBuilder);
            }

            // Get the compiled kernel function.
            var kernelFuncName = mangler.Mangle(method, true);
            var kernelFunc     = LLVM.GetNamedFunction(module, kernelFuncName);

            if (threadIdParamIndex >= 0)
            {
                // If we have a thread ID parameter, then we need to generate a thunk
                // kernel function that calls our actual kernel function. This thunk's
                // responsibility is to determine the thread ID of the kernel.
                var thunkKernelName = "kernel";
                var thunkTargetType = kernelFunc.TypeOf().GetElementType();
                var thunkParamTypes = new List <LLVMTypeRef>(thunkTargetType.GetParamTypes());
                if (threadIdParamIndex < thunkParamTypes.Count)
                {
                    thunkParamTypes.RemoveAt(threadIdParamIndex);
                }
                var thunkKernel = LLVM.AddFunction(
                    module,
                    thunkKernelName,
                    LLVM.FunctionType(
                        thunkTargetType.GetReturnType(),
                        thunkParamTypes.ToArray(),
                        thunkTargetType.IsFunctionVarArg));

                using (var builder = new IRBuilder(moduleBuilder.Context))
                {
                    builder.PositionBuilderAtEnd(thunkKernel.AppendBasicBlock("entry"));
                    var args = new List <LLVMValueRef>(thunkKernel.GetParams());
                    args.Insert(threadIdParamIndex, ComputeUniqueThreadId(builder, module));
                    var call = builder.CreateCall(kernelFunc, args.ToArray(), "");
                    if (call.TypeOf().TypeKind == LLVMTypeKind.LLVMVoidTypeKind)
                    {
                        builder.CreateRetVoid();
                    }
                    else
                    {
                        builder.CreateRet(call);
                    }
                }

                kernelFuncName = thunkKernelName;
                kernelFunc     = thunkKernel;
            }

            // Mark the compiled kernel as a kernel symbol.
            LLVM.AddNamedMetadataOperand(
                module,
                "nvvm.annotations",
                LLVM.MDNode(new LLVMValueRef[]
            {
                kernelFunc,
                MDString("kernel"),
                LLVM.ConstInt(LLVM.Int32TypeInContext(LLVM.GetModuleContext(module)), 1, false)
            }));

            // LLVM.DumpModule(module);

            // Compile that LLVM IR down to PTX.
            LLVMTargetMachineRef machine;
            var ptx = CompileToPtx(module, context.GetDeviceComputeCapability(), out machine);

            // Console.WriteLine(System.Text.Encoding.UTF8.GetString(ptx));

            // Load the PTX kernel.
            return(new CudaModule(assembly, moduleBuilder, machine, context.LoadModulePTX(ptx), kernelFuncName, context));
        }