Parcourir la source

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
Reid Kleckner il y a 8 ans
Parent
commit
c130a20cf3

+ 3 - 3
include/llvm/IR/Function.h

@@ -494,7 +494,7 @@ public:
 
 
   /// copyAttributesFrom - copy all additional attributes (those not needed to
   /// copyAttributesFrom - copy all additional attributes (those not needed to
   /// create a Function) from the Function Src to this one.
   /// 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
   /// deleteBody - This method deletes the body of the function, and converts
   /// the linkage to external.
   /// the linkage to external.
@@ -507,12 +507,12 @@ public:
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
   /// but does not delete it.
   ///
   ///
-  void removeFromParent() override;
+  void removeFromParent();
 
 
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// and deletes it.
   /// and deletes it.
   ///
   ///
-  void eraseFromParent() override;
+  void eraseFromParent();
 
 
   /// Steal arguments from another function.
   /// Steal arguments from another function.
   ///
   ///

+ 6 - 2
include/llvm/IR/GlobalAlias.h

@@ -59,15 +59,19 @@ public:
   // Linkage, Type, Parent and AddressSpace taken from the Aliasee.
   // Linkage, Type, Parent and AddressSpace taken from the Aliasee.
   static GlobalAlias *create(const Twine &Name, GlobalValue *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,
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
   /// but does not delete it.
   ///
   ///
-  void removeFromParent() override;
+  void removeFromParent();
 
 
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// and deletes it.
   /// and deletes it.
   ///
   ///
-  void eraseFromParent() override;
+  void eraseFromParent();
 
 
   /// These methods retrieve and set alias target.
   /// These methods retrieve and set alias target.
   void setAliasee(Constant *Aliasee);
   void setAliasee(Constant *Aliasee);

+ 6 - 2
include/llvm/IR/GlobalIFunc.h

@@ -47,12 +47,16 @@ public:
                              LinkageTypes Linkage, const Twine &Name,
                              LinkageTypes Linkage, const Twine &Name,
                              Constant *Resolver, Module *Parent);
                              Constant *Resolver, Module *Parent);
 
 
+  void copyAttributesFrom(const GlobalIFunc *Src) {
+    GlobalValue::copyAttributesFrom(Src);
+  }
+
   /// This method unlinks 'this' from the containing module, but does not
   /// This method unlinks 'this' from the containing module, but does not
   /// delete it.
   /// delete it.
-  void removeFromParent() final;
+  void removeFromParent();
 
 
   /// This method unlinks 'this' from the containing module and deletes it.
   /// This method unlinks 'this' from the containing module and deletes it.
