/// 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(); }
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 JITOptimizations::runOnFunction(Function& F) { this->LI = &getAnalysis<LoopInfo>(); bool changed = false; FPM = new FunctionPassManager(F.getParent()); // if the user input something we use those passes std::vector<const PassInfo *> &customPasses = JPD->getPassList(); if (customPasses.size() > 0) { for (int i=0; i<customPasses.size();i++) { const PassInfo *pass = customPasses[i]; FPM->add(pass->createPass()); } } else { // Optimization ordering: // - ADCE // - inline // - DSE <---- THIS causes seg faults when running on sqlite3 // test in llvm test-suite // - Instruction Combining // ---- IF LOOPS ---- // - LICM // - Loop Simplify // - Loop Strength Reduction // ------------------ // - SCCP // - Simplify CFG // - SROA FPM->add(createAggressiveDCEPass()); if (JPD->getThresholdT2() != 0) FPM->add(createDynamicInlinerPass(JPD)); FPM->add(createInstructionCombiningPass()); // --- Loop optimizations --- // if (LI->begin() != LI->end()) { FPM->add(createLICMPass()); FPM->add(createLoopSimplifyPass()); FPM->add(createLoopStrengthReducePass()); } // -------------------------- // FPM->add(createSCCPPass()); FPM->add(createCFGSimplificationPass()); FPM->add(createSROAPass(false)); } changed = changed | FPM->doInitialization(); changed = changed | FPM->run(F); changed = changed | FPM->doFinalization(); delete FPM; return changed; }
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; }
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); }
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; }
/// 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 }
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; }
/// 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; }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(formatted_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 target supports exception handling then enable it now. switch (_target->getTargetAsmInfo()->getExceptionHandlingType()) { case ExceptionHandling::Dwarf: llvm::DwarfExceptionHandling = true; break; case ExceptionHandling::SjLj: llvm::SjLjExceptionHandling = true; break; case ExceptionHandling::None: break; default: assert (0 && "Unknown exception handling model!"); } // if options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), (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(new ExistingModuleProvider(mergedModule)); codeGenPasses->add(new TargetData(*_target->getTargetData())); ObjectCodeEmitter* oce = NULL; switch (_target->addPassesToEmitFile(*codeGenPasses, out, TargetMachine::AssemblyFile, CodeGenOpt::Aggressive)) { case FileModel::MachOFile: oce = AddMachOWriter(*codeGenPasses, out, *_target); break; case FileModel::ElfFile: oce = 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, oce, CodeGenOpt::Aggressive)) { 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(); out.flush(); return false; // success }
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; }
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; }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { // if options were requested, set them if (!_codegenOptions.empty()) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<char **>(&_codegenOptions[0])); if (this->determineTarget(errMsg)) return true; Module* mergedModule = _linker.getModule(); // 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 DataLayout instance for this module... passes.add(new DataLayout(*_target->getDataLayout())); passes.add(new TargetTransformInfo(_target->getScalarTargetTransformInfo(), _target->getVectorTargetTransformInfo())); // 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 DataLayout(*_target->getDataLayout())); formatted_raw_ostream Out(out); if (_target->addPassesToEmitFile(*codeGenPasses, Out, TargetMachine::CGFT_ObjectFile)) { 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(); delete codeGenPasses; return false; // success }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); sys::PrintStackTraceOnErrorSignal(); // 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; std::string ErrorMessage; // Load the input module... std::auto_ptr<Module> M; if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { M.reset(ParseBitcodeFile(Buffer, &ErrorMessage)); delete Buffer; } if (M.get() == 0) { cerr << argv[0] << ": "; if (ErrorMessage.size()) cerr << ErrorMessage << "\n"; else cerr << "bitcode didn't read correctly.\n"; return 1; } // Figure out what stream we are supposed to write to... // FIXME: cout is not binary! std::ostream *Out = &std::cout; // Default to printing to stdout... if (OutputFilename != "-") { if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! cerr << argv[0] << ": error opening '" << OutputFilename << "': file exists!\n" << "Use -f command line argument to force output\n"; return 1; } std::ios::openmode io_mode = std::ios::out | std::ios::trunc | std::ios::binary; Out = new std::ofstream(OutputFilename.c_str(), io_mode); if (!Out->good()) { cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; return 1; } // Make sure that the Output file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // 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 && 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... Passes.add(new TargetData(M.get())); FunctionPassManager *FPasses = NULL; if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses = new FunctionPassManager(new ExistingModuleProvider(M.get())); FPasses->add(new TargetData(M.get())); } // 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 (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 cerr << argv[0] << ": cannot create pass: "******"\n"; if (P) { bool isBBPass = dynamic_cast<BasicBlockPass*>(P) != 0; bool isLPass = !isBBPass && dynamic_cast<LoopPass*>(P) != 0; bool isFPass = !isLPass && dynamic_cast<FunctionPass*>(P) != 0; bool isCGSCCPass = !isFPass && dynamic_cast<CallGraphSCCPass*>(P) != 0; addPass(Passes, P); if (AnalyzeOnly) { if (isBBPass) Passes.add(new BasicBlockPassPrinter(PassInf)); else if (isLPass) Passes.add(new LoopPassPrinter(PassInf)); else if (isFPass) Passes.add(new FunctionPassPrinter(PassInf)); else if (isCGSCCPass) Passes.add(new CallGraphSCCPassPrinter(PassInf)); else Passes.add(new ModulePassPrinter(PassInf)); } } 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 (OptLevelO1) { AddOptimizationPasses(Passes, *FPasses, 1); } if (OptLevelO2) { AddOptimizationPasses(Passes, *FPasses, 2); } if (OptLevelO3) { AddOptimizationPasses(Passes, *FPasses, 3); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { 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 out to disk or cout as the last step... if (!NoOutput && !AnalyzeOnly) Passes.add(CreateBitcodeWriterPass(*Out)); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Delete the ofstream. if (Out != &std::cout) delete Out; return 0; } catch (const std::string& msg) { cerr << argv[0] << ": " << msg << "\n"; } catch (...) { cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; } llvm_shutdown(); return 1; }
//===----------------------------------------------------------------------===// // 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; }
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; }