Variables and/or identifiers?

I am having trouble understanding the relationship between LLVM
identifiers, stack (alloca) and variables. In particular, when I need
to create a variable, what should I use? For instance, consider the
following C-like language snippet:

int f()
{
int i = rand();
if(i > 5)
  i = 1;
return i;
}

Ignoring optimizations, what should I use to represent 'i'? Online
demo gives the following output for the above code:

int %_Z1fv() {
entry:
%tmp.0 = call int %rand( ); <int> [#uses=2]
%tmp.2 = setgt int %tmp.0, 5; <bool> [#uses=1]
%retval = select bool %tmp.2, int 1, int %tmp.0; <int> [#uses=1]
ret int %retval
}

but this is optimized, 'i' (tmp.0) is never reassigned a value. It
looks like no matter how convoluted I get, I can't fool the optimizier
:slight_smile: It seems to me that my compiler should allocate an integer on the
stack and use load/store instructions but this doesn't look like what
C front end does. Could someone please clarify the relationships of
above concepts?

I am having trouble understanding the relationship between LLVM
identifiers, stack (alloca) and variables. In particular, when I need
to create a variable, what should I use? For instance, consider the
following C-like language snippet:

From my understanding, the C Frontend initially creates stack variables

on the stack using LLVM's alloca. Whenever the variable is read, a load
instruction reads it into an LLVM virtual register, and writes to the
variable become LLVM stores.

Now, there's an LLVM pass (-mem2reg, I think) that examines all of the
allocas in a program and determines if they can be promoted to LLVM
virtual registers (eliminating the loads and stores). This is probably
what you are seeing: your variables are being promoted by the mem2reg
pass because they don't need to live in memory.

This method makes writing language front ends a lot easier (as they
don't have to worry about the restrictions of Single Static Assignment),
but allows for efficient code (since LLVM virtual registers are put into
native machine registers whenever possible).

The following procedure should demonstrate the above:

llvm-gcc -S -o file.ll file.c
llvm-as -o file.bc file.ll
opt -mem2reg -o file2.bc file.bc
llvm-dis -o file2.ll file2.bc

At the end, file.ll should contain the C Frontend output with all the
allocas, and file2.ll should contain the optimized code which the
variables promoted to LLVM virtual registers.

-- John T.