Global variables have visibility of all the functions within a given module. LLVM provides the GlobalVariable
class to create global variables and set its properties such as linkage type, alignment, and so on. The Module
class has the method getOrInsertGlobal()
to create a global variable. It takes two arguments—the first is the name of the variable and the second is the data type of the variable.
As global variables are part of a module, we create global variables after creating the module. Insert the following code just after creating the module in toy.cpp
:
GlobalVariable *createGlob(IRBuilder<> &Builder, std::string Name) { ModuleOb->getOrInsertGlobal(Name, Builder.getInt32Ty()); GlobalVariable *gVar = ModuleOb->getNamedGlobal(Name); gVar->setLinkage(GlobalValue::CommonLinkage); gVar->setAlignment(4); return gVar; }
Linkage is what determines if multiple declarations of the same object refer to the same object, or to separate ones. The LLVM reference manual cites the following types of Linkages:
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
Alignment gives information about address alignment. An alignment must be a power of 2
. If not specified explicitly, it is set by the target. The maximum alignment is 1 << 29
.
The overall code is as follows:
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include <vector> using namespace llvm; static LLVMContext &Context = getGlobalContext(); static Module *ModuleOb = new Module("my compiler", Context); Function *createFunc(IRBuilder<> &Builder, std::string Name) { FunctionType *funcType = llvm::FunctionType::get(Builder.getInt32Ty(), false); Function *fooFunc = llvm::Function::Create( funcType, llvm::Function::ExternalLinkage, Name, ModuleOb); return fooFunc; } BasicBlock *createBB(Function *fooFunc, std::string Name) { return BasicBlock::Create(Context, Name, fooFunc); } GlobalVariable *createGlob(IRBuilder<> &Builder, std::string Name) { ModuleOb->getOrInsertGlobal(Name, Builder.getInt32Ty()); GlobalVariable *gVar = ModuleOb->getNamedGlobal(Name); gVar->setLinkage(GlobalValue::CommonLinkage); gVar->setAlignment(4); return gVar; } int main(int argc, char *argv[]) { static IRBuilder<> Builder(Context); GlobalVariable *gVar = createGlob(Builder, "x"); Function *fooFunc = createFunc(Builder, "foo"); BasicBlock *entry = createBB(fooFunc, "entry"); Builder.SetInsertPoint(entry); verifyFunction(*fooFunc); ModuleOb->dump(); return 0; }
Compile the toy.cpp
:
$ clang++ -O3 toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core` -o toy
The output will be as follows:
; ModuleID = 'my compiler' @x = common global i32, align 4 define i32 @foo() { entry: }
18.220.245.233