[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