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

Nick Lewycky nicholas at mxc.ca
Fri Oct 24 16:53:12 PDT 2014


Rafael Espindola wrote:
> 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.

Fantastic!!

Nick

>
> 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) {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list