(no subject)

Hi There ,

Again ,I’m newbie to LLVM and please pardon me …if you guys feel that ,the below question is very basic :slight_smile:

Here i go ,compiled the below sample with clang i.e clang enum.c -S -emit-llvm and there respective file are

$ cat enum.c
int main()
{
enum type{one=1,two,three} s;
s = one;
return s;
}

$ cat enum.s
; ModuleID = ‘enum.c’
target datalayout = “e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32”
target triple = “i386-pc-cygwin”

define i32 @main() nounwind {
%1 = alloca i32, align 4
%s = alloca i32, align 4
store i32 0, i32* %1
store i32 1, i32* %s, align 4
%2 = load i32* %s, align 4
ret i32 %2
}

Question : Why there is extra 4 bytes on stack i.e “%1 = alloca i32, align 4” ???

Thanks
~Umesh

Hi Umesh,

Again ,I'm newbie to LLVM and please pardon me ..if you guys feel that ,the
below question is very basic :slight_smile:

Here i go ,compiled the below sample with clang i.e *clang enum.c -S -emit-llvm*
and there respective file are

$ cat enum.c
int main()
{
  enum type{one=1,two,three} s;
  s = one;
  return s;
}

$ cat enum.s
; ModuleID = 'enum.c'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32"
target triple = "i386-pc-cygwin"

define i32 @main() nounwind {
   %1 = alloca i32, align 4
   %s = alloca i32, align 4
   store i32 0, i32* %1
   store i32 1, i32* %s, align 4
   %2 = load i32* %s, align 4
   ret i32 %2
}

*Question :* Why there is extra 4 bytes on stack i.e *"%1 = alloca i32, align
4"* ???

I think this would normally be used for storing the return value in more
complicated cases. If you compile with optimization it will go away.

Ciao, Duncan.

Hi Duncan,
Appreciate you response here and yeah any optimization switch for clang will make this extra bytes go away …Was very curious to know why these extra bytes for and can you please elaborate more on “for storing the return value in
more complicated cases” …That helps me understand the LLVM internals :slight_smile:

Thanks
~Umesh

Hi Umesh,

The compiler generates an alloca (stack space) for every local variable defined in a function. Along with local variables this also includes space to store the function parameters and also the variable that holds the return value.

For example:

Int x(int a, int b) {

Return a + b;

}

Would compile to something like this:

Define i32 @x(i32 %a, i32 %b) {

%ret.addr = alloca i32

%a.addr = alloca i32

%b.addr = alloca i32

Store i32 %a, i32 *%a.addr

Store i32 %b, i32 *%b.addr

%1 = load i32* %a.addr

%2 = load i32* %b.addr

%3 = add nsw i32 %1, %2

Store i32 %3, i32* %ret.addr

%4 = load i32* %ret.addr

Ret %4

}

So firstly Clang would create variables on the stack to hold the parameters and the return value, then store the parameters there (function prologue).

Then, to perform the add, it would load the arguments from their local variable storage (in this case %a.addr and %b.addr), perform the add and write the result back to its local variable storage (%ret.addr)

Finally to return it will load the return value variable and return it.

Does this make things clearer?

Cheers,

James

Hi James,

Thank you very much for the explanation .

FYI .LLVM Dead store elimination (DSE) transformation eliminates those extra bytes. i.e

$ opt -f -S -dse enum.s
; ModuleID = ‘enum.s’
target datalayout = “e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32”
target triple = “i386-pc-cygwin”

define i32 @main() nounwind {
%s = alloca i32, align 4
store i32 1, i32* %s, align 4
%1 = load i32* %s, align 4
ret i32 %1
}

Duncan, Debugging the Clang source code here for the reason “why these extra bytes”,But still you have anything in your kit,Please let me know :).

Thanks
~Umesh