I am trying to create such module with API (it's equivalent to c++: const char* ss[] = {"s1","s2"};): @ss = global [2 x i8*] [i8* getelementptr inbounds ([3 x i8]* @.str1, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8]* @.str2, i32 0, i32 0)] ; <[2 x i8*]*> [#uses=0] @.str1 = private constant [3 x i8] c"s1\00", align 1 ; <[3 x i8]*> [#uses=1] @.str2 = private constant [3 x i8] c"s2\00", align 1 ; <[3 x i8]*> [#uses=1] Code below doesn't compile because to initialize GlobalVariable I need ConstantArray*, ConstantArray::get requires vector<Constant*>, but getelementptr is an instruction and it's not Constant*, but Value*. What is the correct way to create such module? It's really tye Yuri --- c++ code --- #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Analysis/Verifier.h" #include <stdio.h> #include <vector> using namespace llvm; using namespace std; Constant* mk_string(Module *M, LLVMContext &Context, const string &svalue) { ArrayType *Ty = ArrayType::get(Type::getInt8Ty(Context),svalue.size()+1); GlobalVariable *GV = new llvm::GlobalVariable( *M, Ty, true, GlobalValue::InternalLinkage, ConstantArray::get(Context,svalue), "str", 0, false, 0); vector<Constant*> idxs; idxs.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0, false)); idxs.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0, false)); return (GetElementPtrInst::Create( GV, idxs.begin(), idxs.end(), "gepi", (BasicBlock*)0 )); } main() { LLVMContext Context; Module *M = new Module("test", Context); // vector<Constant*> strs; strs.push_back(mk_string(M, Context, "s1")); strs.push_back(mk_string(M, Context, "s2")); ArrayType *Ty = ArrayType::get(Type::getInt8Ty(Context)->getPointerTo(),2); new llvm::GlobalVariable( *M, Ty, true, GlobalValue::InternalLinkage, ConstantArray::get(Ty,strs), "ss", 0, false, 0); verifyModule(*M); delete M; }
Eugene Toder
2010-Jun-01 19:41 UTC
[LLVMdev] How to create global string array? (user question)
I think ConstantExpr::getGetElementPtr() returns a Constant*. On Tue, Jun 1, 2010 at 8:34 PM, Yuri <yuri at rawbw.com> wrote:> I am trying to create such module with API (it's equivalent to c++: > const char* ss[] = {"s1","s2"};): > > @ss = global [2 x i8*] [i8* getelementptr inbounds ([3 x i8]* @.str1, > i32 0, i32 0), i8* getelementptr inbounds ([3 x i8]* @.str2, i32 0, i32 > 0)] ; <[2 x i8*]*> [#uses=0] > @.str1 = private constant [3 x i8] c"s1\00", align 1 ; <[3 x i8]*> [#uses=1] > @.str2 = private constant [3 x i8] c"s2\00", align 1 ; <[3 x i8]*> [#uses=1] > > Code below doesn't compile because to initialize GlobalVariable I need > ConstantArray*, ConstantArray::get requires vector<Constant*>, but > getelementptr is an instruction and it's not Constant*, but Value*. > > What is the correct way to create such module? It's really tye > > Yuri > > --- c++ code --- > #include "llvm/LLVMContext.h" > #include "llvm/Module.h" > #include "llvm/DerivedTypes.h" > #include "llvm/Constants.h" > #include "llvm/Instructions.h" > #include "llvm/Analysis/Verifier.h" > #include <stdio.h> > #include <vector> > using namespace llvm; > using namespace std; > > Constant* mk_string(Module *M, LLVMContext &Context, const string &svalue) { > ArrayType *Ty = ArrayType::get(Type::getInt8Ty(Context),svalue.size()+1); > GlobalVariable *GV = new llvm::GlobalVariable( > *M, > Ty, > true, > GlobalValue::InternalLinkage, > ConstantArray::get(Context,svalue), > "str", > 0, > false, > 0); > > vector<Constant*> idxs; > idxs.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0, false)); > idxs.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0, false)); > return (GetElementPtrInst::Create( > GV, > idxs.begin(), > idxs.end(), > "gepi", > (BasicBlock*)0 > )); > } > > main() { > LLVMContext Context; > Module *M = new Module("test", Context); > // > vector<Constant*> strs; > strs.push_back(mk_string(M, Context, "s1")); > strs.push_back(mk_string(M, Context, "s2")); > ArrayType *Ty > ArrayType::get(Type::getInt8Ty(Context)->getPointerTo(),2); > new llvm::GlobalVariable( > *M, > Ty, > true, > GlobalValue::InternalLinkage, > ConstantArray::get(Ty,strs), > "ss", > 0, > false, > 0); > verifyModule(*M); > delete M; > } > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
o.j.sivart at gmail.com
2010-Jun-01 21:57 UTC
[LLVMdev] How to create global string array? (user question)
I have found an invaluable way to find an answer (not necessarily the best answer, but an initial answer at least) is to write a simple c source file, compile it to bitcode (clang -S -emit-llvm sourcefile.c), then get llc to produce a cpp file containing the calls required to produce that bitcode (llc -march=cpp sourcefile.s). I find that the resulting source file (sourcefile.s.cpp) is usually enough to make an initial start on figuring out how to do what I want if I can't otherwise find it in the docs. In your case sourcefile.c would simply be: const char* ss[] = {"s1","s2"}; On 02/06/2010, at 5:04 AM, Yuri wrote:> I am trying to create such module with API (it's equivalent to c++: > const char* ss[] = {"s1","s2"};): > > @ss = global [2 x i8*] [i8* getelementptr inbounds ([3 x i8]* @.str1, > i32 0, i32 0), i8* getelementptr inbounds ([3 x i8]* @.str2, i32 0, i32 > 0)] ; <[2 x i8*]*> [#uses=0] > @.str1 = private constant [3 x i8] c"s1\00", align 1 ; <[3 x i8]*> [#uses=1] > @.str2 = private constant [3 x i8] c"s2\00", align 1 ; <[3 x i8]*> [#uses=1] > > Code below doesn't compile because to initialize GlobalVariable I need > ConstantArray*, ConstantArray::get requires vector<Constant*>, but > getelementptr is an instruction and it's not Constant*, but Value*. > > What is the correct way to create such module? It's really tye > > Yuri > > --- c++ code --- > #include "llvm/LLVMContext.h" > #include "llvm/Module.h" > #include "llvm/DerivedTypes.h" > #include "llvm/Constants.h" > #include "llvm/Instructions.h" > #include "llvm/Analysis/Verifier.h" > #include <stdio.h> > #include <vector> > using namespace llvm; > using namespace std; > > Constant* mk_string(Module *M, LLVMContext &Context, const string &svalue) { > ArrayType *Ty = ArrayType::get(Type::getInt8Ty(Context),svalue.size()+1); > GlobalVariable *GV = new llvm::GlobalVariable( > *M, > Ty, > true, > GlobalValue::InternalLinkage, > ConstantArray::get(Context,svalue), > "str", > 0, > false, > 0); > > vector<Constant*> idxs; > idxs.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0, false)); > idxs.push_back(ConstantInt::get(Type::getInt32Ty(Context), 0, false)); > return (GetElementPtrInst::Create( > GV, > idxs.begin(), > idxs.end(), > "gepi", > (BasicBlock*)0 > )); > } > > main() { > LLVMContext Context; > Module *M = new Module("test", Context); > // > vector<Constant*> strs; > strs.push_back(mk_string(M, Context, "s1")); > strs.push_back(mk_string(M, Context, "s2")); > ArrayType *Ty = > ArrayType::get(Type::getInt8Ty(Context)->getPointerTo(),2); > new llvm::GlobalVariable( > *M, > Ty, > true, > GlobalValue::InternalLinkage, > ConstantArray::get(Ty,strs), > "ss", > 0, > false, > 0); > verifyModule(*M); > delete M; > } > > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev