forked from OSchip/llvm-project
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 llvm-svn: 302823
This commit is contained in:
parent
aeffffdb44
commit
e7c7854cb1
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<Function>(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.
|
||||
|
|
|
@ -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<NAME *>(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<NAME *>(this)->eraseFromParent();
|
||||
#include "llvm/IR/Value.def"
|
||||
default:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("not a global");
|
||||
}
|
||||
|
||||
unsigned GlobalValue::getAlignment() const {
|
||||
if (auto *GA = dyn_cast<GlobalAlias>(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<GlobalObject>(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<GlobalVariable>(Src)) {
|
||||
setThreadLocalMode(SrcVar->getThreadLocalMode());
|
||||
setExternallyInitialized(SrcVar->isExternallyInitialized());
|
||||
setAttributes(SrcVar->getAttributes());
|
||||
}
|
||||
setThreadLocalMode(Src->getThreadLocalMode());
|
||||
setExternallyInitialized(Src->isExternallyInitialized());
|
||||
setAttributes(Src->getAttributes());
|
||||
}
|
||||
|
||||
void GlobalVariable::dropAllReferences() {
|
||||
|
|
|
@ -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<GlobalObject>(NewGV)) {
|
||||
// Metadata for global variables and function declarations is copied eagerly.
|
||||
if (isa<GlobalVariable>(SGV) || SGV->isDeclaration())
|
||||
|
|
Loading…
Reference in New Issue