Explicitly Freeing Allocas

Hello,

I would just like to ask if it's possible to explicitly free allocas. This
is because I need to call functions that take structs of different sizes as
input, (possibly inside of loops) and I would rather avoid a stack overflow.

If this is not possible, an alternate solution would be for me to allocate
an array of bytes larger than all the struct types I may be using, and cast
that pointer to the right type each type. In that case, I would like to know
how I can find out what the size of a struct is. I've heard of people
talking about using "the right target data", but I have no idea how to
actually do that, and I find the doxygen info doesn't make it any clearer.

Thank you for your help,

- Max

Nyx wrote:

Hello,

I would just like to ask if it's possible to explicitly free allocas. This
is because I need to call functions that take structs of different sizes as
input, (possibly inside of loops) and I would rather avoid a stack overflow.
  

No, it's not legal to free memory returned by alloca. Such memory is
allocated on the stack; the code generator usually converts this to an
adjustment of the stack pointer on function entry whenever possible.

If this is not possible, an alternate solution would be for me to allocate
an array of bytes larger than all the struct types I may be using, and cast
that pointer to the right type each type. In that case, I would like to know
how I can find out what the size of a struct is. I've heard of people
talking about using "the right target data", but I have no idea how to
actually do that, and I find the doxygen info doesn't make it any clearer.
  

This sounds like your best option. The TargetData pass is a pass that
informs other passes of machine specific information and can, for
example, give you the number of bytes used to store a type.

Read the document on Writing an LLVM Pass
(http://llvm.org/docs/WritingAnLLVMPass.html) to learn how to have your
pass declare the TargetData pass as a prerequisite and to get a pointer
to it when your
runOnFunction/runOnModule/runOnBasicBlock/runOn<whatever> method is
called. Then use the doxygen documentation to find the correct method
of the TargetData pass
(http://llvm.org/doxygen/classllvm_1_1TargetData.html) to use to get the
size of the type that you allocated via alloca.

-- John T.

Nyx wrote:

Hello,

I would just like to ask if it's possible to explicitly free allocas. This
is because I need to call functions that take structs of different sizes as
input, (possibly inside of loops) and I would rather avoid a stack overflow.

You can't explicitly free a specific alloca, but you can use the llvm.stacksave and llvm.stackrestore intrinsics to free all allocas performed after calling the stacksave intrinsic.

http://llvm.org/docs/LangRef.html#int_stacksave

That sounds rather cumbersome, is there no simpler way to get the actual size
of a struct?

John Criswell wrote:

What kind of overhead does that have? Does it only restore the stack pointer
to what it was (what I want), or does it do more than that, and try to
restore values that were on the stack prior to save, etc?

Frits van Bommel wrote:

Hi,

If this is not possible, an alternate solution would be for me to allocate
an array of bytes larger than all the struct types I may be using, and cast
that pointer to the right type each type. In that case, I would like to know
how I can find out what the size of a struct is. I've heard of people
talking about using "the right target data", but I have no idea how to
actually do that, and I find the doxygen info doesn't make it any clearer.

you can get the size in a target independent way using
ConstantExpr::getSizeOf. You can also get the alignment
using ConstantExpr::getAlignOf, but this is less useful.

Ciao,

Duncan.

In the TargetData class (available from you ExecutionEngine), you have some informations available (such as StructLayout…).

Nyx wrote:
[re: llvm.stacksave & stackrestore]

What kind of overhead does that have? Does it only restore the stack pointer
to what it was (what I want), or does it do more than that, and try to
restore values that were on the stack prior to save, etc?

It basically just copies and restores the stack pointer, though I guess the langref isn't exactly very clear on that point.

I went ahead and implemented the allocation based on the maximum size of all
structs seen so far... The problem is, the TargetData object from
ExecutionEngine gives me a size of 12 for a struct containing a pointer and
an i64 (on a 32-bit machine). However, the generated code seems to assume an
alignment of 8, and tries to read the i64 value at offset 8, which obviously
reads an invalid value.

Does the getSizeInBytes() method from StructLayout not take the alignment
into account?

- Max

Olivier Meurant wrote:

Nyx wrote:

I went ahead and implemented the allocation based on the maximum size of all
structs seen so far... The problem is, the TargetData object from
ExecutionEngine gives me a size of 12 for a struct containing a pointer and
an i64 (on a 32-bit machine). However, the generated code seems to assume an
alignment of 8, and tries to read the i64 value at offset 8, which obviously
reads an invalid value.

Does the getSizeInBytes() method from StructLayout not take the alignment
into account?

You should use getTypeAllocSize. You can also get this without knowing
the target using ConstantExpr::getSizeOf.

Ciao,

Duncan.