[llvm] r220580 - Don't ever call materializeAllPermanently during LTO.

Rafael Espindola rafael.espindola at gmail.com
Fri Oct 24 11:13:05 PDT 2014


Author: rafael
Date: Fri Oct 24 13:13:04 2014
New Revision: 220580

URL: http://llvm.org/viewvc/llvm-project?rev=220580&view=rev
Log:
Don't ever call materializeAllPermanently during LTO.

To do this, change the representation of lazy loaded functions.

The previous representation cannot differentiate between a function whose body
has been removed and one whose body hasn't been read from the .bc file. That
means that in order to drop a function, the entire body had to be read.

Modified:
    llvm/trunk/include/llvm/IR/Function.h
    llvm/trunk/include/llvm/IR/GVMaterializer.h
    llvm/trunk/include/llvm/IR/GlobalObject.h
    llvm/trunk/include/llvm/IR/GlobalValue.h
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h
    llvm/trunk/lib/IR/Function.cpp
    llvm/trunk/lib/IR/Globals.cpp
    llvm/trunk/lib/IR/Module.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Linker/LinkModules.cpp
    llvm/trunk/lib/Object/IRObjectFile.cpp
    llvm/trunk/tools/gold/gold-plugin.cpp

Modified: llvm/trunk/include/llvm/IR/Function.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Function.h (original)
+++ llvm/trunk/include/llvm/IR/Function.h Fri Oct 24 13:13:04 2014
@@ -143,6 +143,9 @@ public:
   /// arguments.
   bool isVarArg() const;
 
+  bool isMaterializable() const;
+  void setIsMaterializable(bool V);
+
   /// getIntrinsicID - This method returns the ID number of the specified
   /// function, or Intrinsic::not_intrinsic if the function is not an
   /// intrinsic, or if the pointer is null.  This value is always defined to be

Modified: llvm/trunk/include/llvm/IR/GVMaterializer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GVMaterializer.h?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GVMaterializer.h (original)
+++ llvm/trunk/include/llvm/IR/GVMaterializer.h Fri Oct 24 13:13:04 2014
@@ -32,10 +32,6 @@ protected:
 public:
   virtual ~GVMaterializer();
 
-  /// True if GV can be materialized from whatever backing store this
-  /// GVMaterializer uses and has not been materialized yet.
-  virtual bool isMaterializable(const GlobalValue *GV) const = 0;
-
   /// True if GV has been materialized and can be dematerialized back to
   /// whatever backing store this GVMaterializer uses.
   virtual bool isDematerializable(const GlobalValue *GV) const = 0;

Modified: llvm/trunk/include/llvm/IR/GlobalObject.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalObject.h?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalObject.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalObject.h Fri Oct 24 13:13:04 2014
@@ -35,12 +35,24 @@ protected:
 
   std::string Section;     // Section to emit this into, empty means default
   Comdat *ObjComdat;
+  static const unsigned AlignmentBits = 5;
+  static const unsigned GlobalObjectSubClassDataBits =
+      GlobalValueSubClassDataBits - AlignmentBits;
+
+private:
+  static const unsigned AlignmentMask = (1 << AlignmentBits) - 1;
+
 public:
   unsigned getAlignment() const {
-    return (1u << getGlobalValueSubClassData()) >> 1;
+    unsigned Data = getGlobalValueSubClassData();
+    unsigned AlignmentData = Data & AlignmentMask;
+    return (1u << AlignmentData) >> 1;
   }
   void setAlignment(unsigned Align);
 
+  unsigned getGlobalObjectSubClassData() const;
+  void setGlobalObjectSubClassData(unsigned Val);
+
   bool hasSection() const { return !StringRef(getSection()).empty(); }
   const char *getSection() const { return Section.c_str(); }
   void setSection(StringRef S);

Modified: llvm/trunk/include/llvm/IR/GlobalValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalValue.h?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalValue.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalValue.h Fri Oct 24 13:13:04 2014
@@ -84,6 +84,7 @@ private:
   // (19 + 3 + 2 + 1 + 2 + 5) == 32.
   unsigned SubClassData : 19;
 protected:
+  static const unsigned GlobalValueSubClassDataBits = 19;
   unsigned getGlobalValueSubClassData() const {
     return SubClassData;
   }
@@ -326,6 +327,13 @@ public:
   /// the current translation unit.
   bool isDeclaration() const;
 
