[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