Beispiel #1
0
bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
  GlobalValue *DGV = getLinkedToGlobal(&GV);

  if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration()))
    return false;

  if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) {
    auto *DGVar = dyn_cast<GlobalVariable>(DGV);
    auto *SGVar = dyn_cast<GlobalVariable>(&GV);
    if (DGVar && SGVar) {
      if (DGVar->isDeclaration() && SGVar->isDeclaration() &&
          (!DGVar->isConstant() || !SGVar->isConstant())) {
        DGVar->setConstant(false);
        SGVar->setConstant(false);
      }
      if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) {
        unsigned Align = std::max(DGVar->getAlignment(), SGVar->getAlignment());
        SGVar->setAlignment(Align);
        DGVar->setAlignment(Align);
      }
    }

    GlobalValue::VisibilityTypes Visibility =
        getMinVisibility(DGV->getVisibility(), GV.getVisibility());
    DGV->setVisibility(Visibility);
    GV.setVisibility(Visibility);

    bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr();
    DGV->setUnnamedAddr(HasUnnamedAddr);
    GV.setUnnamedAddr(HasUnnamedAddr);
  }

  // Don't want to append to global_ctors list, for example, when we
  // are importing for ThinLTO, otherwise the global ctors and dtors
  // get executed multiple times for local variables (the latter causing
  // double frees).
  if (GV.hasAppendingLinkage() && isPerformingImport())
    return false;

  if (isPerformingImport()) {
    if (!doImportAsDefinition(&GV))
      return false;
  } else if (!DGV && !shouldOverrideFromSrc() &&
             (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() ||
              GV.hasAvailableExternallyLinkage()))
    return false;

  if (GV.isDeclaration())
    return false;

  if (const Comdat *SC = GV.getComdat()) {
    bool LinkFromSrc;
    Comdat::SelectionKind SK;
    std::tie(SK, LinkFromSrc) = ComdatsChosen[SC];
    if (!LinkFromSrc)
      return false;
  }

  bool LinkFromSrc = true;
  if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV))
    return true;
  if (LinkFromSrc)
    ValuesToLink.insert(&GV);
  return false;
}
Beispiel #2
0
bool ModuleLinker::run() {
  Module &DstM = Mover.getModule();
  DenseSet<const Comdat *> ReplacedDstComdats;

  for (const auto &SMEC : SrcM->getComdatSymbolTable()) {
    const Comdat &C = SMEC.getValue();
    if (ComdatsChosen.count(&C))
      continue;
    Comdat::SelectionKind SK;
    bool LinkFromSrc;
    if (getComdatResult(&C, SK, LinkFromSrc))
      return true;
    ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc);

    if (!LinkFromSrc)
      continue;

    Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();
    Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(C.getName());
    if (DstCI == ComdatSymTab.end())
      continue;

    // The source comdat is replacing the dest one.
    const Comdat *DstC = &DstCI->second;
    ReplacedDstComdats.insert(DstC);
  }

  // Alias have to go first, since we are not able to find their comdats
  // otherwise.
  for (auto I = DstM.alias_begin(), E = DstM.alias_end(); I != E;) {
    GlobalAlias &GV = *I++;
    dropReplacedComdat(GV, ReplacedDstComdats);
  }

  for (auto I = DstM.global_begin(), E = DstM.global_end(); I != E;) {
    GlobalVariable &GV = *I++;
    dropReplacedComdat(GV, ReplacedDstComdats);
  }

  for (auto I = DstM.begin(), E = DstM.end(); I != E;) {
    Function &GV = *I++;
    dropReplacedComdat(GV, ReplacedDstComdats);
  }

  for (GlobalVariable &GV : SrcM->globals())
    if (GV.hasLinkOnceLinkage())
      if (const Comdat *SC = GV.getComdat())
        LazyComdatMembers[SC].push_back(&GV);

  for (Function &SF : *SrcM)
    if (SF.hasLinkOnceLinkage())
      if (const Comdat *SC = SF.getComdat())
        LazyComdatMembers[SC].push_back(&SF);

  for (GlobalAlias &GA : SrcM->aliases())
    if (GA.hasLinkOnceLinkage())
      if (const Comdat *SC = GA.getComdat())
        LazyComdatMembers[SC].push_back(&GA);

  // Insert all of the globals in src into the DstM module... without linking
  // initializers (which could refer to functions not yet mapped over).
  for (GlobalVariable &GV : SrcM->globals())
    if (linkIfNeeded(GV))
      return true;

  for (Function &SF : *SrcM)
    if (linkIfNeeded(SF))
      return true;

  for (GlobalAlias &GA : SrcM->aliases())
    if (linkIfNeeded(GA))
      return true;

  for (unsigned I = 0; I < ValuesToLink.size(); ++I) {
    GlobalValue *GV = ValuesToLink[I];
    const Comdat *SC = GV->getComdat();
    if (!SC)
      continue;
    for (GlobalValue *GV2 : LazyComdatMembers[SC]) {
      GlobalValue *DGV = getLinkedToGlobal(GV2);
      bool LinkFromSrc = true;
      if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))
        return true;
      if (LinkFromSrc)
        ValuesToLink.insert(GV2);
    }
  }

  if (shouldInternalizeLinkedSymbols()) {
    for (GlobalValue *GV : ValuesToLink)
      Internalize.insert(GV->getName());
  }

  // FIXME: Propagate Errors through to the caller instead of emitting
  // diagnostics.
  bool HasErrors = false;
  if (Error E = Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
                           [this](GlobalValue &GV, IRMover::ValueAdder Add) {
                             addLazyFor(GV, Add);
                           },
                           !isPerformingImport())) {
    handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
      DstM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, EIB.message()));
      HasErrors = true;
    });
  }
  if (HasErrors)
    return true;

  for (auto &P : Internalize) {
    GlobalValue *GV = DstM.getNamedValue(P.first());
    GV->setLinkage(GlobalValue::InternalLinkage);
  }

  return false;
}
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {

  ValueInfo VI;
  if (GV.hasName()) {
    VI = ImportIndex.getValueInfo(GV.getGUID());
    // Set synthetic function entry counts.
    if (VI && ImportIndex.hasSyntheticEntryCounts()) {
      if (Function *F = dyn_cast<Function>(&GV)) {
        if (!F->isDeclaration()) {
          for (auto &S : VI.getSummaryList()) {
            FunctionSummary *FS = dyn_cast<FunctionSummary>(S->getBaseObject());
            if (FS->modulePath() == M.getModuleIdentifier()) {
              F->setEntryCount(Function::ProfileCount(FS->entryCount(),
                                                      Function::PCT_Synthetic));
              break;
            }
          }
        }
      }
    }
    // Check the summaries to see if the symbol gets resolved to a known local
    // definition.
    if (VI && VI.isDSOLocal()) {
      GV.setDSOLocal(true);
      if (GV.hasDLLImportStorageClass())
        GV.setDLLStorageClass(GlobalValue::DefaultStorageClass);
    }
  }

  // Mark read-only variables which can be imported with specific attribute.
  // We can't internalize them now because IRMover will fail to link variable
  // definitions to their external declarations during ThinLTO import. We'll
  // internalize read-only variables later, after import is finished.
  // See internalizeImmutableGVs.
  //
  // If global value dead stripping is not enabled in summary then
  // propagateConstants hasn't been run. We can't internalize GV
  // in such case.
  if (!GV.isDeclaration() && VI && ImportIndex.withGlobalValueDeadStripping()) {
    const auto &SL = VI.getSummaryList();
    auto *GVS = SL.empty() ? nullptr : dyn_cast<GlobalVarSummary>(SL[0].get());
    if (GVS && GVS->isReadOnly())
      cast<GlobalVariable>(&GV)->addAttribute("thinlto-internalize");
  }

  bool DoPromote = false;
  if (GV.hasLocalLinkage() &&
      ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) {
    // Save the original name string before we rename GV below.
    auto Name = GV.getName().str();
    // Once we change the name or linkage it is difficult to determine
    // again whether we should promote since shouldPromoteLocalToGlobal needs
    // to locate the summary (based on GUID from name and linkage). Therefore,
    // use DoPromote result saved above.
    GV.setName(getName(&GV, DoPromote));
    GV.setLinkage(getLinkage(&GV, DoPromote));
    if (!GV.hasLocalLinkage())
      GV.setVisibility(GlobalValue::HiddenVisibility);

    // If we are renaming a COMDAT leader, ensure that we record the COMDAT
    // for later renaming as well. This is required for COFF.
    if (const auto *C = GV.getComdat())
      if (C->getName() == Name)
        RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName()));
  } else
    GV.setLinkage(getLinkage(&GV, /* DoPromote */ false));

  // Remove functions imported as available externally defs from comdats,
  // as this is a declaration for the linker, and will be dropped eventually.
  // It is illegal for comdats to contain declarations.
  auto *GO = dyn_cast<GlobalObject>(&GV);
  if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
    // The IRMover should not have placed any imported declarations in
    // a comdat, so the only declaration that should be in a comdat
    // at this point would be a definition imported as available_externally.
    assert(GO->hasAvailableExternallyLinkage() &&
           "Expected comdat on definition (possibly available external)");
    GO->setComdat(nullptr);
  }
}
Beispiel #4
0
bool ModuleLinker::run() {
  for (const auto &SMEC : SrcM.getComdatSymbolTable()) {
    const Comdat &C = SMEC.getValue();
    if (ComdatsChosen.count(&C))
      continue;
    Comdat::SelectionKind SK;
    bool LinkFromSrc;
    if (getComdatResult(&C, SK, LinkFromSrc))
      return true;
    ComdatsChosen[&C] = std::make_pair(SK, LinkFromSrc);
  }

  for (GlobalVariable &GV : SrcM.globals())
    if (const Comdat *SC = GV.getComdat())
      ComdatMembers[SC].push_back(&GV);

  for (Function &SF : SrcM)
    if (const Comdat *SC = SF.getComdat())
      ComdatMembers[SC].push_back(&SF);

  for (GlobalAlias &GA : SrcM.aliases())
    if (const Comdat *SC = GA.getComdat())
      ComdatMembers[SC].push_back(&GA);

  // Insert all of the globals in src into the DstM module... without linking
  // initializers (which could refer to functions not yet mapped over).
  for (GlobalVariable &GV : SrcM.globals())
    if (linkIfNeeded(GV))
      return true;

  for (Function &SF : SrcM)
    if (linkIfNeeded(SF))
      return true;

  for (GlobalAlias &GA : SrcM.aliases())
    if (linkIfNeeded(GA))
      return true;

  if (ImportIndex) {
    ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex,
                                              FunctionsToImport);
    if (ThinLTOProcessing.run())
      return true;
    for (auto *GV : ThinLTOProcessing.getNewExportedValues())
      ValuesToLink.insert(GV);
  }

  for (unsigned I = 0; I < ValuesToLink.size(); ++I) {
    GlobalValue *GV = ValuesToLink[I];
    const Comdat *SC = GV->getComdat();
    if (!SC)
      continue;
    for (GlobalValue *GV2 : ComdatMembers[SC])
      ValuesToLink.insert(GV2);
  }

  if (shouldInternalizeLinkedSymbols()) {
    for (GlobalValue *GV : ValuesToLink)
      Internalize.insert(GV->getName());
  }

  if (Mover.move(SrcM, ValuesToLink.getArrayRef(),
                 [this](GlobalValue &GV, IRMover::ValueAdder Add) {
                   addLazyFor(GV, Add);
                 },
                 ValIDToTempMDMap, false))
    return true;
  Module &DstM = Mover.getModule();
  for (auto &P : Internalize) {
    GlobalValue *GV = DstM.getNamedValue(P.first());
    GV->setLinkage(GlobalValue::InternalLinkage);
  }

  return false;
}