Kinda noob questions

Hi all,

I have 2 simple questions…

First, just for you to know, I’m making a compiler (kinda obvious) and the language definition is mine, so there is no much constraint for me, it’s written in Java (it generates a .ll file as output) and it’s just for fun by now, maybe a serious project after I learn all the stuff needed…

and sorry bad english

  1. I want to know if when I do this kind of thing:

entry:
%x = alloca i32
%y = alloca i32
… normal instructions…
other_block:
%z = alloca i32

br … label %other_block

the stack “grows” when alloca is “called”, or its the same as putting “%z = alloca” in the beggining?
or… if alloca is in a loop, the stack grows every time it iterates??

  1. does the LLVM optimizes this:

; this code (arg → var) is very similar to what gcc generates
define void @foo(i32 %arg0) {
entry:
%var0 = alloca i32
store i32 %arg0, i32* var0

%x = load i32* %var0

; never more stores to %var0 or pass it to any function
}

to something like:

define void @foo(i32 arg0) {
entry:
; no alloca

%x = %arg0

}

does it???

I’m asking because I can check in my compiler if some arg is only readed or if its used as a var before generate the IR, an then only create (alloca) a %var if the arg is used for read-write :stuck_out_tongue: (my language is “safe” (no pointers))
If LLVM optimizes it, I’ll let it… if not, I’ll do this optimization

Thanks in advance :stuck_out_tongue:

Hi all,

I have 2 simple questions…

First, just for you to know, I’m making a compiler (kinda obvious) and the language definition is mine, so there is no much constraint for me, it’s written in Java (it generates a .ll file as output) and it’s just for fun by now, maybe a serious project after I learn all the stuff needed…

and sorry bad english

  1. I want to know if when I do this kind of thing:

entry:
%x = alloca i32
%y = alloca i32
… normal instructions…
other_block:
%z = alloca i32

br … label %other_block

the stack “grows” when alloca is “called”, or its the same as putting “%z = alloca” in the beggining?
or… if alloca is in a loop, the stack grows every time it iterates??

Yes, you can have alloca’s instead of loops, and they will grow the size of the stack frame each time they are executed dynamically.

  1. does the LLVM optimizes this:

; this code (arg → var) is very similar to what gcc generates
define void @foo(i32 %arg0) {
entry:
%var0 = alloca i32
store i32 %arg0, i32* var0

%x = load i32* %var0

; never more stores to %var0 or pass it to any function
}

to something like:

define void @foo(i32 arg0) {
entry:
; no alloca

%x = %arg0

}

does it???

I suspect that mem2reg plus a few additional optimizations will do this for you.

– John T.

mem2reg is sufficient. There's also no limit on the number of loads
and stores you can do without disturbing the optimization; just
don't do anything too opaque with the address.

John.

Thank you John and John :stuck_out_tongue:

these optimizations (mem2reg and the “few additional” ones) I have to enable then or something like this?? (I compile the .ll to .o with the sequence llvm-as, llc, as)

Yet about dynamic stack allocation, what is (generally) better? to pre alloc everything at start, or let it be?

Imagine this pseudo-code

while (x) {
int b = 0;

}

using alloca where b is declared, it will grow the stack dynamically, but it will shrink it at } or in llvm’s words in the end of a block where b is not accessible anymore? Can I force its deallocation??

Thanks again

Thank you John and John :stuck_out_tongue:

these optimizations (mem2reg and the "few additional" ones) I have to enable then or something like this?? (I compile the .ll to .o with the sequence llvm-as, llc, as)

Look into 'opt'.

Yet about dynamic stack allocation, what is (generally) better? to pre alloc everything at start, or let it be?

Imagine this pseudo-code

while (x) {
  int b = 0;
  ...
}

using alloca where b is declared, it will grow the stack dynamically, but it will shrink it at } or in llvm's words in the end of a block where b is not accessible anymore? Can I force its deallocation??

Unless you're actually reliant on dynamic allocation — e.g. you don't know the size statically, or you're intending to repeatedly allocate memory — you should always allocate in the entry block. LLVM is reasonably good at re-using stack slots when it can.

John.