-  void eraseFromParent() final;
+  void eraseFromParent();
 
 
   /// These methods retrieve and set ifunc resolver function.
   /// These methods retrieve and set ifunc resolver function.
   void setResolver(Constant *Resolver) {
   void setResolver(Constant *Resolver) {

+ 3 - 1
include/llvm/IR/GlobalObject.h

@@ -150,8 +150,10 @@ public:
 
 
   void addTypeMetadata(unsigned Offset, Metadata *TypeID);
   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:
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Value *V) {
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::FunctionVal ||
     return V->getValueID() == Value::FunctionVal ||

+ 5 - 3
include/llvm/IR/GlobalValue.h

@@ -435,10 +435,12 @@ public:
 
 
   bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
   bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
 
 
+protected:
   /// Copy all additional attributes (those not needed to create a GlobalValue)
   /// Copy all additional attributes (those not needed to create a GlobalValue)
   /// from the GlobalValue Src to this one.
   /// 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
   /// 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
   /// usual symbol prefix before the symbol name is used then return linkage
   /// name after skipping this special LLVM prefix.
   /// name after skipping this special LLVM prefix.
@@ -530,10 +532,10 @@ public:
 
 
   /// This method unlinks 'this' from the containing module, but does not delete
   /// This method unlinks 'this' from the containing module, but does not delete
   /// it.
   /// it.
-  virtual void removeFromParent() = 0;
+  void removeFromParent();
 
 
   /// This method unlinks 'this' from the containing module and deletes it.
   /// 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...
   /// Get the module that this global value is contained inside of...
   Module *getParent() { return Parent; }
   Module *getParent() { return Parent; }

+ 3 - 3
include/llvm/IR/GlobalVariable.h

@@ -158,17 +158,17 @@ public:
 
 
   /// copyAttributesFrom - copy all additional attributes (those not needed to
   /// copyAttributesFrom - copy all additional attributes (those not needed to
   /// create a GlobalVariable) from the GlobalVariable Src to this one.
   /// 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,
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
   /// but does not delete it.
   ///
   ///
-  void removeFromParent() override;
+  void removeFromParent();
 
 
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// eraseFromParent - This method unlinks 'this' from the containing module
   /// and deletes it.
   /// and deletes it.
   ///
   ///
-  void eraseFromParent() override;
+  void eraseFromParent();
 
 
   /// Drop all references in preparation to destroy the GlobalVariable. This
   /// Drop all references in preparation to destroy the GlobalVariable. This
   /// drops not only the reference to the initializer but also to any metadata.
   /// drops not only the reference to the initializer but also to any metadata.

+ 11 - 15
lib/IR/Function.cpp

@@ -416,24 +416,20 @@ void Function::clearGC() {
 
 
 /// Copy all additional attributes (those not needed to create a Function) from
 /// Copy all additional attributes (those not needed to create a Function) from
 /// the Function Src to this one.
 /// the Function Src to this one.
-void Function::copyAttributesFrom(const GlobalValue *Src) {
+void Function::copyAttributesFrom(const Function *Src) {
   GlobalObject::copyAttributesFrom(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
   else
     clearGC();
     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.
 /// Table of string intrinsic names indexed by enum value.

+ 31 - 11
lib/IR/Globals.cpp

@@ -69,6 +69,30 @@ void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
   setDLLStorageClass(Src->getDLLStorageClass());
   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 {
 unsigned GlobalValue::getAlignment() const {
   if (auto *GA = dyn_cast<GlobalAlias>(this)) {
   if (auto *GA = dyn_cast<GlobalAlias>(this)) {
     // In general we cannot compute this at the IR level, but we try.
     // 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!");
   assert(getAlignment() == Align && "Alignment representation error!");
 }
 }
 
 
-void GlobalObject::copyAttributesFrom(const GlobalValue *Src) {
+void GlobalObject::copyAttributesFrom(const GlobalObject *Src) {
   GlobalValue::copyAttributesFrom(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,
 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)
 /// Copy all additional attributes (those not needed to create a GlobalVariable)
 /// from the GlobalVariable Src to this one.
 /// from the GlobalVariable Src to this one.
-void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
+void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) {
   GlobalObject::copyAttributesFrom(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() {
 void GlobalVariable::dropAllReferences() {

+ 11 - 7
lib/Linker/IRMover.cpp

@@ -602,6 +602,7 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) {
                          /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
                          /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
                          SGVar->getType()->getAddressSpace());
                          SGVar->getType()->getAddressSpace());
   NewDGV->setAlignment(SGVar->getAlignment());
   NewDGV->setAlignment(SGVar->getAlignment());
+  NewDGV->copyAttributesFrom(SGVar);
   return NewDGV;
   return NewDGV;
 }
 }
 
 
@@ -610,8 +611,11 @@ GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) {
 Function *IRLinker::copyFunctionProto(const Function *SF) {
 Function *IRLinker::copyFunctionProto(const Function *SF) {
   // If there is no linkage to be performed or we are linking from the source,
   // If there is no linkage to be performed or we are linking from the source,
   // bring SF over.
   // 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.
 /// 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,
   // If there is no linkage to be performed or we're linking from the source,
   // bring over SGA.
   // bring over SGA.
   auto *Ty = TypeMap.get(SGA->getValueType());
   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,
 GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
@@ -648,8 +654,6 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
   else if (SGV->hasExternalWeakLinkage())
   else if (SGV->hasExternalWeakLinkage())
     NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);
     NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);
 
 
-  NewGV->copyAttributesFrom(SGV);
-
   if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {
   if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {
     // Metadata for global variables and function declarations is copied eagerly.
     // Metadata for global variables and function declarations is copied eagerly.
     if (isa<GlobalVariable>(SGV) || SGV->isDeclaration())
     if (isa<GlobalVariable>(SGV) || SGV->isDeclaration())