Emitting a global variable

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:

ExternalLinkage

Externally visible function.

AvailableExternallyLinkage

Available for inspection, not emission.

LinkOnceAnyLinkage

Keep one copy of function when linking (inline)

LinkOnceODRLinkage

Same, but only replaced by something equivalent.

WeakAnyLinkage

Keep one copy of named function when linking (weak)

WeakODRLinkage

Same, but only replaced by something equivalent.

AppendingLinkage

Special purpose, only applies to global arrays.

InternalLinkage

Rename collisions when linking (static functions).

PrivateLinkage

Like internal, but omit from symbol table.

ExternalWeakLinkage

ExternalWeak linkage description.

CommonLinkage

Tentative definitions

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:
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.245.233