本文整理汇总了C++中CallGraphSCC类的典型用法代码示例。如果您正苦于以下问题:C++ CallGraphSCC类的具体用法?C++ CallGraphSCC怎么用?C++ CallGraphSCC使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了CallGraphSCC类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: addNoRecurseAttrs
static bool addNoRecurseAttrs(const CallGraphSCC &SCC) {
// Try and identify functions that do not recurse.
// If the SCC contains multiple nodes we know for sure there is recursion.
if (!SCC.isSingular())
return false;
const CallGraphNode *CGN = *SCC.begin();
Function *F = CGN->getFunction();
if (!F || F->isDeclaration() || F->doesNotRecurse())
return false;
// If all of the calls in F are identifiable and are to norecurse functions, F
// is norecurse. This check also detects self-recursion as F is not currently
// marked norecurse, so any called from F to F will not be marked norecurse.
if (std::all_of(CGN->begin(), CGN->end(),
[](const CallGraphNode::CallRecord &CR) {
Function *F = CR.second->getFunction();
return F && F->doesNotRecurse();
}))
// Function calls a potentially recursive function.
return setDoesNotRecurse(*F);
// Nothing else we can deduce usefully during the postorder traversal.
return false;
}
示例2: addNoRecurseAttrs
static bool addNoRecurseAttrs(const CallGraphSCC &SCC,
SmallVectorImpl<WeakVH> &Revisit) {
// Try and identify functions that do not recurse.
// If the SCC contains multiple nodes we know for sure there is recursion.
if (!SCC.isSingular())
return false;
const CallGraphNode *CGN = *SCC.begin();
Function *F = CGN->getFunction();
if (!F || F->isDeclaration() || F->doesNotRecurse())
return false;
// If all of the calls in F are identifiable and are to norecurse functions, F
// is norecurse. This check also detects self-recursion as F is not currently
// marked norecurse, so any called from F to F will not be marked norecurse.
if (std::all_of(CGN->begin(), CGN->end(),
[](const CallGraphNode::CallRecord &CR) {
Function *F = CR.second->getFunction();
return F && F->doesNotRecurse();
}))
// Function calls a potentially recursive function.
return setDoesNotRecurse(*F);
// We know that F is not obviously recursive, but we haven't been able to
// prove that it doesn't actually recurse. Add it to the Revisit list to try
// again top-down later.
Revisit.push_back(F);
return false;
}
示例3: runOnSCC
bool AnalysisEngine::runOnSCC(CallGraphSCC &scc) {
for (CallGraphSCC::iterator i = scc.begin(),
e = scc.end(); i != e; ++i) {
CallGraphNode *cgnode = *i;
Function *f = cgnode->getFunction();
FunctionSimulator fsimulator(f);
fsimulator.simulate();
}
}
示例4: DEBUG
/// RefreshCallGraph - Scan the functions in the specified CFG and resync the
/// callgraph with the call sites found in it. This is used after
/// FunctionPasses have potentially munged the callgraph, and can be used after
/// CallGraphSCC passes to verify that they correctly updated the callgraph.
///
/// This function returns true if it devirtualized an existing function call,
/// meaning it turned an indirect call into a direct call. This happens when
/// a function pass like GVN optimizes away stuff feeding the indirect call.
/// This never happens in checking mode.
///
bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC,
CallGraph &CG, bool CheckingMode) {
DenseMap<Value*, CallGraphNode*> CallSites;
DEBUG(dbgs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
<< " nodes:\n";
for (CallGraphSCC::iterator I = CurSCC.begin(), E = CurSCC.end();
I != E; ++I)
(*I)->dump();
);
示例5: RefreshCallGraph
bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
CallGraph &CG, bool &CallGraphUpToDate,
bool &DevirtualizedCall) {
bool Changed = false;
PMDataManager *PM = P->getAsPMDataManager();
if (!PM) {
CallGraphSCCPass *CGSP = (CallGraphSCCPass*)P;
if (!CallGraphUpToDate) {
DevirtualizedCall |= RefreshCallGraph(CurSCC, CG, false);
CallGraphUpToDate = true;
}
{
TimeRegion PassTimer(getPassTimer(CGSP));
Changed = CGSP->runOnSCC(CurSCC);
}
// After the CGSCCPass is done, when assertions are enabled, use
// RefreshCallGraph to verify that the callgraph was correctly updated.
#ifndef NDEBUG
if (Changed)
RefreshCallGraph(CurSCC, CG, true);
#endif
return Changed;
}
assert(PM->getPassManagerType() == PMT_FunctionPassManager &&
"Invalid CGPassManager member");
FPPassManager *FPP = (FPPassManager*)P;
// Run pass P on all functions in the current SCC.
for (CallGraphSCC::iterator I = CurSCC.begin(), E = CurSCC.end();
I != E; ++I) {
if (Function *F = (*I)->getFunction()) {
dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName());
{
TimeRegion PassTimer(getPassTimer(FPP));
Changed |= FPP->runOnFunction(*F);
}
F->getContext().yield();
}
}
// The function pass(es) modified the IR, they may have clobbered the
// callgraph.
if (Changed && CallGraphUpToDate) {
DEBUG(dbgs() << "CGSCCPASSMGR: Pass Dirtied SCC: "
<< P->getPassName() << '\n');
CallGraphUpToDate = false;
}
return Changed;
}
示例6: runOnSCC
bool SRETPromotion::runOnSCC(CallGraphSCC &SCC) {
bool Changed = false;
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I)
if (CallGraphNode *NewNode = PromoteReturn(*I)) {
SCC.ReplaceNode(*I, NewNode);
Changed = true;
}
return Changed;
}
示例7: DEBUG
bool BottomUpPass::runOnSCC(CallGraphSCC &SCC)
{
// NumCalls =0;
// CallGraph CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
//DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
//const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr;
//const TargetLibraryInfo *TLI = getAnalysisIfAvailable<TargetLibraryInfo>();
SmallPtrSet<Function*, 8> SCCFunctions;
DEBUG(dbgs() << "\nInliner visiting SCC:");
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
if (F) {SCCFunctions.insert(F); NumFuncitons++; }
DEBUG(dbgs() << " " << (F ? F->getName() : "INDIRECTNODE"));
}
// NumCalls = SCCFunctions.size();
DEBUG(dbgs() << "\nSizeof the SCC: "<<SCC.size());
//Collect all the call sites.
SmallVector<std::pair<CallSite, int>, 16> CallSites;
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
if (!F)
{
//Check waht kind of call it is:
// errs()<<"\nCallGRaph node dump -- ";
// (*I)->dump();
continue;
}
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
CallSite CS(cast<Value>(I));
// If this isn't a call, or it is a call to an intrinsic, it can
// never be inlined.
if (!CS || isa<IntrinsicInst>(I))
continue;
// If this is a direct call to an external function, we can never inline
// it. If it is an indirect call, inlining may resolve it to be a
// direct call, so we keep it.
if (CS.getCalledFunction() && CS.getCalledFunction()->isDeclaration())
continue;
CallSites.push_back(std::make_pair(CS, -1));
}
}
DEBUG(dbgs() << ": " << CallSites.size() << " call sites.\n");
NumCalls +=CallSites.size();
}
示例8: CVER_DEBUG
bool CverPruneStack::PruneWithSCCCallGraph(CallGraphSCC &SCC) {
CVER_DEBUG("-----------------------------------\n");
bool mayCallCast = false;
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
if (!F)
continue;
CVER_DEBUG(" F : " << F->getName() << "\n");
// Check if this function may call __cver_handle_stack_enter
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
if (CallInst *CI = dyn_cast<CallInst>(I)) {
Function *Callee = CI->getCalledFunction();
if (!Callee) {
CVER_DEBUG("\t mayCallCast due to indirect calls\n");
// Indirect call, and we lost the control.
mayCallCast = true;
break;
} else if (Callee->getName() == sCast) {
CVER_DEBUG("\t mayCallCast due to explicit __cver_handle_cast\n");
mayCallCast = true;
break;
}
}
} // End of I loop.
if (mayCallCast)
break;
} // End of BB loop.
}
bool isModified = false;
SmallVector<Instruction *, 16> InstToDelete;
// If there must not exist __stack_handle_cast, we prune all
// __cver_handle_stack_enter and __cver_handle_stack_exit in SCC.
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
if (!F)
continue;
if (!mayCallCast)
isModified = CollectStackInvokeInstructions(F, InstToDelete);
}
for (Instruction *inst : InstToDelete) {
CVER_DEBUG( "(prunning) : " << *inst << "\n");
inst->eraseFromParent();
}
return isModified;
}
示例9: runOnSCC
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;
}
示例10: RefreshCallGraph
/// Scan the functions in the specified CFG and resync the
/// callgraph with the call sites found in it. This is used after
/// FunctionPasses have potentially munged the callgraph, and can be used after
/// CallGraphSCC passes to verify that they correctly updated the callgraph.
///
/// This function returns true if it devirtualized an existing function call,
/// meaning it turned an indirect call into a direct call. This happens when
/// a function pass like GVN optimizes away stuff feeding the indirect call.
/// This never happens in checking mode.
bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
bool CheckingMode) {
DenseMap<Value*, CallGraphNode*> CallSites;
LLVM_DEBUG(dbgs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size()
<< " nodes:\n";
for (CallGraphNode *CGN
: CurSCC) CGN->dump(););
示例11: updateCallGraph
// Rebuild CGN after we extracted parts of the code from ParentFunc into
// NewFuncs. Builds CGNs for the NewFuncs and adds them to the current SCC.
void coro::updateCallGraph(Function &ParentFunc, ArrayRef<Function *> NewFuncs,
CallGraph &CG, CallGraphSCC &SCC) {
// Rebuild CGN from scratch for the ParentFunc
auto *ParentNode = CG[&ParentFunc];
ParentNode->removeAllCalledFunctions();
buildCGN(CG, ParentNode);
SmallVector<CallGraphNode *, 8> Nodes(SCC.begin(), SCC.end());
for (Function *F : NewFuncs) {
CallGraphNode *Callee = CG.getOrInsertFunction(F);
Nodes.push_back(Callee);
buildCGN(CG, Callee);
}
SCC.initialize(Nodes);
}
示例12: runOnSCC
bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) {
bool Changed = false, LocalChange;
DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
DL = DLP ? &DLP->getDataLayout() : nullptr;
do { // Iterate until we stop promoting from this SCC.
LocalChange = false;
// Attempt to promote arguments from all functions in this SCC.
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
if (CallGraphNode *CGN = PromoteArguments(*I)) {
LocalChange = true;
SCC.ReplaceNode(*I, CGN);
}
}
Changed |= LocalChange; // Remember that we changed something.
} while (LocalChange);
return Changed;
}
示例13: createDevirtTriggerFunc
// Make sure that there is a devirtualization trigger function that CoroSplit
// pass uses the force restart CGSCC pipeline. If devirt trigger function is not
// found, we will create one and add it to the current SCC.
static void createDevirtTriggerFunc(CallGraph &CG, CallGraphSCC &SCC) {
Module &M = CG.getModule();
if (M.getFunction(CORO_DEVIRT_TRIGGER_FN))
return;
LLVMContext &C = M.getContext();
auto *FnTy = FunctionType::get(Type::getVoidTy(C), Type::getInt8PtrTy(C),
/*IsVarArgs=*/false);
Function *DevirtFn =
Function::Create(FnTy, GlobalValue::LinkageTypes::PrivateLinkage,
CORO_DEVIRT_TRIGGER_FN, &M);
DevirtFn->addFnAttr(Attribute::AlwaysInline);
auto *Entry = BasicBlock::Create(C, "entry", DevirtFn);
ReturnInst::Create(C, Entry);
auto *Node = CG.getOrInsertFunction(DevirtFn);
SmallVector<CallGraphNode *, 8> Nodes(SCC.begin(), SCC.end());
Nodes.push_back(Node);
SCC.initialize(Nodes);
}
示例14: runOnSCC
bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) {
if (skipSCC(SCC))
return false;
// Get the callgraph information that we need to update to reflect our
// changes.
CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
LegacyAARGetter AARGetter(*this);
bool Changed = false, LocalChange;
// Iterate until we stop promoting from this SCC.
do {
LocalChange = false;
// Attempt to promote arguments from all functions in this SCC.
for (CallGraphNode *OldNode : SCC) {
Function *OldF = OldNode->getFunction();
if (!OldF)
continue;
auto ReplaceCallSite = [&](CallSite OldCS, CallSite NewCS) {
Function *Caller = OldCS.getInstruction()->getParent()->getParent();
CallGraphNode *NewCalleeNode =
CG.getOrInsertFunction(NewCS.getCalledFunction());
CallGraphNode *CallerNode = CG[Caller];
CallerNode->replaceCallEdge(OldCS, NewCS, NewCalleeNode);
};
if (Function *NewF = promoteArguments(OldF, AARGetter, MaxElements,
{ReplaceCallSite})) {
LocalChange = true;
// Update the call graph for the newly promoted function.
CallGraphNode *NewNode = CG.getOrInsertFunction(NewF);
NewNode->stealCalledFunctionsFrom(OldNode);
if (OldNode->getNumReferences() == 0)
delete CG.removeFunctionFromModule(OldNode);
else
OldF->setLinkage(Function::ExternalLinkage);
// And updat ethe SCC we're iterating as well.
SCC.ReplaceNode(OldNode, NewNode);
}
}
// Remember that we changed something.
Changed |= LocalChange;
} while (LocalChange);
return Changed;
}
示例15: runImpl
static bool runImpl(CallGraphSCC &SCC, CallGraph &CG,
function_ref<AAResults &(Function &F)> AARGetter,
unsigned MaxElements) {
bool Changed = false, LocalChange;
do { // Iterate until we stop promoting from this SCC.
LocalChange = false;
// Attempt to promote arguments from all functions in this SCC.
for (CallGraphNode *OldNode : SCC) {
if (CallGraphNode *NewNode =
PromoteArguments(OldNode, CG, AARGetter, MaxElements)) {
LocalChange = true;
SCC.ReplaceNode(OldNode, NewNode);
}
}
Changed |= LocalChange; // Remember that we changed something.
} while (LocalChange);
return Changed;
}