liberty/lib/Utilities/InlineFunctionWithVmap.cpp
/// Once we have cloned code over from a callee into the caller,
/// update the specified callgraph to reflect the changes we made.
/// Note that it's possible that not all code was copied over, so only
/// some edges of the callgraph may remain.
Once we have cloned code over from a callee into the caller,
update the specified callgraph to reflect the changes we made.
Note that it's possible that not all code was copied over, so only
some edges of the callgraph may remain.
Once we have cloned code over from a callee into the caller update the specified callgraph to reflect the changes we made . Note that it ' s possible that not all code was copied over so only some edges of the callgraph may remain .
static void UpdateCallGraphAfterInlining(CallSite CS,
                                         Function::iterator FirstNewBlock,
                                         ValueToValueMapTy &VMap,
                                         InlineFunctionInfo &IFI) {
  CallGraph &CG = *IFI.CG;
  const Function *Caller = CS.getCaller();
  const Function *Callee = CS.getCalledFunction();
  CallGraphNode *CalleeNode = CG[Callee];
  CallGraphNode *CallerNode = CG[Caller];
  CallGraphNode::iterator I = CalleeNode->begin(), E = CalleeNode->end();
  CallGraphNode::CalledFunctionsVector CallCache;
  if (CalleeNode == CallerNode) {
    CallCache.assign(I, E);
    I = CallCache.begin();
    E = CallCache.end();
  }
  for (; I != E; ++I) {
    const Value *OrigCall = I->first;
    ValueToValueMapTy::iterator VMI = VMap.find(OrigCall);
    if (VMI == VMap.end() || VMI->second == nullptr)
      continue;
    auto *NewCall = dyn_cast<CallBase>(VMI->second);
    if (!NewCall)
      continue;
    if (NewCall->getCalledFunction() &&
        NewCall->getCalledFunction()->isIntrinsic())
      continue;
    IFI.InlinedCalls.push_back(NewCall);
    if (!I->second->getFunction())
      if (Function *F = NewCall->getCalledFunction()) {
        CallerNode->addCalledFunction(NewCall, CG[F]);
        continue;
      }
    CallerNode->addCalledFunction(NewCall, I->second);
  }
  CallerNode->removeCallEdgeFor(*cast<CallBase>(CS.getInstruction()));
}
static void UpdateCallGraphAfterInlining ( CallSite CS , Function :: iterator FirstNewBlock , ValueToValueMapTy & VMap , InlineFunctionInfo & IFI ) { CallGraph & CG = * IFI . CG ; const Function * Caller = CS . getCaller ( ) ; const Function * Callee = CS . getCalledFunction ( ) ; CallGraphNode * CalleeNode = CG [ Callee ] ; CallGraphNode * CallerNode = CG [ Caller ] ; CallGraphNode :: iterator I = CalleeNode -> begin ( ) , E = CalleeNode -> end ( ) ; CallGraphNode :: CalledFunctionsVector CallCache ; if ( CalleeNode == CallerNode ) { CallCache . assign ( I , E ) ; I = CallCache . begin ( ) ; E = CallCache . end ( ) ; } for ( ; I != E ; ++ I ) { const Value * OrigCall = I -> first ; ValueToValueMapTy :: iterator VMI = VMap . find ( OrigCall ) ; if ( VMI == VMap . end ( ) || VMI -> second == nullptr ) continue ; auto * NewCall = dyn_cast < CallBase > ( VMI -> second ) ; if ( ! NewCall ) continue ; if ( NewCall -> getCalledFunction ( ) && NewCall -> getCalledFunction ( ) -> isIntrinsic ( ) ) continue ; IFI . InlinedCalls . push_back ( NewCall ) ; if ( ! I -> second -> getFunction ( ) ) if ( Function * F = NewCall -> getCalledFunction ( ) ) { CallerNode -> addCalledFunction ( NewCall , CG [ F ] ) ; continue ; } CallerNode -> addCalledFunction ( NewCall , I -> second ) ; } CallerNode -> removeCallEdgeFor ( * cast < CallBase > ( CS . getInstruction ( ) ) ) ; }
Once we have cloned code over from a callee into the caller,
update the specified callgraph to reflect the changes we made.
Once we have cloned code over from a callee into the caller update the specified callgraph to reflect the changes we made .
// Since we inlined some uninlined call sites in the callee into the caller, // add edges from the caller to all of the callees of the callee. // Consider the case where CalleeNode == CallerNode. // Only copy the edge if the call was inlined! // If the call was inlined, but then constant folded, there is no edge to // add.  Check for this case. // We do not treat intrinsic calls like real function calls because we // expect them to become inline code; do not add an edge for an intrinsic. // Remember that this call site got inlined for the client of // InlineFunction. // It's possible that inlining the callsite will cause it to go from an // indirect to a direct call by resolving a function pointer.  If this // happens, set the callee of the new call site to a more precise // destination.  This can also happen if the call graph node of the caller // was just unnecessarily imprecise. // Indirect call site resolved to direct call. // Update the call graph by deleting the edge from Callee to Caller.  We must // do this after the loop above in case Caller and Callee are the same.