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); }
public void AddBasicAliasAnalysisPass() => LLVM.AddBasicAliasAnalysisPass(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); }
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); }