// 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); }
// 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); }