llvmlite icon indicating copy to clipboard operation
llvmlite copied to clipboard

How to get address of array constatn?

Open heckad opened this issue 4 years ago • 5 comments

For example, I have string constantnt

from llvmlite.llvmpy.core import Constant

c = Constant.stringz("Hellow world")

How to get the address of 'H'?

I tried to write

c.gep(int32(0)

but got TypeError: can only call gep() on pointer constants, not '[12 x i8]'

heckad avatar May 29 '21 11:05 heckad

I think this might be a bug? The documentation does seem to indicate that it should work:

In [14]: c.gep?
Signature: c.gep(indices)
Docstring: Call getelementptr on this pointer constant.
File:      ~/miniconda3/envs/numba_3.8/lib/python3.8/site-packages/llvmlite/ir/values.py
Type:      method

In [15]: c
Out[15]: <ir.Constant type='[13 x i8]' value=bytearray(b'Hellow world\x00')>

esc avatar May 31 '21 12:05 esc

Seams need to convert const to GlobalVariable.

        g = ir.GlobalVariable(builder.module, arg.type, 'g')
        g.global_constant = True
        g.linkage = "internal"
        g.initializer = arg
        g.align = 1

        arg = g.gep([ir.IntType(32)(0),ir.IntType(32)(0)])

This working as expect. But I am not good in llvm ir. Maybe experts suggest a better solution. I would suggest adding a method to Constants that converts costs to global var with global_constant = True.

@esc, what do you say?

heckad avatar May 31 '21 14:05 heckad

Seams need to convert const to GlobalVariable.

        g = ir.GlobalVariable(builder.module, arg.type, 'g')
        g.global_constant = True
        g.linkage = "internal"
        g.initializer = arg
        g.align = 1

        arg = g.gep([ir.IntType(32)(0),ir.IntType(32)(0)])

This working as expect. But I am not good in llvm ir. Maybe experts suggest a better solution. I would suggest adding a method to Constants that converts costs to global var with global_constant = True.

@esc, what do you say?

I'm not certain either, would defer to @sklam and @stuartarchibald in this case.

esc avatar May 31 '21 14:05 esc

The error message:

TypeError: can only call gep() on pointer constants, not '[12 x i8]'

is correct. In LLVM, [12 x i8] is not a pointer type and GEP requires pointers. The equivalent for C int[3] would be [3 x i32]*. You can achieve that by storing the constant in stack allocated memory (via alloca) or in GlobalVariable as mentioned in https://github.com/numba/llvmlite/issues/724#issuecomment-851535649. GlobalVariable is always a pointer slot.

sklam avatar Jun 01 '21 14:06 sklam

Maybe add a method to the constant that converts to GlobalVariable, or a class method to GlobalVariable which construct g from const? What you think, @sklam?

Also, it would be nice to have the ability to initialize global_constant, linkage, initializer, align in the constructor.

heckad avatar Jun 01 '21 15:06 heckad