Not allowed to reuse variables?

Hello!

I am having trouble with identifiers:

%tmpFunction = load int ()** %puts_kernelPTR
...
%tmpFunction = load int ()** %puts_kernelPTR

generates

Redefinition of value named 'tmpFunction' in the 'int () *' type plane!

Is it not allowed to reuse variables? Is there some way to do it?

Anders

LLVM uses the Static Single Assignment (SSA) form, which means that any
variable can have exactly ONE static location where it is assigned.

If this is straight-line code, an easy way to solve it is to rename the
second occurrence of it, and then use it for all points below the second
definition:

  %tmpFunction = load int ()** %puts_kernelPTR
  [ use tmpFunction here ]
  ...
  %tmpFunction1 = load int ()** %puts_kernelPTR
  [ use tmpFunction1 below ]

If this is in a loop and you MUST use the same variable name, then what
you need is a 'phi' node which merges multiple values across control
flow edges into one variable. An example: if you compile this function

  void foo(int j) {
    int i;
    for (i=0; i < j; ++i)
      foo(i);
  }

what you get is:

void %foo(int %j) {
entry:
    %tmp.24 = setgt int %j, 0
    br bool %tmp.24, label %no_exit, label %return

no_exit:
    %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]
    %i.0.0 = cast uint %indvar to int
    call void %foo( int %i.0.0 )
    %inc = add int %i.0.0, 1
    %tmp.2 = setlt int %inc, %j
    %indvar.next = add uint %indvar, 1
    br bool %tmp.2, label %no_exit, label %return

return:
    ret void
}

note how %indvar is a result of merging values from %indvar.next (which is
defined BELOW %indvar) as well as 0, coming in from above -- %entry block.

HTH.

Note that if you're working on a front-end though, that you shouldn't
worry about creating PHI nodes at all. Typically you should just stack
allocate any variables that can be modified, and use load/store
instructions to access them. The LLVM optimizer will promote the stack
locations to SSA form (registers) for you.

Thus, if you have code like this:

  X = A + B;

You should generate code that looks like this:

  %X = alloca int
  ...

  %tmp1 = load int* %A
  %tmp2 = load int* %B
  %tmp3 = add int %tmp1, %tmp2
  store int %tmp3, int* %X

Note that this is really ugly, but is usually all eliminated by the
optimizers, and makes the front-end much easier to handle. :slight_smile:

-Chris