From: Reid Kleckner Date: Thu, 11 May 2017 21:14:29 +0000 (+0000) Subject: De-virtualize GlobalValue X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c130a20cf306739c9afa2a65fa05bf29cd72bd6a;p=llvm De-virtualize GlobalValue The erase/remove from parent methods now use a switch table to remove themselves from their appropriate parent ilist. The copyAttributesFrom method is now completely non-virtual, since we only ever copy attributes from a global of the appropriate type. Pre-requisite to de-virtualizing Value to save a vptr (https://reviews.llvm.org/D31261). NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302823 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h index 4e4128138cb..8a2a6ed87eb 100644 --- a/include/llvm/IR/Function.h +++ b/include/llvm/IR/Function.h @@ -494,7 +494,7 @@ public: /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a Function) from the Function Src to this one. - void copyAttributesFrom(const GlobalValue *Src) override; + void copyAttributesFrom(const Function *Src); /// deleteBody - This method deletes the body of the function, and converts /// the linkage to external. @@ -507,12 +507,12 @@ public: /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - void removeFromParent() override; + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - void eraseFromParent() override; + void eraseFromParent(); /// Steal arguments from another function. /// diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h index 37a291dfeb7..d4bf0d7e1ed 100644 --- a/include/llvm/IR/GlobalAlias.h +++ b/include/llvm/IR/GlobalAlias.h @@ -59,15 +59,19 @@ public: // Linkage, Type, Parent and AddressSpace taken from the Aliasee. static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee); + void copyAttributesFrom(const GlobalValue *Src) { + GlobalValue::copyAttributesFrom(Src); + } + /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - void removeFromParent() override; + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - void eraseFromParent() override; + void eraseFromParent(); /// These methods retrieve and set alias target. void setAliasee(Constant *Aliasee); diff --git a/include/llvm/IR/GlobalIFunc.h b/include/llvm/IR/GlobalIFunc.h index bfaa9960cb1..d90c7c78ed2 100644 --- a/include/llvm/IR/GlobalIFunc.h +++ b/include/llvm/IR/GlobalIFunc.h @@ -47,12 +47,16 @@ public: LinkageTypes Linkage, const Twine &Name, Constant *Resolver, Module *Parent); + void copyAttributesFrom(const GlobalIFunc *Src) { + GlobalValue::copyAttributesFrom(Src); + } + /// This method unlinks 'this' from the containing module, but does not /// delete it. - void removeFromParent() final; + void removeFromParent(); /// This method unlinks 'this' from the containing module and deletes it. - void eraseFromParent() final; + void eraseFromParent(); /// These methods retrieve and set ifunc resolver function. void setResolver(Constant *Resolver) { diff --git a/include/llvm/IR/GlobalObject.h b/include/llvm/IR/GlobalObject.h index f3789bafefe..fc38f698027 100644 --- a/include/llvm/IR/GlobalObject.h +++ b/include/llvm/IR/GlobalObject.h @@ -150,8 +150,10 @@ public: void addTypeMetadata(unsigned Offset, Metadata *TypeID); - void copyAttributesFrom(const GlobalValue *Src) override; +protected: + void copyAttributesFrom(const GlobalObject *Src); +public: // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Value *V) { return V->getValueID() == Value::FunctionVal || diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h index bb30fa8be86..b595c225ce8 100644 --- a/include/llvm/IR/GlobalValue.h +++ b/include/llvm/IR/GlobalValue.h @@ -435,10 +435,12 @@ public: bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); } +protected: /// Copy all additional attributes (those not needed to create a GlobalValue) /// from the GlobalValue Src to this one. - virtual void copyAttributesFrom(const GlobalValue *Src); + void copyAttributesFrom(const GlobalValue *Src); +public: /// If special LLVM prefix that is used to inform the asm printer to not emit /// usual symbol prefix before the symbol name is used then return linkage /// name after skipping this special LLVM prefix. @@ -530,10 +532,10 @@ public: /// This method unlinks 'this' from the containing module, but does not delete /// it. - virtual void removeFromParent() = 0; + void removeFromParent(); /// This method unlinks 'this' from the containing module and deletes it. - virtual void eraseFromParent() = 0; + void eraseFromParent(); /// Get the module that this global value is contained inside of... Module *getParent() { return Parent; } diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h index c25e08059ce..21d334c8f01 100644 --- a/include/llvm/IR/GlobalVariable.h +++ b/include/llvm/IR/GlobalVariable.h @@ -158,17 +158,17 @@ public: /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalVariable) from the GlobalVariable Src to this one. - void copyAttributesFrom(const GlobalValue *Src) override; + void copyAttributesFrom(const GlobalVariable *Src); /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - void removeFromParent() override; + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - void eraseFromParent() override; + void eraseFromParent(); /// Drop all references in preparation to destroy the GlobalVariable. This /// drops not only the reference to the initializer but also to any metadata. diff --git a/lib/IR/Function.cpp b/lib/IR/Function.cpp index 98f7508cde8..16a9e51b830 100644 --- a/lib/IR/Function.cpp +++ b/lib/IR/Function.cpp @@ -416,24 +416,20 @@ void Function::clearGC() { /// Copy all additional attributes (those not needed to create a Function) from /// the Function Src to this one. -void Function::copyAttributesFrom(const GlobalValue *Src) { +void Function::copyAttributesFrom(const Function *Src) { GlobalObject::copyAttributesFrom(Src); - const Function *SrcF = dyn_cast(Src); - if (!SrcF) - return; - - setCallingConv(SrcF->getCallingConv()); - setAttributes(SrcF->getAttributes()); - if (SrcF->hasGC()) - setGC(SrcF->getGC()); + setCallingConv(Src->getCallingConv()); + setAttributes(Src->getAttributes()); + if (Src->hasGC()) + setGC(Src->getGC()); else clearGC(); - if (SrcF->hasPersonalityFn()) - setPersonalityFn(SrcF->getPersonalityFn()); - if (SrcF->hasPrefixData()) - setPrefixData(SrcF->getPrefixData()); - if (SrcF->hasPrologueData()) - setPrologueData(SrcF->getPrologueData()); + if (Src->hasPersonalityFn()) + setPersonalityFn(Src->getPersonalityFn()); + if (Src->hasPrefixData()) + setPrefixData(Src->getPrefixData()); + if (Src->hasPrologueData()) + setPrologueData(Src->getPrologueData()); } /// Table of string intrinsic names indexed by enum value. diff --git a/lib/IR/Globals.cpp b/lib/IR/Globals.cpp index 5fbf51e0089..10ba1a64ad0 100644 --- a/lib/IR/Globals.cpp +++ b/lib/IR/Globals.cpp @@ -69,6 +69,30 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { setDLLStorageClass(Src->getDLLStorageClass()); } +void GlobalValue::removeFromParent() { + switch (getValueID()) { +#define HANDLE_GLOBAL_VALUE(NAME) \ + case Value::NAME##Val: \ + return static_cast(this)->removeFromParent(); +#include "llvm/IR/Value.def" + default: + break; + } + llvm_unreachable("not a global"); +} + +void GlobalValue::eraseFromParent() { + switch (getValueID()) { +#define HANDLE_GLOBAL_VALUE(NAME) \ + case Value::NAME##Val: \ + return static_cast(this)->eraseFromParent(); +#include "llvm/IR/Value.def" + default: + break; + } + llvm_unreachable("not a global"); +} + unsigned GlobalValue::getAlignment() const { if (auto *GA = dyn_cast(this)) { // In general we cannot compute this at the IR level, but we try. @@ -93,12 +117,10 @@ void GlobalObject::setAlignment(unsigned Align) { assert(getAlignment() == Align && "Alignment representation error!"); } -void GlobalObject::copyAttributesFrom(const GlobalValue *Src) { +void GlobalObject::copyAttributesFrom(const GlobalObject *Src) { GlobalValue::copyAttributesFrom(Src); - if (const auto *GV = dyn_cast(Src)) { - setAlignment(GV->getAlignment()); - setSection(GV->getSection()); - } + setAlignment(Src->getAlignment()); + setSection(Src->getSection()); } std::string GlobalValue::getGlobalIdentifier(StringRef Name, @@ -333,13 +355,11 @@ void GlobalVariable::setInitializer(Constant *InitVal) { /// Copy all additional attributes (those not needed to create a GlobalVariable) /// from the GlobalVariable Src to this one. -void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { +void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) { GlobalObject::copyAttributesFrom(Src); - if (const GlobalVariable *SrcVar = dyn_cast(Src)) { - setThreadLocalMode(SrcVar->getThreadLocalMode()); - setExternallyInitialized(SrcVar->isExternallyInitialized()); - setAttributes(SrcVar->getAttributes()); - } + setThreadLocalMode(Src->getThreadLocalMode()); + setExternallyInitialized(Src->isExternallyInitialized()); + setAttributes(Src->getAttributes()); } void GlobalVariable::dropAllReferences() { diff --git a/lib/Linker/IRMover.cpp b/lib/Linker/IRMover.cpp index 15a46a2d042..ecef1efda1a 100644 --- a/lib/Linker/IRMover.cpp +++ b/lib/Linker/IRMover.cpp @@ -602,6 +602,7 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(), SGVar->getType()->getAddressSpace()); NewDGV->setAlignment(SGVar->getAlignment()); + NewDGV->copyAttributesFrom(SGVar); return NewDGV; } @@ -610,8 +611,11 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { Function *IRLinker::copyFunctionProto(const Function *SF) { // If there is no linkage to be performed or we are linking from the source, // bring SF over. - return Function::Create(TypeMap.get(SF->getFunctionType()), - GlobalValue::ExternalLinkage, SF->getName(), &DstM); + auto *F = + Function::Create(TypeMap.get(SF->getFunctionType()), + GlobalValue::ExternalLinkage, SF->getName(), &DstM); + F->copyAttributesFrom(SF); + return F; } /// Set up prototypes for any aliases that come over from the source module. @@ -619,9 +623,11 @@ GlobalValue *IRLinker::copyGlobalAliasProto(const GlobalAlias *SGA) { // If there is no linkage to be performed or we're linking from the source, // bring over SGA. auto *Ty = TypeMap.get(SGA->getValueType()); - return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(), - GlobalValue::ExternalLinkage, SGA->getName(), - &DstM); + auto *GA = + GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(), + GlobalValue::ExternalLinkage, SGA->getName(), &DstM); + GA->copyAttributesFrom(SGA); + return GA; } GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, @@ -648,8 +654,6 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, else if (SGV->hasExternalWeakLinkage()) NewGV->setLinkage(GlobalValue::ExternalWeakLinkage); - NewGV->copyAttributesFrom(SGV); - if (auto *NewGO = dyn_cast(NewGV)) { // Metadata for global variables and function declarations is copied eagerly. if (isa(SGV) || SGV->isDeclaration())