/// This routine adds optimization passes based on selected optimization level, /// OptLevel. /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, unsigned OptLevel, unsigned SizeLevel) { FPM.add(createVerifierPass()); // Verify that input is correct MPM.add(createDebugInfoVerifierPass()); // Verify that debug info is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; Builder.SizeLevel = SizeLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel); } else { Builder.Inliner = createAlwaysInlinerPass(); } Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; // This is final, unless there is a #pragma vectorize enable if (DisableLoopVectorization) Builder.LoopVectorize = false; // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) else if (!Builder.LoopVectorize) Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; // When #pragma vectorize is on for SLP, do the same as above Builder.SLPVectorize = DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); }
/// AddOptimizationPasses - This routine adds optimization passes /// based on selected optimization level, OptLevel. This routine /// duplicates llvm-gcc behaviour. /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, unsigned OptLevel, unsigned SizeLevel) { FPM.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; Builder.SizeLevel = SizeLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { unsigned Threshold = 225; if (SizeLevel == 1) // -Os Threshold = 75; else if (SizeLevel == 2) // -Oz Threshold = 25; if (OptLevel > 2) Threshold = 275; Builder.Inliner = createFunctionInliningPass(Threshold); } else { Builder.Inliner = createAlwaysInlinerPass(); } Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = OptLevel == 0; Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); }
bool LLVMOptimizeModule(LLVMModuleRef Mod) { Module* M = unwrap(Mod); // Create a PassManager to hold and optimize the collection of passes we are // about to build. PassManager Passes; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple())); // Add an appropriate DataLayout instance for this module. // const std::string &ModuleDataLayout = M->getDataLayout(); // if (!ModuleDataLayout.empty()) { // DataLayout *TD = NULL; // new DataLayout(ModuleDataLayout); // Passes.add(TD); // } Passes.add(createVerifierPass()); // Verify that input is correct // -std-compile-opts adds the same module passes as -O3. PassManagerBuilder Builder; Builder.Inliner = createFunctionInliningPass(); Builder.OptLevel = 3; Builder.populateModulePassManager(Passes); // Now that we have all of the passes ready, run them. bool change = Passes.run(*M); return change; }
void LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) { PassManagerBuilder *Builder = unwrap(PMB); legacy::PassManagerBase *MPM = unwrap(PM); Builder->populateModulePassManager(*MPM); }
Module * llvmutil_extractmodule(Module * OrigMod, TargetMachine * TM, std::vector<llvm::GlobalValue*> * livevalues, std::vector<std::string> * symbolnames, bool internalizeandoptimize) { assert(symbolnames == NULL || livevalues->size() == symbolnames->size()); ValueToValueMapTy VMap; #if LLVM_VERSION >= 34 Module * M = llvmutil_extractmodulewithproperties(OrigMod->getModuleIdentifier(), OrigMod, (llvm::GlobalValue **)&(*livevalues)[0], livevalues->size(), AlwaysCopy, NULL, VMap); #else Module * M = CloneModule(OrigMod, VMap); internalizeandoptimize = true; //we need to do this regardless of the input because it is the only way we can extract just the needed functions from the module #endif //rename values to symbolsnames std::vector<const char *> names; for(size_t i = 0; i < livevalues->size(); i++) { GlobalValue * fn = cast<GlobalValue>(VMap[(*livevalues)[i]]); const std::string & name = (*symbolnames)[i]; GlobalValue * gv = M->getNamedValue(name); if(gv) { //if there is already a symbol with this name, rename it gv->setName(Twine((*symbolnames)[i],"_renamed")); } fn->setName(name); //and set our function to this name assert(fn->getName() == name); names.push_back(name.c_str()); //internalize pass has weird interface, so we need to copy the names here } if (!internalizeandoptimize) return M; //at this point we run optimizations on the module //first internalize all functions not mentioned in "names" using an internalize pass and then perform //standard optimizations PassManager MPM; llvmutil_addtargetspecificpasses(&MPM, TM); MPM.add(createVerifierPass()); //make sure we haven't messed stuff up yet MPM.add(createInternalizePass(names)); MPM.add(createGlobalDCEPass()); //run this early since anything not in the table of exported functions is still in this module //this will remove dead functions PassManagerBuilder PMB; PMB.OptLevel = 3; PMB.SizeLevel = 0; #if LLVM_VERSION >= 35 PMB.LoopVectorize = true; PMB.SLPVectorize = true; #endif PMB.populateModulePassManager(MPM); MPM.run(*M); return M; }
void LLVMZigOptimizeModule(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref) { TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref); Module* module = unwrap(module_ref); TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); PassManagerBuilder *PMBuilder = new PassManagerBuilder(); PMBuilder->OptLevel = target_machine->getOptLevel(); PMBuilder->SizeLevel = 0; PMBuilder->BBVectorize = true; PMBuilder->SLPVectorize = true; PMBuilder->LoopVectorize = true; PMBuilder->DisableUnitAtATime = false; PMBuilder->DisableUnrollLoops = false; PMBuilder->MergeFunctions = true; PMBuilder->PrepareForLTO = true; PMBuilder->RerollLoops = true; PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); PMBuilder->LibraryInfo = &tlii; PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel); // Set up the per-function pass manager. legacy::FunctionPassManager *FPM = new legacy::FunctionPassManager(module); FPM->add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); #ifndef NDEBUG bool verify_module = true; #else bool verify_module = false; #endif if (verify_module) { FPM->add(createVerifierPass()); } PMBuilder->populateFunctionPassManager(*FPM); // Set up the per-module pass manager. legacy::PassManager *MPM = new legacy::PassManager(); MPM->add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); PMBuilder->populateModulePassManager(*MPM); // run per function optimization passes FPM->doInitialization(); for (Function &F : *module) if (!F.isDeclaration()) FPM->run(F); FPM->doFinalization(); // run per module optimization passes MPM->run(*module); }
Function &OptimizeForRuntime(Function &F) { #ifdef DEBUG static PassManagerBuilder Builder = getDebugBuilder(); #else static PassManagerBuilder Builder = getBuilder(); #endif Module *M = F.getParent(); opt::GenerateOutput = true; polly::opt::PollyParallel = true; FunctionPassManager PM = FunctionPassManager(M); Builder.populateFunctionPassManager(PM); PM.doInitialization(); PM.run(F); PM.doFinalization(); if (opt::havePapi()) { PassManager MPM; Builder.populateModulePassManager(MPM); MPM.add(polli::createTraceMarkerPass()); MPM.run(*M); } if (opt::haveLikwid()) { PassManager MPM; Builder.populateModulePassManager(MPM); MPM.add(polli::createLikwidMarkerPass()); MPM.run(*M); } DEBUG( StoreModule(*M, M->getModuleIdentifier() + ".after.polly.ll") ); opt::GenerateOutput = false; return F; }
Module * llvmutil_extractmodule(Module * OrigMod, TargetMachine * TM, std::vector<Function*> * livefns, std::vector<std::string> * symbolnames) { assert(symbolnames == NULL || livefns->size() == symbolnames->size()); ValueToValueMapTy VMap; Module * M = CloneModule(OrigMod, VMap); PassManager * MPM = new PassManager(); llvmutil_addtargetspecificpasses(MPM, TM); std::vector<const char *> names; for(size_t i = 0; i < livefns->size(); i++) { Function * fn = cast<Function>(VMap[(*livefns)[i]]); const char * name; if(symbolnames) { GlobalAlias * ga = new GlobalAlias(fn->getType(), Function::ExternalLinkage, (*symbolnames)[i], fn, M); name = copyName(ga->getName()); } else { name = copyName(fn->getName()); } names.push_back(name); //internalize pass has weird interface, so we need to copy the names here } //at this point we run optimizations on the module //first internalize all functions not mentioned in "names" using an internalize pass and then perform //standard optimizations MPM->add(createVerifierPass()); //make sure we haven't messed stuff up yet MPM->add(createInternalizePass(names)); MPM->add(createGlobalDCEPass()); //run this early since anything not in the table of exported functions is still in this module //this will remove dead functions //clean up the name list for(size_t i = 0; i < names.size(); i++) { free((char*)names[i]); names[i] = NULL; } PassManagerBuilder PMB; PMB.OptLevel = 3; PMB.DisableUnrollLoops = true; PMB.populateModulePassManager(*MPM); //PMB.populateLTOPassManager(*MPM, false, false); //no need to re-internalize, we already did it MPM->run(*M); delete MPM; MPM = NULL; return M; }
void llvmutil_addoptimizationpasses(PassManagerBase * fpm) { PassManagerBuilder PMB; PMB.OptLevel = 3; PMB.SizeLevel = 0; PMB.DisableUnitAtATime = true; #if LLVM_VERSION <= 34 && LLVM_VERSION >= 32 PMB.LoopVectorize = false; #elif LLVM_VERSION >= 35 PMB.LoopVectorize = true; PMB.SLPVectorize = true; #endif PassManagerWrapper W(fpm); PMB.populateModulePassManager(W); }
static void AddStandardCompilePasses(PassManagerBase &PM) { PM.add(createVerifierPass()); // Verify that input is correct // If the -strip-debug command line option was specified, do it. if (StripDebug) addPass(PM, createStripSymbolsPass(true)); if (DisableOptimizations) return; // -std-compile-opts adds the same module passes as -O3. PassManagerBuilder Builder; if (!DisableInline) Builder.Inliner = createFunctionInliningPass(); Builder.OptLevel = 3; Builder.populateModulePassManager(PM); }
/** * Adds a set of optimization passes to the given module/function pass * managers based on the given optimization and size reduction levels. * * The selection mirrors Clang behavior and is based on LLVM's * PassManagerBuilder. */ static void addOptimizationPasses(PassManagerBase &mpm, FunctionPassManager &fpm, unsigned optLevel, unsigned sizeLevel) { fpm.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder builder; builder.OptLevel = optLevel; builder.SizeLevel = sizeLevel; if (willInline()) { unsigned threshold = 225; if (sizeLevel == 1) // -Os threshold = 75; else if (sizeLevel == 2) // -Oz threshold = 25; if (optLevel > 2) threshold = 275; builder.Inliner = createFunctionInliningPass(threshold); } else { builder.Inliner = createAlwaysInlinerPass(); } builder.DisableSimplifyLibCalls = disableSimplifyLibCalls; builder.DisableUnitAtATime = !unitAtATime; builder.DisableUnrollLoops = optLevel == 0; /* builder.Vectorize is set in ctor from command line switch */ if (!disableLangSpecificPasses) { if (!disableSimplifyDruntimeCalls) builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addSimplifyDRuntimeCallsPass); #if USE_METADATA if (!disableGCToStack) builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addGarbageCollect2StackPass); #endif // USE_METADATA } #if LDC_LLVM_VER >= 301 // EP_OptimizerLast does not exist in LLVM 3.0, add it manually below. builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addStripExternalsPass); #endif builder.populateFunctionPassManager(fpm); builder.populateModulePassManager(mpm); #if LDC_LLVM_VER < 301 addStripExternalsPass(builder, mpm); #endif }
/// This routine adds optimization passes based on selected optimization level, /// OptLevel. /// /// OptLevel - Optimization Level static void AddOptimizationPasses(legacy::PassManagerBase &MPM, legacy::FunctionPassManager &FPM, TargetMachine *TM, unsigned OptLevel, unsigned SizeLevel) { if (!NoVerify || VerifyEach) FPM.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; Builder.SizeLevel = SizeLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel); } else { Builder.Inliner = createAlwaysInlinerLegacyPass(); } Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; // This is final, unless there is a #pragma vectorize enable if (DisableLoopVectorization) Builder.LoopVectorize = false; // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) else if (!Builder.LoopVectorize) Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; // When #pragma vectorize is on for SLP, do the same as above Builder.SLPVectorize = DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; // Add target-specific passes that need to run as early as possible. if (TM) Builder.addExtension( PassManagerBuilder::EP_EarlyAsPossible, [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { TM->addEarlyAsPossiblePasses(PM); }); if (Coroutines) addCoroutinePassesToExtensionPoints(Builder); Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); }
void llvmutil_optimizemodule(Module * M, TargetMachine * TM) { PassManager MPM; llvmutil_addtargetspecificpasses(&MPM, TM); MPM.add(createVerifierPass()); //make sure we haven't messed stuff up yet MPM.add(createGlobalDCEPass()); //run this early since anything not in the table of exported functions is still in this module //this will remove dead functions PassManagerBuilder PMB; PMB.OptLevel = 3; PMB.SizeLevel = 0; PMB.Inliner = createFunctionInliningPass(PMB.OptLevel, 0); #if LLVM_VERSION >= 35 PMB.LoopVectorize = true; PMB.SLPVectorize = true; #endif PMB.populateModulePassManager(MPM); MPM.run(*M); }
/// AddOptimizationPasses - This routine adds optimization passes /// based on selected optimization level, OptLevel. This routine /// duplicates llvm-gcc behaviour. /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, unsigned OptLevel) { PassManagerBuilder Builder; Builder.OptLevel = OptLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { unsigned Threshold = 225; if (OptLevel > 2) Threshold = 275; Builder.Inliner = createFunctionInliningPass(Threshold); } else { Builder.Inliner = createAlwaysInlinerPass(); } Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = OptLevel == 0; Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); }
void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilder PMBuilder; PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (LangOpts.AddressSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addAddressSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) PMBuilder.LibraryInfo->disableAllFunctions(); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { // FIXME: Derive these constants in a principled fashion. unsigned Threshold = 225; if (CodeGenOpts.OptimizeSize == 1) // -Os Threshold = 75; else if (CodeGenOpts.OptimizeSize == 2) // -Oz Threshold = 25; else if (OptLevel > 2) Threshold = 275; PMBuilder.Inliner = createFunctionInliningPass(Threshold); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. PMBuilder.Inliner = createAlwaysInlinerPass(); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(); if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) { MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes, CodeGenOpts.EmitGcovArcs, TargetTriple.isMacOSX())); if (!CodeGenOpts.DebugInfo) MPM->add(createStripSymbolsPass(true)); } PMBuilder.populateModulePassManager(*MPM); }
// This is the method invoked by the EE to Jit code. CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo, CORINFO_METHOD_INFO *MethodInfo, UINT Flags, BYTE **NativeEntry, ULONG *NativeSizeOfCode) { // Bail if input is malformed if (nullptr == JitInfo || nullptr == MethodInfo || nullptr == NativeEntry || nullptr == NativeSizeOfCode) { return CORJIT_INTERNALERROR; } // Prep main outputs *NativeEntry = nullptr; *NativeSizeOfCode = 0; // Set up state for this thread (if necessary) LLILCJitPerThreadState *PerThreadState = State.get(); if (PerThreadState == nullptr) { PerThreadState = new LLILCJitPerThreadState(); State.set(PerThreadState); } // Set up context for this Jit request LLILCJitContext Context = LLILCJitContext(PerThreadState); // Fill in context information from the CLR Context.JitInfo = JitInfo; Context.MethodInfo = MethodInfo; Context.Flags = Flags; JitInfo->getEEInfo(&Context.EEInfo); // Fill in context information from LLVM Context.LLVMContext = &PerThreadState->LLVMContext; std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo); Context.CurrentModule = M.get(); Context.CurrentModule->setTargetTriple(LLILC_TARGET_TRIPLE); Context.MethodName = Context.CurrentModule->getModuleIdentifier(); Context.TheABIInfo = ABIInfo::get(*Context.CurrentModule); // Initialize per invocation JIT options. This should be done after the // rest of the Context is filled out as it has dependencies on JitInfo, // Flags and MethodInfo. JitOptions JitOptions(Context); Context.Options = &JitOptions; EngineBuilder Builder(std::move(M)); std::string ErrStr; Builder.setErrorStr(&ErrStr); std::unique_ptr<RTDyldMemoryManager> MM(new EEMemoryManager(&Context)); Builder.setMCJITMemoryManager(std::move(MM)); TargetOptions Options; if (Context.Options->OptLevel != OptLevel::DEBUG_CODE) { Builder.setOptLevel(CodeGenOpt::Level::Default); } else { Builder.setOptLevel(CodeGenOpt::Level::None); Options.NoFramePointerElim = true; } Builder.setTargetOptions(Options); ExecutionEngine *NewEngine = Builder.create(); if (!NewEngine) { errs() << "Could not create ExecutionEngine: " << ErrStr << "\n"; return CORJIT_INTERNALERROR; } // Don't allow the EE to search for external symbols. NewEngine->DisableSymbolSearching(); Context.EE = NewEngine; // Now jit the method. CorJitResult Result = CORJIT_INTERNALERROR; if (Context.Options->DumpLevel == DumpLevel::VERBOSE) { Context.outputDebugMethodName(); } bool HasMethod = this->readMethod(&Context); if (HasMethod) { if (Context.Options->DoInsertStatepoints) { // If using Precise GC, run the GC-Safepoint insertion // and lowering passes before generating code. legacy::PassManager Passes; Passes.add(createPlaceSafepointsPass()); PassManagerBuilder PMBuilder; PMBuilder.OptLevel = 0; // Set optimization level to -O0 PMBuilder.SizeLevel = 0; // so that no additional phases are run. PMBuilder.populateModulePassManager(Passes); Passes.add(createRewriteStatepointsForGCPass(false)); Passes.run(*Context.CurrentModule); } Context.EE->generateCodeForModule(Context.CurrentModule); // You need to pick up the COFFDyld changes from the MS branch of LLVM // or this will fail with an "Incompatible object format!" error // from LLVM's dynamic loader. uint64_t FunctionAddress = Context.EE->getFunctionAddress(Context.MethodName); *NativeEntry = (BYTE *)FunctionAddress; // TODO: ColdCodeSize, or separated code, is not enabled or included. *NativeSizeOfCode = Context.HotCodeSize + Context.ReadOnlyDataSize; // This is a stop-gap point to issue a default stub of GC info. This lets // the CLR consume our methods cleanly. (and the ETW tracing still works) // Down the road this will be superseded by a CLR specific // GCMetadataPrinter instance or similar. this->outputGCInfo(&Context); // Dump out any enabled timing info. TimerGroup::printAll(errs()); // Tell the CLR that we've successfully generated code for this method. Result = CORJIT_OK; } // Clean up a bit delete Context.EE; Context.EE = nullptr; delete Context.TheABIInfo; Context.TheABIInfo = nullptr; return Result; }
int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. #endif // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif // @LOCALMOD-BEGIN initializeAddPNaClExternalDeclsPass(Registry); initializeAllocateDataSegmentPass(Registry); initializeBackendCanonicalizePass(Registry); initializeCanonicalizeMemIntrinsicsPass(Registry); initializeCleanupUsedGlobalsMetadataPass(Registry); initializeConstantInsertExtractElementIndexPass(Registry); initializeExpandAllocasPass(Registry); initializeExpandArithWithOverflowPass(Registry); initializeExpandByValPass(Registry); initializeExpandConstantExprPass(Registry); initializeExpandCtorsPass(Registry); initializeExpandGetElementPtrPass(Registry); initializeExpandIndirectBrPass(Registry); initializeExpandLargeIntegersPass(Registry); initializeExpandShuffleVectorPass(Registry); initializeExpandSmallArgumentsPass(Registry); initializeExpandStructRegsPass(Registry); initializeExpandTlsConstantExprPass(Registry); initializeExpandTlsPass(Registry); initializeExpandVarArgsPass(Registry); initializeFixVectorLoadStoreAlignmentPass(Registry); initializeFlattenGlobalsPass(Registry); initializeGlobalCleanupPass(Registry); initializeGlobalizeConstantVectorsPass(Registry); initializeInsertDivideCheckPass(Registry); initializeInternalizeUsedGlobalsPass(Registry); initializeNormalizeAlignmentPass(Registry); initializePNaClABIVerifyFunctionsPass(Registry); initializePNaClABIVerifyModulePass(Registry); initializePNaClSjLjEHPass(Registry); initializePromoteI1OpsPass(Registry); initializePromoteIntegersPass(Registry); initializeRemoveAsmMemoryPass(Registry); initializeRenameEntryPointPass(Registry); initializeReplacePtrsWithIntsPass(Registry); initializeResolveAliasesPass(Registry); initializeResolvePNaClIntrinsicsPass(Registry); initializeRewriteAtomicsPass(Registry); initializeRewriteLLVMIntrinsicsPass(Registry); initializeRewritePNaClLibraryCallsPass(Registry); initializeSandboxIndirectCallsPass(Registry); initializeSandboxMemoryAccessesPass(Registry); initializeSimplifyAllocasPass(Registry); initializeSimplifyStructRegSignaturesPass(Registry); initializeStripAttributesPass(Registry); initializeStripMetadataPass(Registry); initializeStripModuleFlagsPass(Registry); initializeStripTlsPass(Registry); initializeSubstituteUndefsPass(Registry); // Emscripten passes: initializeExpandI64Pass(Registry); initializeExpandInsertExtractElementPass(Registry); initializeLowerEmAsyncifyPass(Registry); initializeLowerEmExceptionsPass(Registry); initializeLowerEmSetjmpPass(Registry); initializeNoExitRuntimePass(Registry); // Emscripten passes end. // @LOCALMOD-END cl::ParseCommandLineOptions(argc, argv, "LLVM automatic testcase reducer. See\nhttp://" "llvm.org/cmds/bugpoint.html" " for more information.\n"); #ifndef DEBUG_BUGPOINT sys::SetInterruptFunction(BugpointInterruptFunction); #endif LLVMContext& Context = getGlobalContext(); // If we have an override, set it and then track the triple we want Modules // to use. if (!OverrideTriple.empty()) { TargetTriple.setTriple(Triple::normalize(OverrideTriple)); outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n"; } if (MemoryLimit < 0) { // Set the default MemoryLimit. Be sure to update the flag's description if // you change this. if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else MemoryLimit = 300; } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind, Context); if (D.addSources(InputFilenames)) return 1; AddToDriver PM(D); if (StandardLinkOpts) { PassManagerBuilder Builder; Builder.Inliner = createFunctionInliningPass(); Builder.populateLTOPassManager(PM); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { PassManagerBuilder Builder; if (OptLevelO1) Builder.Inliner = createAlwaysInlinerPass(); else if (OptLevelO2) Builder.Inliner = createFunctionInliningPass(225); else Builder.Inliner = createFunctionInliningPass(275); // Note that although clang/llvm-gcc use two separate passmanagers // here, it shouldn't normally make a difference. Builder.populateFunctionPassManager(PM); Builder.populateModulePassManager(PM); } for (std::vector<const PassInfo*>::iterator I = PassList.begin(), E = PassList.end(); I != E; ++I) { const PassInfo* PI = *I; D.addPass(PI->getPassArgument()); } // Bugpoint has the ability of generating a plethora of core files, so to // avoid filling up the disk, we prevent it #ifndef DEBUG_BUGPOINT sys::Process::PreventCoreFiles(); #endif std::string Error; bool Failure = D.run(Error); if (!Error.empty()) { errs() << Error; return 1; } return Failure; }
int main(int argc, char* argv[]) { if(argc < 2) { cerr << "Usage: " << argv[0] << " bf_file" << endl; return -1; } ifstream sourceFile(argv[1]); string line, source; while(getline(sourceFile, line)) source += line; // Setup a module and engine for JIT-ing std::string error; InitializeNativeTarget(); Module* module = new Module("bfcode", getGlobalContext()); InitializeNativeTarget(); LLVMLinkInJIT(); ExecutionEngine *engine = EngineBuilder(module) .setErrorStr(&error) .setOptLevel(CodeGenOpt::Aggressive) .create(); if(!engine) { cout << "No engine created: " << error << endl; return -1; } module->setDataLayout(engine->getTargetData()->getStringRepresentation()); // Compile the BF to IR cout << "Parsing… " << flush; Function* func = makeFunc(module, source.c_str()); cout << "done" << endl; { ofstream dst("out.ll"); raw_os_ostream rawdst(dst); rawdst << *module; } // Run optimization passes cout << "Optimizing… " << flush; PassManagerBuilder PMBuilder; FunctionPassManager pm(module); PMBuilder.populateFunctionPassManager(pm); pm.add(new TargetData(*(engine->getTargetData()))); pm.add(createVerifierPass()); // Eliminate simple loops such as [>>++<<-] pm.add(createInstructionCombiningPass()); // Cleanup for scalarrepl. pm.add(createLICMPass()); // Hoist loop invariants pm.add(createPromoteMemoryToRegisterPass()); pm.add(createIndVarSimplifyPass()); // Canonicalize indvars pm.add(createLoopDeletionPass()); // Delete dead loops pm.add(createConstantPropagationPass()); // Propagate constants pm.add(new CondProp); // Propagate conditionals // Simplify code for(int repeat=0; repeat < 3; repeat++) { pm.add(createPromoteMemoryToRegisterPass()); pm.add(createGVNPass()); // Remove redundancies pm.add(createSCCPPass()); // Constant prop with SCCP pm.add(createLoopDeletionPass()); pm.add(createLoopUnrollPass()); pm.add(createCFGSimplificationPass()); // Merge & remove BBs pm.add(createInstructionCombiningPass()); pm.add(createConstantPropagationPass()); // Propagate constants pm.add(createAggressiveDCEPass()); // Delete dead instructions pm.add(createCFGSimplificationPass()); // Merge & remove BBs pm.add(createDeadStoreEliminationPass()); // Delete dead stores pm.add(createMemCpyOptPass()); // Combine multiple stores into memset's //pm.add(new PutCharAggregatePass); } pm.add(createPromoteMemoryToRegisterPass()); // Process foreach (Function& f, *module) if (!f.isDeclaration) pm.run(f); PassManager pmm; PMBuilder.populateModulePassManager(pmm); pmm.add(createConstantMergePass()); pmm.add(createGlobalOptimizerPass()); pmm.add(createGlobalDCEPass()); pmm.add(createIPConstantPropagationPass()); pmm.run(*module); foreach (Function& f, *module) if (!f.isDeclaration) pm.run(f); pmm.run(*module); cout << "done" << endl; { ofstream dst("optout.ll"); raw_os_ostream rawdst(dst); rawdst << *module; } // Compile … cout << "Compiling…" << flush; int (*bf)() = (int (*)())engine->getPointerToFunction(func); cout << " done" << endl; // … and run! return bf(); }
vector<char> CodeGen_PTX_Dev::compile_to_src() { #ifdef WITH_PTX debug(2) << "In CodeGen_PTX_Dev::compile_to_src"; // DISABLED - hooked in here to force PrintBeforeAll option - seems to be the only way? /*char* argv[] = { "llc", "-print-before-all" };*/ /*int argc = sizeof(argv)/sizeof(char*);*/ /*cl::ParseCommandLineOptions(argc, argv, "Halide PTX internal compiler\n");*/ llvm::Triple triple(module->getTargetTriple()); // Allocate target machine std::string err_str; const llvm::Target *target = TargetRegistry::lookupTarget(triple.str(), err_str); internal_assert(target) << err_str << "\n"; TargetOptions options; #if LLVM_VERSION < 50 options.LessPreciseFPMADOption = true; #endif options.PrintMachineCode = false; options.AllowFPOpFusion = FPOpFusion::Fast; options.UnsafeFPMath = true; options.NoInfsFPMath = true; options.NoNaNsFPMath = true; options.HonorSignDependentRoundingFPMathOption = false; options.NoZerosInBSS = false; options.GuaranteedTailCallOpt = false; options.StackAlignmentOverride = 0; std::unique_ptr<TargetMachine> target_machine(target->createTargetMachine(triple.str(), mcpu(), mattrs(), options, llvm::Reloc::PIC_, #if LLVM_VERSION < 60 llvm::CodeModel::Default, #else llvm::CodeModel::Small, #endif CodeGenOpt::Aggressive)); internal_assert(target_machine.get()) << "Could not allocate target machine!"; #if LLVM_VERSION >= 60 module->setDataLayout(target_machine->createDataLayout()); #endif // Set up passes llvm::SmallString<8> outstr; raw_svector_ostream ostream(outstr); ostream.SetUnbuffered(); legacy::FunctionPassManager function_pass_manager(module.get()); legacy::PassManager module_pass_manager; module_pass_manager.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); function_pass_manager.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); // NVidia's libdevice library uses a __nvvm_reflect to choose // how to handle denormalized numbers. (The pass replaces calls // to __nvvm_reflect with a constant via a map lookup. The inliner // pass then resolves these situations to fast code, often a single // instruction per decision point.) // // The default is (more) IEEE like handling. FTZ mode flushes them // to zero. (This may only apply to single-precision.) // // The libdevice documentation covers other options for math accuracy // such as replacing division with multiply by the reciprocal and // use of fused-multiply-add, but they do not seem to be controlled // by this __nvvvm_reflect mechanism and may be flags to earlier compiler // passes. #define kDefaultDenorms 0 #define kFTZDenorms 1 #if LLVM_VERSION <= 40 StringMap<int> reflect_mapping; reflect_mapping[StringRef("__CUDA_FTZ")] = kFTZDenorms; module_pass_manager.add(createNVVMReflectPass(reflect_mapping)); #else // Insert a module flag for the FTZ handling. module->addModuleFlag(llvm::Module::Override, "nvvm-reflect-ftz", kFTZDenorms); if (kFTZDenorms) { for (llvm::Function &fn : *module) { fn.addFnAttr("nvptx-f32ftz", "true"); } } #endif PassManagerBuilder b; b.OptLevel = 3; #if LLVM_VERSION >= 50 b.Inliner = createFunctionInliningPass(b.OptLevel, 0, false); #else b.Inliner = createFunctionInliningPass(b.OptLevel, 0); #endif b.LoopVectorize = true; b.SLPVectorize = true; #if LLVM_VERSION > 40 target_machine->adjustPassManager(b); #endif b.populateFunctionPassManager(function_pass_manager); b.populateModulePassManager(module_pass_manager); // Override default to generate verbose assembly. target_machine->Options.MCOptions.AsmVerbose = true; // Output string stream // Ask the target to add backend passes as necessary. bool fail = target_machine->addPassesToEmitFile(module_pass_manager, ostream, TargetMachine::CGFT_AssemblyFile, true); if (fail) { internal_error << "Failed to set up passes to emit PTX source\n"; } // Run optimization passes function_pass_manager.doInitialization(); for (llvm::Module::iterator i = module->begin(); i != module->end(); i++) { function_pass_manager.run(*i); } function_pass_manager.doFinalization(); module_pass_manager.run(*module); if (debug::debug_level() >= 2) { dump(); } debug(2) << "Done with CodeGen_PTX_Dev::compile_to_src"; debug(1) << "PTX kernel:\n" << outstr.c_str() << "\n"; vector<char> buffer(outstr.begin(), outstr.end()); buffer.push_back(0); return buffer; #else // WITH_PTX return vector<char>(); #endif }
void CompileContext::CreateEE() { string errMsg; if (verifyModule(*module, &raw_string_ostream(errMsg))) { Alert((char*)errMsg.c_str()); } EE.reset(EngineBuilder(module) .setEngineKind(EngineKind::JIT) .setUseMCJIT(true) .setOptLevel(CodeGenOpt::Aggressive) .create()); EE->InstallLazyFunctionCreator(HspLazyFunctionCreator); #define REGISTER_RT_(t, name, func) \ do {\ Function *KnownFunction = Function::Create(\ TypeBuilder<t, false>::get(context),\ GlobalValue::ExternalLinkage, name,\ module);\ EE->addGlobalMapping(KnownFunction, (void*)(intptr_t)func);\ } while (false); #define REGISTER_RT(t, func) REGISTER_RT_(t, #func, func) REGISTER_RT(void(int, int), Prgcmd); REGISTER_RT(void(int, int), Modcmd); REGISTER_RT(void(void*, int, int), VarSet); REGISTER_RT(void(void*, int), VarSetIndex1); REGISTER_RT(void(void*, int, int), VarSetIndex2); REGISTER_RT(void(void*, int, int), VarSetIndex1i); REGISTER_RT(void(void*, int, int, int), VarSetIndex2i); REGISTER_RT(void(void*, double, int), VarSetIndex1d); REGISTER_RT(void(void*, double, int, int), VarSetIndex2d); REGISTER_RT(void(int), StackPushi); REGISTER_RT_(void(int), "PushInt", StackPushi); REGISTER_RT(void(int), StackPushd); REGISTER_RT_(void(double), "PushDouble", StackPushd); REGISTER_RT(void(int), StackPushl); REGISTER_RT_(void(int), "PushLabel", StackPushl); REGISTER_RT(void(char*), PushStr); REGISTER_RT(void(void*, int), PushVar); REGISTER_RT(void(void*, int), PushVAP); REGISTER_RT(void(), PushDefault); REGISTER_RT(void(), PushFuncEnd); REGISTER_RT(void(int), PushFuncPrm1); REGISTER_RT(void(int), PushFuncPrmI); REGISTER_RT(void(int), PushFuncPrmD); REGISTER_RT(void(int, int), PushFuncPrm); REGISTER_RT(void(int, int), PushFuncPAP); REGISTER_RT(void*(int), FuncPrm); REGISTER_RT(void*(int), LocalPrm); REGISTER_RT(int(int), FuncPrmI); REGISTER_RT(double(int), FuncPrmD); REGISTER_RT(void(), CalcAddI); REGISTER_RT(void(), CalcSubI); REGISTER_RT(void(), CalcMulI); REGISTER_RT(void(), CalcDivI); REGISTER_RT(void(), CalcModI); REGISTER_RT(void(), CalcAndI); REGISTER_RT(void(), CalcOrI); REGISTER_RT(void(), CalcXorI); REGISTER_RT(void(), CalcEqI); REGISTER_RT(void(), CalcNeI); REGISTER_RT(void(), CalcGtI); REGISTER_RT(void(), CalcLtI); REGISTER_RT(void(), CalcGtEqI); REGISTER_RT(void(), CalcLtEqI); REGISTER_RT(void(), CalcRrI); REGISTER_RT(void(), CalcLrI); REGISTER_RT(void(int, int), PushIntfunc); REGISTER_RT(void(void*, int, int), VarCalc); REGISTER_RT(void(void*, int), VarInc); REGISTER_RT(void(int), TaskSwitch); REGISTER_RT(char(), HspIf); REGISTER_RT(void(int, int), PushSysvar); REGISTER_RT(void(int, int), PushExtvar); REGISTER_RT(void(int, int), PushModcmd); REGISTER_RT(void(int, int), Extcmd); REGISTER_RT(void(int, int), Intcmd); REGISTER_RT(void(int, int), PushDllfunc); REGISTER_RT(void(int, int), PushDllctrl); REGISTER_RT(int(), GetTaskID); //REGISTER_RT(int(Hsp3r*, int, int), Hsp3rReset); REGISTER_RT(void(void*, int), HspVarCoreArray2); REGISTER_RT(double(int, int), CallDoubleIntfunc); REGISTER_RT(int(int, int), CallIntIntfunc); REGISTER_RT(double(int, int), CallDoubleSysvar); REGISTER_RT(int(int, int), CallIntSysvar); REGISTER_RT(int(), PopInt); REGISTER_RT(double(), PopDouble); //REGISTER_RT(char(), HspIf); //REGISTER_RT(void(int, int), PushSysvar); #undef REGISTER_RT Passes.reset(new PassManager()); FPM.reset(new FunctionPassManager(module)); Passes->add(new DataLayoutPass(module)); Passes->add(createVerifierPass()); PassManagerBuilder Builder; Builder.OptLevel = 3; Builder.SizeLevel = 0; Builder.Inliner = createFunctionInliningPass(Builder.OptLevel, Builder.SizeLevel); Builder.populateModulePassManager(*Passes); Builder.populateLTOPassManager(*Passes, false, true); Builder.populateFunctionPassManager(*FPM); Builder.populateModulePassManager(*Passes); FPM->doInitialization(); for (auto& f : *module) { // Run the FPM on this function FPM->run(f); } return; }
int compile(list<string> args, list<string> kgen_args, string merge, list<string> merge_args, string input, string output, int arch, string host_compiler, string fileprefix) { // // The LLVM compiler to emit IR. // const char* llvm_compiler = "kernelgen-gfortran"; // // Interpret kernelgen compile options. // for (list<string>::iterator iarg = kgen_args.begin(), iearg = kgen_args.end(); iarg != iearg; iarg++) { const char* arg = (*iarg).c_str(); if (!strncmp(arg, "-Wk,--llvm-compiler=", 20)) llvm_compiler = arg + 20; } // // Generate temporary output file. // Check if output file is specified in the command line. // Replace or add output to the temporary file. // cfiledesc tmp_output = cfiledesc::mktemp(fileprefix); bool output_specified = false; for (list<string>::iterator iarg = args.begin(), iearg = args.end(); iarg != iearg; iarg++) { const char* arg = (*iarg).c_str(); if (!strcmp(arg, "-o")) { iarg++; *iarg = tmp_output.getFilename(); output_specified = true; break; } } if (!output_specified) { args.push_back("-o"); args.push_back(tmp_output.getFilename()); } // // 1) Compile source code using regular host compiler. // { if (verbose) { cout << host_compiler; for (list<string>::iterator iarg = args.begin(), iearg = args.end(); iarg != iearg; iarg++) cout << " " << *iarg; cout << endl; } int status = execute(host_compiler, args, "", NULL, NULL); if (status) return status; } // // 2) Emit LLVM IR. // string out = ""; { list<string> emit_ir_args; for (list<string>::iterator iarg = args.begin(), iearg = args.end(); iarg != iearg; iarg++) { const char* arg = (*iarg).c_str(); if (!strcmp(arg, "-c") || !strcmp(arg, "-o")) { iarg++; continue; } if (!strcmp(arg, "-g")) { continue; } emit_ir_args.push_back(*iarg); } emit_ir_args.push_back("-fplugin=/opt/kernelgen/lib/dragonegg.so"); emit_ir_args.push_back("-fplugin-arg-dragonegg-emit-ir"); emit_ir_args.push_back("-S"); emit_ir_args.push_back(input); emit_ir_args.push_back("-o"); emit_ir_args.push_back("-"); if (verbose) { cout << llvm_compiler; for (list<string>::iterator iarg = emit_ir_args.begin(), iearg = emit_ir_args.end(); iarg != iearg; iarg++) cout << " " << *iarg; cout << endl; } int status = execute(llvm_compiler, emit_ir_args, "", &out, NULL); if (status) return status; } // // 3) Record existing module functions. // LLVMContext &context = getGlobalContext(); SMDiagnostic diag; MemoryBuffer* buffer1 = MemoryBuffer::getMemBuffer(out); auto_ptr<Module> m1; m1.reset(ParseIR(buffer1, diag, context)); //m1.get()->dump(); // // 4) Inline calls and extract loops into new functions. // MemoryBuffer* buffer2 = MemoryBuffer::getMemBuffer(out); auto_ptr<Module> m2; m2.reset(ParseIR(buffer2, diag, context)); { PassManager manager; manager.add(createInstructionCombiningPass()); manager.run(*m2.get()); } std::vector<CallInst *> LoopFuctionCalls; { PassManager manager; manager.add(createBranchedLoopExtractorPass(LoopFuctionCalls)); manager.run(*m2.get()); } //m2.get()->dump(); // // 5) Replace call to loop functions with call to launcher. // Append "always inline" attribute to all other functions. // Type* int32Ty = Type::getInt32Ty(context); Function* launch = Function::Create( TypeBuilder<types::i<32>(types::i<8>*, types::i<64>, types::i<32>*), true>::get(context), GlobalValue::ExternalLinkage, "kernelgen_launch", m2.get()); for (Module::iterator f1 = m2.get()->begin(), fe1 = m2.get()->end(); f1 != fe1; f1++) { Function* func = f1; if (func->isDeclaration()) continue; // Search for the current function in original module // functions list. // If function is not in list of original module, then // it is generated by the loop extractor. // Append "always inline" attribute to all other functions. if (m1.get()->getFunction(func->getName())) { const AttrListPtr attr = func->getAttributes(); const AttrListPtr attr_new = attr.addAttr(~0U, Attribute::AlwaysInline); func->setAttributes(attr_new); continue; } // Each such function must be extracted to the // standalone module and packed into resulting // object file data section. if (verbose) cout << "Preparing loop function " << func->getName().data() << " ..." << endl; // Reset to default visibility. func->setVisibility(GlobalValue::DefaultVisibility); // Reset to default linkage. func->setLinkage(GlobalValue::ExternalLinkage); // Replace call to this function in module with call to launcher. bool found = false; for (Module::iterator f2 = m2->begin(), fe2 = m2->end(); (f2 != fe2) && !found; f2++) for (Function::iterator bb = f2->begin(); (bb != f2->end()) && !found; bb++) for (BasicBlock::iterator i = bb->begin(); i != bb->end(); i++) { // Check if instruction in focus is a call. CallInst* call = dyn_cast<CallInst>(cast<Value>(i)); if (!call) continue; // Check if function is called (needs -instcombine pass). Function* callee = call->getCalledFunction(); if (!callee) continue; if (callee->isDeclaration()) continue; if (callee->getName() != func->getName()) continue; // Create a constant array holding original called // function name. Constant* name = ConstantArray::get( context, callee->getName(), true); // Create and initialize the memory buffer for name. ArrayType* nameTy = cast<ArrayType>(name->getType()); AllocaInst* nameAlloc = new AllocaInst(nameTy, "", call); StoreInst* nameInit = new StoreInst(name, nameAlloc, "", call); Value* Idx[2]; Idx[0] = Constant::getNullValue(Type::getInt32Ty(context)); Idx[1] = ConstantInt::get(Type::getInt32Ty(context), 0); GetElementPtrInst* namePtr = GetElementPtrInst::Create(nameAlloc, Idx, "", call); // Add pointer to the original function string name. SmallVector<Value*, 16> call_args; call_args.push_back(namePtr); // Add size of the aggregated arguments structure. { BitCastInst* BC = new BitCastInst( call->getArgOperand(0), Type::getInt64PtrTy(context), "", call); LoadInst* LI = new LoadInst(BC, "", call); call_args.push_back(LI); } // Add original aggregated structure argument. call_args.push_back(call->getArgOperand(0)); // Create new function call with new call arguments // and copy old call properties. CallInst* newcall = CallInst::Create(launch, call_args, "", call); //newcall->takeName(call); newcall->setCallingConv(call->getCallingConv()); newcall->setAttributes(call->getAttributes()); newcall->setDebugLoc(call->getDebugLoc()); // Replace old call with new one. call->replaceAllUsesWith(newcall); call->eraseFromParent(); found = true; break; } } //m2.get()->dump(); // // 6) Apply optimization passes to the resulting common // module. // { PassManager manager; manager.add(createLowerSetJmpPass()); PassManagerBuilder builder; builder.Inliner = createFunctionInliningPass(); builder.OptLevel = 3; builder.DisableSimplifyLibCalls = true; builder.populateModulePassManager(manager); manager.run(*m2.get()); } //m2.get()->dump(); // // 7) Embed the resulting module into object file. // { string ir_string; raw_string_ostream ir(ir_string); ir << (*m2.get()); celf e(tmp_output.getFilename(), output); e.getSection(".data")->addSymbol( "__kernelgen_" + string(input), ir_string.c_str(), ir_string.size() + 1); } return 0; }
void swift::performLLVMOptimizations(IRGenOptions &Opts, llvm::Module *Module, llvm::TargetMachine *TargetMachine) { SharedTimer timer("LLVM optimization"); // Set up a pipeline. PassManagerBuilder PMBuilder; if (Opts.Optimize && !Opts.DisableLLVMOptzns) { PMBuilder.OptLevel = 3; PMBuilder.Inliner = llvm::createFunctionInliningPass(200); PMBuilder.SLPVectorize = true; PMBuilder.LoopVectorize = true; PMBuilder.MergeFunctions = true; } else { PMBuilder.OptLevel = 0; if (!Opts.DisableLLVMOptzns) PMBuilder.Inliner = llvm::createAlwaysInlinerPass(/*insertlifetime*/false); } PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, addSwiftStackPromotionPass); // If the optimizer is enabled, we run the ARCOpt pass in the scalar optimizer // and the Contract pass as late as possible. if (!Opts.DisableLLVMARCOpts) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addSwiftARCOptPass); PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addSwiftContractPass); } if (Opts.Sanitize == SanitizerKind::Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (Opts.Sanitize == SanitizerKind::Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } // Configure the function passes. legacy::FunctionPassManager FunctionPasses(Module); FunctionPasses.add(createTargetTransformInfoWrapperPass( TargetMachine->getTargetIRAnalysis())); if (Opts.Verify) FunctionPasses.add(createVerifierPass()); PMBuilder.populateFunctionPassManager(FunctionPasses); // The PMBuilder only knows about LLVM AA passes. We should explicitly add // the swift AA pass after the other ones. if (!Opts.DisableLLVMARCOpts) { FunctionPasses.add(createSwiftAAWrapperPass()); FunctionPasses.add(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) { if (auto *WrapperPass = P.getAnalysisIfAvailable<SwiftAAWrapperPass>()) AAR.addAAResult(WrapperPass->getResult()); })); } // Run the function passes. FunctionPasses.doInitialization(); for (auto I = Module->begin(), E = Module->end(); I != E; ++I) if (!I->isDeclaration()) FunctionPasses.run(*I); FunctionPasses.doFinalization(); // Configure the module passes. legacy::PassManager ModulePasses; ModulePasses.add(createTargetTransformInfoWrapperPass( TargetMachine->getTargetIRAnalysis())); PMBuilder.populateModulePassManager(ModulePasses); // The PMBuilder only knows about LLVM AA passes. We should explicitly add // the swift AA pass after the other ones. if (!Opts.DisableLLVMARCOpts) { ModulePasses.add(createSwiftAAWrapperPass()); ModulePasses.add(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) { if (auto *WrapperPass = P.getAnalysisIfAvailable<SwiftAAWrapperPass>()) AAR.addAAResult(WrapperPass->getResult()); })); } // If we're generating a profile, add the lowering pass now. if (Opts.GenerateProfile) ModulePasses.add(createInstrProfilingPass()); if (Opts.Verify) ModulePasses.add(createVerifierPass()); if (Opts.PrintInlineTree) ModulePasses.add(createInlineTreePrinterPass()); // Do it. ModulePasses.run(*Module); }
int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. #endif // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif cl::ParseCommandLineOptions(argc, argv, "LLVM automatic testcase reducer. See\nhttp://" "llvm.org/cmds/bugpoint.html" " for more information.\n"); #ifndef DEBUG_BUGPOINT sys::SetInterruptFunction(BugpointInterruptFunction); #endif LLVMContext& Context = getGlobalContext(); // If we have an override, set it and then track the triple we want Modules // to use. if (!OverrideTriple.empty()) { TargetTriple.setTriple(Triple::normalize(OverrideTriple)); outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n"; } if (MemoryLimit < 0) { // Set the default MemoryLimit. Be sure to update the flag's description if // you change this. if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else MemoryLimit = 400; } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind, Context); if (D.addSources(InputFilenames)) return 1; AddToDriver PM(D); if (StandardLinkOpts) { PassManagerBuilder Builder; Builder.Inliner = createFunctionInliningPass(); Builder.populateLTOPassManager(PM); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { PassManagerBuilder Builder; if (OptLevelO1) Builder.Inliner = createAlwaysInlinerPass(); else if (OptLevelO2) Builder.Inliner = createFunctionInliningPass(225); else Builder.Inliner = createFunctionInliningPass(275); // Note that although clang/llvm-gcc use two separate passmanagers // here, it shouldn't normally make a difference. Builder.populateFunctionPassManager(PM); Builder.populateModulePassManager(PM); } for (std::vector<const PassInfo*>::iterator I = PassList.begin(), E = PassList.end(); I != E; ++I) { const PassInfo* PI = *I; D.addPass(PI->getPassArgument()); } // Bugpoint has the ability of generating a plethora of core files, so to // avoid filling up the disk, we prevent it #ifndef DEBUG_BUGPOINT sys::Process::PreventCoreFiles(); #endif std::string Error; bool Failure = D.run(Error); if (!Error.empty()) { errs() << Error; return 1; } return Failure; }
// main - Entry point for the sync compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize target first, so that --version shows registered targets. LLVMInitializeVerilogBackendTarget(); LLVMInitializeVerilogBackendTargetInfo(); LLVMInitializeVerilogBackendTargetMC(); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); SMDiagnostic Err; LuaScript *S = &scriptEngin(); S->init(); // Run the lua script. if (!S->runScriptFile(InputFilename, Err)){ Err.print(argv[0], errs()); return 1; } S->updateStatus(); // Load the module to be compiled... std::auto_ptr<Module> M; M.reset(ParseIRFile(S->getValue<std::string>("InputFile"), Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; } Module &mod = *M.get(); // TODO: Build the right triple. Triple TheTriple(mod.getTargetTriple()); TargetOptions TO; std::auto_ptr<TargetMachine> target(TheVBackendTarget.createTargetMachine(TheTriple.getTriple(), "", S->getDataLayout(), TO)); // Build up all of the passes that we want to do to the module. PassManagerBuilder Builder; Builder.DisableUnrollLoops = true; Builder.LibraryInfo = new TargetLibraryInfo(); Builder.LibraryInfo->disableAllFunctions(); Builder.OptLevel = 3; Builder.SizeLevel = 2; Builder.DisableSimplifyLibCalls = true; Builder.Inliner = createHLSInlinerPass(); Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, LoopOptimizerEndExtensionFn); PassManager Passes; Passes.add(new TargetData(*target->getTargetData())); // Add the immutable target-specific alias analysis ahead of all others AAs. Passes.add(createVAliasAnalysisPass(target->getIntrinsicInfo())); Passes.add(createVerifierPass()); // This is the final bitcode, internalize it to expose more optimization // opportunities. Note that we should internalize it before SW/HW partition, // otherwise we may lost some information that help the later internalize. Passes.add(createInternalizePass(true)); // Perform Software/Hardware partition. Passes.add(createFunctionFilterPass(S->getOutputStream("SoftwareIROutput"))); Passes.add(createGlobalDCEPass()); // Optimize the hardware part. //Builder.populateFunctionPassManager(*FPasses); Builder.populateModulePassManager(Passes); Builder.populateLTOPassManager(Passes, /*Internalize*/true, /*RunInliner*/true); //PM.add(createPrintModulePass(&dbgs())); // We do not use the stream that passing into addPassesToEmitFile. formatted_raw_ostream formatted_nulls(nulls()); // Ask the target to add backend passes as necessary. target->addPassesToEmitFile(Passes, formatted_nulls, TargetMachine::CGFT_Null, false/*NoVerify*/); // Analyse the slack between registers. Passes.add(createCombPathDelayAnalysisPass()); Passes.add(createVerilogASTWriterPass(S->getOutputStream("RTLOutput"))); // Run some scripting passes. for (LuaScript::scriptpass_it I = S->passes_begin(), E = S->passes_end(); I != E; ++I) { const luabind::object &o = *I; Pass *P = createScriptingPass( luabind::object_cast<std::string>(I.key()).c_str(), luabind::object_cast<std::string>(o["FunctionScript"]).c_str(), luabind::object_cast<std::string>(o["GlobalScript"]).c_str()); Passes.add(P); } // Run the passes. Passes.run(mod); // If no error occur, keep the files. S->keepAllFiles(); return 0; }
static void addOptimizationPasses(PassManagerBase &mpm, FunctionPassManager &fpm, #endif unsigned optLevel, unsigned sizeLevel) { fpm.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder builder; builder.OptLevel = optLevel; builder.SizeLevel = sizeLevel; if (willInline()) { unsigned threshold = 225; if (sizeLevel == 1) // -Os threshold = 75; else if (sizeLevel == 2) // -Oz threshold = 25; if (optLevel > 2) threshold = 275; builder.Inliner = createFunctionInliningPass(threshold); } else { builder.Inliner = createAlwaysInlinerPass(); } #if LDC_LLVM_VER < 304 builder.DisableSimplifyLibCalls = disableSimplifyLibCalls; #endif builder.DisableUnitAtATime = !unitAtATime; builder.DisableUnrollLoops = optLevel == 0; #if LDC_LLVM_VER >= 304 builder.DisableUnrollLoops = (disableLoopUnrolling.getNumOccurrences() > 0) ? disableLoopUnrolling : optLevel == 0; // This is final, unless there is a #pragma vectorize enable if (disableLoopVectorization) builder.LoopVectorize = false; // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) else if (!builder.LoopVectorize) builder.LoopVectorize = optLevel > 1 && sizeLevel < 2; // When #pragma vectorize is on for SLP, do the same as above builder.SLPVectorize = disableSLPVectorization ? false : optLevel > 1 && sizeLevel < 2; #else /* builder.Vectorize is set in ctor from command line switch */ #endif #if LDC_LLVM_VER >= 303 if (opts::sanitize == opts::AddressSanitizer) { builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (opts::sanitize == opts::MemorySanitizer) { builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (opts::sanitize == opts::ThreadSanitizer) { builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } #endif if (!disableLangSpecificPasses) { if (!disableSimplifyDruntimeCalls) builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addSimplifyDRuntimeCallsPass); if (!disableGCToStack) builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addGarbageCollect2StackPass); } // EP_OptimizerLast does not exist in LLVM 3.0, add it manually below. builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addStripExternalsPass); builder.populateFunctionPassManager(fpm); builder.populateModulePassManager(mpm); }
int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT InitLLVM X(argc, argv); #endif // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeAggressiveInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif if (std::getenv("bar") == (char*) -1) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); } cl::ParseCommandLineOptions(argc, argv, "LLVM automatic testcase reducer. See\nhttp://" "llvm.org/cmds/bugpoint.html" " for more information.\n"); #ifndef DEBUG_BUGPOINT sys::SetInterruptFunction(BugpointInterruptFunction); #endif LLVMContext Context; // If we have an override, set it and then track the triple we want Modules // to use. if (!OverrideTriple.empty()) { TargetTriple.setTriple(Triple::normalize(OverrideTriple)); outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n"; } if (MemoryLimit < 0) { // Set the default MemoryLimit. Be sure to update the flag's description if // you change this. if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else MemoryLimit = 400; #if (LLVM_ADDRESS_SANITIZER_BUILD || LLVM_MEMORY_SANITIZER_BUILD || \ LLVM_THREAD_SANITIZER_BUILD) // Starting from kernel 4.9 memory allocated with mmap is counted against // RLIMIT_DATA. Sanitizers need to allocate tens of terabytes for shadow. MemoryLimit = 0; #endif } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind, Context); if (D.addSources(InputFilenames)) return 1; AddToDriver PM(D); if (StandardLinkOpts) { PassManagerBuilder Builder; Builder.Inliner = createFunctionInliningPass(); Builder.populateLTOPassManager(PM); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { PassManagerBuilder Builder; if (OptLevelO1) Builder.Inliner = createAlwaysInlinerLegacyPass(); else if (OptLevelOs || OptLevelO2) Builder.Inliner = createFunctionInliningPass( 2, OptLevelOs ? 1 : 0, false); else Builder.Inliner = createFunctionInliningPass(275); Builder.populateFunctionPassManager(PM); Builder.populateModulePassManager(PM); } for (const PassInfo *PI : PassList) D.addPass(PI->getPassArgument()); // Bugpoint has the ability of generating a plethora of core files, so to // avoid filling up the disk, we prevent it #ifndef DEBUG_BUGPOINT sys::Process::PreventCoreFiles(); #endif if (Error E = D.run()) { errs() << toString(std::move(E)); return 1; } return 0; }
static bool ParseFile(const std::string &Filename, const std::vector<std::string> &IncludeDirs, SmallVectorImpl<std::string> &OutputFiles) { ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (std::error_code EC = MBOrErr.getError()) { llvm::errs() << "Could not open input file '" << Filename << "': " << EC.message() <<"\n"; return true; } std::unique_ptr<llvm::MemoryBuffer> MB = std::move(MBOrErr.get()); // Record the location of the include directory so that the lexer can find it // later. SourceMgr SrcMgr; SrcMgr.setIncludeDirs(IncludeDirs); // Tell SrcMgr about this buffer, which is what Parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(MB), llvm::SMLoc()); LangOptions Opts; Opts.DefaultReal8 = DefaultReal8; Opts.DefaultDouble8 = DefaultDouble8; Opts.DefaultInt8 = DefaultInt8; Opts.ReturnComments = ReturnComments; if(!FreeForm && !FixedForm) { llvm::StringRef Ext = llvm::sys::path::extension(Filename); if(Ext.equals_lower(".f")) { Opts.FixedForm = 1; Opts.FreeForm = 0; } } else if(FixedForm) { Opts.FixedForm = 1; Opts.FreeForm = 0; } TextDiagnosticPrinter TDP(SrcMgr); DiagnosticsEngine Diag(new DiagnosticIDs,&SrcMgr, &TDP, false); // Chain in -verify checker, if requested. if(RunVerifier) Diag.setClient(new VerifyDiagnosticConsumer(Diag)); ASTContext Context(SrcMgr, Opts); Sema SA(Context, Diag); Parser P(SrcMgr, Opts, Diag, SA); Diag.getClient()->BeginSourceFile(Opts, &P.getLexer()); P.ParseProgramUnits(); Diag.getClient()->EndSourceFile(); // Dump if(PrintAST || DumpAST) { auto Dumper = CreateASTDumper(""); Dumper->HandleTranslationUnit(Context); delete Dumper; } // Emit if(!SyntaxOnly && !Diag.hadErrors()) { flang::TargetOptions TargetOptions; TargetOptions.Triple = TargetTriple.empty()? llvm::sys::getDefaultTargetTriple() : TargetTriple; TargetOptions.CPU = llvm::sys::getHostCPUName(); auto CG = CreateLLVMCodeGen(Diag, Filename == ""? std::string("module") : Filename, CodeGenOptions(), TargetOptions, llvm::getGlobalContext()); CG->Initialize(Context); CG->HandleTranslationUnit(Context); BackendAction BA = Backend_EmitObj; if(EmitASM) BA = Backend_EmitAssembly; if(EmitLLVM) BA = Backend_EmitLL; const llvm::Target *TheTarget = 0; std::string Err; TheTarget = llvm::TargetRegistry::lookupTarget(TargetOptions.Triple, Err); CodeGenOpt::Level TMOptLevel = CodeGenOpt::Default; switch(OptLevel) { case 0: TMOptLevel = CodeGenOpt::None; break; case 3: TMOptLevel = CodeGenOpt::Aggressive; break; } llvm::TargetOptions Options; auto TM = TheTarget->createTargetMachine(TargetOptions.Triple, TargetOptions.CPU, "", Options, Reloc::Default, CodeModel::Default, TMOptLevel); if(!(EmitLLVM && OptLevel == 0)) { auto TheModule = CG->GetModule(); auto PM = new llvm::legacy::PassManager(); //llvm::legacy::FunctionPassManager *FPM = new llvm::legacy::FunctionPassManager(TheModule); //FPM->add(new DataLayoutPass()); //PM->add(new llvm::DataLayoutPass()); //TM->addAnalysisPasses(*PM); PM->add(createPromoteMemoryToRegisterPass()); PassManagerBuilder PMBuilder; PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = 0; PMBuilder.LoopVectorize = true; PMBuilder.SLPVectorize = true; unsigned Threshold = 225; if (OptLevel > 2) Threshold = 275; PMBuilder.Inliner = createFunctionInliningPass(Threshold); PMBuilder.populateModulePassManager(*PM); //llvm::legacy::PassManager *MPM = new llvm::legacy::PassManager(); //PMBuilder.populateModulePassManager(*MPM); PM->run(*TheModule); //MPM->run(*TheModule); delete PM; //delete MPM; } if(Interpret) { //const char *Env[] = { "", nullptr }; //Execute(CG->ReleaseModule(), Env); } else if(OutputFile == "-"){ // FIXME: outputting to stdout is broken //EmitFile(llvm::outs(), CG->GetModule(), TM, BA); OutputFiles.push_back(GetOutputName("stdout",BA)); EmitOutputFile(OutputFiles.back(), CG->GetModule(), TM, BA); }else { OutputFiles.push_back(GetOutputName(Filename, BA)); EmitOutputFile(OutputFiles.back(), CG->GetModule(), TM, BA); } delete CG; } return Diag.hadErrors(); }
void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilder PMBuilder; PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, addObjCARCAPElimPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (CodeGenOpts.BoundsChecking > 0) { BoundsChecking = CodeGenOpts.BoundsChecking; PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (LangOpts.AddressSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addAddressSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPass); } if (LangOpts.ThreadSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) PMBuilder.LibraryInfo->disableAllFunctions(); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { // FIXME: Derive these constants in a principled fashion. unsigned Threshold = 225; if (CodeGenOpts.OptimizeSize == 1) // -Os Threshold = 75; else if (CodeGenOpts.OptimizeSize == 2) // -Oz Threshold = 25; else if (OptLevel > 2) Threshold = 275; PMBuilder.Inliner = createFunctionInliningPass(Threshold); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. PMBuilder.Inliner = createAlwaysInlinerPass(false); else PMBuilder.Inliner = createAlwaysInlinerPass(); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(); if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) { MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes, CodeGenOpts.EmitGcovArcs, TargetTriple.isMacOSX())); if (CodeGenOpts.DebugInfo == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } // Add the memory safety passes for control-flow integrity if (CodeGenOpts.MemSafety) { // Make sure everything that can be in an LLVM register is. MPM->add (createPromoteMemoryToRegisterPass()); MPM->add (createUnifyFunctionExitNodesPass()); MPM->add (new CFIChecks()); } PMBuilder.populateModulePassManager(*MPM); if (CodeGenOpts.SoftBound) { // Make sure SoftBound+CETS is run after optimization with atleast mem2reg run MPM->add(new DominatorTree()); MPM->add(new DominanceFrontier()); MPM->add(new LoopInfo()); MPM->add(new InitializeSoftBound()); MPM->add(new SoftBoundCETSPass()); } // Add the memory safety passes if (CodeGenOpts.MemSafety) { MPM->add (createCommonMSCInfoPass()); MPM->add (createSAFECodeMSCInfoPass()); // C standard library / format string function transforms if (!CodeGenOpts.BaggyBounds) { MPM->add (new StringTransform()); MPM->add (new FormatStringTransform()); MPM->add (new RegisterVarargCallSites()); MPM->add (new LoggingFunctions()); } MPM->add (new InitAllocas()); MPM->add (createRegisterGlobalsPass(/*RegUncertain=*/true, /*MakeInternal=*/false)); MPM->add (createRemoveUnsuitableGlobalRegistrationsPass()); MPM->add (new RegisterMainArgs()); MPM->add (createInstrumentFreeCallsPass()); MPM->add (new RegisterCustomizedAllocation()); MPM->add (new LoopInfo ()); MPM->add (new DominatorTree ()); MPM->add (createRegisterStackPoolsPass(/*RegByval=*/true)); MPM->add (createUnregisterStackPoolsPass()); MPM->add (createSpecializeCMSCallsPass()); MPM->add (new RegisterRuntimeInitializer(CodeGenOpts.MemSafetyLogFile.c_str())); MPM->add (new DebugInstrument()); MPM->add (createInstrumentMemoryAccessesPass()); MPM->add (createInstrumentGEPsPass()); MPM->add (createSpecializeCMSCallsPass()); MPM->add (new ScalarEvolution()); MPM->add (new ArrayBoundsCheckLocal()); MPM->add (createOptimizeGEPChecksPass()); MPM->add (createExactCheckOptPass()); MPM->add (new ScalarEvolution()); MPM->add (createLocalArrayBoundsAnalysisPass()); MPM->add (createOptimizeFastMemoryChecksPass()); MPM->add (createOptimizeIdenticalLSChecksPass()); MPM->add (new DominatorTree()); MPM->add (new ScalarEvolution()); MPM->add (createOptimizeImpliedFastLSChecksPass()); MPM->add (new OptimizeChecks()); MPM->add (createOptimizeMemoryRegistrationsPass(/*AllowFastChecks=*/true)); if (CodeGenOpts.MemSafeTerminate) { MPM->add (llvm::createSCTerminatePass ()); } } if (CodeGenOpts.BaggyBounds) { MPM->add (new InsertBaggyBoundsChecks()); } // // Rerun the LLVM optimizations again. // PMBuilder.populateModulePassManager(*MPM); // For SAFECode, do the debug instrumentation and OOB rewriting after // all optimization is done. if (CodeGenOpts.MemSafety) { MPM->add (new DebugInstrument()); MPM->add (new RewriteOOB()); } }