static void llvm_init(){ ExecutionEngine *ee = tcg_llvm_ctx->getExecutionEngine(); FunctionPassManager *fpm = tcg_llvm_ctx->getFunctionPassManager(); Module *mod = tcg_llvm_ctx->getModule(); LLVMContext &ctx = mod->getContext(); // Link logging function in with JIT Function *logFunc; std::vector<Type*> argTypes; // DynValBuffer* argTypes.push_back(IntegerType::get(ctx, 8*sizeof(uintptr_t))); // DynValEntryType argTypes.push_back(IntegerType::get(ctx, 8*sizeof(DynValEntryType))); // LogOp argTypes.push_back(IntegerType::get(ctx, 8*sizeof(LogOp))); // Dynamic value argTypes.push_back(IntegerType::get(ctx, 8*sizeof(uintptr_t))); logFunc = Function::Create( FunctionType::get(Type::getVoidTy(ctx), argTypes, false), Function::ExternalLinkage, "log_dynval", mod); logFunc->addFnAttr(Attribute::AlwaysInline); ee->addGlobalMapping(logFunc, (void*) &log_dynval); // Create instrumentation pass and add to function pass manager llvm::FunctionPass *instfp = createPandaInstrFunctionPass(mod); fpm->add(instfp); PIFP = static_cast<PandaInstrFunctionPass*>(instfp); }
bool PassBuilder::parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E, bool VerifyEachPass, bool DebugLogging) { auto &Name = E.Name; auto &InnerPipeline = E.InnerPipeline; // First handle complex passes like the pass managers which carry pipelines. if (!InnerPipeline.empty()) { if (Name == "function") { FunctionPassManager NestedFPM(DebugLogging); if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass, DebugLogging)) return false; // Add the nested pass manager with the appropriate adaptor. FPM.addPass(std::move(NestedFPM)); return true; } if (Name == "loop") { LoopPassManager LPM(DebugLogging); if (!parseLoopPassPipeline(LPM, InnerPipeline, VerifyEachPass, DebugLogging)) return false; // Add the nested pass manager with the appropriate adaptor. FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM))); return true; } if (auto Count = parseRepeatPassName(Name)) { FunctionPassManager NestedFPM(DebugLogging); if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass, DebugLogging)) return false; FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM))); return true; } // Normal passes can't have pipelines. return false; } // Now expand the basic registered passes from the .inc file. #define FUNCTION_PASS(NAME, CREATE_PASS) \ if (Name == NAME) { \ FPM.addPass(CREATE_PASS); \ return true; \ } #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">") { \ FPM.addPass( \ RequireAnalysisPass< \ std::remove_reference<decltype(CREATE_PASS)>::type, Function>()); \ return true; \ } \ if (Name == "invalidate<" NAME ">") { \ FPM.addPass(InvalidateAnalysisPass< \ std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } #include "PassRegistry.def" return false; }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out, std::string& errMsg) { if ( this->determineTarget(errMsg) ) return true; // mark which symbols can not be internalized this->applyScopeRestrictions(); Module* mergedModule = _linker.getModule(); // if options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<char **>(&_codegenOptions[0])); // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline, /*VerifyEach=*/ false); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule); codeGenPasses->add(new TargetData(*_target->getTargetData())); formatted_raw_ostream Out(out); if (_target->addPassesToEmitFile(*codeGenPasses, Out, TargetMachine::CGFT_AssemblyFile, CodeGenOpt::Aggressive)) { errMsg = "target file type not supported"; return true; } // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) if (!it->isDeclaration()) codeGenPasses->run(*it); codeGenPasses->doFinalization(); return false; // success }
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over // all the functions in a module, so we do that manually here. You'll find // similar code in clang's BackendUtil.cpp file. extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { FunctionPassManager *P = unwrap<FunctionPassManager>(PM); P->doInitialization(); for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; ++I) if (!I->isDeclaration()) P->run(*I); P->doFinalization(); }
static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) { if (Name == "no-op-function") { FPM.addPass(NoOpFunctionPass()); return true; } if (Name == "print") { FPM.addPass(PrintFunctionPass(dbgs())); return true; } return false; }
void optimize(cpu_t *cpu) { FunctionPassManager pm = FunctionPassManager(cpu->mod); pm.add(createPromoteMemoryToRegisterPass()); pm.add(createInstructionCombiningPass()); pm.add(createConstantPropagationPass()); pm.add(createDeadCodeEliminationPass()); pm.run(*cpu->cur_func); }
bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM, StringRef &PipelineText, bool VerifyEachPass, bool DebugLogging) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("function(")) { FunctionPassManager NestedFPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("function(")); if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. FPM.addPass(std::move(NestedFPM)); } else if (PipelineText.startswith("loop(")) { LoopPassManager NestedLPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("loop(")); if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass, DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM))); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); if (!parseFunctionPassName(FPM, PipelineText.substr(0, End))) return false; if (VerifyEachPass) FPM.addPass(VerifierPass()); PipelineText = PipelineText.substr(End); } if (PipelineText.empty() || PipelineText[0] == ')') return true; assert(PipelineText[0] == ','); PipelineText = PipelineText.substr(1); } }
ExecutionEngine *MCJITHelper::compileModule(Module *M) { if (M == OpenModule) closeCurrentModule(); std::string ErrStr; ExecutionEngine *NewEngine = EngineBuilder(M) .setErrorStr(&ErrStr) .setMCJITMemoryManager(new HelpingMemoryManager(this)) .create(); if (!NewEngine) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); } // Create a function pass manager for this engine FunctionPassManager *FPM = new FunctionPassManager(M); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. FPM->add(new DataLayout(*NewEngine->getDataLayout())); // Provide basic AliasAnalysis support for GVN. FPM->add(createBasicAliasAnalysisPass()); // Promote allocas to registers. FPM->add(createPromoteMemoryToRegisterPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. FPM->add(createInstructionCombiningPass()); // Reassociate expressions. FPM->add(createReassociatePass()); // Eliminate Common SubExpressions. FPM->add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). FPM->add(createCFGSimplificationPass()); FPM->doInitialization(); // For each function in the module Module::iterator it; Module::iterator end = M->end(); for (it = M->begin(); it != end; ++it) { // Run the FPM on this function FPM->run(*it); } // We don't need this anymore delete FPM; // Store this engine EngineMap[M] = NewEngine; NewEngine->finalizeObject(); return NewEngine; }
/// 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); }
/// 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); }
bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM, ArrayRef<PipelineElement> Pipeline, bool VerifyEachPass, bool DebugLogging) { for (const auto &Element : Pipeline) { if (!parseFunctionPass(FPM, Element, VerifyEachPass, DebugLogging)) return false; if (VerifyEachPass) FPM.addPass(VerifierPass()); } return true; }
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; }
/** * 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 }
FunctionPassManager* Builder::getStandardOptimizer() { FunctionPassManager* optimizer = new FunctionPassManager(this->_mod); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. if (this->_jit) { optimizer->add(new DataLayoutPass(*this->_jit->getDataLayout())); } // Provide basic AliasAnalysis support for GVN. optimizer->add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. optimizer->add(createInstructionCombiningPass()); // Reassociate expressions. optimizer->add(createReassociatePass()); // Eliminate Common SubExpressions. optimizer->add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). optimizer->add(createCFGSimplificationPass()); optimizer->doInitialization(); return optimizer; }
void optimize(cpu_t *cpu) { dyncom_engine_t* de = cpu->dyncom_engine; FunctionPassManager pm = FunctionPassManager(de->mod); std::string data_layout = de->exec_engine->getTargetData()->getStringRepresentation(); TargetData *TD = new TargetData(data_layout); pm.add(TD); pm.add(createPromoteMemoryToRegisterPass()); pm.add(createInstructionCombiningPass()); pm.add(createConstantPropagationPass()); pm.add(createDeadCodeEliminationPass()); pm.run(*de->cur_func); }
void PassManagerBuilder::populateFunctionPassManager(FunctionPassManager &FPM) { addExtensionsToPM(EP_EarlyAsPossible, FPM); // Add LibraryInfo if we have some. if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo)); if (OptLevel == 0) return; addInitialAliasAnalysisPasses(FPM); FPM.add(createCFGSimplificationPass()); if (UseNewSROA) FPM.add(createSROAPass()); else FPM.add(createScalarReplAggregatesPass()); FPM.add(createEarlyCSEPass()); FPM.add(createLowerExpectIntrinsicPass()); }
void *MCJITHelper::getPointerToFunction(Function* F) { // See if an existing instance of MCJIT has this function. EngineVector::iterator begin = Engines.begin(); EngineVector::iterator end = Engines.end(); EngineVector::iterator it; for (it = begin; it != end; ++it) { void *P = (*it)->getPointerToFunction(F); if (P) return P; } // If we didn't find the function, see if we can generate it. if (OpenModule) { std::string ErrStr; ExecutionEngine *NewEngine = EngineBuilder(OpenModule) .setErrorStr(&ErrStr) .setMCJITMemoryManager(new HelpingMemoryManager(this)) .create(); if (!NewEngine) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); } // Create a function pass manager for this engine FunctionPassManager *FPM = new FunctionPassManager(OpenModule); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. FPM->add(new DataLayout(*NewEngine->getDataLayout())); // Provide basic AliasAnalysis support for GVN. FPM->add(createBasicAliasAnalysisPass()); // Promote allocas to registers. FPM->add(createPromoteMemoryToRegisterPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. FPM->add(createInstructionCombiningPass()); // Reassociate expressions. FPM->add(createReassociatePass()); // Eliminate Common SubExpressions. FPM->add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). FPM->add(createCFGSimplificationPass()); FPM->doInitialization(); // For each function in the module Module::iterator it; Module::iterator end = OpenModule->end(); for (it = OpenModule->begin(); it != end; ++it) { // Run the FPM on this function FPM->run(*it); } // We don't need this anymore delete FPM; OpenModule = NULL; Engines.push_back(NewEngine); NewEngine->finalizeObject(); return NewEngine->getPointerToFunction(F); } return NULL; }
ExecutionEngine *MCJITHelper::compileModule(Module *M) { assert(EngineMap.find(M) == EngineMap.end()); if (M == CurrentModule) closeCurrentModule(); std::string ErrStr; ExecutionEngine *EE = EngineBuilder(M) .setErrorStr(&ErrStr) .setMCJITMemoryManager(new HelpingMemoryManager(this)) .create(); if (!EE) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); } if (UseObjectCache) EE->setObjectCache(&OurObjectCache); // Get the ModuleID so we can identify IR input files const std::string ModuleID = M->getModuleIdentifier(); // If we've flagged this as an IR file, it doesn't need function passes run. if (0 != ModuleID.compare(0, 3, "IR:")) { FunctionPassManager *FPM = 0; // Create a FPM for this module FPM = new FunctionPassManager(M); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. FPM->add(new DataLayout(*EE->getDataLayout())); // Provide basic AliasAnalysis support for GVN. FPM->add(createBasicAliasAnalysisPass()); // Promote allocas to registers. FPM->add(createPromoteMemoryToRegisterPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. FPM->add(createInstructionCombiningPass()); // Reassociate expressions. FPM->add(createReassociatePass()); // Eliminate Common SubExpressions. FPM->add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). FPM->add(createCFGSimplificationPass()); FPM->doInitialization(); // For each function in the module Module::iterator it; Module::iterator end = M->end(); for (it = M->begin(); it != end; ++it) { // Run the FPM on this function FPM->run(*it); } delete FPM; } EE->finalizeObject(); // Store this engine EngineMap[M] = EE; return EE; }
void BackendPass::CreatePasses(const clang::LangOptions& LangOpts, const clang::CodeGenOptions& CodeGenOpts) { // See clang/lib/CodeGen/BackendUtil.cpp EmitAssemblyHelper::CreatePasses() unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilderWithOpts PMBuilder(LangOpts, CodeGenOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; #if 0 if (!CodeGenOpts.SampleProfileFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addSampleProfileLoaderPass); #endif // 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 (LangOpts.Sanitize.LocalBounds) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (LangOpts.Sanitize.Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (LangOpts.Sanitize.Memory) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (LangOpts.Sanitize.Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } if (LangOpts.Sanitize.DataFlow) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addDataFlowSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addDataFlowSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(m_Module->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; // Creates a SimpleInliner that requests InsertLifetime. PMBuilder.Inliner = new InlinerKeepDeadFunc(createFunctionInliningPass(Threshold)); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. PMBuilder.Inliner = new InlinerKeepDeadFunc(createAlwaysInlinerPass(false)); else PMBuilder.Inliner = new InlinerKeepDeadFunc(createAlwaysInlinerPass()); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // The Inliner is a module pass; register it. PMBuilder.populateModulePassManager(*getPerModulePasses()); }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); // Allocate a full target machine description only if necessary. // FIXME: The choice of target should be controllable on the command line. std::auto_ptr<TargetMachine> target; SMDiagnostic Err; // Load the input module... std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return 1; } // Figure out what stream we are supposed to write to... // FIXME: outs() is not binary! raw_ostream *Out = &outs(); // Default to printing to stdout... if (OutputFilename != "-") { if (NoOutput || AnalyzeOnly) { errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output or --analyze options are used.\n"; } else { // Make sure that the Output file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); std::string ErrorInfo; Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; delete Out; return 1; } } } // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) if (CheckBitcodeOutputToConsole(*Out, !Quiet)) NoOutput = true; // Create a PassManager to hold and optimize the collection of passes we are // about to build... // PassManager Passes; // Add an appropriate TargetData instance for this module... TargetData *TD = 0; const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) TD = new TargetData(ModuleDataLayout); else if (!DefaultDataLayout.empty()) TD = new TargetData(DefaultDataLayout); if (TD) Passes.add(TD); FunctionPassManager *FPasses = NULL; if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses = new FunctionPassManager(M.get()); if (TD) FPasses->add(new TargetData(*TD)); } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2); OptLevelO2 = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { PassKind Kind = P->getPassKind(); addPass(Passes, P); if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: Passes.add(new BasicBlockPassPrinter(PassInf)); break; case PT_Loop: Passes.add(new LoopPassPrinter(PassInf)); break; case PT_Function: Passes.add(new FunctionPassPrinter(PassInf)); break; case PT_CallGraphSCC: Passes.add(new CallGraphSCCPassPrinter(PassInf)); break; default: Passes.add(new ModulePassPrinter(PassInf)); break; } } } if (PrintEachXForm) Passes.add(createPrintModulePass(&errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, 1); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, 3); if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator I = M.get()->begin(), E = M.get()->end(); I != E; ++I) FPasses->run(*I); } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // Write bitcode or assembly out to disk or outs() as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) Passes.add(createPrintModulePass(Out)); else Passes.add(createBitcodeWriterPass(*Out)); } // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Delete the raw_fd_ostream. if (Out != &outs()) delete Out; return 0; }
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); }
void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; 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 (LangOpts.Sanitize.Bounds) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (LangOpts.Sanitize.Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (LangOpts.Sanitize.Memory) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (LangOpts.Sanitize.Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } // This should depend on duetto, non on byte addressable if (!TM->getDataLayout()->isByteAddressable()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDuettoNativeRewriterPass); // 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(TM); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(TM); if (!CodeGenOpts.DisableGCov && (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if // LLVM's -default-gcov-version flag is set to something invalid. GCOVOptions Options; Options.EmitNotes = CodeGenOpts.EmitGcovNotes; Options.EmitData = CodeGenOpts.EmitGcovArcs; memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4); Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum; Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData; MPM->add(createGCOVProfilerPass(Options)); if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } PMBuilder.populateModulePassManager(*MPM); }
void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); if (!CodeGenOpts.SampleProfileFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addSampleProfileLoaderPass); // 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.FsSemanticConfFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addFsSemanticPass); if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (CodeGenOpts.SanitizeCoverage) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addSanitizerCoveragePass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addSanitizerCoveragePass); } if (LangOpts.Sanitize.has(SanitizerKind::Address)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addDataFlowSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addDataFlowSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = createTLI(TargetTriple, CodeGenOpts); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { PMBuilder.Inliner = createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); 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.VerifyModule) MPM->add(createDebugInfoVerifierPass()); if (!CodeGenOpts.DisableGCov && (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if // LLVM's -default-gcov-version flag is set to something invalid. GCOVOptions Options; Options.EmitNotes = CodeGenOpts.EmitGcovNotes; Options.EmitData = CodeGenOpts.EmitGcovArcs; memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4); Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum; Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData; MPM->add(createGCOVProfilerPass(Options)); if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } PMBuilder.populateModulePassManager(*MPM); }
static int compileInternal(const char *input, int optimize, int optsize, const char *argv0, raw_fd_ostream *fd, CompilerInstance &Clang) { std::string ErrMsg; LLVMContext &Context = getGlobalContext(); std::auto_ptr<Module> M; MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(input, &ErrMsg); if (!Buffer) { errs() << "Could not open temp input file '" << input << "'\n"; return 2; } M.reset(ParseBitcodeFile(Buffer, Context, &ErrMsg)); delete Buffer; if (M.get() == 0) { errs() << "Cannot parse temp input file '" << input << "'" << ErrMsg << "\n"; return 2; } // FIXME: Remove TargetData! //XXX M->setTargetTriple(""); //XXX M->setDataLayout(""); // TODO: let clang handle these PassManager Passes; FunctionPassManager *FPasses = NULL; if (optimize) { FPasses = new FunctionPassManager(M.get()); // FPasses->add(new TargetData(M.get()));//XXX createStandardFunctionPasses(FPasses, optimize); } // Passes.add(new TargetData(M.get()));//XXX unsigned threshold = optsize ? 75 : optimize > 2 ? 275 : 225; createStandardModulePasses(&Passes, optimize, optsize, true, optimize > 1 && !optsize, false, false, optimize > 1 ? createFunctionInliningPass(threshold) : createAlwaysInlinerPass()); if (optimize) { FPasses->doInitialization(); for (Module::iterator I = M.get()->begin(), E = M.get()->end(); I != E; ++I) FPasses->run(*I); Passes.add(createVerifierPass()); Passes.run(*M.get()); } std::string Err2; //TODO: directly construct our target const Target *TheTarget = TargetRegistry::lookupTarget("clambc-generic-generic", Err2); if (TheTarget == 0) { errs() << argv0 << ": error auto-selecting target for module '" << Err2 << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } std::auto_ptr<TargetMachine> Target(TheTarget->createTargetMachine("clambc-generic-generic", "")); //TODO: send it to the -o specified on cmdline // Figure out where we are going to send the output... formatted_raw_ostream *Out2 = new formatted_raw_ostream(*fd, formatted_raw_ostream::DELETE_STREAM); if (Out2 == 0) return 2; CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (optimize) { case 0: OLvl = CodeGenOpt::None; break; case 3: OLvl = CodeGenOpt::Aggressive; break; default: break; } PassManager PM; PM.add(new TargetData(M.get()));//XXX if (Target->addPassesToEmitWholeFile(PM, *Out2, TargetMachine::CGFT_AssemblyFile, OLvl)) { errs() << argv0<< ": target does not support generation of this" << " file type!\n"; if (Out2 != &fouts()) delete Out2; // And the Out file is empty and useless, so remove it now. // sys::Path(OutputFilename).eraseFromDisk(); return 2; } PM.run(*M.get()); delete Out2; 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); }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { if ( this->determineTarget(errMsg) ) return true; Module* mergedModule = _linker.getModule(); // if options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<char **>(&_codegenOptions[0])); // mark which symbols can not be internalized this->applyScopeRestrictions(); // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); // Enabling internalize here would use its AllButMain variant. It // keeps only main if it exists and does nothing for libraries. Instead // we create the pass ourselves with the symbol list provided by the linker. PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false, !DisableInline, DisableGVNLoadPRE); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule); codeGenPasses->add(new TargetData(*_target->getTargetData())); formatted_raw_ostream Out(out); if (_target->addPassesToEmitFile(*codeGenPasses, Out, TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; return true; } bool UsingSAFECode = false; // Add the SAFECode optimization/finalization passes. // Note that we only run these passes (which require DSA) if we detect // that run-time checks have been added to the code. for (unsigned index = 0; index < numChecks; ++index) { if (mergedModule->getFunction(RuntimeChecks[index].name)) { UsingSAFECode = true; break; } } if (UsingSAFECode) { passes.add(new TargetData(*_target->getTargetData())); passes.add(createSAFECodeMSCInfoPass()); passes.add(createExactCheckOptPass()); passes.add(new ScalarEvolution()); passes.add(createLocalArrayBoundsAnalysisPass()); passes.add(createOptimizeFastMemoryChecksPass()); passes.add(createOptimizeIdenticalLSChecksPass()); passes.add(new DominatorTree()); passes.add(new ScalarEvolution()); passes.add(createOptimizeImpliedFastLSChecksPass()); if (mergedModule->getFunction("main")) { passes.add(new CompleteChecks()); } #ifdef POOLALLOC LowerSafecodeIntrinsic::IntrinsicMappingEntry *MapStart, *MapEnd; MapStart = RuntimeDebug; MapEnd = &RuntimeDebug[sizeof(RuntimeDebug) / sizeof(RuntimeDebug[0])]; // Add the automatic pool allocation passes passes.add(new OptimizeSafeLoadStore()); passes.add(new PA::AllNodesHeuristic()); //passes.add(new PoolAllocate()); passes.add(new PoolAllocateSimple()); // SAFECode's debug runtime needs to replace some of the poolalloc // intrinsics; LowerSafecodeIntrinsic handles the replacement. passes.add(new LowerSafecodeIntrinsic(MapStart, MapEnd)); #endif // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); #ifdef POOLALLOC if (const char *OutFileName = getenv("PA_BITCODE_FILE")) { // Write out the pool allocated bitcode file for debugging purposes. std::cerr << "Writing out poolalloc bitcode file to " << OutFileName; std::cerr << std::endl; std::string error; tool_output_file PAFile(OutFileName, error, raw_fd_ostream::F_Binary); if (!error.empty()) { std::cerr << "Error writing out poolalloc bitcode file: " << error; std::cerr << std::endl; } else { WriteBitcodeToFile(mergedModule, PAFile.os()); PAFile.os().close(); PAFile.keep(); } } #endif } // Run the code generator, and write assembly file codeGenPasses->doInitialization(); // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) if (!it->isDeclaration()) codeGenPasses->run(*it); codeGenPasses->doFinalization(); delete codeGenPasses; return false; // success }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errMsg) { if ( this->determineTarget(errMsg) ) return true; // mark which symbols can not be internalized this->applyScopeRestrictions(); Module* mergedModule = _linker.getModule(); // If target supports exception handling then enable it now. if ( _target->getTargetAsmInfo()->doesSupportExceptionHandling() ) llvm::ExceptionHandling = true; // set codegen model switch( _codeModel ) { case LTO_CODEGEN_PIC_MODEL_STATIC: _target->setRelocationModel(Reloc::Static); break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC: _target->setRelocationModel(Reloc::PIC_); break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: _target->setRelocationModel(Reloc::DynamicNoPIC); break; } // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); // Now that we internalized some globals, see if we can hack on them! passes.add(createGlobalOptimizerPass()); // Linking modules together can lead to duplicated global constants, only // keep one copy of each constant... passes.add(createConstantMergePass()); // If the -s command line option was specified, strip the symbols out of the // resulting program to make it smaller. -s is a GLD option that we are // supporting. passes.add(createStripSymbolsPass()); // Propagate constants at call sites into the functions they call. passes.add(createIPConstantPropagationPass()); // Remove unused arguments from functions... passes.add(createDeadArgEliminationPass()); passes.add(createFunctionInliningPass()); // Inline small functions passes.add(createPruneEHPass()); // Remove dead EH info passes.add(createGlobalDCEPass()); // Remove dead functions // If we didn't decide to inline a function, check to see if we can // transform it to pass arguments by value instead of by reference. passes.add(createArgumentPromotionPass()); // The IPO passes may leave cruft around. Clean up after them. passes.add(createInstructionCombiningPass()); passes.add(createJumpThreadingPass()); // Thread jumps. passes.add(createScalarReplAggregatesPass()); // Break up allocas // Run a few AA driven optimizations here and now, to cleanup the code. passes.add(createGlobalsModRefPass()); // IP alias analysis passes.add(createLICMPass()); // Hoist loop invariants passes.add(createGVNPass()); // Remove common subexprs passes.add(createMemCpyOptPass()); // Remove dead memcpy's passes.add(createDeadStoreEliminationPass()); // Nuke dead stores // Cleanup and simplify the code after the scalar optimizations. passes.add(createInstructionCombiningPass()); passes.add(createJumpThreadingPass()); // Thread jumps. // Delete basic blocks, which optimization passes may have killed... passes.add(createCFGSimplificationPass()); // Now that we have optimized the program, discard unreachable functions... passes.add(createGlobalDCEPass()); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager* codeGenPasses = new FunctionPassManager(new ExistingModuleProvider(mergedModule)); codeGenPasses->add(new TargetData(*_target->getTargetData())); MachineCodeEmitter* mce = NULL; switch (_target->addPassesToEmitFile(*codeGenPasses, out, TargetMachine::AssemblyFile, true)) { case FileModel::MachOFile: mce = AddMachOWriter(*codeGenPasses, out, *_target); break; case FileModel::ElfFile: mce = AddELFWriter(*codeGenPasses, out, *_target); break; case FileModel::AsmFile: break; case FileModel::Error: case FileModel::None: errMsg = "target file type not supported"; return true; } if (_target->addPassesToEmitFileFinish(*codeGenPasses, mce, true)) { errMsg = "target does not support generation of this file type"; return true; } // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) { if (!it->isDeclaration()) codeGenPasses->run(*it); } codeGenPasses->doFinalization(); return false; // success }
int main(int argc, char **argv){ cl::ParseCommandLineOptions(argc, argv, "llvm_trace_test\n"); char directory[250]; strncpy(directory, LogDir.c_str(), 250); int len = strlen(directory); if (len > 230){ printf("Directory name too long\n"); exit(1); } LLVMContext &Context = getGlobalContext(); // Load the bitcode... SMDiagnostic Err; Module *Mod = ParseIRFile(strncat(directory, "/llvm-mod.bc", 12), Err, Context); if (!Mod) { Err.print(argv[0], errs()); exit(1); } // Load dynamic log directory[len] = '\0'; dlog = fopen(strncat(directory, "/llvm-memlog.log", 16), "r"); if (!dlog){ printf("Could not find log of dynamic values in specified directory\n"); exit(1); } // Load function log directory[len] = '\0'; flog = fopen(strncat(directory, "/llvm-functions.log", 19), "r"); if (!flog){ printf("Could not find log of LLVM functions in specified directory\n"); exit(1); } // Initialize test function pass FunctionPassManager *FPasses = new FunctionPassManager(Mod); FunctionPass *fp = static_cast<FunctionPass*>(createTestFunctionPass()); FPasses->add(fp); FPasses->doInitialization(); char funcline[500]; Function *F; // Check trace while (true){ strncpy(funcline, "\0", 1); char *s = fgets(funcline, sizeof(funcline), flog); if (feof(flog)){ break; // Done processing trace } // System call information - ignore for test if (!strncmp(funcline, "taint", 5)){ continue; } funcline[strlen(funcline)-1] = '\0'; // remove newline F = Mod->getFunction(funcline); if (F == NULL){ fprintf(stderr, "Error: unknown function, %s\n", funcline); exit(1); } //printf("%s\n", F->getName().str().c_str()); FPasses->run(*F); // Call runOnFunction() } fclose(flog); fclose(dlog); printf("Trace and dynamic log are aligned.\n"); return 0; }
MonoEERef mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee) { std::string Error; MonoEE *mono_ee; init_llvm (); mono_ee = new MonoEE (); MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager (); mono_mm->alloc_cb = alloc_cb; mono_mm->dlsym_cb = dlsym_cb; mono_mm->exception_cb = exception_cb; mono_ee->mm = mono_mm; /* * The Default code model doesn't seem to work on amd64, * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call * memset using a normal pcrel code which is in 32bit memory, while memset isn't. */ TargetOptions opts; opts.JITExceptionHandling = 1; StringRef cpu_name = sys::getHostCPUName (); // EngineBuilder no longer has a copy assignment operator (?) std::unique_ptr<Module> Owner(unwrap(MP)); EngineBuilder b (std::move(Owner)); ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create (); g_assert (EE); mono_ee->EE = EE; MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb); EE->RegisterJITEventListener (listener); mono_ee->listener = listener; FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP)); mono_ee->fpm = fpm; fpm->add(new DataLayoutPass(*EE->getDataLayout())); if (PassList.size() > 0) { /* Use the passes specified by the env variable */ /* Only the passes in force_pass_linking () can be used */ for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); fpm->add (P); } } else { /* Use the same passes used by 'opt' by default, without the ipo passes */ const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg"; char **args; int i; args = g_strsplit (opts, " ", 1000); for (i = 0; args [i]; i++) ; llvm::cl::ParseCommandLineOptions (i, args, ""); g_strfreev (args); for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop); fpm->add (P); } /* fpm->add(createInstructionCombiningPass()); fpm->add(createReassociatePass()); fpm->add(createGVNPass()); fpm->add(createCFGSimplificationPass()); */ } *ee = wrap (EE); return mono_ee; }
/// Optimize module M using various IPO passes. Use exportList to /// internalize selected symbols. Target platform is selected /// based on information available to module M. No new target /// features are selected. enum LTOStatus LTO::optimize(Module *M, std::ostream &Out, std::vector<const char *> &exportList) { // Instantiate the pass manager to organize the passes. PassManager Passes; // Collect Target info getTarget(M); if (!Target) return LTO_NO_TARGET; // If target supports exception handling then enable it now. if (Target->getTargetAsmInfo()->doesSupportExceptionHandling()) ExceptionHandling = true; // Start off with a verification pass. Passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... Passes.add(new TargetData(*Target->getTargetData())); // Internalize symbols if export list is nonemty if (!exportList.empty()) Passes.add(createInternalizePass(exportList)); // Now that we internalized some globals, see if we can hack on them! Passes.add(createGlobalOptimizerPass()); // Linking modules together can lead to duplicated global constants, only // keep one copy of each constant... Passes.add(createConstantMergePass()); // If the -s command line option was specified, strip the symbols out of the // resulting program to make it smaller. -s is a GLD option that we are // supporting. Passes.add(createStripSymbolsPass()); // Propagate constants at call sites into the functions they call. Passes.add(createIPConstantPropagationPass()); // Remove unused arguments from functions... Passes.add(createDeadArgEliminationPass()); Passes.add(createFunctionInliningPass()); // Inline small functions Passes.add(createPruneEHPass()); // Remove dead EH info Passes.add(createGlobalDCEPass()); // Remove dead functions // If we didn't decide to inline a function, check to see if we can // transform it to pass arguments by value instead of by reference. Passes.add(createArgumentPromotionPass()); // The IPO passes may leave cruft around. Clean up after them. Passes.add(createInstructionCombiningPass()); Passes.add(createScalarReplAggregatesPass()); // Break up allocas // Run a few AA driven optimizations here and now, to cleanup the code. Passes.add(createGlobalsModRefPass()); // IP alias analysis Passes.add(createLICMPass()); // Hoist loop invariants Passes.add(createGVNPass()); // Remove common subexprs Passed.add(createMemCpyOptPass()); // Remove dead memcpy's Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores // Cleanup and simplify the code after the scalar optimizations. Passes.add(createInstructionCombiningPass()); // Delete basic blocks, which optimization passes may have killed... Passes.add(createCFGSimplificationPass()); // Now that we have optimized the program, discard unreachable functions... Passes.add(createGlobalDCEPass()); // Make sure everything is still good. Passes.add(createVerifierPass()); FunctionPassManager *CodeGenPasses = new FunctionPassManager(new ExistingModuleProvider(M)); CodeGenPasses->add(new TargetData(*Target->getTargetData())); MachineCodeEmitter *MCE = 0; switch (Target->addPassesToEmitFile(*CodeGenPasses, Out, TargetMachine::AssemblyFile, true)) { default: case FileModel::Error: return LTO_WRITE_FAILURE; case FileModel::AsmFile: break; case FileModel::MachOFile: MCE = AddMachOWriter(*CodeGenPasses, Out, *Target); break; case FileModel::ElfFile: MCE = AddELFWriter(*CodeGenPasses, Out, *Target); break; } if (Target->addPassesToEmitFileFinish(*CodeGenPasses, MCE, true)) return LTO_WRITE_FAILURE; // Run our queue of passes all at once now, efficiently. Passes.run(*M); // Run the code generator, if present. CodeGenPasses->doInitialization(); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { if (!I->isDeclaration()) CodeGenPasses->run(*I); } CodeGenPasses->doFinalization(); return LTO_OPT_SUCCESS; }