Factor code to copy global value attributes like
authorDuncan Sands <baldrick@free.fr>
Mon, 26 May 2008 19:58:59 +0000 (19:58 +0000)
committerDuncan Sands <baldrick@free.fr>
Mon, 26 May 2008 19:58:59 +0000 (19:58 +0000)
the section or the visibility from one global
value to another: copyAttributesFrom.  This is
particularly useful for duplicating functions:
previously this was done by explicitly copying
each attribute in turn at each place where a
new function was created out of an old one, with
the result that obscure attributes were regularly
forgotten (like the collector or the section).
Hopefully now everything is uniform and nothing
is forgotten.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51567 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/llvm/Function.h
include/llvm/GlobalValue.h
include/llvm/GlobalVariable.h
lib/Linker/LinkModules.cpp
lib/Transforms/IPO/ArgumentPromotion.cpp
lib/Transforms/IPO/DeadArgumentElimination.cpp
lib/Transforms/IPO/ExtractGV.cpp
lib/Transforms/IPO/StructRetPromotion.cpp
lib/Transforms/Utils/CloneFunction.cpp
lib/Transforms/Utils/CloneModule.cpp
lib/VMCore/Function.cpp
lib/VMCore/Globals.cpp

index 5dd8502d3ab33510fab4fbfaa1bf1c0a7f09b5cf..ef824579262f0afa4d1f9a6e7c1b07ed781b688c 100644 (file)
@@ -204,6 +204,10 @@ public:
     return paramHasAttr(1, ParamAttr::StructRet);
   }
 
+  /// copyAttributesFrom - copy all additional attributes (those not needed to
+  /// create a Function) from the Function Src to this one.
+  void copyAttributesFrom(const GlobalValue *Src);
+
   /// deleteBody - This method deletes the body of the function, and converts
   /// the linkage to external.
   ///
index b13a122e1a396d0f61e94e95755fcbdd735bda88..bc0c0a79375327afea18eacc26644ab44ca84cca 100644 (file)
@@ -110,6 +110,10 @@ public:
   void setLinkage(LinkageTypes LT) { Linkage = LT; }
   LinkageTypes getLinkage() const { return Linkage; }
 
+  /// copyAttributesFrom - copy all additional attributes (those not needed to
+  /// create a GlobalValue) from the GlobalValue Src to this one.
+  virtual void copyAttributesFrom(const GlobalValue *Src);
+
   /// hasNotBeenReadFromBitcode - If a module provider is being used to lazily
   /// stream in functions from disk, this method can be used to check to see if
   /// the function has been read in yet or not.  Unless you are working on the
index ac72b77e7659939fa9390bb309edfa1a06d10c53..a578cd1c090a6e8684caa64e32eae1903a25b7a4 100644 (file)
@@ -118,6 +118,10 @@ public:
   bool isThreadLocal() const { return isThreadLocalSymbol; }
   void setThreadLocal(bool Val) { isThreadLocalSymbol = Val; }
 
+  /// copyAttributesFrom - copy all additional attributes (those not needed to
+  /// create a GlobalVariable) from the GlobalVariable Src to this one.
+  void copyAttributesFrom(const GlobalValue *Src);
+
   /// removeFromParent - This method unlinks 'this' from the containing module,
   /// but does not delete it.
   ///
index fae7d9d748dcfa0663a1678ddcf0c12501df2c0d..66c68ca87f907223d75b2bcdf213149926397120 100644 (file)
@@ -351,20 +351,10 @@ static void ForceRenaming(GlobalValue *GV, const std::string &Name) {
 /// CopyGVAttributes - copy additional attributes (those not needed to construct
 /// a GlobalValue) from the SrcGV to the DestGV. 
 static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
-  // Propagate alignment, visibility and section info.
-  DestGV->setAlignment(std::max(DestGV->getAlignment(), SrcGV->getAlignment()));
-  DestGV->setSection(SrcGV->getSection());
-  DestGV->setVisibility(SrcGV->getVisibility());
-  if (const Function *SrcF = dyn_cast<Function>(SrcGV)) {
-    Function *DestF = cast<Function>(DestGV);
-    DestF->setCallingConv(SrcF->getCallingConv());
-    DestF->setParamAttrs(SrcF->getParamAttrs());
-    if (SrcF->hasCollector())
-      DestF->setCollector(SrcF->getCollector());
-  } else if (const GlobalVariable *SrcVar = dyn_cast<GlobalVariable>(SrcGV)) {
-    GlobalVariable *DestVar = cast<GlobalVariable>(DestGV);
-    DestVar->setThreadLocal(SrcVar->isThreadLocal());
-  }
+  // Use the maximum alignment, rather than just copying the alignment of SrcGV.
+  unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment());
+  DestGV->copyAttributesFrom(SrcGV);
+  DestGV->setAlignment(Alignment);
 }
 
 /// GetLinkageResult - This analyzes the two global values and determines what
