Operations on constant array value?

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

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

2010/1/11 Eli Friedman <eli.friedman@gmail.com>

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.

2010/1/11 Garrison Venn <gvenn.cfe.dev@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

I have not tried this, but a linkage type of PrivateLinkage would not add to the symbol table according
to the doc.

LLVMSetLinkage(g, LLVMPrivateLinkage);

Garrison

2010/1/11 Garrison Venn <gvenn.cfe.dev@gmail.com>

I have not tried this, but a linkage type of PrivateLinkage would not add to the symbol table according
to the doc.

LLVMSetLinkage(g, LLVMPrivateLinkage);

Thanks - I hadn’t thought of that.

Sorry to keep this thread alive, but I’m learning so …

There is more. The doc for GlobalValue::LinkageTypes or the C API LLVMLinkage is not as clear as the
lang ref manual. See: http://llvm.org/docs/LangRef.html#linkage. I’m pointing this out because something
like LinkerPrivateLinkage (LLVMLinkerPrivateLinkage), or another one, might be more appropriate to
your throw away use case (if I understand your use correctly). One should test this of course, and/or one
of the experts could chime in hint hint. :slight_smile:

Anyway thought this info. might be useful, however rehashed.

Garrison

2010/1/11 Garrison Venn <gvenn.cfe.dev@gmail.com>

Sorry to keep this thread alive, but I’m learning so …

There is more. The doc for GlobalValue::LinkageTypes or the C API LLVMLinkage is not as clear as the
lang ref manual. See: http://llvm.org/docs/LangRef.html#linkage. I’m pointing this out because something
like LinkerPrivateLinkage (LLVMLinkerPrivateLinkage), or another one, might be more appropriate to
your throw away use case (if I understand your use correctly). One should test this of course, and/or one
of the experts could chime in hint hint. :slight_smile:

I think I’d understand the LLVM linkage document better if I had more knowledge of ELF - I suspect there’s a close correspondance between LLVM linkage types and corresponding features in ELF but I could be confused here.

I also found the documentation on derived types less clear in places. I might have missed it but I don’t think it’s made explicit what operations are allowed on derived types (actually none?)

Otherwise the LLVM documentation is generally very good and this together with the clear and orthogonal nature of the IR has enabled me to make huge progress towards replacing my compiler’s back end with LLVM in a couple of weekends and a few evenings.

– James