public void TestLazyIRCompilation( ) { using (Library.InitializeLLVM( )) { Library.RegisterNative( ); using (LLVMContextRef context = LLVMContextCreate( )) { string nativeTriple = LLVMGetDefaultTargetTriple(); Assert.IsFalse(string.IsNullOrWhiteSpace(nativeTriple)); Assert.IsTrue(LLVMGetTargetFromTriple(nativeTriple, out LLVMTargetRef targetHandle, out string errorMessag).Succeeded); LLVMTargetMachineRef machine = LLVMCreateTargetMachine( targetHandle, nativeTriple, string.Empty, string.Empty, LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelJITDefault); using ( machine ) { LLVMOrcJITStackRef orcJit = LLVMOrcCreateInstance(machine); using ( orcJit ) { // try several different modules with the same function name replacing the previous AddAndExecuteTestModule(orcJit, context, machine, 42); AddAndExecuteTestModule(orcJit, context, machine, 12345678); AddAndExecuteTestModule(orcJit, context, machine, 87654321); } } } } }
public static void EmitToFile(this LLVMTargetMachineRef self, Module module, string filename) { if (module is null) { throw new ArgumentNullException(nameof(module)); } try { var filenameMarshaled = Marshal.StringToCoTaskMemAnsi(filename); if (LLVM.TargetMachineEmitToFile( self, module.GetModuleRef(), filenameMarshaled, LLVMCodeGenFileType.LLVMObjectFile, out string error)) { throw new Exception(error); } } catch (System.AccessViolationException e) { Console.WriteLine("==================================="); module.Dump(); Console.WriteLine("==================================="); throw new Exception($"Failed to emit module '{module}' to file '{filename}': {e.Message}"); } catch (Exception e) { throw new Exception($"Failed to emit module '{module}' to file '{filename}': {e.Message}"); } }
/// <summary cref="DisposeBase.Dispose(bool)"/> protected override void Dispose(bool disposing) { if (LLVMTargetMachine.Pointer != IntPtr.Zero) { DisposeTargetMachine(LLVMTargetMachine); LLVMTargetMachine = default(LLVMTargetMachineRef); } }
private void makeObjectFile() { LLVM.InitializeX86TargetMC(); LLVM.InitializeX86Target(); LLVM.InitializeX86TargetInfo(); LLVM.InitializeX86AsmParser(); LLVM.InitializeX86AsmPrinter(); LLVMTargetRef target = LLVM.GetFirstTarget(); if (target.Pointer == IntPtr.Zero) { return; } string triple = getTargetTriple(); LLVMTargetMachineRef targetMachine = LLVM.CreateTargetMachine(target, triple, "generic", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault); #if EMIT_TO_FILE string message; unsafe { fixed(char *fileName = options.OutPath) { LLVM.TargetMachineEmitToFile(targetMachine, module, new IntPtr(fileName), LLVMCodeGenFileType.LLVMObjectFile, out message); LLVM.DisposeTargetMachine(targetMachine); } } if (!String.IsNullOrEmpty(message)) { log.globalError("Failed to emit object file. LLVM Error: {0}", message); } #else LLVM.TargetMachineEmitToMemoryBuffer(targetMachine, module, LLVMCodeGenFileType.LLVMObjectFile, out var _, out var memoryBuffer); size_t bufferSize = LLVM.GetBufferSize(memoryBuffer); IntPtr bufferStart = LLVM.GetBufferStart(memoryBuffer); unsafe { Stream s = new UnmanagedMemoryStream((byte *)bufferStart.ToPointer(), bufferSize); FileInfo file = new FileInfo(options.OutPath); if (file.Exists) { file.Delete(); } using (FileStream fs = file.Open(FileMode.Create, FileAccess.Write)) using (DisposableBuffer unused = new DisposableBuffer(memoryBuffer)) { s.CopyTo(fs); } } #endif }
private LLVMTargetDataRef TargetDataFromTriple(string triple) { LLVMTargetRef target = LLVMTargetRef.GetTargetFromTriple(triple); LLVMTargetMachineRef targetMachine = target.CreateTargetMachine(triple, "", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault); return(targetMachine.CreateTargetDataLayout()); }
// Create a new module with the given name. // The passed target triple can be used for cross compilation. // If it is null, the current platform will be used. public Module(string name, string targetTriple, bool useOptimizations) { // Create the module and the builder. this.Mod = LLVM.ModuleCreateWithName(name); this.Builder = LLVM.CreateBuilder(); // Get the default target triple if necessary: if (targetTriple == null) { targetTriple = Marshal.PtrToStringAnsi(LLVM.GetDefaultTargetTriple()); } // Select the target based on the triple. if (LLVM.GetTargetFromTriple(targetTriple, out var target, out var error)) { throw new ArgumentException($"Failed to obtain target from triple '{ targetTriple }': { error }"); } LLVM.SetTarget(this.Mod, targetTriple); // Create a target machine. this._targetMachine = LLVM.CreateTargetMachine(target, targetTriple, "generic", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocPIC, LLVMCodeModel.LLVMCodeModelDefault); // Create a data layout from the machine and assign it to the module. var dataLayout = LLVM.CreateTargetDataLayout(this._targetMachine); LLVM.SetModuleDataLayout(this.Mod, dataLayout); // Create the function pass manager for optimized runs. if (useOptimizations) { var funcPassManager = LLVM.CreateFunctionPassManagerForModule(this.Mod); // Add some nice optimization passes. LLVM.AddBasicAliasAnalysisPass(funcPassManager); LLVM.AddPromoteMemoryToRegisterPass(funcPassManager); LLVM.AddInstructionCombiningPass(funcPassManager); LLVM.AddReassociatePass(funcPassManager); LLVM.AddGVNPass(funcPassManager); LLVM.AddCFGSimplificationPass(funcPassManager); // TODO: Add more! // Initialize the manager and its passes and store it. LLVM.InitializeFunctionPassManager(funcPassManager); this._funcPassManager = funcPassManager; } else { this._funcPassManager = null; } }
/// <summary>Creates a <see cref="TargetMachine"/> for the target and specified parameters</summary> /// <param name="triple">Target triple for this machine (e.g. -mtriple)</param> /// <param name="cpu">CPU for this machine (e.g. -mcpu)</param> /// <param name="features">Features for this machine (e.g. -mattr...)</param> /// <param name="optLevel">Optimization level</param> /// <param name="relocationMode">Relocation mode for generated code</param> /// <param name="codeModel"><see cref="CodeModel"/> to use for generated code</param> /// <returns><see cref="TargetMachine"/> based on the specified parameters</returns> public TargetMachine CreateTargetMachine(string triple , string cpu = null , string features = null , CodeGenOpt optLevel = CodeGenOpt.Default , RelocationMode relocationMode = RelocationMode.Default , CodeModel codeModel = CodeModel.Default ) { LLVMTargetMachineRef targetMachineHandle = InternalCreateTargetMachine(this, triple, cpu, features, optLevel, relocationMode, codeModel); return(new TargetMachine(targetMachineHandle)); }
public void CompileModule(string file) { string error; LLVMTargetRef tref; LLVM.GetTargetFromTriple(TargetPlatform, out tref, out error); LLVMTargetMachineRef machineRef = LLVM.CreateTargetMachine(tref, TargetPlatform, "generic", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault); LLVM.TargetMachineEmitToFile(machineRef, Module, Marshal.StringToHGlobalAnsi(file), LLVMCodeGenFileType.LLVMObjectFile, out error); LLVM.DisposeTargetMachine(machineRef); }
private CudaModule( ClrAssembly sourceAssembly, ModuleBuilder intermediateModule, LLVMTargetMachineRef targetMachine, CUmodule compiledModule, string entryPointName, CudaContext context) { this.SourceAssembly = sourceAssembly; this.IntermediateModule = intermediateModule; this.TargetMachine = targetMachine; this.TargetData = LLVM.CreateTargetDataLayout(TargetMachine); this.CompiledModule = compiledModule; this.EntryPointName = entryPointName; this.Context = context; }
private static byte[] CompileToPtx( LLVMModuleRef module, Version computeCapability, out LLVMTargetMachineRef machine) { string triple = "nvptx64-nvidia-cuda"; LLVMTargetRef target; string error; if (LLVM.GetTargetFromTriple( triple, out target, out error)) { throw new Exception(error); } machine = LLVM.CreateTargetMachine( target, triple, $"sm_{computeCapability.Major}{computeCapability.Minor}", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault); LLVMMemoryBufferRef asmBuf; if (LLVM.TargetMachineEmitToMemoryBuffer(machine, module, LLVMCodeGenFileType.LLVMAssemblyFile, out error, out asmBuf)) { throw new Exception(error); } var asmLength = (int)LLVM.GetBufferSize(asmBuf); var asmBytes = new byte[asmLength]; Marshal.Copy(LLVM.GetBufferStart(asmBuf), asmBytes, 0, asmLength); LLVM.DisposeMemoryBuffer(asmBuf); return(asmBytes); }
private static LLVMModuleRef CreateModule(LLVMContextRef context, LLVMTargetMachineRef machine, int magicNumber) { var module = LLVMModuleCreateWithNameInContext("test", context); var layout = LLVMCreateTargetDataLayout(machine); LLVMSetModuleDataLayout(module, layout); LLVMTypeRef int32T = LLVMInt32TypeInContext(context); LLVMTypeRef signature = LLVMFunctionType(int32T, null, 0, false); LLVMValueRef main = LLVMAddFunction(module, "main", signature); LLVMBasicBlockRef entryBlock = LLVMAppendBasicBlock(main, "entry"); LLVMBuilderRef builder = LLVMCreateBuilder( ); LLVMPositionBuilderAtEnd(builder, entryBlock); LLVMValueRef constNum = LLVMConstInt(int32T, ( ulong )magicNumber, true); LLVMBuildRet(builder, constNum); Debug.WriteLine(LLVMPrintModuleToString(module)); return(module); }
public void Compile() { string triple = "x86_64-pc-linux-gnu"; LLVM.InitializeX86TargetInfo(); LLVM.InitializeX86Target(); LLVM.InitializeX86TargetMC(); LLVM.InitializeX86AsmParser(); LLVM.InitializeX86AsmPrinter(); LLVM.SetTarget(ModuleRef, triple); var fnPassManager = LLVM.CreateFunctionPassManagerForModule(ModuleRef); var modulePassManager = LLVM.CreatePassManager(); LLVM.InitializeFunctionPassManager(fnPassManager); // Optimizations LLVM.AddPromoteMemoryToRegisterPass(fnPassManager); LLVM.AddInstructionCombiningPass(fnPassManager); LLVM.AddJumpThreadingPass(fnPassManager); LLVM.AddEarlyCSEPass(fnPassManager); LLVM.AddConstantPropagationPass(fnPassManager); LLVM.AddCFGSimplificationPass(fnPassManager); LLVM.AddReassociatePass(fnPassManager); LLVM.AddLoopUnrollPass(fnPassManager); LLVM.AddLoopRerollPass(fnPassManager); LLVM.AddLoopDeletionPass(fnPassManager); LLVM.AddLoopRotatePass(fnPassManager); LLVM.AddLoopIdiomPass(fnPassManager); LLVM.AddLoopUnswitchPass(fnPassManager); LLVM.AddDeadStoreEliminationPass(fnPassManager); LLVM.AddBasicAliasAnalysisPass(fnPassManager); LLVM.AddIndVarSimplifyPass(fnPassManager); LLVM.AddSCCPPass(fnPassManager); LLVM.AddLICMPass(fnPassManager); LLVM.AddCorrelatedValuePropagationPass(fnPassManager); LLVM.AddScopedNoAliasAAPass(modulePassManager); LLVM.AddDeadArgEliminationPass(modulePassManager); LLVM.AddTailCallEliminationPass(modulePassManager); LLVM.AddLoopUnswitchPass(modulePassManager); LLVM.AddIPSCCPPass(modulePassManager); LLVM.AddReassociatePass(modulePassManager); LLVM.AddAlwaysInlinerPass(modulePassManager); // O2 LLVM.AddNewGVNPass(fnPassManager); LLVM.AddLowerExpectIntrinsicPass(fnPassManager); LLVM.AddScalarReplAggregatesPassSSA(fnPassManager); LLVM.AddMergedLoadStoreMotionPass(fnPassManager); LLVM.AddSLPVectorizePass(fnPassManager); LLVM.AddConstantMergePass(modulePassManager); LLVM.AddConstantMergePass(modulePassManager); LLVM.AddFunctionInliningPass(modulePassManager); void RecurseTypes(Collection <TypeDefinition> collection, Action <TypeDefinition> callback) { foreach (TypeDefinition typeDef in collection) { callback(typeDef); RecurseTypes(typeDef.NestedTypes, callback); } } // First, declare all types and only define the types in a later pass. // The reason is that we may have cycles of types. var typeList = new List <TypeDefinition>(); foreach (ModuleDefinition moduleDef in assemblyDefinition.Modules) { RecurseTypes(moduleDef.Types, typeDef => { typeList.Add(typeDef); TypeLookup.DeclareType(typeDef); }); } // Now, we have all types, so we can declare the methods. // Again, we may have cycles so the methods are declared and defined in separate passes. // Also define the types now. var methodCompilerLookup = new Dictionary <MethodDefinition, MethodCompiler>(); foreach (var typeDef in typeList) { TypeLookup.DefineType(typeDef); StaticFieldLookup.DeclareFieldsFor(typeDef); foreach (MethodDefinition methodDef in typeDef.Methods) { methodCompilerLookup.Add(methodDef, new MethodCompiler(this, methodDef)); } } // Compile the methods. Action <TypeDefinition> methodCompilationFn = typeDef => { foreach (MethodDefinition methodDef in typeDef.Methods) { var methodCompiler = methodCompilerLookup[methodDef]; methodCompiler.Compile(); if (!LLVM.VerifyFunction(methodCompiler.FunctionValueRef, LLVMVerifierFailureAction.LLVMPrintMessageAction)) { LLVM.RunFunctionPassManager(fnPassManager, methodCompiler.FunctionValueRef); } } }; if (LLVM.StartMultithreaded()) { Parallel.ForEach(typeList, methodCompilationFn); } else { typeList.ForEach(methodCompilationFn); } // Free memory already. MethodLookup.Finish(); methodCompilerLookup.Clear(); Console.WriteLine("-------------------"); if (LLVM.VerifyModule(ModuleRef, LLVMVerifierFailureAction.LLVMPrintMessageAction, out var outMsg)) { Console.WriteLine(outMsg); } LLVM.RunPassManager(modulePassManager, ModuleRef); // Cleanup LLVM.DisposePassManager(modulePassManager); LLVM.DumpModule(ModuleRef); // XXX string errorMsg; LLVMTargetRef targetRef; if (LLVM.GetTargetFromTriple(triple, out targetRef, out errorMsg)) { Console.WriteLine(errorMsg); } LLVMTargetMachineRef machineRef = LLVM.CreateTargetMachine(targetRef, triple, "generic", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault); System.IO.File.Delete("test.s"); if (LLVM.TargetMachineEmitToFile(machineRef, ModuleRef, Marshal.StringToHGlobalAnsi("test.s"), LLVMCodeGenFileType.LLVMAssemblyFile, out errorMsg)) { Console.WriteLine(errorMsg); } Console.WriteLine("written"); LLVM.DisposeTargetMachine(machineRef); }
private static void AddAndExecuteTestModule(LLVMOrcJITStackRef orcJit, LLVMContextRef context, LLVMTargetMachineRef machine, int expectedResult) { LLVMModuleRef module = CreateModule(context, machine, expectedResult); LLVMErrorRef err = LLVMOrcAddEagerlyCompiledIR(orcJit, out ulong jitHandle, module, SymbolResolver, IntPtr.Zero); Assert.IsTrue(err.IsInvalid); // ORC now owns the module, so it must never be released module.SetHandleAsInvalid(); LLVMOrcGetMangledSymbol(orcJit, out string mangledName, "main"); err = LibLLVMOrcGetSymbolAddress(orcJit, out ulong funcAddress, mangledName, false); Assert.IsTrue(err.IsInvalid); Assert.AreNotEqual(0ul, funcAddress); var callableMain = Marshal.GetDelegateForFunctionPointer <TestMain>(( IntPtr )funcAddress); Assert.AreEqual(expectedResult, callableMain( )); LLVMOrcRemoveModule(orcJit, jitHandle); }
public static void Dispose(this LLVMTargetMachineRef self) { LLVM.DisposeTargetMachine(self); }
public static extern int GetTargetMachineData(LLVMTargetMachineRef* T);
public static extern System.IntPtr GetTargetMachineCPU(LLVMTargetMachineRef* T);
public static extern void DisposeTargetMachine(LLVMTargetMachineRef* T);
private static extern LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef @TM);
public static extern LLVMTargetRef* GetTargetMachineTarget(LLVMTargetMachineRef* T);
internal TargetMachine(LLVMTargetMachineRef targetMachine) => _targetMachine = targetMachine;
public static extern System.IntPtr GetTargetMachineFeatureString(LLVMTargetMachineRef* T);
internal TargetMachine(Context context, LLVMTargetMachineRef targetMachineHandle) { TargetMachineHandle = targetMachineHandle; Context = context; }
public static extern int TargetMachineEmitToFile(LLVMTargetMachineRef* T, LLVMModuleRef* M, [In][MarshalAs(UnmanagedType.LPStr)] string Filename, LLVMCodeGenFileType codegen, [MarshalAs(UnmanagedType.LPStr)] ref StringBuilder ErrorMessage);
internal TargetMachine(LLVMTargetMachineRef targetMachineHandle) { targetMachineHandle.ValidateNotDefault(nameof(targetMachineHandle)); TargetMachineHandle = targetMachineHandle; }