[clang] 2f8f58d - [IR] Add method to GlobalVariable to change type of initializer. (#102553)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 9 09:22:44 PDT 2024


Author: Eli Friedman
Date: 2024-08-09T09:22:40-07:00
New Revision: 2f8f58dd17a11934e8c8ec212b6474f76fb18e61

URL: https://github.com/llvm/llvm-project/commit/2f8f58dd17a11934e8c8ec212b6474f76fb18e61
DIFF: https://github.com/llvm/llvm-project/commit/2f8f58dd17a11934e8c8ec212b6474f76fb18e61.diff

LOG: [IR] Add method to GlobalVariable to change type of initializer. (#102553)

With opaque pointers, nothing directly uses the value type, so we can
mutate it if we want. This avoid doing a complicated RAUW dance.

Added: 
    

Modified: 
    clang/lib/CodeGen/CGDecl.cpp
    llvm/include/llvm/IR/GlobalVariable.h
    llvm/lib/IR/Globals.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 882dbad456379a..563f728e29d781 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -370,38 +370,12 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
   assert(VarSize == CstSize && "Emitted constant has unexpected size");
 #endif
 
-  // The initializer may 
diff er in type from the global. Rewrite
-  // the global to match the initializer.  (We have to do this
-  // because some types, like unions, can't be completely represented
-  // in the LLVM type system.)
-  if (GV->getValueType() != Init->getType()) {
-    llvm::GlobalVariable *OldGV = GV;
-
-    GV = new llvm::GlobalVariable(
-        CGM.getModule(), Init->getType(), OldGV->isConstant(),
-        OldGV->getLinkage(), Init, "",
-        /*InsertBefore*/ OldGV, OldGV->getThreadLocalMode(),
-        OldGV->getType()->getPointerAddressSpace());
-    GV->setVisibility(OldGV->getVisibility());
-    GV->setDSOLocal(OldGV->isDSOLocal());
-    GV->setComdat(OldGV->getComdat());
-
-    // Steal the name of the old global
-    GV->takeName(OldGV);
-
-    // Replace all uses of the old global with the new global
-    OldGV->replaceAllUsesWith(GV);
-
-    // Erase the old global, since it is no longer used.
-    OldGV->eraseFromParent();
-  }
-
   bool NeedsDtor =
       D.needsDestruction(getContext()) == QualType::DK_cxx_destructor;
 
   GV->setConstant(
       D.getType().isConstantStorage(getContext(), true, !NeedsDtor));
-  GV->setInitializer(Init);
+  GV->replaceInitializer(Init);
 
   emitter.finalize(GV);
 

diff  --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h
index bcaf8e91432ba9..0736c300de72f5 100644
--- a/llvm/include/llvm/IR/GlobalVariable.h
+++ b/llvm/include/llvm/IR/GlobalVariable.h
@@ -147,10 +147,16 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
     return static_cast<Constant*>(Op<0>().get());
   }
   /// setInitializer - Sets the initializer for this global variable, removing
-  /// any existing initializer if InitVal==NULL.  If this GV has type T*, the
-  /// initializer must have type T.
+  /// any existing initializer if InitVal==NULL. The initializer must have the
+  /// type getValueType().
   void setInitializer(Constant *InitVal);
 
+  /// replaceInitializer - Sets the initializer for this global variable, and
+  /// sets the value type of the global to the type of the initializer. The
+  /// initializer must not be null.  This may affect the global's alignment if
+  /// it isn't explicitly set.
+  void replaceInitializer(Constant *InitVal);
+
   /// If the value is a global constant, its value is immutable throughout the
   /// runtime execution of the program.  Assigning a value into the constant
   /// leads to undefined behavior.

diff  --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index cc37d7371cce35..2bc69cdb712b0a 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -503,6 +503,12 @@ void GlobalVariable::setInitializer(Constant *InitVal) {
   }
 }
 
+void GlobalVariable::replaceInitializer(Constant *InitVal) {
+  assert(InitVal && "Can't compute type of null initializer");
+  ValueType = InitVal->getType();
+  setInitializer(InitVal);
+}
+
 /// Copy all additional attributes (those not needed to create a GlobalVariable)
 /// from the GlobalVariable Src to this one.
 void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) {


        


More information about the cfe-commits mailing list