Пример #1
0
/// Make sure GV is visible from both modules. Delete is true if it is
/// being deleted from this module.
/// This also makes sure GV cannot be dropped so that references from
/// the split module remain valid.
static void makeVisible(GlobalValue &GV, bool Delete, bool IsDeletePass) {
  bool Local = GV.hasLocalLinkage();
  if (Local || Delete) {
    // This changes members from private -> hidden -> causes linker errors when using llvm-link
    if (!IsDeletePass)
      GV.setLinkage(GlobalValue::ExternalLinkage);
    if (Local)
      GV.setVisibility(GlobalValue::HiddenVisibility);
    return;
  }

  if (!GV.hasLinkOnceLinkage()) {
    assert(!GV.isDiscardableIfUnused());
    return;
  }

  // Map linkonce* to weak* so that llvm doesn't drop this GV.
  switch(GV.getLinkage()) {
  default:
    llvm_unreachable("Unexpected linkage");
  case GlobalValue::LinkOnceAnyLinkage:
    GV.setLinkage(GlobalValue::WeakAnyLinkage);
    return;
  case GlobalValue::LinkOnceODRLinkage:
    GV.setLinkage(GlobalValue::WeakODRLinkage);
    return;
  }
}
Пример #2
0
GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
                                            bool ForDefinition) {
  GlobalValue *NewGV;
  if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) {
    NewGV = copyGlobalVariableProto(SGVar);
  } else if (auto *SF = dyn_cast<Function>(SGV)) {
    NewGV = copyFunctionProto(SF);
  } else {
    if (ForDefinition)
      NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV));
    else
      NewGV = new GlobalVariable(
          DstM, TypeMap.get(SGV->getType()->getElementType()),
          /*isConstant*/ false, GlobalValue::ExternalLinkage,
          /*init*/ nullptr, SGV->getName(),
          /*insertbefore*/ nullptr, SGV->getThreadLocalMode(),
          SGV->getType()->getAddressSpace());
  }

  if (ForDefinition)
    NewGV->setLinkage(SGV->getLinkage());
  else if (SGV->hasExternalWeakLinkage() || SGV->hasWeakLinkage() ||
           SGV->hasLinkOnceLinkage())
    NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);

  NewGV->copyAttributesFrom(SGV);
  return NewGV;
}
Пример #3
0
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
  bool DoPromote = false;
  if (GV.hasLocalLinkage() &&
      ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) {
    // 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);
  } 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_or_null<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);
  }
}
Пример #4
0
/// Make sure GV is visible from both modules. Delete is true if it is
/// being deleted from this module.
/// This also makes sure GV cannot be dropped so that references from
/// the split module remain valid.
static void makeVisible(GlobalValue &GV, bool Delete) {
  bool Local = GV.hasLocalLinkage();
  if (Local)
    GV.setVisibility(GlobalValue::HiddenVisibility);

  if (Local || Delete) {
    GV.setLinkage(GlobalValue::ExternalLinkage);
    return;
  }

  if (!GV.hasLinkOnceLinkage()) {
    assert(!GV.isDiscardableIfUnused());
    return;
  }

  // Map linkonce* to weak* so that llvm doesn't drop this GV.
  switch(GV.getLinkage()) {
  default:
    llvm_unreachable("Unexpected linkage");
  case GlobalValue::LinkOnceAnyLinkage:
    GV.setLinkage(GlobalValue::WeakAnyLinkage);
    return;
  case GlobalValue::LinkOnceODRLinkage:
    GV.setLinkage(GlobalValue::WeakODRLinkage);
    return;
  }
}
Пример #5
0
void ThinLTOGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
  if (GV.hasLocalLinkage() &&
      (doPromoteLocalToGlobal(&GV) || isPerformingImport())) {
    GV.setName(getName(&GV));
    GV.setLinkage(getLinkage(&GV));
    if (!GV.hasLocalLinkage())
      GV.setVisibility(GlobalValue::HiddenVisibility);
    if (isModuleExporting())
      NewExportedValues.insert(&GV);
    return;
  }
  GV.setLinkage(getLinkage(&GV));
}
// llvm_mark_decl_weak - Used by varasm.c, called when a decl is found to be
// weak, but it already had an llvm object created for it. This marks the LLVM
// object weak as well.
void llvm_mark_decl_weak(tree decl) {
  assert(DECL_LLVM_SET_P(decl) && DECL_WEAK(decl) &&
         isa<GlobalValue>(DECL_LLVM(decl)) && "Decl isn't marked weak!");
  GlobalValue *GV = cast<GlobalValue>(DECL_LLVM(decl));

  // Do not mark something that is already known to be linkonce or internal.
  if (GV->hasExternalLinkage()) {
    if (GV->isDeclaration())
      GV->setLinkage(GlobalValue::ExternalWeakLinkage);
    else
      GV->setLinkage(GlobalValue::WeakLinkage);
  }
}
Пример #7
0
/// gold informs us that all symbols have been read. At this point, we use
/// get_symbols to see if any of our definitions have been overridden by a
/// native object file. Then, perform optimization and codegen.
static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
  if (Modules.empty())
    return LDPS_OK;

  LLVMContext Context;
  std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
  Linker L(Combined.get());

  std::string DefaultTriple = sys::getDefaultTargetTriple();

  StringSet<> Internalize;
  StringSet<> Maybe;
  for (claimed_file &F : Modules) {
    std::unique_ptr<Module> M =
        getModuleForFile(Context, F, ApiFile, Internalize, Maybe);
    if (!options::triple.empty())
      M->setTargetTriple(options::triple.c_str());
    else if (M->getTargetTriple().empty()) {
      M->setTargetTriple(DefaultTriple);
    }

    if (L.linkInModule(M.get()))
      message(LDPL_FATAL, "Failed to link module");
  }

  for (const auto &Name : Internalize) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (GV)
      internalize(*GV);
  }

  for (const auto &Name : Maybe) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (!GV)
      continue;
    GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
    if (canBeOmittedFromSymbolTable(GV))
      internalize(*GV);
  }

  if (options::generate_bc_file != options::BC_NO) {
    std::string path;
    if (options::generate_bc_file == options::BC_ONLY)
      path = output_name;
    else
      path = output_name + ".bc";
    saveBCFile(path, *L.getModule());
    if (options::generate_bc_file == options::BC_ONLY)
      return LDPS_OK;
  }

  codegen(*L.getModule());

  if (!options::extra_library_path.empty() &&
      set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)
    message(LDPL_FATAL, "Unable to set the extra library path.");

  return LDPS_OK;
}
Пример #8
0
void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {

  // Check the summaries to see if the symbol gets resolved to a known local
  // definition.
  if (GV.hasName()) {
    ValueInfo VI = ImportIndex.getValueInfo(GV.getGUID());
    if (VI) {
      // Need to check all summaries are local in case of hash collisions.
      bool IsLocal = VI.getSummaryList().size() &&
          llvm::all_of(VI.getSummaryList(),
                       [](const std::unique_ptr<GlobalValueSummary> &Summary) {
                         return Summary->isDSOLocal();
                       });
      if (IsLocal)
        GV.setDSOLocal(true);
    }
  }

  bool DoPromote = false;
  if (GV.hasLocalLinkage() &&
      ((DoPromote = shouldPromoteLocalToGlobal(&GV)) || isPerformingImport())) {
    // 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);
  } 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_or_null<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);
  }
}
Пример #9
0
static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
  if (V.hasLocalLinkage()) {
    if (R.needsRenaming(V))
      V.setName(R.getRename(V));
    V.setLinkage(GlobalValue::ExternalLinkage);
    V.setVisibility(GlobalValue::HiddenVisibility);
  }
  V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
  assert(!R.needsRenaming(V) && "Invalid global name.");
}
Пример #10
0
GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
                                            bool ForDefinition) {
  GlobalValue *NewGV;
  if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) {
    NewGV = copyGlobalVariableProto(SGVar);
  } else if (auto *SF = dyn_cast<Function>(SGV)) {
    NewGV = copyFunctionProto(SF);
  } else {
    if (ForDefinition)
      NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV));
    else
      NewGV = new GlobalVariable(
          DstM, TypeMap.get(SGV->getValueType()),
          /*isConstant*/ false, GlobalValue::ExternalLinkage,
          /*init*/ nullptr, SGV->getName(),
          /*insertbefore*/ nullptr, SGV->getThreadLocalMode(),
          SGV->getType()->getAddressSpace());
  }

  if (ForDefinition)
    NewGV->setLinkage(SGV->getLinkage());
  else if (SGV->hasExternalWeakLinkage())
    NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);

  NewGV->copyAttributesFrom(SGV);

  if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {
    // Metadata for global variables and function declarations is copied eagerly.
    if (isa<GlobalVariable>(SGV) || SGV->isDeclaration())
      NewGO->copyMetadata(cast<GlobalObject>(SGV), 0);
  }

  // Remove these copied constants in case this stays a declaration, since
  // they point to the source module. If the def is linked the values will
  // be mapped in during linkFunctionBody.
  if (auto *NewF = dyn_cast<Function>(NewGV)) {
    NewF->setPersonalityFn(nullptr);
    NewF->setPrefixData(nullptr);
    NewF->setPrologueData(nullptr);
  }

  return NewGV;
}
Пример #11
0
static void keepGlobalValue(GlobalValue &GV,
                            std::vector<GlobalAlias *> &KeptAliases) {
  assert(!GV.hasLocalLinkage());

  if (auto *GA = dyn_cast<GlobalAlias>(&GV))
    KeptAliases.push_back(GA);

  switch (GV.getLinkage()) {
  default:
    break;
  case GlobalValue::LinkOnceAnyLinkage:
    GV.setLinkage(GlobalValue::WeakAnyLinkage);
    break;
  case GlobalValue::LinkOnceODRLinkage:
    GV.setLinkage(GlobalValue::WeakODRLinkage);
    break;
  }

  assert(!GV.isDiscardableIfUnused());
}
Пример #12
0
/// linkFunctionProto - Link the function in the source module into the
/// destination module if needed, setting up mapping information.
bool ModuleLinker::linkFunctionProto(Function *SF) {
  GlobalValue *DGV = getLinkedToGlobal(SF);
  llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;

  if (DGV) {
    GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;
    bool LinkFromSrc = false;
    GlobalValue::VisibilityTypes NV;
    if (getLinkageResult(DGV, SF, NewLinkage, NV, LinkFromSrc))
      return true;
    NewVisibility = NV;

    if (!LinkFromSrc) {
      // Set calculated linkage
      DGV->setLinkage(NewLinkage);
      DGV->setVisibility(*NewVisibility);

      // Make sure to remember this mapping.
      ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType()));
      
      // Track the function from the source module so we don't attempt to remap 
      // it.
      DoNotLinkFromSource.insert(SF);
      
      return false;
    }
  }
  
  // If there is no linkage to be performed or we are linking from the source,
  // bring SF over.
  Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()),
                                     SF->getLinkage(), SF->getName(), DstM);
  CopyGVAttributes(NewDF, SF);
  if (NewVisibility)
    NewDF->setVisibility(*NewVisibility);

  if (DGV) {
    // Any uses of DF need to change to NewDF, with cast.
    DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDF, DGV->getType()));
    DGV->eraseFromParent();
  } else {
    // Internal, LO_ODR, or LO linkage - stick in set to ignore and lazily link.
    if (SF->hasLocalLinkage() || SF->hasLinkOnceLinkage() ||
        SF->hasAvailableExternallyLinkage()) {
      DoNotLinkFromSource.insert(SF);
      LazilyLinkFunctions.push_back(SF);
    }
  }
  
  ValueMap[SF] = NewDF;
  return false;
}
Пример #13
0
/// LinkAliasProto - Set up prototypes for any aliases that come over from the
/// source module.
bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) {
  GlobalValue *DGV = getLinkedToGlobal(SGA);
  llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;

  if (DGV) {
    GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;
    GlobalValue::VisibilityTypes NV;
    bool LinkFromSrc = false;
    if (getLinkageResult(DGV, SGA, NewLinkage, NV, LinkFromSrc))
      return true;
    NewVisibility = NV;

    if (!LinkFromSrc) {
      // Set calculated linkage.
      DGV->setLinkage(NewLinkage);
      DGV->setVisibility(*NewVisibility);

      // Make sure to remember this mapping.
      ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType()));
      
      // Track the alias from the source module so we don't attempt to remap it.
      DoNotLinkFromSource.insert(SGA);
      
      return false;
    }
  }
  
  // If there is no linkage to be performed or we're linking from the source,
  // bring over SGA.
  GlobalAlias *NewDA = new GlobalAlias(TypeMap.get(SGA->getType()),
                                       SGA->getLinkage(), SGA->getName(),
                                       /*aliasee*/0, DstM);
  CopyGVAttributes(NewDA, SGA);
  if (NewVisibility)
    NewDA->setVisibility(*NewVisibility);

  if (DGV) {
    // Any uses of DGV need to change to NewDA, with cast.
    DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDA, DGV->getType()));
    DGV->eraseFromParent();
  }
  
  ValueMap[SGA] = NewDA;
  return false;
}
Пример #14
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());
  }

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

  return false;
}
Пример #15
0
static std::unique_ptr<Module>
getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View,
                 ld_plugin_input_file &Info, raw_fd_ostream *ApiFile,
                 StringSet<> &Internalize, StringSet<> &Maybe,
                 std::vector<GlobalValue *> &Keep,
                 StringMap<unsigned> &Realign) {
  MemoryBufferRef BufferRef(StringRef((const char *)View, Info.filesize),
                            Info.name);
  ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
      object::IRObjectFile::create(BufferRef, Context);

  if (std::error_code EC = ObjOrErr.getError())
    message(LDPL_FATAL, "Could not read bitcode from file : %s",
            EC.message().c_str());

  object::IRObjectFile &Obj = **ObjOrErr;

  Module &M = Obj.getModule();

  M.materializeMetadata();
  UpgradeDebugInfo(M);

  SmallPtrSet<GlobalValue *, 8> Used;
  collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);

  unsigned SymNum = 0;
  for (auto &ObjSym : Obj.symbols()) {
    GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl());
    if (GV && GV->hasAppendingLinkage())
      Keep.push_back(GV);

    if (shouldSkip(ObjSym.getFlags()))
      continue;
    ld_plugin_symbol &Sym = F.syms[SymNum];
    ++SymNum;

    ld_plugin_symbol_resolution Resolution =
        (ld_plugin_symbol_resolution)Sym.resolution;

    if (options::generate_api_file)
      *ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n';

    if (!GV) {
      freeSymName(Sym);
      continue; // Asm symbol.
    }

    ResolutionInfo &Res = ResInfo[Sym.name];
    if (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP && !Res.IsLinkonceOdr)
      Resolution = LDPR_PREVAILING_DEF;

    // In ThinLTO mode change all prevailing resolutions to LDPR_PREVAILING_DEF.
    // For ThinLTO the IR files are compiled through the backend independently,
    // so we need to ensure that any prevailing linkonce copy will be emitted
    // into the object file by making it weak. Additionally, we can skip the
    // IRONLY handling for internalization, which isn't performed in ThinLTO
    // mode currently anyway.
    if (options::thinlto && (Resolution == LDPR_PREVAILING_DEF_IRONLY_EXP ||
                             Resolution == LDPR_PREVAILING_DEF_IRONLY))
      Resolution = LDPR_PREVAILING_DEF;

    GV->setUnnamedAddr(Res.UnnamedAddr);
    GV->setVisibility(Res.Visibility);

    // Override gold's resolution for common symbols. We want the largest
    // one to win.
    if (GV->hasCommonLinkage()) {
      if (Resolution == LDPR_PREVAILING_DEF_IRONLY)
        Res.CommonInternal = true;

      if (Resolution == LDPR_PREVAILING_DEF_IRONLY ||
          Resolution == LDPR_PREVAILING_DEF)
        Res.UseCommon = true;

      const DataLayout &DL = GV->getParent()->getDataLayout();
      uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
      unsigned Align = GV->getAlignment();

      if (Res.UseCommon && Size >= Res.CommonSize) {
        // Take GV.
        if (Res.CommonInternal)
          Resolution = LDPR_PREVAILING_DEF_IRONLY;
        else
          Resolution = LDPR_PREVAILING_DEF;
        cast<GlobalVariable>(GV)->setAlignment(
            std::max(Res.CommonAlign, Align));
      } else {
        // Do not take GV, it's smaller than what we already have in the
        // combined module.
        Resolution = LDPR_PREEMPTED_IR;
        if (Align > Res.CommonAlign)
          // Need to raise the alignment though.
          Realign[Sym.name] = Align;
      }

      Res.CommonSize = std::max(Res.CommonSize, Size);
      Res.CommonAlign = std::max(Res.CommonAlign, Align);
    }

    switch (Resolution) {
    case LDPR_UNKNOWN:
      llvm_unreachable("Unexpected resolution");

    case LDPR_RESOLVED_IR:
    case LDPR_RESOLVED_EXEC:
    case LDPR_RESOLVED_DYN:
    case LDPR_PREEMPTED_IR:
    case LDPR_PREEMPTED_REG:
      break;

    case LDPR_UNDEF:
      if (!GV->isDeclarationForLinker())
        assert(GV->hasComdat());
      break;

    case LDPR_PREVAILING_DEF_IRONLY: {
      Keep.push_back(GV);
      // The IR linker has to be able to map this value to a declaration,
      // so we can only internalize after linking.
      if (!Used.count(GV))
        Internalize.insert(GV->getName());
      break;
    }

    case LDPR_PREVAILING_DEF:
      Keep.push_back(GV);
      // There is a non IR use, so we have to force optimizations to keep this.
      switch (GV->getLinkage()) {
      default:
        break;
      case GlobalValue::LinkOnceAnyLinkage:
        GV->setLinkage(GlobalValue::WeakAnyLinkage);
        break;
      case GlobalValue::LinkOnceODRLinkage:
        GV->setLinkage(GlobalValue::WeakODRLinkage);
        break;
      }
      break;

    case LDPR_PREVAILING_DEF_IRONLY_EXP: {
      // We can only check for address uses after we merge the modules. The
      // reason is that this GV might have a copy in another module
      // and in that module the address might be significant, but that
      // copy will be LDPR_PREEMPTED_IR.
      Maybe.insert(GV->getName());
      Keep.push_back(GV);
      break;
    }
    }

    freeSymName(Sym);
  }

  return Obj.takeModule();
}
Пример #16
0
/// gold informs us that all symbols have been read. At this point, we use
/// get_symbols to see if any of our definitions have been overridden by a
/// native object file. Then, perform optimization and codegen.
static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
  if (Modules.empty())
    return LDPS_OK;

  if (unsigned NumOpts = options::extra.size())
    cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);

  // If we are doing ThinLTO compilation, simply build the combined
  // module index/summary and emit it. We don't need to parse the modules
  // and link them in this case.
  if (options::thinlto) {
    ModuleSummaryIndex CombinedIndex;
    uint64_t NextModuleId = 0;
    for (claimed_file &F : Modules) {
      PluginInputFile InputFile(F.handle);

      std::unique_ptr<ModuleSummaryIndex> Index =
          getModuleSummaryIndexForFile(F, InputFile.file());

      // Skip files without a module summary.
      if (Index)
        CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
    }

    std::error_code EC;
    raw_fd_ostream OS(output_name + ".thinlto.bc", EC,
                      sys::fs::OpenFlags::F_None);
    if (EC)
      message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s",
              output_name.data(), EC.message().c_str());
    WriteIndexToFile(CombinedIndex, OS);
    OS.close();

    if (options::thinlto_index_only) {
      cleanup_hook();
      exit(0);
    }

    thinLTOBackends(ApiFile, CombinedIndex);
    return LDPS_OK;
  }

  LLVMContext Context;
  Context.setDiscardValueNames(options::DiscardValueNames);
  Context.enableDebugTypeODRUniquing(); // Merge debug info types.
  Context.setDiagnosticHandler(diagnosticHandlerForContext, nullptr, true);

  std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
  IRMover L(*Combined);

  StringSet<> Internalize;
  StringSet<> Maybe;
  for (claimed_file &F : Modules) {
    PluginInputFile InputFile(F.handle);
    const void *View = getSymbolsAndView(F);
    if (!View)
      continue;
    if (linkInModule(Context, L, F, View, InputFile.file(), ApiFile,
                     Internalize, Maybe))
      message(LDPL_FATAL, "Failed to link module");
  }

  for (const auto &Name : Internalize) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (GV)
      internalize(*GV);
  }

  for (const auto &Name : Maybe) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (!GV)
      continue;
    GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
    if (canBeOmittedFromSymbolTable(GV))
      internalize(*GV);
  }

  if (options::TheOutputType == options::OT_DISABLE)
    return LDPS_OK;

  if (options::TheOutputType != options::OT_NORMAL) {
    std::string path;
    if (options::TheOutputType == options::OT_BC_ONLY)
      path = output_name;
    else
      path = output_name + ".bc";
    saveBCFile(path, *Combined);
    if (options::TheOutputType == options::OT_BC_ONLY)
      return LDPS_OK;
  }

  CodeGen codeGen(std::move(Combined));
  codeGen.runAll();

  if (!options::extra_library_path.empty() &&
      set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)
    message(LDPL_FATAL, "Unable to set the extra library path.");

  return LDPS_OK;
}
Пример #17
0
void BitcodeCompiler::add(BitcodeFile &F) {
  std::unique_ptr<IRObjectFile> Obj =
      check(IRObjectFile::create(F.MB, Context));
  std::vector<GlobalValue *> Keep;
  unsigned BodyIndex = 0;
  ArrayRef<SymbolBody *> Bodies = F.getSymbols();

  Module &M = Obj->getModule();
  if (M.getDataLayoutStr().empty())
    fatal("invalid bitcode file: " + F.getName() + " has no datalayout");

  // If a symbol appears in @llvm.used, the linker is required
  // to treat the symbol as there is a reference to the symbol
  // that it cannot see. Therefore, we can't internalize.
  SmallPtrSet<GlobalValue *, 8> Used;
  collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false);

  for (const BasicSymbolRef &Sym : Obj->symbols()) {
    GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
    // Ignore module asm symbols.
    if (!GV)
      continue;
    if (GV->hasAppendingLinkage()) {
      Keep.push_back(GV);
      continue;
    }
    if (BitcodeFile::shouldSkip(Sym))
      continue;
    SymbolBody *B = Bodies[BodyIndex++];
    if (!B || &B->repl() != B || !isa<DefinedBitcode>(B))
      continue;
    switch (GV->getLinkage()) {
    default:
      break;
    case llvm::GlobalValue::LinkOnceAnyLinkage:
      GV->setLinkage(GlobalValue::WeakAnyLinkage);
      break;
    case llvm::GlobalValue::LinkOnceODRLinkage:
      GV->setLinkage(GlobalValue::WeakODRLinkage);
      break;
    }

    // We collect the set of symbols we want to internalize here
    // and change the linkage after the IRMover executed, i.e. after
    // we imported the symbols and satisfied undefined references
    // to it. We can't just change linkage here because otherwise
    // the IRMover will just rename the symbol.
    // Shared libraries need to be handled slightly differently.
    // For now, let's be conservative and just never internalize
    // symbols when creating a shared library.
    if (!Config->Shared && !Config->ExportDynamic && !B->isUsedInRegularObj() &&
        !B->MustBeInDynSym)
      if (!Used.count(GV))
        InternalizedSyms.insert(GV->getName());

    Keep.push_back(GV);
  }

  Mover.move(Obj->takeModule(), Keep,
             [](GlobalValue &, IRMover::ValueAdder) {});
}
Пример #18
0
/// gold informs us that all symbols have been read. At this point, we use
/// get_symbols to see if any of our definitions have been overridden by a
/// native object file. Then, perform optimization and codegen.
static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
  if (Modules.empty())
    return LDPS_OK;

  LLVMContext Context;
  Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);

  // If we are doing ThinLTO compilation, simply build the combined
  // function index/summary and emit it. We don't need to parse the modules
  // and link them in this case.
  if (options::thinlto) {
    std::unique_ptr<FunctionInfoIndex> CombinedIndex(new FunctionInfoIndex());
    uint64_t NextModuleId = 0;
    for (claimed_file &F : Modules) {
      ld_plugin_input_file File;
      if (get_input_file(F.handle, &File) != LDPS_OK)
        message(LDPL_FATAL, "Failed to get file information");

      std::unique_ptr<FunctionInfoIndex> Index =
          getFunctionIndexForFile(Context, F, File);
      CombinedIndex->mergeFrom(std::move(Index), ++NextModuleId);
    }

    std::error_code EC;
    raw_fd_ostream OS(output_name + ".thinlto.bc", EC,
                      sys::fs::OpenFlags::F_None);
    if (EC)
      message(LDPL_FATAL, "Unable to open %s.thinlto.bc for writing: %s",
              output_name.data(), EC.message().c_str());
    WriteFunctionSummaryToFile(CombinedIndex.get(), OS);
    OS.close();

    cleanup_hook();
    exit(0);
  }

  std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
  Linker L(Combined.get());

  std::string DefaultTriple = sys::getDefaultTargetTriple();

  StringSet<> Internalize;
  StringSet<> Maybe;
  for (claimed_file &F : Modules) {
    ld_plugin_input_file File;
    if (get_input_file(F.handle, &File) != LDPS_OK)
      message(LDPL_FATAL, "Failed to get file information");
    std::unique_ptr<Module> M =
        getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe);
    if (!options::triple.empty())
      M->setTargetTriple(options::triple.c_str());
    else if (M->getTargetTriple().empty()) {
      M->setTargetTriple(DefaultTriple);
    }

    if (L.linkInModule(M.get()))
      message(LDPL_FATAL, "Failed to link module");
    if (release_input_file(F.handle) != LDPS_OK)
      message(LDPL_FATAL, "Failed to release file information");
  }

  for (const auto &Name : Internalize) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (GV)
      internalize(*GV);
  }

  for (const auto &Name : Maybe) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (!GV)
      continue;
    GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
    if (canBeOmittedFromSymbolTable(GV))
      internalize(*GV);
  }

  if (options::TheOutputType == options::OT_DISABLE)
    return LDPS_OK;

  if (options::TheOutputType != options::OT_NORMAL) {
    std::string path;
    if (options::TheOutputType == options::OT_BC_ONLY)
      path = output_name;
    else
      path = output_name + ".bc";
    saveBCFile(path, *L.getModule());
    if (options::TheOutputType == options::OT_BC_ONLY)
      return LDPS_OK;
  }

  codegen(std::move(Combined));

  if (!options::extra_library_path.empty() &&
      set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)
    message(LDPL_FATAL, "Unable to set the extra library path.");

  return LDPS_OK;
}
Пример #19
0
void BitcodeCompiler::add(BitcodeFile &F) {
  std::unique_ptr<IRObjectFile> Obj = std::move(F.Obj);
  std::vector<GlobalValue *> Keep;
  unsigned BodyIndex = 0;
  ArrayRef<Symbol *> Syms = F.getSymbols();

  Module &M = Obj->getModule();
  if (M.getDataLayoutStr().empty())
    fatal("invalid bitcode file: " + F.getName() + " has no datalayout");

  // Discard non-compatible debug infos if necessary.
  M.materializeMetadata();
  UpgradeDebugInfo(M);

  // If a symbol appears in @llvm.used, the linker is required
  // to treat the symbol as there is a reference to the symbol
  // that it cannot see. Therefore, we can't internalize.
  SmallPtrSet<GlobalValue *, 8> Used;
  collectUsedGlobalVariables(M, Used, /* CompilerUsed */ false);

  for (const BasicSymbolRef &Sym : Obj->symbols()) {
    uint32_t Flags = Sym.getFlags();
    GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
    if (GV && GV->hasAppendingLinkage())
      Keep.push_back(GV);
    if (BitcodeFile::shouldSkip(Flags))
      continue;
    Symbol *S = Syms[BodyIndex++];
    if (Flags & BasicSymbolRef::SF_Undefined) {
      handleUndefinedAsmRefs(Sym, GV, AsmUndefinedRefs);
      continue;
    }
    auto *B = dyn_cast<DefinedBitcode>(S->body());
    if (!B || B->File != &F)
      continue;

    // We collect the set of symbols we want to internalize here
    // and change the linkage after the IRMover executed, i.e. after
    // we imported the symbols and satisfied undefined references
    // to it. We can't just change linkage here because otherwise
    // the IRMover will just rename the symbol.
    if (GV && shouldInternalize(Used, S, GV))
      InternalizedSyms.insert(GV->getName());

    // At this point we know that either the combined LTO object will provide a
    // definition of a symbol, or we will internalize it. In either case, we
    // need to undefine the symbol. In the former case, the real definition
    // needs to be able to replace the original definition without conflicting.
    // In the latter case, we need to allow the combined LTO object to provide a
    // definition with the same name, for example when doing parallel codegen.
    undefine(S);

    if (!GV)
      // Module asm symbol.
      continue;

    switch (GV->getLinkage()) {
    default:
      break;
    case llvm::GlobalValue::LinkOnceAnyLinkage:
      GV->setLinkage(GlobalValue::WeakAnyLinkage);
      break;
    case llvm::GlobalValue::LinkOnceODRLinkage:
      GV->setLinkage(GlobalValue::WeakODRLinkage);
      break;
    }

    Keep.push_back(GV);
  }

  if (Error E = Mover.move(Obj->takeModule(), Keep,
                           [](GlobalValue &, IRMover::ValueAdder) {})) {
    handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) {
      fatal("failed to link module " + F.getName() + ": " + EIB.message());
    });
  }
}
Пример #20
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;
}
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);
  }
}
Пример #22
0
/// linkGlobalProto - Loop through the global variables in the src module and
/// merge them into the dest module.
bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) {
  GlobalValue *DGV = getLinkedToGlobal(SGV);
  llvm::Optional<GlobalValue::VisibilityTypes> NewVisibility;

  if (DGV) {
    // Concatenation of appending linkage variables is magic and handled later.
    if (DGV->hasAppendingLinkage() || SGV->hasAppendingLinkage())
      return linkAppendingVarProto(cast<GlobalVariable>(DGV), SGV);
    
    // Determine whether linkage of these two globals follows the source
    // module's definition or the destination module's definition.
    GlobalValue::LinkageTypes NewLinkage = GlobalValue::InternalLinkage;
    GlobalValue::VisibilityTypes NV;
    bool LinkFromSrc = false;
    if (getLinkageResult(DGV, SGV, NewLinkage, NV, LinkFromSrc))
      return true;
    NewVisibility = NV;

    // If we're not linking from the source, then keep the definition that we
    // have.
    if (!LinkFromSrc) {
      // Special case for const propagation.
      if (GlobalVariable *DGVar = dyn_cast<GlobalVariable>(DGV))
        if (DGVar->isDeclaration() && SGV->isConstant() && !DGVar->isConstant())
          DGVar->setConstant(true);
      
      // Set calculated linkage and visibility.
      DGV->setLinkage(NewLinkage);
      DGV->setVisibility(*NewVisibility);

      // Make sure to remember this mapping.
      ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType()));
      
      // Track the source global so that we don't attempt to copy it over when 
      // processing global initializers.
      DoNotLinkFromSource.insert(SGV);
      
      return false;
    }
  }
  
  // No linking to be performed or linking from the source: simply create an
  // identical version of the symbol over in the dest module... the
  // initializer will be filled in later by LinkGlobalInits.
  GlobalVariable *NewDGV =
    new GlobalVariable(*DstM, TypeMap.get(SGV->getType()->getElementType()),
                       SGV->isConstant(), SGV->getLinkage(), /*init*/0,
                       SGV->getName(), /*insertbefore*/0,
                       SGV->isThreadLocal(),
                       SGV->getType()->getAddressSpace());
  // Propagate alignment, visibility and section info.
  CopyGVAttributes(NewDGV, SGV);
  if (NewVisibility)
    NewDGV->setVisibility(*NewVisibility);

  if (DGV) {
    DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV, DGV->getType()));
    DGV->eraseFromParent();
  }
  
  // Make sure to remember this mapping.
  ValueMap[SGV] = NewDGV;
  return false;
}
Пример #23
0
static void internalize(GlobalValue &GV) {
  if (GV.isDeclarationForLinker())
    return; // We get here if there is a matching asm definition.
  if (!GV.hasLocalLinkage())
    GV.setLinkage(GlobalValue::InternalLinkage);
}
Пример #24
0
/// gold informs us that all symbols have been read. At this point, we use
/// get_symbols to see if any of our definitions have been overridden by a
/// native object file. Then, perform optimization and codegen.
static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
  if (Modules.empty())
    return LDPS_OK;

  LLVMContext Context;
  Context.setDiagnosticHandler(diagnosticHandler, nullptr, true);

  std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));
  Linker L(Combined.get());

  std::string DefaultTriple = sys::getDefaultTargetTriple();

  StringSet<> Internalize;
  StringSet<> Maybe;
  for (claimed_file &F : Modules) {
    ld_plugin_input_file File;
    if (get_input_file(F.handle, &File) != LDPS_OK)
      message(LDPL_FATAL, "Failed to get file information");
    std::unique_ptr<Module> M =
        getModuleForFile(Context, F, File, ApiFile, Internalize, Maybe);
    if (!options::triple.empty())
      M->setTargetTriple(options::triple.c_str());
    else if (M->getTargetTriple().empty()) {
      M->setTargetTriple(DefaultTriple);
    }

    if (L.linkInModule(M.get()))
      message(LDPL_FATAL, "Failed to link module");
    if (release_input_file(F.handle) != LDPS_OK)
      message(LDPL_FATAL, "Failed to release file information");
  }

  for (const auto &Name : Internalize) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (GV)
      internalize(*GV);
  }

  for (const auto &Name : Maybe) {
    GlobalValue *GV = Combined->getNamedValue(Name.first());
    if (!GV)
      continue;
    GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
    if (canBeOmittedFromSymbolTable(GV))
      internalize(*GV);
  }

  // @LOCALMOD-BEGIN
  // Perform symbol wrapping.
  unsigned num_wrapped;
  if ((*get_num_wrapped)(&num_wrapped) != LDPS_OK) {
    (*message)(LDPL_ERROR, "Unable to get the number of wrapped symbols.");
    return LDPS_ERR;
  }
  for (unsigned i = 0; i < num_wrapped; ++i) {
    const char *sym;
    if ((*get_wrapped)(i, &sym) != LDPS_OK) {
      (*message)(LDPL_ERROR, "Unable to wrap symbol %u/%u.", i, num_wrapped);
      return LDPS_ERR;
    }
    wrapSymbol(Combined.get(), sym);
  }
  // @LOCALMOD-END

  if (options::TheOutputType == options::OT_DISABLE)
    return LDPS_OK;

  if (options::TheOutputType != options::OT_NORMAL) {
    std::string path;
    if (options::TheOutputType == options::OT_BC_ONLY)
      path = output_name;
    else
      path = output_name + ".bc";
    saveBCFile(path, *L.getModule());
    if (options::TheOutputType == options::OT_BC_ONLY)
      return LDPS_OK;
  }

  codegen(*L.getModule());

  if (!options::extra_library_path.empty() &&
      set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)
    message(LDPL_FATAL, "Unable to set the extra library path.");

  return LDPS_OK;
}
Пример #25
0
Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
                                                    bool ForAlias) {
  GlobalValue *DGV = getLinkedToGlobal(SGV);

  bool ShouldLink = shouldLink(DGV, *SGV);

  // just missing from map
  if (ShouldLink) {
    auto I = ValueMap.find(SGV);
    if (I != ValueMap.end())
      return cast<Constant>(I->second);

    I = AliasValueMap.find(SGV);
    if (I != AliasValueMap.end())
      return cast<Constant>(I->second);
  }

  if (!ShouldLink && ForAlias)
    DGV = nullptr;

  // Handle the ultra special appending linkage case first.
  assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage());
  if (SGV->hasAppendingLinkage())
    return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
                                 cast<GlobalVariable>(SGV));

  GlobalValue *NewGV;
  if (DGV && !ShouldLink) {
    NewGV = DGV;
  } else {
    // If we are done linking global value bodies (i.e. we are performing
    // metadata linking), don't link in the global value due to this
    // reference, simply map it to null.
    if (DoneLinkingBodies)
      return nullptr;

    NewGV = copyGlobalValueProto(SGV, ShouldLink);
    if (ShouldLink || !ForAlias)
      forceRenaming(NewGV, SGV->getName());
  }

  // Overloaded intrinsics have overloaded types names as part of their
  // names. If we renamed overloaded types we should rename the intrinsic
  // as well.
  if (Function *F = dyn_cast<Function>(NewGV))
    if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F))
      NewGV = Remangled.getValue();

  if (ShouldLink || ForAlias) {
    if (const Comdat *SC = SGV->getComdat()) {
      if (auto *GO = dyn_cast<GlobalObject>(NewGV)) {
        Comdat *DC = DstM.getOrInsertComdat(SC->getName());
        DC->setSelectionKind(SC->getSelectionKind());
        GO->setComdat(DC);
      }
    }
  }

  if (!ShouldLink && ForAlias)
    NewGV->setLinkage(GlobalValue::InternalLinkage);

  Constant *C = NewGV;
  if (DGV)
    C = ConstantExpr::getBitCast(NewGV, TypeMap.get(SGV->getType()));

  if (DGV && NewGV != DGV) {
    DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType()));
    DGV->eraseFromParent();
  }

  return C;
}
Пример #26
0
static void internalize(GlobalValue &GV) {
  assert(!GV.hasLocalLinkage() &&
         "Trying to internalize a symbol with local linkage!");
  GV.setLinkage(GlobalValue::InternalLinkage);
}