alloca behavior in llvm IR

Hi, there,

I am not quite clear about the behavior of alloca instruction in llvm IR.

I saw the code fragment as above. Is it possible that alloca is not static?
And what is the behavior when alloca is not static?
When alloca is not in the entry block, it is not static. How would it behave?

The compiler will modify sp in the middle of the function to allocate
more memory on the stack. If your alloca is in a loop it might even do
that repeatedly (@llvm.stacksave and @llvm.stackrestore can help
here).

Would it adjust the stack for the current function?

The memory would become part of the current function's stack frame,
and still get freed when it returns.

Cheers.

Tim.

Hi, Tim,

Thanks. Here comes another question. Given the code below.

How would the compiler compute the address of "a"? Would the compiler access "a" through the frame pointer?

That's usually what happens, yes. Sometimes it may be yet another
pointer called a "base pointer" though (for example
Compiler Explorer computes var's address from x19 because
the stack was realigned so the offset from the frame pointer is no
longer a compile-time constant).

if that's true, when will the frame pointer be set?

It's generally set in prologue code emitted by XYZFrameLowering.cpp.

And when is a frame pointer is needed?

That's not an easy question to answer I'm afraid. Some platforms
always require a frame pointer (to improve back-traces for example),
otherwise there's a whole host of odd edge-cases in what functions
need that add a frame pointer to the mix.

For example the function that makes the decision on AArch64 is here:

Cheers.

Tim.

Thanks, Tim.

When there are dynamic allocas, is it always that the compiler will insert @llvm.stacksave() and @llvm.stackrestore()?
When there is a need to insert @llvm.stacksave() and @llvm.stackrestore(), how does the compiler decide where it should insert them?

Best Regards,
Jerry

When there are dynamic allocas, is it always that the compiler will insert @llvm.stacksave() and @llvm.stackrestore()?

Clang always emits them for variable length arrays as far as I know
(e.g. "int arr[n]"), but C's actual "alloca" function
(alloca(3) - Linux manual page) makes the
memory available until the function returns so Clang can't use
stackrestore anywhere there.

When there is a need to insert @llvm.stacksave() and @llvm.stackrestore(), how does the compiler decide where it should insert them?

The stacksave should go just before the alloca you want to reclaim
later, which is usually pretty easy to do.

The stackrestore ideally goes just after the last instruction that
uses the memory involved. That's difficult to determine though (and
impossible to implement if it happens in another function). So in
practice source languages have scoping rules that say when a variable
is *allowed* to be accessed, and compilers put the stackrestore at the
end of the scope.

In C and C++ that's at the '}' of the block the variable is declared

Cheers.

Tim.

Hi, Tim.

I am also not quite clear about the convention of alloca.
when the size of a variable is known at compile-time, is it always that clang will put the alloca for the variable at the start of entry block?
when will clang put alloca at other block? And when will clang put alloca at entry block?
when clang put alloca at other block, does it mean that the size of the variable of alloca is not known at compile-time?
Thanks!

Best Regards,
Jerry

Hi 林政宗,
  As Tim has mentioned `alloca` which is included in `<alloca.h>`, I
think you can write some demos and observe what the behavior is. For
example,

#include <alloca.h>

void foo(void *);
bool bar(void);
void spam() {
 if (bar()) {
   auto *p = alloca(1024);
   foo(p);
 }
}

which gives LLVM IR

; Function Attrs: uwtable mustprogress
define dso_local void @_Z4spamv() local_unnamed_addr #0 {
entry:
 %call = tail call zeroext i1 @_Z3barv()
 br i1 %call, label %if.then, label %if.end

if.then:                                          ; preds = %entry
 %0 = alloca [1024 x i8], align 16
 %.sub = getelementptr inbounds [1024 x i8], [1024 x i8]* %0, i64 0, i64 0
 call void @_Z3fooPv(i8* nonnull %.sub)
 br label %if.end

if.end:                                           ; preds = %if.then, %entry
 ret void
}

Best regards,
Kai

Hi, Kai

thanks. but I mean the alloca in llvm IR, not alloca in C.

Best Regards,
Jerry

发件人: Kai Luo gluokai@gmail.com
日期: 2020年12月23日周三 晚上7:26
收件人: 林政宗 jackie_linzz@126.com
抄送: Tim Northover t.p.northover@gmail.com, llvm-dev@lists.llvm.org
主 题: Re: [llvm-dev] alloca behavior in llvm IR