Hi, I've read http://llvm.org/docs/LangRef.html#t_array and http://llvm.org/docs/GetElementPtr.html and if I've understood right there are no operations that act directly on arrays - instead I need to use getelementptr on a pointer to an array to get a pointer to an array element. I also understand that there is no 'address of' operation. As a result I can't figure out how to use constant derived types without assigning them to a global. Say I want to use the C bindings function LLVMValueRef LLVMConstString(char *, int, int) to get an int8* pointer to a C string constant - there doesn't seem to be any way to directly use the resulting [N x i8] value directly and there's no operator that gives me its address. The only way I can see to get a pointer to the string constant array is to go through a global variable, for example: g = LLVMAddGlobal(module, LLVMTypeOf(v), "__string_" + string_literal_number); string_literal_number = string_literal_number + 1; v = LLVMConstString(string_literal, string_literal.Length, 0); LLVMSetInitializer(g, v); elements = { LLVMConstInt(LLVMInt32Type(), 0L, 0), LLVMConstInt(LLVMInt32Type(), 0L, 0) }; return LLVMConstInBoundsGEP(g, elements, 2); Is it possible to get the address of an element of a constant array or struct without first initializing a global variable to the constant? Thanks in advance, -- James Williams -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100111/adb4421a/attachment.html>
On Mon, Jan 11, 2010 at 7:07 AM, James Williams <junk at giantblob.com> wrote:> Hi, > > I've read http://llvm.org/docs/LangRef.html#t_array and > http://llvm.org/docs/GetElementPtr.html and if I've understood right there > are no operations that act directly on arrays - instead I need to use > getelementptr on a pointer to an array to get a pointer to an array element. > I also understand that there is no 'address of' operation. > > As a result I can't figure out how to use constant derived types without > assigning them to a global. Say I want to use the C bindings function > LLVMValueRef LLVMConstString(char *, int, int) to get an int8* pointer to a > C string constant - there doesn't seem to be any way to directly use the > resulting [N x i8] value directly and there's no operator that gives me its > address. > > The only way I can see to get a pointer to the string constant array is to > go through a global variable, for example: > > g = LLVMAddGlobal(module, LLVMTypeOf(v), "__string_" + > string_literal_number); > string_literal_number = string_literal_number + 1; > v = LLVMConstString(string_literal, string_literal.Length, 0); > LLVMSetInitializer(g, v); > elements = { LLVMConstInt(LLVMInt32Type(), 0L, 0), > LLVMConstInt(LLVMInt32Type(), 0L, 0) }; > return LLVMConstInBoundsGEP(g, elements, 2); > > Is it possible to get the address of an element of a constant array or > struct without first initializing a global variable to the constant?No. -Eli
Does the C API have an equivalent of stack storage? Via the C++ APIs one can shove the string constant on the stack via a store instruction operation on an alloca instruction--the address needed is the alloca. For example: llvm::Value* stringVar = builder.CreateAlloca(stringConstant->getType()); builder.CreateStore(stringConstant, stringVar); The stringVar is your address. Garrison On Jan 11, 2010, at 10:07, James Williams wrote:> Hi, > > I've read http://llvm.org/docs/LangRef.html#t_array and http://llvm.org/docs/GetElementPtr.html and if I've understood right there are no operations that act directly on arrays - instead I need to use getelementptr on a pointer to an array to get a pointer to an array element. I also understand that there is no 'address of' operation. > > As a result I can't figure out how to use constant derived types without assigning them to a global. Say I want to use the C bindings function LLVMValueRef LLVMConstString(char *, int, int) to get an int8* pointer to a C string constant - there doesn't seem to be any way to directly use the resulting [N x i8] value directly and there's no operator that gives me its address. > > The only way I can see to get a pointer to the string constant array is to go through a global variable, for example: > > g = LLVMAddGlobal(module, LLVMTypeOf(v), "__string_" + string_literal_number); > string_literal_number = string_literal_number + 1; > v = LLVMConstString(string_literal, string_literal.Length, 0); > LLVMSetInitializer(g, v); > elements = { LLVMConstInt(LLVMInt32Type(), 0L, 0), LLVMConstInt(LLVMInt32Type(), 0L, 0) }; > return LLVMConstInBoundsGEP(g, elements, 2); > > Is it possible to get the address of an element of a constant array or struct without first initializing a global variable to the constant? > > Thanks in advance, > -- James Williams > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100111/096ca6cd/attachment.html>
2010/1/11 Eli Friedman <eli.friedman at gmail.com>> On Mon, Jan 11, 2010 at 7:07 AM, James Williams <junk at giantblob.com> > wrote: > > Hi, > > > > I've read http://llvm.org/docs/LangRef.html#t_array and > > http://llvm.org/docs/GetElementPtr.html and if I've understood right > there > > are no operations that act directly on arrays - instead I need to use > > getelementptr on a pointer to an array to get a pointer to an array > element. > > I also understand that there is no 'address of' operation. > > > > As a result I can't figure out how to use constant derived types without > > assigning them to a global. Say I want to use the C bindings function > > LLVMValueRef LLVMConstString(char *, int, int) to get an int8* pointer to > a > > C string constant - there doesn't seem to be any way to directly use the > > resulting [N x i8] value directly and there's no operator that gives me > its > > address. > > > > The only way I can see to get a pointer to the string constant array is > to > > go through a global variable, for example: > > > > g = LLVMAddGlobal(module, LLVMTypeOf(v), "__string_" + > > string_literal_number); > > string_literal_number = string_literal_number + 1; > > v = LLVMConstString(string_literal, string_literal.Length, 0); > > LLVMSetInitializer(g, v); > > elements = { LLVMConstInt(LLVMInt32Type(), 0L, 0), > > LLVMConstInt(LLVMInt32Type(), 0L, 0) }; > > return LLVMConstInBoundsGEP(g, elements, 2); > > > > Is it possible to get the address of an element of a constant array or > > struct without first initializing a global variable to the constant? > > No. >OK. I'd have preferred to have to avoid bloating the module symbol table with global symbols that will never be referenced but it's no big deal.> > -Eli > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100111/de036a05/attachment.html>
2010/1/11 Garrison Venn <gvenn.cfe.dev at gmail.com>> Does the C API have an equivalent of stack storage? Via the C++ APIs one > can shove the string constant on the stack via > a store instruction operation on an alloca instruction--the address needed > is the alloca. For example: > > llvm::Value* stringVar = builder.CreateAlloca(stringConstant->getType()); > builder.CreateStore(stringConstant, stringVar); > > The stringVar is your address. > > Garrison >Thanks but I want something I can use to generate code for a pointer to a C string in any context so I should avoid alloca. Otherwise I'll risk massive stack growth if the generated code is within a loop for example. It looks like using a global variable is the canonical way to do this so I'll stick with it. -- James> > On Jan 11, 2010, at 10:07, James Williams wrote: > > Hi, > > I've read http://llvm.org/docs/LangRef.html#t_array and > http://llvm.org/docs/GetElementPtr.html and if I've understood right there > are no operations that act directly on arrays - instead I need to use > getelementptr on a pointer to an array to get a pointer to an array element. > I also understand that there is no 'address of' operation. > > As a result I can't figure out how to use constant derived types without > assigning them to a global. Say I want to use the C bindings function > LLVMValueRef LLVMConstString(char *, int, int) to get an int8* pointer to a > C string constant - there doesn't seem to be any way to directly use the > resulting [N x i8] value directly and there's no operator that gives me its > address. > > The only way I can see to get a pointer to the string constant array is to > go through a global variable, for example: > > g = LLVMAddGlobal(module, LLVMTypeOf(v), "__string_" + > string_literal_number); > string_literal_number = string_literal_number + 1; > v = LLVMConstString(string_literal, string_literal.Length, 0); > LLVMSetInitializer(g, v); > elements = { LLVMConstInt(LLVMInt32Type(), 0L, 0), > LLVMConstInt(LLVMInt32Type(), 0L, 0) }; > return LLVMConstInBoundsGEP(g, elements, 2); > > Is it possible to get the address of an element of a constant array or > struct without first initializing a global variable to the constant? > > Thanks in advance, > -- James Williams > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20100111/2b59cd2f/attachment.html>