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(); }
public override void VisitMethodDeclaration(MethodDeclarationSyntax node) { var parameters = node.ParameterList.Parameters; var paramCount = (uint)parameters.Count; LLVMTypeRef[] paramTypesArr = new LLVMTypeRef[Math.Max(paramCount, 1)]; // always need 1 for deref { uint index = 0; foreach (var parameter in parameters) { paramTypesArr[index] = this.semanticModel.GetTypeInfo(parameter.Type).LLVMTypeRef(); } } var returnType = this.semanticModel.GetTypeInfo(node.ReturnType).LLVMTypeRef(); var functionType = LLVM.FunctionType(returnType, out paramTypesArr[0], paramCount, False); this.function = LLVM.AddFunction(this.module, node.Identifier.Text, functionType); this.symbolTable.Add(node, this.function); // add to symbol table var body = node.Body; // extern methods if (body == null) { return; } LLVM.PositionBuilderAtEnd(this.builder, LLVM.AppendBasicBlock(this.function, "entry")); { uint index = 0; foreach (var parameter in parameters) { var llvmParam = LLVM.GetParam(this.function, index); var alloca = LLVM.BuildAlloca(this.builder, paramTypesArr[index], parameter.Identifier.Text); LLVM.BuildStore(this.builder, llvmParam, alloca); this.symbolTable.Add(parameter, llvmParam); // TODO: this.MarkGCRoot(llvmParam, tuple.Item2); } } var localVariableVisitor = new VariableDeclarationVisitor(this.semanticModel, this.builder); localVariableVisitor.Visit(node); var variables = localVariableVisitor.Variables; foreach (var entry in variables) { this.symbolTable.Add(entry.Key, entry.Value); // TODO: this.MarkGCRoot(entry.Value, this.semanticModel.GetTypeInfo(parent.Type)); } this.Visit(body); if (this.semanticModel.GetTypeInfo(node.ReturnType).Type.SpecialType == SpecialType.System_Void) { LLVM.BuildRetVoid(this.builder); } else { LLVM.BuildRet(this.builder, LLVM.ConstNull(returnType)); } }