index b3d783d2aed8f88614a82c24c03774c0d65928cd..7dd94f5bc82539da6c0f3ec034fdaf5c902f5271 100644 (file)
@@ -478,15 +478,13 @@ Function *ArgPromotion::DoPromotion(Function *F,
 
   // Create the new function body and insert it into the module...
   Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
-  NF->setCallingConv(F->getCallingConv());
+  NF->copyAttributesFrom(F);
 
   // Recompute the parameter attributes list based on the new arguments for
   // the function.
   NF->setParamAttrs(PAListPtr::get(ParamAttrsVec.begin(), ParamAttrsVec.end()));
   ParamAttrsVec.clear();
-  
-  if (F->hasCollector())
-    NF->setCollector(F->getCollector());
+
   F->getParent()->getFunctionList().insert(F, NF);
   NF->takeName(F);
 
index 9b3efe0962bff19603ba9374753f7f3c61eb0ba1..2dab6952247d35e7bc7281ba35f56fded7e07fab 100644 (file)
@@ -163,10 +163,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
 
   // Create the new function body and insert it into the module...
   Function *NF = Function::Create(NFTy, Fn.getLinkage());
-  NF->setCallingConv(Fn.getCallingConv());
-  NF->setParamAttrs(Fn.getParamAttrs());
-  if (Fn.hasCollector())
-    NF->setCollector(Fn.getCollector());
+  NF->copyAttributesFrom(&Fn);
   Fn.getParent()->getFunctionList().insert(&Fn, NF);
   NF->takeName(&Fn);
 
@@ -556,10 +553,8 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
 
   // Create the new function body and insert it into the module...
   Function *NF = Function::Create(NFTy, F->getLinkage());
-  NF->setCallingConv(F->getCallingConv());
+  NF->copyAttributesFrom(F);
   NF->setParamAttrs(NewPAL);
-  if (F->hasCollector())
-    NF->setCollector(F->getCollector());
   F->getParent()->getFunctionList().insert(F, NF);
   NF->takeName(F);
 
index 46232b880b1d797421580bbbf3d01693ac5d84dd..03a8e5cebca9173d1833e3b67b35dd7e5f208415 100644 (file)
@@ -123,10 +123,7 @@ namespace {
         if (std::find(Named.begin(), Named.end(), &*I) == Named.end()) {
           Function *New = Function::Create(I->getFunctionType(),
                                            GlobalValue::ExternalLinkage);
-          New->setCallingConv(I->getCallingConv());
-          New->setParamAttrs(I->getParamAttrs());
-          if (I->hasCollector())
-            New->setCollector(I->getCollector());
+          New->copyAttributesFrom(I);
 
           // If it's not the named function, delete the body of the function
           I->dropAllReferences();
index f857dce669ca6393e6ca0dfffec1265382b4be59..174a6fa7671b2d9456216835805a97da5d94b99e 100644 (file)
@@ -232,7 +232,7 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
 
   FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg());
   Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
-  NF->setCallingConv(F->getCallingConv());
+  NF->copyAttributesFrom(F);
   NF->setParamAttrs(PAListPtr::get(ParamAttrsVec.begin(), ParamAttrsVec.end()));
   F->getParent()->getFunctionList().insert(F, NF);
   NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
index 57369143b451bf0850c64c815cd072bd5de7d083..9e3fe329928190d9963d640eb2b14506d7dba3d7 100644 (file)
@@ -80,11 +80,8 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
     assert(ValueMap.count(I) && "No mapping from source argument specified!");
 #endif
 
-  // Clone the parameter attributes
-  NewFunc->setParamAttrs(OldFunc->getParamAttrs());
-
-  // Clone the calling convention
-  NewFunc->setCallingConv(OldFunc->getCallingConv());
+  // Clone any attributes.
+  NewFunc->copyAttributesFrom(OldFunc);
 
   // Loop over all of the basic blocks in the function, cloning them as
   // appropriate.  Note that we save BE this way in order to handle cloning of
@@ -339,8 +336,8 @@ void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
        E = OldFunc->arg_end(); II != E; ++II)
     assert(ValueMap.count(II) && "No mapping from source argument specified!");
 #endif
-  
-  PruningFunctionCloner PFC(NewFunc, OldFunc, ValueMap, Returns, 
+
+  PruningFunctionCloner PFC(NewFunc, OldFunc, ValueMap, Returns,
                             NameSuffix, CodeInfo, TD);
 
   // Clone the entry block, and anything recursively reachable from it.
index e75f915cb9ef5cf1d20e324c6d705d5c023a57c8..c94c531b0166d74214c78989b927608e73dc14b0 100644 (file)
@@ -65,10 +65,7 @@ Module *llvm::CloneModule(const Module *M,
     Function *NF =
       Function::Create(cast<FunctionType>(I->getType()->getElementType()),
                        GlobalValue::ExternalLinkage, I->getName(), New);
-    NF->setCallingConv(I->getCallingConv());
-    NF->setParamAttrs(I->getParamAttrs());
-    if (I->hasCollector())
-      NF->setCollector(I->getCollector());
+    NF->copyAttributesFrom(I);
     ValueMap[I]= NF;
   }
 
index 49e69e1b2c1f75445c977fc3cb803642ca7c4ff5..2ab1194949653e9a2b96575a4e2b5e73b263bca1 100644 (file)
@@ -284,6 +284,18 @@ void Function::clearCollector() {
   }
 }
 
+/// copyAttributesFrom - copy all additional attributes (those not needed to
+/// create a Function) from the Function Src to this one.
+void Function::copyAttributesFrom(const GlobalValue *Src) {
+  assert(isa<Function>(Src) && "Expected a Function!");
+  GlobalValue::copyAttributesFrom(Src);
+  const Function *SrcF = cast<Function>(Src);
+  setCallingConv(SrcF->getCallingConv());
+  setParamAttrs(SrcF->getParamAttrs());
+  if (SrcF->hasCollector())
+    setCollector(SrcF->getCollector());
+}
+
 /// 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
index 1a328d80f6874c34e738fafe128976136aa9ceef..229b0127a4a4dfd0d864b17f63b4deb60ee63e14 100644 (file)
@@ -79,7 +79,16 @@ void GlobalValue::destroyConstant() {
   assert(0 && "You can't GV->destroyConstant()!");
   abort();
 }
-  
+
+/// copyAttributesFrom - copy all additional attributes (those not needed to
+/// create a GlobalValue) from the GlobalValue Src to this one.
+void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
+  setAlignment(Src->getAlignment());
+  setSection(Src->getSection());
+  setVisibility(Src->getVisibility());
+}
+
+
 //===----------------------------------------------------------------------===//
 // GlobalVariable Implementation
 //===----------------------------------------------------------------------===//
@@ -160,6 +169,16 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To,
   this->setOperand(0, cast<Constant>(To));
 }
 
+/// copyAttributesFrom - copy all additional attributes (those not needed to
+/// create a GlobalVariable) from the GlobalVariable Src to this one.
+void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
+  assert(isa<GlobalVariable>(Src) && "Expected a GlobalVariable!");
+  GlobalValue::copyAttributesFrom(Src);
+  const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
+  setThreadLocal(SrcVar->isThreadLocal());
+}
+
+
 //===----------------------------------------------------------------------===//
 // GlobalAlias Implementation
 //===----------------------------------------------------------------------===//