// Out of line constructor provides default values for pass options and // registers all common codegen passes. TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm) : ImmutablePass(ID), PM(&pm), TM(&TM) { Impl = new PassConfigImpl(); // Register all target independent codegen passes to activate their PassIDs, // including this pass itself. initializeCodeGen(*PassRegistry::getPassRegistry()); // Also register alias analysis passes required by codegen passes. initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry()); initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); if (StringRef(PrintMachineInstrs.getValue()).equals("")) TM.Options.PrintMachineCode = true; if (EnableIPRA.getNumOccurrences()) TM.Options.EnableIPRA = EnableIPRA; else { // If not explicitly specified, use target default. TM.Options.EnableIPRA |= TM.useIPRA(); } if (TM.Options.EnableIPRA) setRequiresCodeGenSCCOrder(); if (EnableGlobalISelAbort.getNumOccurrences()) TM.Options.GlobalISelAbort = EnableGlobalISelAbort; setStartStopPasses(); }
int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); cl::ParseCommandLineOptions(argc, argv, "Bitcode strip tool\n"); int input_fd = open(InputFilename.c_str(), O_RDONLY); unsigned char *wrapper = NULL; char *bitcode = NULL; // Read bitcode wrapper size_t bitcode_size = 0; size_t wrapper_size = ReadBitcodeWrapper(input_fd, &wrapper, bitcode_size); // Read bitcode bitcode = (char*) calloc(1, bitcode_size); size_t nread = read(input_fd, (void*) bitcode, bitcode_size); if (nread != bitcode_size) { errs() << "Could not read bitcode\n"; return 1; } // Strip bitcode std::string BCString; StripBitcode(bitcode, bitcode_size, BCString, Context); // Update bitcode size WriteInt32(wrapper, 12, BCString.length()); // Default to input filename if (OutputFilename.empty()) OutputFilename.getValue() = InputFilename; // Output stripped bitcode std::error_code EC; tool_output_file Out(OutputFilename.c_str(), EC, sys::fs::F_None); if (EC) { errs() << EC.message() << '\n'; return 1; } Out.os().write((const char *) wrapper, wrapper_size); Out.os().write(BCString.c_str(), BCString.length()); Out.keep(); // Clean up free((void *) wrapper); free((void *) bitcode); close(input_fd); return 0; }
int main(int argc, const char **argv) { CommonOptionsParser OptionsParser(argc, argv, NoGlobalStyleCategory); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); MatchFinder finder; // Snarf abstract-only namespaces from the environment. std::vector<std::string> abstract_namespaces_v, banned_namespaces_v; std::copy(abstract_namespaces.begin(), abstract_namespaces.end(), std::back_inserter(abstract_namespaces_v)); std::copy(banned_namespaces.begin(), banned_namespaces.end(), std::back_inserter(banned_namespaces_v)); std::unique_ptr<RuleCheckerBase> rules[] = { make_unique<DisallowNew>(), make_unique<DisallowDelete>(), make_unique<DisallowGlobals>(), make_unique<DisallowNonAbstract>(abstract_namespaces_v), make_unique<DisallowCoupling>(banned_namespaces_v) }; size_t rules_size = sizeof(rules) / sizeof(rules[0]); auto rules_begin = &rules[0]; auto rules_end = &rules[rules_size]; std::vector<std::string> analyze_paths_v; std::copy(analyze_paths.begin(), analyze_paths.end(), std::back_inserter(analyze_paths_v)); for (size_t i = 0; i < sizeof(rules) / sizeof(rules[0]); ++i) { auto &rule = rules[i]; rule->setAnalyzePaths(analyze_paths_v); rule->SetupMatches(finder); rule->getPrinter().setDebug(Debug.getValue()); } #ifndef NDEBUG llvm::DebugFlag = Debug.getValue(); #endif return Tool.run(newFrontendActionFactory(&finder).get()) || (Werror.getValue() && std::any_of (rules_begin, rules_end, [] (const std::unique_ptr<RuleCheckerBase> &rule) { return rule->getPrinter().getWarnings(); })); }
/*! * Initialization of pointer analysis */ void PointerAnalysis::initialize(Module& module) { /// whether we have already built PAG if(pag == NULL) { /// run class hierarchy analysis chgraph = new CHGraph(); chgraph->buildCHG(module); DBOUT(DGENERAL, outs() << pasMsg("Building Symbol table ...\n")); SymbolTableInfo* symTable = SymbolTableInfo::Symbolnfo(); symTable->buildMemModel(module); DBOUT(DGENERAL, outs() << pasMsg("Building PAG ...\n")); if (!Graphtxt.getValue().empty()) { PAGBuilderFromFile fileBuilder(Graphtxt.getValue()); pag = fileBuilder.build(); } else { PAGBuilder builder; pag = builder.build(module); } // dump the PAG graph if (dumpGraph()) PAG::getPAG()->dump("pag_initial"); // print to command line of the PAG graph if (PAGPrint) pag->print(); } typeSystem = new TypeSystem(pag); mod = &module; /// initialise pta call graph if(EnableThreadCallGraph) ptaCallGraph = new ThreadCallGraph(mod); else ptaCallGraph = new PTACallGraph(mod); callGraphSCCDetection(); }
bool TFA::runOnModule(Module &M) { if (Input.getValue() == llvm::cl::BOU_UNSET || Input.getValue() == llvm::cl::BOU_TRUE) { InputValues &IV = getAnalysis<InputValues> (); inputDepValues = IV.getInputDepValues(); } else { InputDep &IV = getAnalysis<InputDep> (); inputDepValues = IV.getInputDepValues(); } bSSA &bssa = getAnalysis<bSSA> (); depGraph = bssa.newGraph; DEBUG( // display dependence graph string Error; std::string tmp = M.getModuleIdentifier(); replace(tmp.begin(), tmp.end(), '\\', '_'); std::string Filename = "/tmp/" + tmp + ".dot"; //Print dependency graph (in dot format) depGraph->toDot(M.getModuleIdentifier(), Filename); DisplayGraph(Filename, true, GraphProgram::DOT); );
void Executor::initTimers() { static bool first = true; if (first) { first = false; setupHandler(); } if (MaxTime) { addTimer(new HaltTimer(this), MaxTime.getValue()); } }
/// \brief Emit an inline hint if \p F is globally hot or cold. /// /// If \p F consumes a significant fraction of samples (indicated by /// SampleProfileGlobalHotThreshold), apply the InlineHint attribute for the /// inliner to consider the function hot. /// /// If \p F consumes a small fraction of samples (indicated by /// SampleProfileGlobalColdThreshold), apply the Cold attribute for the inliner /// to consider the function cold. /// /// FIXME - This setting of inline hints is sub-optimal. Instead of marking a /// function globally hot or cold, we should be annotating individual callsites. /// This is not currently possible, but work on the inliner will eventually /// provide this ability. See http://reviews.llvm.org/D15003 for details and /// discussion. /// /// \returns True if either attribute was applied to \p F. bool SampleProfileLoader::emitInlineHints(Function &F) { if (TotalCollectedSamples == 0) return false; uint64_t FunctionSamples = Samples->getTotalSamples(); double SamplesPercent = (double)FunctionSamples / (double)TotalCollectedSamples * 100.0; // If the function collected more samples than the hot threshold, mark // it globally hot. if (SamplesPercent >= SampleProfileGlobalHotThreshold) { F.addFnAttr(llvm::Attribute::InlineHint); std::string Msg; raw_string_ostream S(Msg); S << "Applied inline hint to globally hot function '" << F.getName() << "' with " << format("%.2f", SamplesPercent) << "% of samples (threshold: " << format("%.2f", SampleProfileGlobalHotThreshold.getValue()) << "%)"; S.flush(); emitOptimizationRemark(F.getContext(), DEBUG_TYPE, F, DebugLoc(), Msg); return true; } // If the function collected fewer samples than the cold threshold, mark // it globally cold. if (SamplesPercent <= SampleProfileGlobalColdThreshold) { F.addFnAttr(llvm::Attribute::Cold); std::string Msg; raw_string_ostream S(Msg); S << "Applied cold hint to globally cold function '" << F.getName() << "' with " << format("%.2f", SamplesPercent) << "% of samples (threshold: " << format("%.2f", SampleProfileGlobalColdThreshold.getValue()) << "%)"; S.flush(); emitOptimizationRemark(F.getContext(), DEBUG_TYPE, F, DebugLoc(), Msg); return true; } return false; }
// This checks whether the transformation is legal. // Also returns false in cases where it's potentially legal, but // we don't even want to try. bool X86CallFrameOptimization::isLegal(MachineFunction &MF) { if (NoX86CFOpt.getValue()) return false; // We currently only support call sequences where *all* parameters. // are passed on the stack. // No point in running this in 64-bit mode, since some arguments are // passed in-register in all common calling conventions, so the pattern // we're looking for will never match. if (STI->is64Bit()) return false; // We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset // in the compact unwind encoding that Darwin uses. So, bail if there // is a danger of that being generated. if (STI->isTargetDarwin() && (!MF.getMMI().getLandingPads().empty() || (MF.getFunction()->needsUnwindTableEntry() && !TFL->hasFP(MF)))) return false; // You would expect straight-line code between call-frame setup and // call-frame destroy. You would be wrong. There are circumstances (e.g. // CMOV_GR8 expansion of a select that feeds a function call!) where we can // end up with the setup and the destroy in different basic blocks. // This is bad, and breaks SP adjustment. // So, check that all of the frames in the function are closed inside // the same block, and, for good measure, that there are no nested frames. unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode(); unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode(); for (MachineBasicBlock &BB : MF) { bool InsideFrameSequence = false; for (MachineInstr &MI : BB) { if (MI.getOpcode() == FrameSetupOpcode) { if (InsideFrameSequence) return false; InsideFrameSequence = true; } else if (MI.getOpcode() == FrameDestroyOpcode) { if (!InsideFrameSequence) return false; InsideFrameSequence = false; } } if (InsideFrameSequence) return false; } return true; }
// This checks whether the transformation is legal. // Also returns false in cases where it's potentially legal, but // we don't even want to try. bool X86CallFrameOptimization::isLegal(MachineFunction &MF) { if (NoX86CFOpt.getValue()) return false; // We can't encode multiple DW_CFA_GNU_args_size or DW_CFA_def_cfa_offset // in the compact unwind encoding that Darwin uses. So, bail if there // is a danger of that being generated. if (STI->isTargetDarwin() && (!MF.getLandingPads().empty() || (MF.getFunction().needsUnwindTableEntry() && !TFL->hasFP(MF)))) return false; // It is not valid to change the stack pointer outside the prolog/epilog // on 64-bit Windows. if (STI->isTargetWin64()) return false; // You would expect straight-line code between call-frame setup and // call-frame destroy. You would be wrong. There are circumstances (e.g. // CMOV_GR8 expansion of a select that feeds a function call!) where we can // end up with the setup and the destroy in different basic blocks. // This is bad, and breaks SP adjustment. // So, check that all of the frames in the function are closed inside // the same block, and, for good measure, that there are no nested frames. unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode(); unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode(); for (MachineBasicBlock &BB : MF) { bool InsideFrameSequence = false; for (MachineInstr &MI : BB) { if (MI.getOpcode() == FrameSetupOpcode) { if (InsideFrameSequence) return false; InsideFrameSequence = true; } else if (MI.getOpcode() == FrameDestroyOpcode) { if (!InsideFrameSequence) return false; InsideFrameSequence = false; } } if (InsideFrameSequence) return false; } return true; }
// This checks whether the transformation is legal. // Also returns false in cases where it's potentially legal, but // we don't even want to try. bool X86CallFrameOptimization::isLegal(MachineFunction &MF) { if (NoX86CFOpt.getValue()) return false; // We currently only support call sequences where *all* parameters. // are passed on the stack. // No point in running this in 64-bit mode, since some arguments are // passed in-register in all common calling conventions, so the pattern // we're looking for will never match. const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>(); if (STI.is64Bit()) return false; // You would expect straight-line code between call-frame setup and // call-frame destroy. You would be wrong. There are circumstances (e.g. // CMOV_GR8 expansion of a select that feeds a function call!) where we can // end up with the setup and the destroy in different basic blocks. // This is bad, and breaks SP adjustment. // So, check that all of the frames in the function are closed inside // the same block, and, for good measure, that there are no nested frames. unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode(); unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode(); for (MachineBasicBlock &BB : MF) { bool InsideFrameSequence = false; for (MachineInstr &MI : BB) { if (MI.getOpcode() == FrameSetupOpcode) { if (InsideFrameSequence) return false; InsideFrameSequence = true; } else if (MI.getOpcode() == FrameDestroyOpcode) { if (!InsideFrameSequence) return false; InsideFrameSequence = false; } } if (InsideFrameSequence) return false; } return true; }
int main(int argc, const char *argv[]) { cl::ParseCommandLineOptions(argc, argv, "SPIR verifier"); if (InputFilename.empty()) { errs() << HelpMessage; return 1; } StringRef Path = InputFilename; LLVMContext Ctx; OwningPtr<MemoryBuffer> result; // Parse the bitcode file into a module. error_code ErrCode = MemoryBuffer::getFile(Path, result); if (!result.get()) { errs() << "Buffer Creation Error. " << ErrCode.message() << "\n"; return 1; } std::string ErrMsg; Module *M = ParseBitcodeFile(result.get(), Ctx, &ErrMsg); if (!M) { outs() << "According to this SPIR Verifier, " << Path << " is an invalid SPIR module.\n"; errs() << "Bitcode parsing error. " << ErrMsg << "\n"; return 1; } // Run the verification pass, and report errors if necessary. SpirValidation Validation; Validation.runOnModule(*M); const ErrorPrinter *EP = Validation.getErrorPrinter(); if (EP->hasErrors()) { outs() << "According to this SPIR Verifier, " << Path << " is an invalid SPIR module.\n"; errs() << "The module contains the following errors:\n\n"; EP->print(errs(), LITMode.getValue()); return 1; } outs() << "According to this SPIR Verifier, " << Path << " is a valid SPIR module.\n"; return 0; }
// Out of line constructor provides default values for pass options and // registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) : ImmutablePass(ID), PM(&pm), Started(true), Stopped(false), AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false), DisableVerify(false), EnableTailMerge(true) { Impl = new PassConfigImpl(); // Register all target independent codegen passes to activate their PassIDs, // including this pass itself. initializeCodeGen(*PassRegistry::getPassRegistry()); // Also register alias analysis passes required by codegen passes. initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry()); initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry()); // Substitute Pseudo Pass IDs for real ones. substitutePass(&EarlyTailDuplicateID, &TailDuplicateID); substitutePass(&PostRAMachineLICMID, &MachineLICMID); if (StringRef(PrintMachineInstrs.getValue()).equals("")) TM->Options.PrintMachineCode = true; }
void RegionInfo::print(raw_ostream &OS, const Module *) const { OS << "Region tree:\n"; TopLevelRegion->print(OS, true, 0, printStyle.getValue()); OS << "End region tree\n"; }
void Region::dump() const { print(dbgs(), true, getDepth(), printStyle.getValue()); }
/// Add the complete set of target-independent postISel code generator passes. /// /// This can be read as the standard order of major LLVM CodeGen stages. Stages /// with nontrivial configuration or multiple passes are broken out below in /// add%Stage routines. /// /// Any TargetPassConfig::addXX routine may be overriden by the Target. The /// addPre/Post methods with empty header implementations allow injecting /// target-specific fixups just before or after major stages. Additionally, /// targets have the flexibility to change pass order within a stage by /// overriding default implementation of add%Stage routines below. Each /// technique has maintainability tradeoffs because alternate pass orders are /// not well supported. addPre/Post works better if the target pass is easily /// tied to a common pass. But if it has subtle dependencies on multiple passes, /// the target should override the stage instead. /// /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection /// before/after any target-independent pass. But it's currently overkill. void TargetPassConfig::addMachinePasses() { // Insert a machine instr printer pass after the specified pass. // If -print-machineinstrs specified, print machineinstrs after all passes. if (StringRef(PrintMachineInstrs.getValue()).equals("")) TM->Options.PrintMachineCode = true; else if (!StringRef(PrintMachineInstrs.getValue()) .equals("option-unspecified")) { const PassRegistry *PR = PassRegistry::getPassRegistry(); const PassInfo *TPI = PR->getPassInfo(PrintMachineInstrs.getValue()); const PassInfo *IPI = PR->getPassInfo(StringRef("print-machineinstrs")); assert (TPI && IPI && "Pass ID not registered!"); const char *TID = (const char *)(TPI->getTypeInfo()); const char *IID = (const char *)(IPI->getTypeInfo()); insertPass(TID, IID); } // Print the instruction selected machine code... printAndVerify("After Instruction Selection"); // Expand pseudo-instructions emitted by ISel. if (addPass(&ExpandISelPseudosID)) printAndVerify("After ExpandISelPseudos"); // Add passes that optimize machine instructions in SSA form. if (getOptLevel() != CodeGenOpt::None) { addMachineSSAOptimization(); } else { // If the target requests it, assign local variables to stack slots relative // to one another and simplify frame index references where possible. addPass(&LocalStackSlotAllocationID); } // Run pre-ra passes. if (addPreRegAlloc()) printAndVerify("After PreRegAlloc passes"); // Run register allocation and passes that are tightly coupled with it, // including phi elimination and scheduling. if (getOptimizeRegAlloc()) addOptimizedRegAlloc(createRegAllocPass(true)); else addFastRegAlloc(createRegAllocPass(false)); // Run post-ra passes. if (addPostRegAlloc()) printAndVerify("After PostRegAlloc passes"); // Insert prolog/epilog code. Eliminate abstract frame index references... addPass(&PrologEpilogCodeInserterID); printAndVerify("After PrologEpilogCodeInserter"); /// Add passes that optimize machine instructions after register allocation. if (getOptLevel() != CodeGenOpt::None) addMachineLateOptimization(); // Expand pseudo instructions before second scheduling pass. addPass(&ExpandPostRAPseudosID); printAndVerify("After ExpandPostRAPseudos"); // Run pre-sched2 passes. if (addPreSched2()) printAndVerify("After PreSched2 passes"); // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None) { if (MISchedPostRA) addPass(&PostMachineSchedulerID); else addPass(&PostRASchedulerID); printAndVerify("After PostRAScheduler"); } // GC if (addGCPasses()) { if (PrintGCInfo) addPass(createGCInfoPrinter(dbgs())); } // Basic block placement. if (getOptLevel() != CodeGenOpt::None) addBlockPlacement(); if (addPreEmitPass()) printAndVerify("After PreEmit passes"); addPass(&StackMapLivenessID); }
RegisterArguments() : SpecializeArguments(ArgumentsFileName == "" ? "arguments" : ArgumentsFileName.getValue().c_str(), SpecializeProgName.getValue() == "" ? NULL : SpecializeProgName.getValue().c_str()) { }
void LatencyAccountant::exportStats(const XRayFileHeader &Header, F Fn) const { std::vector<TupleType> Results; Results.reserve(FunctionLatencies.size()); for (auto FT : FunctionLatencies) { const auto &FuncId = FT.first; auto &Timings = FT.second; Results.emplace_back(FuncId, Timings.size(), getStats(Timings)); auto &Row = std::get<2>(Results.back()); if (Header.CycleFrequency) { double CycleFrequency = Header.CycleFrequency; Row.Min /= CycleFrequency; Row.Median /= CycleFrequency; Row.Pct90 /= CycleFrequency; Row.Pct99 /= CycleFrequency; Row.Max /= CycleFrequency; Row.Sum /= CycleFrequency; } Row.Function = FuncIdHelper.SymbolOrNumber(FuncId); Row.DebugInfo = FuncIdHelper.FileLineAndColumn(FuncId); } // Sort the data according to user-provided flags. switch (AccountSortOutput) { case SortField::FUNCID: sortByKey(Results, [](const TupleType &X) { return std::get<0>(X); }); break; case SortField::COUNT: sortByKey(Results, [](const TupleType &X) { return std::get<1>(X); }); break; case SortField::MIN: sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Min; }); break; case SortField::MED: sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Median; }); break; case SortField::PCT90: sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Pct90; }); break; case SortField::PCT99: sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Pct99; }); break; case SortField::MAX: sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Max; }); break; case SortField::SUM: sortByKey(Results, [](const TupleType &X) { return std::get<2>(X).Sum; }); break; case SortField::FUNC: llvm_unreachable("Not implemented"); } if (AccountTop > 0) { auto MaxTop = std::min(AccountTop.getValue(), static_cast<int>(Results.size())); Results.erase(Results.begin() + MaxTop, Results.end()); } for (const auto &R : Results) Fn(std::get<0>(R), std::get<1>(R), std::get<2>(R)); }
/// Add the complete set of target-independent postISel code generator passes. /// /// This can be read as the standard order of major LLVM CodeGen stages. Stages /// with nontrivial configuration or multiple passes are broken out below in /// add%Stage routines. /// /// Any TargetPassConfig::addXX routine may be overriden by the Target. The /// addPre/Post methods with empty header implementations allow injecting /// target-specific fixups just before or after major stages. Additionally, /// targets have the flexibility to change pass order within a stage by /// overriding default implementation of add%Stage routines below. Each /// technique has maintainability tradeoffs because alternate pass orders are /// not well supported. addPre/Post works better if the target pass is easily /// tied to a common pass. But if it has subtle dependencies on multiple passes, /// the target should override the stage instead. /// /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection /// before/after any target-independent pass. But it's currently overkill. void TargetPassConfig::addMachinePasses() { AddingMachinePasses = true; // Insert a machine instr printer pass after the specified pass. StringRef PrintMachineInstrsPassName = PrintMachineInstrs.getValue(); if (!PrintMachineInstrsPassName.equals("") && !PrintMachineInstrsPassName.equals("option-unspecified")) { if (const PassInfo *TPI = getPassInfo(PrintMachineInstrsPassName)) { const PassRegistry *PR = PassRegistry::getPassRegistry(); const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer")); assert(IPI && "failed to get \"machineinstr-printer\" PassInfo!"); const char *TID = (const char *)(TPI->getTypeInfo()); const char *IID = (const char *)(IPI->getTypeInfo()); insertPass(TID, IID); } } // Print the instruction selected machine code... printAndVerify("After Instruction Selection"); // Expand pseudo-instructions emitted by ISel. addPass(&ExpandISelPseudosID); // Add passes that optimize machine instructions in SSA form. if (getOptLevel() != CodeGenOpt::None) { addMachineSSAOptimization(); } else { // If the target requests it, assign local variables to stack slots relative // to one another and simplify frame index references where possible. addPass(&LocalStackSlotAllocationID, false); } if (TM->Options.EnableIPRA) addPass(createRegUsageInfoPropPass()); // Run pre-ra passes. addPreRegAlloc(); // Run register allocation and passes that are tightly coupled with it, // including phi elimination and scheduling. if (getOptimizeRegAlloc()) addOptimizedRegAlloc(createRegAllocPass(true)); else { if (RegAlloc != &useDefaultRegisterAllocator && RegAlloc != &createFastRegisterAllocator) report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc."); addFastRegAlloc(createRegAllocPass(false)); } // Run post-ra passes. addPostRegAlloc(); // Insert prolog/epilog code. Eliminate abstract frame index references... if (getOptLevel() != CodeGenOpt::None) { addPass(&PostRAMachineSinkingID); addPass(&ShrinkWrapID); } // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only // do so if it hasn't been disabled, substituted, or overridden. if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID)) addPass(createPrologEpilogInserterPass()); /// Add passes that optimize machine instructions after register allocation. if (getOptLevel() != CodeGenOpt::None) addMachineLateOptimization(); // Expand pseudo instructions before second scheduling pass. addPass(&ExpandPostRAPseudosID); // Run pre-sched2 passes. addPreSched2(); if (EnableImplicitNullChecks) addPass(&ImplicitNullChecksID); // Second pass scheduler. // Let Target optionally insert this pass by itself at some other // point. if (getOptLevel() != CodeGenOpt::None && !TM->targetSchedulesPostRAScheduling()) { if (MISchedPostRA) addPass(&PostMachineSchedulerID); else addPass(&PostRASchedulerID); } // GC if (addGCPasses()) { if (PrintGCInfo) addPass(createGCInfoPrinter(dbgs()), false, false); } // Basic block placement. if (getOptLevel() != CodeGenOpt::None) addBlockPlacement(); addPreEmitPass(); if (TM->Options.EnableIPRA) // Collect register usage information and produce a register mask of // clobbered registers, to be used to optimize call sites. addPass(createRegUsageInfoCollector()); addPass(&FuncletLayoutID, false); addPass(&StackMapLivenessID, false); addPass(&LiveDebugValuesID, false); // Insert before XRay Instrumentation. addPass(&FEntryInserterID, false); addPass(&XRayInstrumentationID, false); addPass(&PatchableFunctionID, false); if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None && EnableMachineOutliner != NeverOutline) { bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline); bool AddOutliner = RunOnAllFunctions || TM->Options.SupportsDefaultOutlining; if (AddOutliner) addPass(createMachineOutlinerPass(RunOnAllFunctions)); } // Add passes that directly emit MI after all other MI passes. addPreEmitPass2(); AddingMachinePasses = false; }
//Command line decoder control void startCmdLine(){ LLVMContext &Context = getGlobalContext(); for (unsigned int i =0 ; i < PassList.size(); i++ ){ cout << "Pass added: "<< PassList[i]->getPassName() << endl; cout << "Argument name :" << PassList[i]->getPassArgument() << endl; } clock_t timer = clock(); //Parsing XDF file std::cout << "Parsing file " << XDFFile.getValue() << "." << endl; XDFParser xdfParser(Verbose); Network* network = xdfParser.parseFile(XDFFile, Context); cout << "Network parsed in : "<< (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms, start engine" << endl; //Parsing XCF file if needed if(XCFFile != "") { std::cout << "Parsing file " << XCFFile.getValue() << "." << endl; XCFParser xcfParser(Verbose); map<string, string>* mapping = xcfParser.parseFile(XCFFile); network->setMapping(mapping); } if (enableTrace){ setTraces(network); } //Load network engine->load(network); // Optimizing decoder if (optLevel > 0){ engine->optimize(network, optLevel); } // Verify the given decoder if needed if (Verify){ engine->verify(network, "error.txt"); } // Set input file input_file = (char*)VidFile.c_str(); // Print the given decoder if needed if (OutputDir != ""){ engine->print(network); } //Run network engine->run(network); cout << "End of Jade" << endl; cout << "Total time: " << (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms" << endl; if(XCFFile != "") { cout << "Note: This execution time is calculated from CPU clock. When more than 1 thread were run, " "the value displayed is higher than the real execution time." << endl; } }
static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; std::unique_ptr<Module> M; std::unique_ptr<MIRParser> MIR; Triple TheTriple; bool SkipModule = MCPU == "help" || (!MAttrs.empty() && MAttrs.front() == "help"); // If user just wants to list available options, skip module loading if ((!SkipModule) && (!PrintInstructions.getValue())) { if (StringRef(InputFilename).endswith_lower(".mir")) { MIR = createMIRParserFromFile(InputFilename, Err, Context); if (MIR) { M = MIR->parseLLVMModule(); assert(M && "parseLLVMModule should exit on failure"); } } else M = parseIRFile(InputFilename, Err, Context); if (!M) { Err.print(argv[0], errs()); return 1; } // Verify module immediately to catch problems before doInitialization() is // called on any passes. if (!NoVerify && verifyModule(*M, &errs())) { errs() << argv[0] << ": " << InputFilename << ": error: input module is broken!\n"; return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); TheTriple = Triple(M->getTargetTriple()); } else { TheTriple = Triple(Triple::normalize(TargetTriple)); } if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getDefaultTargetTriple()); // Get the target specific parser. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); if (!TheTarget) { errs() << argv[0] << ": " << Error; return 1; } std::string CPUStr = getCPUStr(), FeaturesStr = getFeaturesStr(); CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: errs() << argv[0] << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); Options.DisableIntegratedAS = NoIntegratedAssembler; Options.MCOptions.ShowMCEncoding = ShowMCEncoding; Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory; Options.MCOptions.AsmVerbose = AsmVerbose; std::unique_ptr<TargetMachine> Target( TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RelocModel, CMModel, OLvl)); assert(Target && "Could not allocate target machine!"); // If we don't have a module then just exit now. We do this down // here since the CPU/Feature help is underneath the target machine // creation. if (SkipModule) return 0; // Figure out where we are going to send the output. std::unique_ptr<tool_output_file> Out = GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]); if (!Out) return 1; { raw_pwrite_stream *OS = &Out->os(); std::unique_ptr<buffer_ostream> BOS; if (FileType != TargetMachine::CGFT_AssemblyFile && !Out->os().supportsSeeking()) { BOS = make_unique<buffer_ostream>(*OS); OS = BOS.get(); } if (PrintInstructions.getValue()) { printInstructions(TheTarget, OS); Out->keep(); return 0; } assert(M && "Should have exited if we didn't have a module!"); if (FloatABIForCalls != FloatABI::Default) Options.FloatABIType = FloatABIForCalls; // Build up all of the passes that we want to do to the module. legacy::PassManager PM; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple())); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); PM.add(new TargetLibraryInfoWrapperPass(TLII)); // Add the target data from the target machine, if it exists, or the module. M->setDataLayout(Target->createDataLayout()); // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. setFunctionAttributes(CPUStr, FeaturesStr, *M); if (RelaxAll.getNumOccurrences() > 0 && FileType != TargetMachine::CGFT_ObjectFile) errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj"; AnalysisID StartBeforeID = nullptr; AnalysisID StartAfterID = nullptr; AnalysisID StopAfterID = nullptr; const PassRegistry *PR = PassRegistry::getPassRegistry(); if (!RunPass.empty()) { if (!StartAfter.empty() || !StopAfter.empty()) { errs() << argv[0] << ": start-after and/or stop-after passes are " "redundant when run-pass is specified.\n"; return 1; } const PassInfo *PI = PR->getPassInfo(RunPass); if (!PI) { errs() << argv[0] << ": run-pass pass is not registered.\n"; return 1; } StopAfterID = StartBeforeID = PI->getTypeInfo(); } else { if (!StartAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StartAfter); if (!PI) { errs() << argv[0] << ": start-after pass is not registered.\n"; return 1; } StartAfterID = PI->getTypeInfo(); } if (!StopAfter.empty()) { const PassInfo *PI = PR->getPassInfo(StopAfter); if (!PI) { errs() << argv[0] << ": stop-after pass is not registered.\n"; return 1; } StopAfterID = PI->getTypeInfo(); } } // Ask the target to add backend passes as necessary. if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, StartBeforeID, StartAfterID, StopAfterID, MIR.get())) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; return 1; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); PM.run(*M); } // Declare success. Out->keep(); return 0; }
static void processOptionImpl(cl::opt<bool> &O, const cl::opt<bool> &Default) { if (!O.getNumOccurrences() || O.getPosition() < Default.getPosition()) O = Default.getValue(); }
// This checks whether the transformation is legal and profitable bool X86CallFrameOptimization::shouldPerformTransformation(MachineFunction &MF) { if (NoX86CFOpt.getValue()) return false; // We currently only support call sequences where *all* parameters. // are passed on the stack. // No point in running this in 64-bit mode, since some arguments are // passed in-register in all common calling conventions, so the pattern // we're looking for will never match. const X86Subtarget &STI = MF.getSubtarget<X86Subtarget>(); if (STI.is64Bit()) return false; // You would expect straight-line code between call-frame setup and // call-frame destroy. You would be wrong. There are circumstances (e.g. // CMOV_GR8 expansion of a select that feeds a function call!) where we can // end up with the setup and the destroy in different basic blocks. // This is bad, and breaks SP adjustment. // So, check that all of the frames in the function are closed inside // the same block, and, for good measure, that there are no nested frames. int FrameSetupOpcode = TII->getCallFrameSetupOpcode(); int FrameDestroyOpcode = TII->getCallFrameDestroyOpcode(); for (MachineBasicBlock &BB : MF) { bool InsideFrameSequence = false; for (MachineInstr &MI : BB) { if (MI.getOpcode() == FrameSetupOpcode) { if (InsideFrameSequence) return false; InsideFrameSequence = true; } else if (MI.getOpcode() == FrameDestroyOpcode) { if (!InsideFrameSequence) return false; InsideFrameSequence = false; } } if (InsideFrameSequence) return false; } // Now that we know the transformation is legal, check if it is // profitable. // TODO: Add a heuristic that actually looks at the function, // and enable this for more cases. // This transformation is always a win when we expected to have // a reserved call frame. Under other circumstances, it may be either // a win or a loss, and requires a heuristic. // For now, enable it only for the relatively clear win cases. bool CannotReserveFrame = MF.getFrameInfo()->hasVarSizedObjects(); if (CannotReserveFrame) return true; // Don't do this when not optimizing for size. bool OptForSize = MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize) || MF.getFunction()->hasFnAttribute(Attribute::MinSize); if (!OptForSize) return false; // Stack re-alignment can make this unprofitable even in terms of size. // As mentioned above, a better heuristic is needed. For now, don't do this // when the required alignment is above 8. (4 would be the safe choice, but // some experimentation showed 8 is generally good). if (TFL->getStackAlignment() > 8) return false; return true; }
int main(int argc, char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; cl::ParseCommandLineOptions(argc, argv, "linker script randomizer\n"); sys::Path ldPath = sys::Program::FindProgramByName("ld"); if (ldPath.isEmpty()) { errs() << "Couldn't find system linker"; llvm_shutdown(); return 1; } sys::Path scriptPath = sys::Path::GetTemporaryDirectory(); if (scriptPath.isEmpty()) { errs() << "Error accessing temporary directory"; llvm_shutdown(); return 1; } scriptPath.appendComponent("ld_script"); scriptPath.makeUnique(false, NULL); sys::Path devNull; std::string errMsg; const char *ldArgs[] = { ldPath.c_str(), "--verbose", NULL }; const sys::Path *redirects[] = { &devNull, &scriptPath, &scriptPath, NULL }; if (sys::Program::ExecuteAndWait(ldPath, ldArgs, 0, redirects, 0, 0, &errMsg)) { errs() << "Error executing linker"; llvm_shutdown(); return 1; } OwningPtr< MemoryBuffer > scriptFile; error_code ec = MemoryBuffer::getFile(scriptPath.c_str(), scriptFile); if (ec) { errs() << "Error reading script file: " << ec.message(); llvm_shutdown(); return 1; } uint32_t minPage = (MinBaseAddress + PAGE_SIZE - 1) / PAGE_SIZE, maxPage = MaxBaseAddress / PAGE_SIZE; if (minPage > maxPage) { errs() << "Base address interval is empty"; llvm_shutdown(); return 1; } uint32_t newAddr = PAGE_SIZE * (minPage + RandomNumberGenerator::Generator().Random(maxPage - minPage + 1)); char oldAddrStr[12]; sprintf(oldAddrStr, "0x%08x", OldBaseAddress.getValue()); llvm::Regex oldAddrRegex(oldAddrStr); StringRef scriptText = scriptFile->getBuffer(); StringRef oldScriptText = scriptText; char newAddrStr[12]; sprintf(newAddrStr, "0x%08x", newAddr); do { // Replace one occurrence of old address with new one oldScriptText = scriptText; scriptText = oldAddrRegex.sub(newAddrStr, scriptText); } while (!scriptText.equals(oldScriptText)); std::cout << scriptText.str(); return 0; }
static std::unique_ptr<tool_output_file> GetOutputStream(const char *TargetName, Triple::OSType OS, const char *ProgName) { // If we don't yet have an output filename, make one. if (PrintInstructions.getValue()) { if (OutputFilename.empty()) { OutputFilename = "hotspot.out"; } } else { if (OutputFilename.empty()) { if (InputFilename == "-") OutputFilename = "-"; else { // If InputFilename ends in .bc or .ll, remove it. StringRef IFN = InputFilename; if (IFN.endswith(".bc") || IFN.endswith(".ll")) OutputFilename = IFN.drop_back(3); else if (IFN.endswith(".mir")) OutputFilename = IFN.drop_back(4); else OutputFilename = IFN; switch (FileType) { case TargetMachine::CGFT_AssemblyFile: if (TargetName[0] == 'c') { if (TargetName[1] == 0) OutputFilename += ".cbe.c"; else if (TargetName[1] == 'p' && TargetName[2] == 'p') OutputFilename += ".cpp"; else OutputFilename += ".s"; } else OutputFilename += ".s"; break; case TargetMachine::CGFT_ObjectFile: if (OS == Triple::Win32) OutputFilename += ".obj"; else OutputFilename += ".o"; break; case TargetMachine::CGFT_Null: OutputFilename += ".null"; break; } } } } // Decide if we need "binary" output. bool Binary = false; switch (FileType) { case TargetMachine::CGFT_AssemblyFile: break; case TargetMachine::CGFT_ObjectFile: case TargetMachine::CGFT_Null: Binary = true; break; } // Open the file. std::error_code EC; sys::fs::OpenFlags OpenFlags = sys::fs::F_None; if (!Binary) OpenFlags |= sys::fs::F_Text; auto FDOut = llvm::make_unique<tool_output_file>(OutputFilename, EC, OpenFlags); if (EC) { errs() << EC.message() << '\n'; return nullptr; } return FDOut; }