Esempio n. 1
0
        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());
        }
Esempio n. 3
0
        private void Optimize()
        {
            var passManager = LLVM.CreatePassManager();

            LLVM.AddBasicAliasAnalysisPass(passManager);
            LLVM.AddInstructionCombiningPass(passManager);
            LLVM.AddGVNPass(passManager);
            LLVM.AddReassociatePass(passManager);

            LLVM.RunPassManager(passManager, _module);
        }
Esempio n. 4
0
    // 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;
        }
    }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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();
        }
Esempio n. 7
0
 public void AddInstructionCombiningPass() => LLVM.AddInstructionCombiningPass(this.Unwrap());
Esempio n. 8
0
        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();
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        /// <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);
        }
Esempio n. 11
0
        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);
        }
Esempio n. 12
0
        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);
        }
Esempio n. 13
0
        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);
        }