Justin
Justin

Reputation: 742

How to declare a global integer instance in LLVM IR?

I was wondering if anyone knew how to declare a global integer instance in LLVM IR. So far, I've been doing the following:

// Create symbol to identify previous block. Added by Justin.
llvm::Type::TypeID stupidTypeID = llvm::Type::IntegerTyID;
llvm::Type* typePtr = llvm::Type::getPrimitiveType(_context, stupidTypeID);
llvm::GlobalVariable* prevBlockID = new llvm::GlobalVariable(typePtr,
                                                           false,
                                                          llvm::GlobalValue::LinkerPrivateLinkage,
                                                           NULL,
                                                           "PREV_BLOCK_ID");

When I try to run, I get the following error:

static llvm::PointerType* llvm::PointerType::get(llvm::Type*, unsigned int): Assertion `EltTy && "Can't get a pointer to <null> type!"' failed.

Upvotes: 1

Views: 786

Answers (1)

Hongxu Chen
Hongxu Chen

Reputation: 5350

It's due to the wrong type. You can have a look at Type::getPrimitiveType implementation here. Simply put, that's NOT the API you are advised to use; for IntegerType, it returns nullptr. Also, in definition of TypeID in llvm/IR/Type.h, there comments that:

/// Note: If you add an element to this, you need to add an element to the
/// Type::getPrimitiveType function, or else things will break!

Basically you can generate the type by 2 approaches:

  • static get API for the specified type
    In your case,

    IntegerType *iTy = IntegerType::get(ctx, 32);  // if it's 32bit INT
    
  • a helper class named TypeBuilder
    It makes type generation more easily and universally. TypeBuilder is especially useful and intuitive when you need to define more complicated types, e.g, FunctionType, of course with the cost of compiling your source code slowly(should you care?).

    IntegerType *intType = TypeBuilder<int, false>::get(ctx);  // normal C int
    IntegerType *intTy = TypeBuilder<types::i<32>, false>::get(ctx);  // if it's 32bit INT
    

BTW, you can also try ELLCC online compiler to get the corresponding C++ code for generating LLVM IR of current c/c++ src, where you need to choose the target of Output Options as LLVM C++ API code. Alternatively you can try it yourself on your machine(Since internally the online compiler simply invokes llc):

llc input.ll -march=cpp -o -

Upvotes: 2

Related Questions