[llvm] r289574 - LTO: Port the new LTO API to ModuleSymbolTable.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 13 11:43:49 PST 2016


Author: pcc
Date: Tue Dec 13 13:43:49 2016
New Revision: 289574

URL: http://llvm.org/viewvc/llvm-project?rev=289574&view=rev
Log:
LTO: Port the new LTO API to ModuleSymbolTable.

Differential Revision: https://reviews.llvm.org/D27077

Modified:
    llvm/trunk/include/llvm/LTO/LTO.h
    llvm/trunk/lib/LTO/LTO.cpp

Modified: llvm/trunk/include/llvm/LTO/LTO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTO.h?rev=289574&r1=289573&r2=289574&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/LTO.h (original)
+++ llvm/trunk/include/llvm/LTO/LTO.h Tue Dec 13 13:43:49 2016
@@ -71,7 +71,7 @@ class LTO;
 struct SymbolResolution;
 class ThinBackendProc;
 
-/// An input file. This is a wrapper for IRObjectFile that exposes only the
+/// An input file. This is a wrapper for ModuleSymbolTable that exposes only the
 /// information that an LTO client should need in order to do symbol resolution.
 class InputFile {
   // FIXME: Remove LTO class friendship once we have bitcode symbol tables.
@@ -80,7 +80,10 @@ class InputFile {
 
   // FIXME: Remove the LLVMContext once we have bitcode symbol tables.
   LLVMContext Ctx;
-  std::unique_ptr<object::IRObjectFile> Obj;
+  ModuleSymbolTable SymTab;
+  std::unique_ptr<Module> Mod;
+  MemoryBufferRef MBRef;
+
   std::vector<StringRef> Comdats;
   DenseMap<const Comdat *, unsigned> ComdatMap;
 
@@ -90,9 +93,9 @@ public:
 
   class symbol_iterator;
 
-  /// This is a wrapper for object::basic_symbol_iterator that exposes only the
-  /// information that an LTO client should need in order to do symbol
-  /// resolution.
+  /// This is a wrapper for ArrayRef<ModuleSymbolTable::Symbol>::iterator that
+  /// exposes only the information that an LTO client should need in order to do
+  /// symbol resolution.
   ///
   /// This object is ephemeral; it is only valid as long as an iterator obtained
   /// from symbols() refers to it.
@@ -100,9 +103,9 @@ public:
     friend symbol_iterator;
     friend LTO;
 
-    object::basic_symbol_iterator I;
+    ArrayRef<ModuleSymbolTable::Symbol>::iterator I;
+    const ModuleSymbolTable &SymTab;
     const InputFile *File;
-    const GlobalValue *GV;
     uint32_t Flags;
     SmallString<64> Name;
 
@@ -112,10 +115,9 @@ public:
     }
 
     void skip() {
-      const object::SymbolicFile *Obj = I->getObject();
-      auto E = Obj->symbol_end();
+      ArrayRef<ModuleSymbolTable::Symbol>::iterator E = SymTab.symbols().end();
       while (I != E) {
-        Flags = I->getFlags();
+        Flags = SymTab.getSymbolFlags(*I);
         if (!shouldSkip())
           break;
         ++I;
@@ -126,14 +128,17 @@ public:
       Name.clear();
       {
         raw_svector_ostream OS(Name);
-        I->printName(OS);
+        SymTab.printSymbolName(OS, *I);
       }
-      GV = cast<object::IRObjectFile>(Obj)->getSymbolGV(I->getRawDataRefImpl());
     }
 
+    bool isGV() const { return I->is<GlobalValue *>(); }
+    GlobalValue *getGV() const { return I->get<GlobalValue *>(); }
+
   public:
-    Symbol(object::basic_symbol_iterator I, const InputFile *File)
-        : I(I), File(File) {
+    Symbol(ArrayRef<ModuleSymbolTable::Symbol>::iterator I,
+           const ModuleSymbolTable &SymTab, const InputFile *File)
+        : I(I), SymTab(SymTab), File(File) {
       skip();
     }
 
@@ -142,16 +147,16 @@ public:
 
     uint32_t getFlags() const { return Flags; }
     GlobalValue::VisibilityTypes getVisibility() const {
-      if (GV)
-        return GV->getVisibility();
+      if (isGV())
+        return getGV()->getVisibility();
       return GlobalValue::DefaultVisibility;
     }
     bool canBeOmittedFromSymbolTable() const {
-      return GV && llvm::canBeOmittedFromSymbolTable(GV);
+      return isGV() && llvm::canBeOmittedFromSymbolTable(getGV());
     }
     bool isTLS() const {
       // FIXME: Expose a thread-local flag for module asm symbols.
-      return GV && GV->isThreadLocal();
+      return isGV() && getGV()->isThreadLocal();
     }
 
     // Returns the index of the comdat this symbol is in or -1 if the symbol
@@ -164,16 +169,16 @@ public:
 
     uint64_t getCommonSize() const {
       assert(Flags & object::BasicSymbolRef::SF_Common);
-      if (!GV)
+      if (!isGV())
         return 0;
-      return GV->getParent()->getDataLayout().getTypeAllocSize(
-          GV->getType()->getElementType());
+      return getGV()->getParent()->getDataLayout().getTypeAllocSize(
+          getGV()->getType()->getElementType());
     }
     unsigned getCommonAlignment() const {
       assert(Flags & object::BasicSymbolRef::SF_Common);
-      if (!GV)
+      if (!isGV())
         return 0;
-      return GV->getAlignment();
+      return getGV()->getAlignment();
     }
   };
 
@@ -181,8 +186,9 @@ public:
     Symbol Sym;
 
   public:
-    symbol_iterator(object::basic_symbol_iterator I, const InputFile *File)
-        : Sym(I, File) {}
+    symbol_iterator(ArrayRef<ModuleSymbolTable::Symbol>::iterator I,
+                    const ModuleSymbolTable &SymTab, const InputFile *File)
+        : Sym(I, SymTab, File) {}
 
     symbol_iterator &operator++() {
       ++Sym.I;
@@ -206,17 +212,13 @@ public:
 
   /// A range over the symbols in this InputFile.
   iterator_range<symbol_iterator> symbols() {
-    return llvm::make_range(symbol_iterator(Obj->symbol_begin(), this),
-                            symbol_iterator(Obj->symbol_end(), this));
+    return llvm::make_range(
+        symbol_iterator(SymTab.symbols().begin(), SymTab, this),
+        symbol_iterator(SymTab.symbols().end(), SymTab, this));
   }
 
-  StringRef getSourceFileName() const {
-    return Obj->getModule().getSourceFileName();
-  }
-
-  MemoryBufferRef getMemoryBufferRef() const {
-    return Obj->getMemoryBufferRef();
-  }
+  StringRef getSourceFileName() const { return Mod->getSourceFileName(); }
+  MemoryBufferRef getMemoryBufferRef() const { return MBRef; }
 
   // Returns a table with all the comdats used by this file.
   ArrayRef<StringRef> getComdatTable() const { return Comdats; }
@@ -399,8 +401,7 @@ private:
   // Global mapping from mangled symbol names to resolutions.
   StringMap<GlobalResolution> GlobalResolutions;
 
-  void addSymbolToGlobalRes(object::IRObjectFile *Obj,
-                            SmallPtrSet<GlobalValue *, 8> &Used,
+  void addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used,
                             const InputFile::Symbol &Sym, SymbolResolution Res,
                             unsigned Partition);
 

Modified: llvm/trunk/lib/LTO/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTO.cpp?rev=289574&r1=289573&r2=289574&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTO.cpp (original)
+++ llvm/trunk/lib/LTO/LTO.cpp Tue Dec 13 13:43:49 2016
@@ -217,13 +217,22 @@ void llvm::thinLTOInternalizeAndPromoteI
 Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) {
   std::unique_ptr<InputFile> File(new InputFile);
 
-  Expected<std::unique_ptr<object::IRObjectFile>> IRObj =
-      IRObjectFile::create(Object, File->Ctx);
-  if (!IRObj)
-    return IRObj.takeError();
-  File->Obj = std::move(*IRObj);
+  ErrorOr<MemoryBufferRef> BCOrErr =
+      IRObjectFile::findBitcodeInMemBuffer(Object);
+  if (!BCOrErr)
+    return errorCodeToError(BCOrErr.getError());
+  File->MBRef = *BCOrErr;
+
+  Expected<std::unique_ptr<Module>> MOrErr =
+      getLazyBitcodeModule(*BCOrErr, File->Ctx,
+                           /*ShouldLazyLoadMetadata*/ true);
+  if (!MOrErr)
+    return MOrErr.takeError();
 
-  for (const auto &C : File->Obj->getModule().getComdatSymbolTable()) {
+  File->Mod = std::move(*MOrErr);
+  File->SymTab.addModule(File->Mod.get());
+
+  for (const auto &C : File->Mod->getComdatSymbolTable()) {
     auto P =
         File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size()));
     assert(P.second);
@@ -235,17 +244,12 @@ Expected<std::unique_ptr<InputFile>> Inp
 }
 
 Expected<int> InputFile::Symbol::getComdatIndex() const {
-  if (!GV)
+  if (!isGV())
     return -1;
-  const GlobalObject *GO;
-  if (auto *GA = dyn_cast<GlobalAlias>(GV)) {
-    GO = GA->getBaseObject();
-    if (!GO)
-      return make_error<StringError>("Unable to determine comdat of alias!",
-                                     inconvertibleErrorCode());
-  } else {
-    GO = cast<GlobalObject>(GV);
-  }
+  const GlobalObject *GO = getGV()->getBaseObject();
+  if (!GO)
+    return make_error<StringError>("Unable to determine comdat of alias!",
+                                   inconvertibleErrorCode());
   if (const Comdat *C = GO->getComdat()) {
     auto I = File->ComdatMap.find(C);
     assert(I != File->ComdatMap.end());
@@ -272,11 +276,10 @@ LTO::LTO(Config Conf, ThinBackend Backen
       ThinLTO(std::move(Backend)) {}
 
 // Add the given symbol to the GlobalResolutions map, and resolve its partition.
-void LTO::addSymbolToGlobalRes(IRObjectFile *Obj,
-                               SmallPtrSet<GlobalValue *, 8> &Used,
+void LTO::addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used,
                                const InputFile::Symbol &Sym,
                                SymbolResolution Res, unsigned Partition) {
-  GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl());
+  GlobalValue *GV = Sym.isGV() ? Sym.getGV() : nullptr;
 
   auto &GlobalRes = GlobalResolutions[Sym.getName()];
   if (GV) {
@@ -321,14 +324,13 @@ Error LTO::add(std::unique_ptr<InputFile
     writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res);
 
   // FIXME: move to backend
-  Module &M = Input->Obj->getModule();
+  Module &M = *Input->Mod;
   if (!Conf.OverrideTriple.empty())
     M.setTargetTriple(Conf.OverrideTriple);
   else if (M.getTargetTriple().empty())
     M.setTargetTriple(Conf.DefaultTriple);
 
-  MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef();
-  Expected<bool> HasThinLTOSummary = hasGlobalValueSummary(MBRef);
+  Expected<bool> HasThinLTOSummary = hasGlobalValueSummary(Input->MBRef);
   if (!HasThinLTOSummary)
     return HasThinLTOSummary.takeError();
 
@@ -346,17 +348,20 @@ Error LTO::addRegularLTO(std::unique_ptr
         llvm::make_unique<Module>("ld-temp.o", RegularLTO.Ctx);
     RegularLTO.Mover = llvm::make_unique<IRMover>(*RegularLTO.CombinedModule);
   }
-  Expected<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
-      IRObjectFile::create(Input->Obj->getMemoryBufferRef(), RegularLTO.Ctx);
-  if (!ObjOrErr)
-    return ObjOrErr.takeError();
-  std::unique_ptr<object::IRObjectFile> Obj = std::move(*ObjOrErr);
+  Expected<std::unique_ptr<Module>> MOrErr =
+      getLazyBitcodeModule(Input->MBRef, RegularLTO.Ctx,
+                           /*ShouldLazyLoadMetadata*/ true);
+  if (!MOrErr)
+    return MOrErr.takeError();
 
-  Module &M = Obj->getModule();
+  Module &M = **MOrErr;
   if (Error Err = M.materializeMetadata())
     return Err;
   UpgradeDebugInfo(M);
 
+  ModuleSymbolTable SymTab;
+  SymTab.addModule(&M);
+
   SmallPtrSet<GlobalValue *, 8> Used;
   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
 
@@ -368,16 +373,18 @@ Error LTO::addRegularLTO(std::unique_ptr
 
   auto ResI = Res.begin();
   for (const InputFile::Symbol &Sym :
-       make_range(InputFile::symbol_iterator(Obj->symbol_begin(), nullptr),
-                  InputFile::symbol_iterator(Obj->symbol_end(), nullptr))) {
+       make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab,
+                                             nullptr),
+                  InputFile::symbol_iterator(SymTab.symbols().end(), SymTab,
+                                             nullptr))) {
     assert(ResI != Res.end());
     SymbolResolution Res = *ResI++;
-    addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0);
+    addSymbolToGlobalRes(Used, Sym, Res, 0);
 
-    GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl());
     if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
       continue;
-    if (Res.Prevailing && GV) {
+    if (Res.Prevailing && Sym.isGV()) {
+      GlobalValue *GV = Sym.getGV();
       Keep.push_back(GV);
       switch (GV->getLinkage()) {
       default:
@@ -396,8 +403,7 @@ Error LTO::addRegularLTO(std::unique_ptr
     if (Sym.getFlags() & object::BasicSymbolRef::SF_Common) {
       // FIXME: We should figure out what to do about commons defined by asm.
       // For now they aren't reported correctly by ModuleSymbolTable.
-      assert(GV);
-      auto &CommonRes = RegularLTO.Commons[GV->getName()];
+      auto &CommonRes = RegularLTO.Commons[Sym.getGV()->getName()];
       CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize());
       CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment());
       CommonRes.Prevailing |= Res.Prevailing;
@@ -407,7 +413,7 @@ Error LTO::addRegularLTO(std::unique_ptr
   }
   assert(ResI == Res.end());
 
-  return RegularLTO.Mover->move(Obj->takeModule(), Keep,
+  return RegularLTO.Mover->move(std::move(*MOrErr), Keep,
                                 [](GlobalValue &, IRMover::ValueAdder) {},
                                 /* LinkModuleInlineAsm */ true,
                                 /* IsPerformingImport */ false);
@@ -416,11 +422,11 @@ Error LTO::addRegularLTO(std::unique_ptr
 // Add a ThinLTO object to the link.
 Error LTO::addThinLTO(std::unique_ptr<InputFile> Input,
                       ArrayRef<SymbolResolution> Res) {
-  Module &M = Input->Obj->getModule();
+  Module &M = *Input->Mod;
   SmallPtrSet<GlobalValue *, 8> Used;
   collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
 
-  MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef();
+  MemoryBufferRef MBRef = Input->MBRef;
   Expected<std::unique_ptr<object::ModuleSummaryIndexObjectFile>>
       SummaryObjOrErr = object::ModuleSummaryIndexObjectFile::create(MBRef);
   if (!SummaryObjOrErr)
@@ -432,12 +438,10 @@ Error LTO::addThinLTO(std::unique_ptr<In
   for (const InputFile::Symbol &Sym : Input->symbols()) {
     assert(ResI != Res.end());
     SymbolResolution Res = *ResI++;
-    addSymbolToGlobalRes(Input->Obj.get(), Used, Sym, Res,
-                         ThinLTO.ModuleMap.size() + 1);
+    addSymbolToGlobalRes(Used, Sym, Res, ThinLTO.ModuleMap.size() + 1);
 
-    GlobalValue *GV = Input->Obj->getSymbolGV(Sym.I->getRawDataRefImpl());
-    if (Res.Prevailing && GV)
-      ThinLTO.PrevailingModuleForGUID[GV->getGUID()] =
+    if (Res.Prevailing && Sym.isGV())
+      ThinLTO.PrevailingModuleForGUID[Sym.getGV()->getGUID()] =
           MBRef.getBufferIdentifier();
   }
   assert(ResI == Res.end());




More information about the llvm-commits mailing list