public void AddMemCpyOptPass() => LLVM.AddMemCpyOptPass(this.Unwrap());
/// <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); }