From: Philip Pfaffe Date: Wed, 2 Jan 2019 15:41:47 +0000 (+0000) Subject: Extend Module::getOrInsertGlobal to control the construction of the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60162315869ce8d72a15a55d5a2c8a4bc7598eaf;p=llvm Extend Module::getOrInsertGlobal to control the construction of the GlobalVariable Summary: Extend Module::getOrInsertGlobal to accept a callback for creating a new GlobalVariable if necessary instead of calling the GV constructor directly using default arguments. Additionally overload getOrInsertGlobal for the previous default behavior. Reviewers: chandlerc Subscribers: hiraditya, llvm-commits, bollu Differential Revision: https://reviews.llvm.org/D56130 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350219 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h index ef4a4a9840b..961b6b7531b 100644 --- a/include/llvm/IR/Module.h +++ b/include/llvm/IR/Module.h @@ -403,11 +403,15 @@ public: } /// Look up the specified global in the module symbol table. - /// 1. If it does not exist, add a declaration of the global and return it. - /// 2. Else, the global exists but has the wrong type: return the function - /// with a constantexpr cast to the right type. - /// 3. Finally, if the existing global is the correct declaration, return - /// the existing global. + /// If it does not exist, invoke a callback to create a declaration of the + /// global and return it. The global is constantexpr casted to the expected + /// type if necessary. + Constant * + getOrInsertGlobal(StringRef Name, Type *Ty, + function_ref CreateGlobalCallback); + + /// Look up the specified global in the module symbol table. If required, this + /// overload constructs the global variable using its constructor's defaults. Constant *getOrInsertGlobal(StringRef Name, Type *Ty); /// @} diff --git a/lib/IR/Module.cpp b/lib/IR/Module.cpp index 70a16cbbf24..93f27304424 100644 --- a/lib/IR/Module.cpp +++ b/lib/IR/Module.cpp @@ -203,16 +203,14 @@ GlobalVariable *Module::getGlobalVariable(StringRef Name, /// with a constantexpr cast to the right type. /// 3. Finally, if the existing global is the correct declaration, return the /// existing global. -Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { +Constant *Module::getOrInsertGlobal( + StringRef Name, Type *Ty, + function_ref CreateGlobalCallback) { // See if we have a definition for the specified global already. GlobalVariable *GV = dyn_cast_or_null(getNamedValue(Name)); - if (!GV) { - // Nope, add it - GlobalVariable *New = - new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, - nullptr, Name); - return New; // Return the new declaration. - } + if (!GV) + GV = CreateGlobalCallback(); + assert(GV && "The CreateGlobalCallback is expected to create a global"); // If the variable exists but has the wrong type, return a bitcast to the // right type. @@ -225,6 +223,14 @@ Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { return GV; } +// Overload to construct a global variable using its constructor's defaults. +Constant *Module::getOrInsertGlobal(StringRef Name, Type *Ty) { + return getOrInsertGlobal(Name, Ty, [&] { + return new GlobalVariable(*this, Ty, false, GlobalVariable::ExternalLinkage, + nullptr, Name); + }); +} + //===----------------------------------------------------------------------===// // Methods for easy access to the global variables in the module. //