[LLVMdev] Not allowed to reuse variables?

Misha Brukman brukman at uiuc.edu
Wed May 5 10:03:01 PDT 2004

On Wed, May 05, 2004 at 03:35:46PM +0200, Anders Alexandersson wrote:
> %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?

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

  %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)

what you get is:

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

    %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

    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.

Misha Brukman :: http://misha.brukman.net :: http://llvm.cs.uiuc.edu

More information about the llvm-dev mailing list