public LLVMModuleRef Generate(SyntaxTree tree) { m_VariablePointers = new Dictionary <VariableSymbol, LLVMValueRef>(); m_FunctionPointers = new Dictionary <FunctionSymbol, LLVMValueRef>(); m_Types = new Dictionary <TypeSymbol, LLVMTypeRef>(); m_BreakableStatementSuccessor = new Dictionary <Statement, LLVMBasicBlockRef>(); m_Module = LLVM.ModuleCreateWithName("test"); m_Builder = LLVM.CreateBuilder(); m_Tree = tree; LoadTypes(m_Tree.GlobalSymbols); foreach (var stmt in m_Tree.Root) { VisitStmt(stmt); } LLVM.DisposeBuilder(m_Builder); LLVMPassManagerRef pm = LLVM.CreatePassManager(); LLVM.AddPromoteMemoryToRegisterPass(pm); LLVM.AddInstructionCombiningPass(pm); LLVM.AddReassociatePass(pm); LLVM.AddGVNPass(pm); LLVM.AddCFGSimplificationPass(pm); LLVM.RunPassManager(pm, m_Module); return(m_Module); }
public override CompilerResult VisitProgram(DesignScriptParser.ProgramContext context) { var success = new LLVMBool(0); module = LLVM.ModuleCreateWithName("DesignScript"); builder = LLVM.CreateBuilder(); LLVM.LinkInMCJIT(); LLVM.InitializeX86TargetInfo(); LLVM.InitializeX86Target(); LLVM.InitializeX86TargetMC(); LLVM.InitializeX86AsmParser(); LLVM.InitializeX86AsmPrinter(); LLVMMCJITCompilerOptions options = new LLVMMCJITCompilerOptions { NoFramePointerElim = 1 }; LLVM.InitializeMCJITCompilerOptions(options); if (LLVM.CreateExecutionEngineForModule(out engine, module, out var errorMessage).Value == 1) { Console.WriteLine(errorMessage); return(new NullCompilerResult()); } #region Add optimization passes // Create a function pass manager for this engine passManager = LLVM.CreateFunctionPassManagerForModule(module); // Do simple "peephole" optimizations and bit-twiddling optzns. LLVM.AddInstructionCombiningPass(passManager); // Reassociate expressions. LLVM.AddReassociatePass(passManager); // Eliminate Common SubExpressions. LLVM.AddGVNPass(passManager); // Simplify the control flow graph (deleting unreachable blocks, etc). LLVM.AddCFGSimplificationPass(passManager); LLVM.InitializeFunctionPassManager(passManager); #endregion base.VisitProgram(context); if (LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error) != success) { Console.WriteLine($"Error: {error}"); } LLVM.DumpModule(module); LLVM.DisposeBuilder(builder); LLVM.DisposeExecutionEngine(engine); return(new NullCompilerResult()); }
private void Optimize() { var passManager = LLVM.CreatePassManager(); LLVM.AddBasicAliasAnalysisPass(passManager); LLVM.AddInstructionCombiningPass(passManager); LLVM.AddGVNPass(passManager); LLVM.AddReassociatePass(passManager); LLVM.RunPassManager(passManager, _module); }
// 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; } }
public override CompilerResult VisitFile([NotNull] LangParser.FileContext context) { module = LLVM.ModuleCreateWithName("Lang"); contexts = new Stack <Context>(); LLVMPassManagerRef passManager = LLVM.CreateFunctionPassManagerForModule(module); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. // LLVM.DisposeTargetData(LLVM.GetExecutionEngineTargetData(engine)); // Provide basic AliasAnalysis support for GVN. LLVM.AddBasicAliasAnalysisPass(passManager); // Promote allocas to registers. LLVM.AddPromoteMemoryToRegisterPass(passManager); // Do simple "peephole" optimizations and bit-twiddling optzns. LLVM.AddInstructionCombiningPass(passManager); // Reassociate expressions. LLVM.AddReassociatePass(passManager); // Eliminate Common SubExpressions. LLVM.AddGVNPass(passManager); // Simplify the control flow graph (deleting unreachable blocks, etc). LLVM.AddCFGSimplificationPass(passManager); LLVM.InitializeFunctionPassManager(passManager); this.passManager = passManager; base.VisitFile(context); LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out string str); LLVM.DumpModule(module); LLVM.WriteBitcodeToFile(module, @"C:\Users\superblaubeere27\Desktop\compilerTest\Compiler\Compiler\code\compiled.bc"); LLVM.DisposePassManager(passManager); LLVM.DisposeModule(module); return(NullCompilerResult.INSTANCE); }
static void Main(string[] args) { string filename = @"test.ni"; string outname = Path.GetFileNameWithoutExtension(filename) + ".bc"; if (args.Length == 1) { filename = args[0]; } module = LLVM.ModuleCreateWithName(Path.GetFileNameWithoutExtension(filename)); builder = LLVM.CreateBuilder(); var FPM = LLVM.CreateFunctionPassManagerForModule(module); LLVM.AddPromoteMemoryToRegisterPass(FPM); LLVM.AddInstructionCombiningPass(FPM); LLVM.AddReassociatePass(FPM); LLVM.AddNewGVNPass(FPM); LLVM.AddCFGSimplificationPass(FPM); LLVM.FinalizeFunctionPassManager(FPM); string file = File.ReadAllText(filename); var lexer = new Lexer(file); var parser = new Parser(lexer, new Visitor(module, builder, FPM)); var token = lexer.NextToken(); LLVM.DumpModule(module); while (lexer.CurrentToken.type != TokenType.EOF) { parser.ParsePrimary(); Console.WriteLine("\n##################################################################################################################\n"); LLVM.DumpModule(module); } string error = ""; Console.WriteLine("\n##################################################################################################################\n"); LLVM.DumpModule(module); LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out error); LLVM.WriteBitcodeToFile(module, outname); var clang = Process.Start("clang++", "test.bc -o test.exe"); clang.WaitForExit(); Console.Read(); }
public void AddInstructionCombiningPass() => LLVM.AddInstructionCombiningPass(this.Unwrap());
private static void Main(string[] args) { Stopwatch sw = new Stopwatch(); sw.Start(); // Make the module, which holds all the code. LLVMModuleRef module = LLVM.ModuleCreateWithName("my cool jit"); LLVMBuilderRef builder = LLVM.CreateBuilder(); LLVM.LinkInMCJIT(); LLVM.InitializeX86TargetInfo(); LLVM.InitializeX86Target(); LLVM.InitializeX86TargetMC(); LLVM.InitializeX86AsmPrinter(); LLVMExecutionEngineRef engine; IntPtr errorMessage; if (LLVM.CreateExecutionEngineForModule(out engine, module, out errorMessage).Value == 1) { Console.WriteLine(Marshal.PtrToStringAnsi(errorMessage)); LLVM.DisposeMessage(errorMessage); return; } var platform = System.Environment.OSVersion.Platform; if (platform == PlatformID.Win32NT) // On Windows, LLVM currently (3.6) does not support PE/COFF { //LLVM.SetTarget(module, string.Concat(Marshal.PtrToStringAnsi(LLVM.GetDefaultTargetTriple()), "-elf")); } var options = new LLVMMCJITCompilerOptions(); var optionsSize = (4 * sizeof(int)) + IntPtr.Size; // LLVMMCJITCompilerOptions has 4 ints and a pointer LLVM.InitializeMCJITCompilerOptions(out options, optionsSize); IntPtr error; LLVM.CreateMCJITCompilerForModule(out engine, module, out options, optionsSize, out error); // Create a function pass manager for this engine LLVMPassManagerRef passManager = LLVM.CreateFunctionPassManagerForModule(module); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. LLVM.AddTargetData(LLVM.GetExecutionEngineTargetData(engine), passManager); LLVMLinkInGC(); sw.Stop(); Console.WriteLine("LLVM Init: " + sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); var tree = CSharpSyntaxTree.ParseText(@" class C { static double F() { float a = 10.0F; int b = (int)a; int c = 10 + b; return (float)c; } }"); var tree2 = CSharpSyntaxTree.ParseText(@" using System; using System.Collections; public enum MiniSharpSimpleType : ushort { Integral, FloatingPoint, Pointer } public class Program2 { public static int Prop { get; set; } } class C { public int Prop {get; set;} int Fjj(int x) { foobar: int aaaw2a = 10; int sdjkdjs = 10; ushort s = 5; switch (s) { case 1: break; case 2: goto case 1; } int aaaa = 10; switch(aaaa) { case 0: goto case 1; case 1: goto default; default: int ssss = 1; break; } if (x >= 0) goto x; x = -x; x: return x; } public object xfoo() { int[] h = new int[10]; ++h[0]; ++Program2.Prop; var c = new C(); ++c.Prop; uint q = 10; var ffffff = -q; float jf = -10.0; int jff = (int)-10.0; var ddddd = !true; int z = +10; int l = ~10; int ff = -10; var k = -10.0F; Hashtable h = new Hashtable(); h[1] = 2; int[] arr = new int[10]; arr[1] = 10; object x = default(int); return new {a = 10}; } static short bar() { return 2; } static short foo(Type t) { var a = 10; return a; } static int Main() { var d = bar() + bar(); foo(typeof(string)); object x = null; object aa = x ?? 0; var ac = 10 as object; short a = 10; short b = 10; var c = a + b; return 0; } } "); sw.Stop(); Console.WriteLine("CSharp Parse Time: " + sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); var sm = tree.GetRoot(); var s = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); var s2 = MetadataReference.CreateFromFile(typeof(Hashtable).Assembly.Location); var compilation = CSharpCompilation.Create("MyCompilation", new[] { tree }, new[] { s }); var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false); sw.Stop(); Console.WriteLine("Semantic Analysis: " + sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); var d = model.Compilation.GetDiagnostics(); var symbolVisitor = new VariableDeclarationVisitor(model, builder); symbolVisitor.Visit(sm); for (int i = 0; i < 100000; ++i) { var stack = new Stack <LLVMValueRef>(); var v = new LLVMIRGenerationVisitor(model, module, builder, stack); v.Visit(sm); LLVM.GetPointerToGlobal(engine, v.Function); } /* * var stack = new Stack<LLVMValueRef>(); * var v = new LLVMIRGenerationVisitor(model, module, builder, stack); * * LLVMTypeRef[] gcrootArgs = new LLVMTypeRef[2]; * gcrootArgs[0] = LLVM.PointerType(LLVM.PointerType(LLVM.Int8Type(), 0), 0); * gcrootArgs[1] = LLVM.PointerType(LLVM.Int8Type(), 0); * * * var gcRootFuncType = LLVM.FunctionType(LLVM.VoidType(), out gcrootArgs[0], 2, new LLVMBool(0)); * * var ff = LLVM.AddFunction(module, "llvm.gcroot", gcRootFuncType); * var argsxx = new LLVMValueRef[2]; * argsxx[0] = LLVM.BuildBitCast(builder, LLVM.ConstNull(LLVM.PointerType(LLVM.Int8Type(), 0)), LLVM.PointerType(LLVM.PointerType(LLVM.Int8Type(), 0), 0), "gc"); * argsxx[1] = LLVM.ConstNull(LLVM.PointerType(LLVM.Int8Type(), 0)); * LLVM.BuildCall(builder, ff, out argsxx[0], 2, ""); */ //var v = new Visitor(model); sw.Stop(); Console.WriteLine("IR Generation: " + sw.ElapsedMilliseconds); sw.Reset(); sw.Start(); // LLVM.SetGC(v.Function, "shadow-stack"); LLVM.DumpModule(module); // LLVM.VerifyFunction(v.Function, LLVMVerifierFailureAction.LLVMAbortProcessAction); //int ddd = f(); LLVM.AddCFGSimplificationPass(passManager); LLVM.AddInstructionCombiningPass(passManager); LLVM.AddBasicAliasAnalysisPass(passManager); LLVM.AddGVNPass(passManager); LLVM.AddPromoteMemoryToRegisterPass(passManager); //LLVM.RunFunctionPassManager(passManager, v.Function); LLVM.DumpModule(module); LLVM.WriteBitcodeToFile(module, @"C:\users\mukul\desktop\h.bc"); sw.Stop(); Console.WriteLine("Dumping + Bitcode Write: " + sw.ElapsedMilliseconds); Console.ReadKey(); // var addMethod = (Add)Marshal.GetDelegateForFunctionPointer(LLVM.GetPointerToGlobal(engine, v.Function), typeof(Add)); // var x = addMethod(); }
private static void Main(string[] args) { // Make the module, which holds all the code. LLVMModuleRef module = LLVM.ModuleCreateWithName("my cool jit"); LLVMBuilderRef builder = LLVM.CreateBuilder(); LLVM.LinkInJIT(); LLVM.InitializeX86TargetInfo(); LLVM.InitializeX86Target(); LLVM.InitializeX86TargetMC(); LLVMExecutionEngineRef engine; IntPtr errorMessage; if (LLVM.CreateExecutionEngineForModule(out engine, module, out errorMessage).Value == 1) { Console.WriteLine(Marshal.PtrToStringAnsi(errorMessage)); LLVM.DisposeMessage(errorMessage); return; } // Create a function pass manager for this engine LLVMPassManagerRef passManager = LLVM.CreateFunctionPassManagerForModule(module); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. LLVM.AddTargetData(LLVM.GetExecutionEngineTargetData(engine), passManager); // Provide basic AliasAnalysis support for GVN. LLVM.AddBasicAliasAnalysisPass(passManager); // Promote allocas to registers. LLVM.AddPromoteMemoryToRegisterPass(passManager); // Do simple "peephole" optimizations and bit-twiddling optzns. LLVM.AddInstructionCombiningPass(passManager); // Reassociate expressions. LLVM.AddReassociatePass(passManager); // Eliminate Common SubExpressions. LLVM.AddGVNPass(passManager); // Simplify the control flow graph (deleting unreachable blocks, etc). LLVM.AddCFGSimplificationPass(passManager); LLVM.InitializeFunctionPassManager(passManager); var codeGenlistener = new CodeGenParserListener(engine, passManager, new CodeGenVisitor(module, builder)); // Install standard binary operators. // 1 is lowest precedence. var binopPrecedence = new Dictionary <char, int>(); binopPrecedence['<'] = 10; binopPrecedence['+'] = 20; binopPrecedence['-'] = 20; binopPrecedence['*'] = 40; // highest. var scanner = new Lexer(Console.In, binopPrecedence); var parser = new Parser(scanner, codeGenlistener); // Prime the first token. Console.Write("ready> "); scanner.GetNextToken(); // Run the main "interpreter loop" now. MainLoop(scanner, parser); // Print out all of the generated code. LLVM.DumpModule(module); }
/// <summary> /// Compiles an IL assembly to LLVM bytecode. /// </summary> /// <param name="moduleName">The module name.</param> public void Compile(string moduleName) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // Create LLVM module and its context. LLVM.EnablePrettyStackTrace(); mModule = LLVM.ModuleCreateWithName(moduleName); mContext = LLVM.GetModuleContext(mModule); // Targets. LLVM.InitializeAllTargetInfos(); LLVM.InitializeAllTargets(); LLVM.InitializeAllTargetMCs(); LLVM.InitializeAllAsmParsers(); LLVM.InitializeAllAsmPrinters(); string triplet = (Options.Target == "default") ? LLVM.GetDefaultTargetTriple() : Options.Target; MyString error = new MyString(); LLVM.SetTarget(mModule, triplet); TargetRef target; if (LLVM.GetTargetFromTriple(triplet, out target, error)) { throw new InvalidOperationException(error.ToString()); } // Optimizer. mFunctionPassManager = LLVM.CreateFunctionPassManagerForModule(mModule); mPassManager = LLVM.CreatePassManager(); LLVM.InitializeFunctionPassManager(mFunctionPassManager); #if !DEBUG // O0 if (Options.Optimization >= OptimizationLevel.O0) { // Function passes. LLVM.AddPromoteMemoryToRegisterPass(mFunctionPassManager); LLVM.AddConstantPropagationPass(mFunctionPassManager); LLVM.AddReassociatePass(mFunctionPassManager); LLVM.AddInstructionCombiningPass(mFunctionPassManager); // Module passes. LLVM.AddAlwaysInlinerPass(mPassManager); LLVM.AddStripDeadPrototypesPass(mPassManager); LLVM.AddStripSymbolsPass(mPassManager); } // O1 if (Options.Optimization >= OptimizationLevel.O1) { // Function passes. LLVM.AddLowerExpectIntrinsicPass(mFunctionPassManager); LLVM.AddEarlyCSEPass(mFunctionPassManager); LLVM.AddLoopRotatePass(mFunctionPassManager); LLVM.AddLoopUnswitchPass(mFunctionPassManager); LLVM.AddLoopUnrollPass(mFunctionPassManager); LLVM.AddLoopDeletionPass(mFunctionPassManager); LLVM.AddTailCallEliminationPass(mFunctionPassManager); LLVM.AddGVNPass(mFunctionPassManager); LLVM.AddDeadStoreEliminationPass(mFunctionPassManager); LLVM.AddJumpThreadingPass(mFunctionPassManager); LLVM.AddCFGSimplificationPass(mFunctionPassManager); LLVM.AddMemCpyOptPass(mFunctionPassManager); // Module passes. LLVM.AddDeadArgEliminationPass(mPassManager); LLVM.AddAggressiveDCEPass(mFunctionPassManager); } // O2 if (Options.Optimization >= OptimizationLevel.O2) { // Function passes. LLVM.AddLoopVectorizePass(mFunctionPassManager); LLVM.AddSLPVectorizePass(mFunctionPassManager); // Module passes. LLVM.AddFunctionInliningPass(mPassManager); LLVM.AddConstantMergePass(mPassManager); LLVM.AddArgumentPromotionPass(mPassManager); } #endif // Initialize types and runtime. string dataLayout = LLVM.GetDataLayout(Module); TargetData = LLVM.CreateTargetData(dataLayout); TypeHelper.Init(TargetData, this); RuntimeHelper.ImportFunctions(Module); mBuiltinCompiler.Compile(); compileModules(); LLVM.RunPassManager(mPassManager, Module); // Log time. stopWatch.Stop(); Logger.LogDetail("Compilation time: " + stopWatch.Elapsed); // Debug: print LLVM assembly code. #if DEBUG Console.WriteLine(LLVM.PrintModuleToString(mModule)); #endif // Verify and throw exception on error. Console.ForegroundColor = ConsoleColor.DarkGray; if (LLVM.VerifyModule(mModule, VerifierFailureAction.ReturnStatusAction, error)) { Logger.LogError("Compilation of module failed."); Logger.LogInfo(error.ToString()); LLVM.DisposeTargetData(TargetData); return; } else { Logger.LogDetail("Compilation of module succeeded."); } // Output assembly or object file. if (!Options.OutputLLVMIR && !Options.OutputLLVMBitCode) { TargetMachineRef machine = LLVM.CreateTargetMachine(target, triplet, "generic", "", CodeGenOptLevel.CodeGenLevelDefault, RelocMode.RelocDefault, CodeModel.CodeModelDefault); LLVM.SetModuleDataLayout(mModule, LLVM.CreateTargetDataLayout(machine)); CodeGenFileType type = (Options.OutputAssembly) ? CodeGenFileType.AssemblyFile : CodeGenFileType.ObjectFile; if (LLVM.TargetMachineEmitToFile(machine, mModule, Options.OutputFile, type, error)) { throw new InvalidOperationException(error.ToString()); } } // Output LLVM IR code to a file. else if (Options.OutputLLVMIR) { if (LLVM.PrintModuleToFile(mModule, Options.OutputFile, error)) { Logger.LogError("Writing the LLVM code to a file failed."); Logger.LogInfo(error.ToString()); } } // Output LLVM bitcode. else if (Options.OutputLLVMBitCode) { if (LLVM.WriteBitcodeToFile(mModule, Options.OutputFile) != 0) { Logger.LogError("Writing the LLVM code to a file failed."); Logger.LogInfo(error.ToString()); } } // Cleanup. LLVM.DisposeTargetData(TargetData); }
public void TestFact() { ModuleRef Module = LLVM.ModuleCreateWithName("fac_module"); TypeRef[] fac_args = { LLVM.Int32Type() }; ValueRef fac = LLVM.AddFunction(Module, "fac", LLVM.FunctionType(LLVM.Int32Type(), fac_args, false)); LLVM.SetFunctionCallConv(fac, (uint)Swigged.LLVM.CallConv.CCallConv); ValueRef n = LLVM.GetParam(fac, 0); BasicBlockRef entry = LLVM.AppendBasicBlock(fac, "entry"); BasicBlockRef iftrue = LLVM.AppendBasicBlock(fac, "iftrue"); BasicBlockRef iffalse = LLVM.AppendBasicBlock(fac, "iffalse"); BasicBlockRef end = LLVM.AppendBasicBlock(fac, "end"); BuilderRef builder = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder, entry); ValueRef If = LLVM.BuildICmp(builder, Swigged.LLVM.IntPredicate.IntEQ, n, LLVM.ConstInt(LLVM.Int32Type(), 0, false), "n == 0"); LLVM.BuildCondBr(builder, If, iftrue, iffalse); LLVM.PositionBuilderAtEnd(builder, iftrue); ValueRef res_iftrue = LLVM.ConstInt(LLVM.Int32Type(), 1, false); LLVM.BuildBr(builder, end); LLVM.PositionBuilderAtEnd(builder, iffalse); ValueRef n_minus = LLVM.BuildSub(builder, n, LLVM.ConstInt(LLVM.Int32Type(), 1, false), "n - 1"); ValueRef[] call_fac_args = { n_minus }; ValueRef call_fac = LLVM.BuildCall(builder, fac, call_fac_args, "fac(n - 1)"); ValueRef res_iffalse = LLVM.BuildMul(builder, n, call_fac, "n * fac(n - 1)"); LLVM.BuildBr(builder, end); LLVM.PositionBuilderAtEnd(builder, end); ValueRef res = LLVM.BuildPhi(builder, LLVM.Int32Type(), "result"); ValueRef[] phi_vals = { res_iftrue, res_iffalse }; BasicBlockRef[] phi_blocks = { iftrue, iffalse }; LLVM.AddIncoming(res, phi_vals, phi_blocks); LLVM.BuildRet(builder, res); MyString error = new MyString(); LLVM.VerifyModule(Module, VerifierFailureAction.PrintMessageAction, error); if (error.ToString() != "") { throw new Exception("Failed"); } ExecutionEngineRef engine; ModuleProviderRef provider = LLVM.CreateModuleProviderForExistingModule(Module); LLVM.CreateJITCompilerForModule(out engine, Module, 0, error); PassManagerRef pass = LLVM.CreatePassManager(); // LLVM.AddTargetData(LLVM.GetExecutionEngineTargetData(engine), pass); LLVM.AddConstantPropagationPass(pass); LLVM.AddInstructionCombiningPass(pass); LLVM.AddPromoteMemoryToRegisterPass(pass); // LLVMAddDemoteMemoryToRegisterPass(pass); // Demotes every possible value to memory LLVM.AddGVNPass(pass); LLVM.AddCFGSimplificationPass(pass); LLVM.RunPassManager(pass, Module); LLVM.DumpModule(Module); ulong input = 10; for (ulong i = 0; i < input; ++i) { GenericValueRef exec_args = LLVM.CreateGenericValueOfInt(LLVM.Int32Type(), input, false); GenericValueRef exec_res = LLVM.RunFunction(engine, fac, 1, out exec_args); var result_of_function = LLVM.GenericValueToInt(exec_res, false); var result_of_csharp_function = Factorial(input); if (result_of_csharp_function != result_of_function) { throw new Exception("Results not the same."); } } LLVM.DisposePassManager(pass); LLVM.DisposeBuilder(builder); LLVM.DisposeExecutionEngine(engine); }
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); }
public bool Compile(CompilerOptions pOptions, out LLVMModuleRef?pModule) { double totalTime = 0; var sw = new System.Diagnostics.Stopwatch(); sw.Start(); //Read source files pModule = null; string source = string.IsNullOrEmpty(pOptions.SourceFile) ? pOptions.Source : ReadSourceFile(pOptions.SourceFile); if (source == null) { return(false); } var lexer = new SmallerLexer(); var stream = lexer.StartTokenStream(source, pOptions.SourceFile); var parser = new SmallerParser(stream); //Create AST var tree = parser.Parse(); if (CompilerErrors.ErrorOccurred) { return(false); } totalTime += RecordPerfData(sw, "Parsed in: "); //Type inference, type checking, AST transformations var compilationModule = ModuleBuilder.Build(tree); if (compilationModule == null) { return(false); } totalTime += RecordPerfData(sw, "Type checked in: "); LLVMModuleRef module = LLVM.ModuleCreateWithName(tree.Name); LLVMPassManagerRef passManager = LLVM.CreateFunctionPassManagerForModule(module); if (pOptions.Optimizations) { LLVM.AddConstantPropagationPass(passManager); //Promote allocas to registers LLVM.AddPromoteMemoryToRegisterPass(passManager); //Do simple peephole optimizations LLVM.AddInstructionCombiningPass(passManager); //Re-associate expressions LLVM.AddReassociatePass(passManager); //Eliminate common subexpressions LLVM.AddGVNPass(passManager); //Simplify control flow graph LLVM.AddCFGSimplificationPass(passManager); } LLVM.InitializeFunctionPassManager(passManager); //Emitting LLVM bytecode using (var c = new EmittingContext(module, passManager, pOptions.Debug)) { compilationModule.Emit(c); if (LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message).Value != 0) { LLVM.DumpModule(module); LLVM.DisposePassManager(passManager); pModule = null; return(false); } } pModule = module; LLVM.DisposePassManager(passManager); totalTime += RecordPerfData(sw, "Emitted bytecode in: "); Console.WriteLine("Total time: " + totalTime + "s"); return(true); }