PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &) { FunctionAnalysisManager &FAM = AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager(); // We pass a lambda into functions to wire them up to the analysis manager // for getting function analyses. auto AARGetter = [&](Function &F) -> AAResults & { return FAM.getResult<AAManager>(F); }; // Fill SCCNodes with the elements of the SCC. Also track whether there are // any external or opt-none nodes that will prevent us from optimizing any // part of the SCC. SCCNodeSet SCCNodes; bool HasUnknownCall = false; for (LazyCallGraph::Node &N : C) { Function &F = N.getFunction(); if (F.hasFnAttribute(Attribute::OptimizeNone)) { // Treat any function we're trying not to optimize as if it were an // indirect call and omit it from the node set used below. HasUnknownCall = true; continue; } // Track whether any functions in this SCC have an unknown call edge. // Note: if this is ever a performance hit, we can common it with // subsequent routines which also do scans over the instructions of the // function. if (!HasUnknownCall) for (Instruction &I : instructions(F)) if (auto CS = CallSite(&I)) if (!CS.getCalledFunction()) { HasUnknownCall = true; break; } SCCNodes.insert(&F); } bool Changed = false; Changed |= addArgumentReturnedAttrs(SCCNodes); Changed |= addReadAttrs(SCCNodes, AARGetter); Changed |= addArgumentAttrs(SCCNodes); // If we have no external nodes participating in the SCC, we can deduce some // more precise attributes as well. if (!HasUnknownCall) { Changed |= addNoAliasAttrs(SCCNodes); Changed |= addNonNullAttrs(SCCNodes); Changed |= removeConvergentAttrs(SCCNodes); Changed |= addNoRecurseAttrs(SCCNodes); } return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all(); }
bool PostOrderFunctionAttrsLegacyPass::runOnSCC(CallGraphSCC &SCC) { TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); bool Changed = false; // We compute dedicated AA results for each function in the SCC as needed. We // use a lambda referencing external objects so that they live long enough to // be queried, but we re-use them each time. Optional<BasicAAResult> BAR; Optional<AAResults> AAR; auto AARGetter = [&](Function &F) -> AAResults & { BAR.emplace(createLegacyPMBasicAAResult(*this, F)); AAR.emplace(createLegacyPMAAResults(*this, F, *BAR)); return *AAR; }; // Fill SCCNodes with the elements of the SCC. Used for quickly looking up // whether a given CallGraphNode is in this SCC. Also track whether there are // any external or opt-none nodes that will prevent us from optimizing any // part of the SCC. SCCNodeSet SCCNodes; bool ExternalNode = false; for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { Function *F = (*I)->getFunction(); if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) { // External node or function we're trying not to optimize - we both avoid // transform them and avoid leveraging information they provide. ExternalNode = true; continue; } SCCNodes.insert(F); } Changed |= addReadAttrs(SCCNodes, AARGetter); Changed |= addArgumentAttrs(SCCNodes); // If we have no external nodes participating in the SCC, we can deduce some // more precise attributes as well. if (!ExternalNode) { Changed |= addNoAliasAttrs(SCCNodes); Changed |= addNonNullAttrs(SCCNodes, *TLI); Changed |= removeConvergentAttrs(SCCNodes); Changed |= addNoRecurseAttrs(SCCNodes); } return Changed; }
static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) { bool Changed = false; // Fill SCCNodes with the elements of the SCC. Used for quickly looking up // whether a given CallGraphNode is in this SCC. Also track whether there are // any external or opt-none nodes that will prevent us from optimizing any // part of the SCC. SCCNodeSet SCCNodes; bool ExternalNode = false; for (CallGraphNode *I : SCC) { Function *F = I->getFunction(); if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) { // External node or function we're trying not to optimize - we both avoid // transform them and avoid leveraging information they provide. ExternalNode = true; continue; } SCCNodes.insert(F); } Changed |= addArgumentReturnedAttrs(SCCNodes); Changed |= addReadAttrs(SCCNodes, AARGetter); Changed |= addArgumentAttrs(SCCNodes); // If we have no external nodes participating in the SCC, we can deduce some // more precise attributes as well. if (!ExternalNode) { Changed |= addNoAliasAttrs(SCCNodes); Changed |= addNonNullAttrs(SCCNodes); Changed |= removeConvergentAttrs(SCCNodes); Changed |= addNoRecurseAttrs(SCCNodes); } return Changed; }