+  bool isDeclarationForLinker() const {
+    if (hasAvailableExternallyLinkage())
+      return true;
+
+    return isDeclaration();
+  }
+
   /// This method unlinks 'this' from the containing module, but does not delete
   /// it.
   virtual void removeFromParent() = 0;

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Fri Oct 24 13:13:04 2014
@@ -469,9 +469,6 @@ public:
   /// Retrieves the GVMaterializer, if any, for this Module.
   GVMaterializer *getMaterializer() const { return Materializer.get(); }
 
-  /// True if the definition of GV has yet to be materializedfrom the
-  /// GVMaterializer.
-  bool isMaterializable(const GlobalValue *GV) const;
   /// Returns true if this GV was loaded from this Module's GVMaterializer and
   /// the GVMaterializer knows how to dematerialize the GV.
   bool isDematerializable(const GlobalValue *GV) const;

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Fri Oct 24 13:13:04 2014
@@ -2070,6 +2070,7 @@ std::error_code BitcodeReader::ParseModu
       // If this is a function with a body, remember the prototype we are
       // creating now, so that we can match up the body with them later.
       if (!isProto) {
+        Func->setIsMaterializable(true);
         FunctionsWithBodies.push_back(Func);
         if (LazyStreamer)
           DeferredFunctionInfo[Func] = 0;
@@ -3281,14 +3282,6 @@ std::error_code BitcodeReader::FindFunct
 
 void BitcodeReader::releaseBuffer() { Buffer.release(); }
 
-bool BitcodeReader::isMaterializable(const GlobalValue *GV) const {
-  if (const Function *F = dyn_cast<Function>(GV)) {
-    return F->isDeclaration() &&
-      DeferredFunctionInfo.count(const_cast<Function*>(F));
-  }
-  return false;
-}
-
 std::error_code BitcodeReader::Materialize(GlobalValue *GV) {
   Function *F = dyn_cast<Function>(GV);
   // If it's not a function or is already material, ignore the request.
@@ -3308,6 +3301,7 @@ std::error_code BitcodeReader::Materiali
 
   if (std::error_code EC = ParseFunctionBody(F))
     return EC;
+  F->setIsMaterializable(false);
 
   // Upgrade any old intrinsic calls in the function.
   for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(),
@@ -3349,6 +3343,7 @@ void BitcodeReader::Dematerialize(Global
 
   // Just forget the function body, we can remat it later.
   F->dropAllReferences();
+  F->setIsMaterializable(true);
 }
 
 std::error_code BitcodeReader::MaterializeModule(Module *M) {

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Fri Oct 24 13:13:04 2014
@@ -223,7 +223,6 @@ public:
 
   void releaseBuffer();
 
-  bool isMaterializable(const GlobalValue *GV) const override;
   bool isDematerializable(const GlobalValue *GV) const override;
   std::error_code Materialize(GlobalValue *GV) override;
   std::error_code MaterializeModule(Module *M) override;

Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Fri Oct 24 13:13:04 2014
@@ -213,6 +213,12 @@ void Argument::removeAttr(AttributeSet A
 // Helper Methods in Function
 //===----------------------------------------------------------------------===//
 
+bool Function::isMaterializable() const {
+  return getGlobalObjectSubClassData();
+}
+
+void Function::setIsMaterializable(bool V) { setGlobalObjectSubClassData(V); }
+
 LLVMContext &Function::getContext() const {
   return getType()->getContext();
 }
@@ -247,6 +253,7 @@ Function::Function(FunctionType *Ty, Lin
                    Linkage, name) {
   assert(FunctionType::isValidReturnType(getReturnType()) &&
          "invalid return type");
+  setIsMaterializable(false);
   SymTab = new ValueSymbolTable();
 
   // If the function has arguments, mark them as lazily built.
@@ -318,6 +325,8 @@ void Function::setParent(Module *parent)
 // delete.
 //
 void Function::dropAllReferences() {
+  setIsMaterializable(false);
+
   for (iterator I = begin(), E = end(); I != E; ++I)
     I->dropAllReferences();
 

Modified: llvm/trunk/lib/IR/Globals.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Globals.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Globals.cpp (original)
+++ llvm/trunk/lib/IR/Globals.cpp Fri Oct 24 13:13:04 2014
@@ -29,7 +29,9 @@ using namespace llvm;
 //===----------------------------------------------------------------------===//
 
 bool GlobalValue::isMaterializable() const {
-  return getParent() && getParent()->isMaterializable(this);
+  if (const Function *F = dyn_cast<Function>(this))
+    return F->isMaterializable();
+  return false;
 }
 bool GlobalValue::isDematerializable() const {
   return getParent() && getParent()->isDematerializable(this);
@@ -77,10 +79,24 @@ void GlobalObject::setAlignment(unsigned
   assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
   assert(Align <= MaximumAlignment &&
          "Alignment is greater than MaximumAlignment!");
-  setGlobalValueSubClassData(Log2_32(Align) + 1);
+  unsigned AlignmentData = Log2_32(Align) + 1;
+  unsigned OldData = getGlobalValueSubClassData();
+  setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData);
   assert(getAlignment() == Align && "Alignment representation error!");
 }
 
+unsigned GlobalObject::getGlobalObjectSubClassData() const {
+  unsigned ValueData = getGlobalValueSubClassData();
+  return ValueData >> AlignmentBits;
+}
+
+void GlobalObject::setGlobalObjectSubClassData(unsigned Val) {
+  unsigned OldData = getGlobalValueSubClassData();
+  setGlobalValueSubClassData((OldData & AlignmentMask) |
+                             (Val << AlignmentBits));
+  assert(getGlobalObjectSubClassData() == Val && "representation error");
+}
+
 void GlobalObject::copyAttributesFrom(const GlobalValue *Src) {
   const auto *GV = cast<GlobalObject>(Src);
   GlobalValue::copyAttributesFrom(GV);
@@ -117,7 +133,7 @@ bool GlobalValue::isDeclaration() const
 
   // Functions are definitions if they have a body.
   if (const Function *F = dyn_cast<Function>(this))
-    return F->empty();
+    return F->empty() && !F->isMaterializable();
 
   // Aliases are always definitions.
   assert(isa<GlobalAlias>(this));

Modified: llvm/trunk/lib/IR/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Module.cpp (original)
+++ llvm/trunk/lib/IR/Module.cpp Fri Oct 24 13:13:04 2014
@@ -389,12 +389,6 @@ void Module::setMaterializer(GVMateriali
   Materializer.reset(GVM);
 }
 
-bool Module::isMaterializable(const GlobalValue *GV) const {
-  if (Materializer)
-    return Materializer->isMaterializable(GV);
-  return false;
-}
-
 bool Module::isDematerializable(const GlobalValue *GV) const {
   if (Materializer)
     return Materializer->isDematerializable(GV);

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Fri Oct 24 13:13:04 2014
@@ -2632,7 +2632,7 @@ bool llvm::verifyModule(const Module &M,
 
   bool Broken = false;
   for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
-    if (!I->isDeclaration())
+    if (!I->isDeclaration() && !I->isMaterializable())
       Broken |= !V.verify(*I);
 
   // Note that this function's return value is inverted from what you would

Modified: llvm/trunk/lib/Linker/LinkModules.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/LinkModules.cpp (original)
+++ llvm/trunk/lib/Linker/LinkModules.cpp Fri Oct 24 13:13:04 2014
@@ -672,21 +672,10 @@ bool ModuleLinker::getComdatResult(const
                                        LinkFromSrc);
 }
 
-// FIXME: Duplicated from the gold plugin. This should be refactored somewhere.
-static bool isDeclaration(const GlobalValue &V) {
-  if (V.hasAvailableExternallyLinkage())
-    return true;
-
-  if (V.isMaterializable())
-    return false;
-
-  return V.isDeclaration();
-}
-
 bool ModuleLinker::shouldLinkFromSource(const GlobalValue &Dest,
                                         const GlobalValue &Src) {
-  bool SrcIsDeclaration = isDeclaration(Src);
-  bool DestIsDeclaration = isDeclaration(Dest);
+  bool SrcIsDeclaration = Src.isDeclarationForLinker();
+  bool DestIsDeclaration = Dest.isDeclarationForLinker();
 
   // FIXME: Make datalayout mandatory and just use getDataLayout().
   DataLayout DL(Dest.getParent());
@@ -1635,14 +1624,16 @@ bool ModuleLinker::run() {
           SF->getPrefixData(), ValueMap, RF_None, &TypeMap, &ValMaterializer));
     }
 
-    // Skip if no body (function is external) or materialize.
-    if (SF->isDeclaration()) {
-      if (!SF->isMaterializable())
-        continue;
+    // Materialize if needed.
+    if (SF->isMaterializable()) {
       if (SF->Materialize(&ErrorMsg))
         return true;
     }
 
+    // Skip if no body (function is external).
+    if (SF->isDeclaration())
+      continue;
+
     linkFunctionBody(DF, SF);
     SF->Dematerialize();
   }
@@ -1684,14 +1675,16 @@ bool ModuleLinker::run() {
                                    &ValMaterializer));
       }
 
-      // Materialize if necessary.
-      if (SF->isDeclaration()) {
-        if (!SF->isMaterializable())
-          continue;
+      // Materialize if needed.
+      if (SF->isMaterializable()) {
         if (SF->Materialize(&ErrorMsg))
           return true;
       }
 
+      // Skip if no body (function is external).
+      if (SF->isDeclaration())
+        continue;
+
       // Erase from vector *before* the function body is linked - linkFunctionBody could
       // invalidate I.
       LazilyLinkFunctions.erase(I);

Modified: llvm/trunk/lib/Object/IRObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/IRObjectFile.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/lib/Object/IRObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/IRObjectFile.cpp Fri Oct 24 13:13:04 2014
@@ -204,16 +204,6 @@ std::error_code IRObjectFile::printSymbo
   return object_error::success;
 }
 
-static bool isDeclaration(const GlobalValue &V) {
-  if (V.hasAvailableExternallyLinkage())
-    return true;
-
-  if (V.isMaterializable())
-    return false;
-
-  return V.isDeclaration();
-}
-
 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
   const GlobalValue *GV = getGV(Symb);
 
@@ -224,7 +214,7 @@ uint32_t IRObjectFile::getSymbolFlags(Da
   }
 
   uint32_t Res = BasicSymbolRef::SF_None;
-  if (isDeclaration(*GV))
+  if (GV->isDeclarationForLinker())
     Res |= BasicSymbolRef::SF_Undefined;
   if (GV->hasPrivateLinkage())
     Res |= BasicSymbolRef::SF_FormatSpecific;

Modified: llvm/trunk/tools/gold/gold-plugin.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=220580&r1=220579&r2=220580&view=diff
==============================================================================
--- llvm/trunk/tools/gold/gold-plugin.cpp (original)
+++ llvm/trunk/tools/gold/gold-plugin.cpp Fri Oct 24 13:13:04 2014
@@ -418,18 +418,8 @@ static void keepGlobalValue(GlobalValue
   assert(!GV.isDiscardableIfUnused());
 }
 
-static bool isDeclaration(const GlobalValue &V) {
-  if (V.hasAvailableExternallyLinkage())
-    return true;
-
-  if (V.isMaterializable())
-    return false;
-
-  return V.isDeclaration();
-}
-
 static void internalize(GlobalValue &GV) {
-  if (isDeclaration(GV))
+  if (GV.isDeclarationForLinker())
     return; // We get here if there is a matching asm definition.
   if (!GV.hasLocalLinkage())
     GV.setLinkage(GlobalValue::InternalLinkage);
@@ -492,6 +482,9 @@ static GlobalObject *makeInternalReplace
   Module *M = GO->getParent();
   GlobalObject *Ret;
   if (auto *F = dyn_cast<Function>(GO)) {
+    if (F->isMaterializable())
+      F->Materialize();
+
     auto *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
                                   F->getName(), M);
 
@@ -620,7 +613,7 @@ getModuleForFile(LLVMContext &Context, c
     case LDPR_RESOLVED_EXEC:
     case LDPR_RESOLVED_DYN:
     case LDPR_UNDEF:
-      assert(isDeclaration(*GV));
+      assert(GV->isDeclarationForLinker());
       break;
 
     case LDPR_PREVAILING_DEF_IRONLY: {
@@ -667,12 +660,6 @@ getModuleForFile(LLVMContext &Context, c
     Sym.comdat_key = nullptr;
   }
 
-  if (!Drop.empty())
-    // This is horrible. Given how lazy loading is implemented, dropping
-    // the body while there is a materializer present doesn't work, the
-    // linker will just read the body back.
-    M->materializeAllPermanently();
-
   ValueToValueMapTy VM;
   LocalValueMaterializer Materializer(Drop);
   for (GlobalAlias *GA : KeptAliases) {





More information about the llvm-commits mailing list