Example #1
0
/// Walk through the instructions in \p F looking for external
/// calls not already in the \p CalledFunctions set. If any are
/// found they are added to the \p Worklist for importing.
static void findExternalCalls(const Module &DestModule, Function &F,
                              const FunctionInfoIndex &Index,
                              StringSet<> &CalledFunctions,
                              SmallVector<StringRef, 64> &Worklist) {
  // We need to suffix internal function calls imported from other modules,
  // prepare the suffix ahead of time.
  std::string Suffix;
  if (F.getParent() != &DestModule)
    Suffix =
        (Twine(".llvm.") +
         Twine(Index.getModuleId(F.getParent()->getModuleIdentifier()))).str();

  for (auto &BB : F) {
    for (auto &I : BB) {
      if (isa<CallInst>(I)) {
        auto CalledFunction = cast<CallInst>(I).getCalledFunction();
        // Insert any new external calls that have not already been
        // added to set/worklist.
        if (!CalledFunction || !CalledFunction->hasName())
          continue;
        // Ignore intrinsics early
        if (CalledFunction->isIntrinsic()) {
          assert(CalledFunction->getIntrinsicID() != 0);
          continue;
        }
        auto ImportedName = CalledFunction->getName();
        auto Renamed = (ImportedName + Suffix).str();
        // Rename internal functions
        if (CalledFunction->hasInternalLinkage()) {
          ImportedName = Renamed;
        }
        auto It = CalledFunctions.insert(ImportedName);
        if (!It.second) {
          // This is a call to a function we already considered, skip.
          continue;
        }
        // Ignore functions already present in the destination module
        auto *SrcGV = DestModule.getNamedValue(ImportedName);
        if (SrcGV) {
          assert(isa<Function>(SrcGV) && "Name collision during import");
          if (!cast<Function>(SrcGV)->isDeclaration()) {
            DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Ignoring "
                         << ImportedName << " already in DestinationModule\n");
            continue;
          }
        }

        Worklist.push_back(It.first->getKey());
        DEBUG(dbgs() << DestModule.getModuleIdentifier()
                     << ": Adding callee for : " << ImportedName << " : "
                     << F.getName() << "\n");
      }
    }
  }
}