[LLVMdev] Question about boolean type variable generation of Global Variable Optimization

JinGu Kang jingu at codeplay.com
Mon Aug 26 07:46:45 PDT 2013


Hi all,

I have tested a simple example with '-Ox' optimization options and saw 
transformation from specific global variable to boolean variable. I 
would like to know what kind of advantages come from this .

The simplified example is as following:

Source code:
  static unsigned int g_3461 = 0xffffffff;

  unsigned int test(unsigned int a) {
    printf("g_3461=%d\n", g_3461);
    g_3461 = 0;
    return a;
  }

  int main(void) {
    int d;
    scanf("%d\n", &d);
    if (g_3461 + d) {
      test(g_3461);
      return 0;
    }
    else
      return 1;
  }

Global Variable Optimizer changes 'g_3461' variable to boolean type and 
its initializer becomes 'false' because this value is store once on 
'test' function and it means that this variable has only two value. The 
users of this also are changed. The comment of code says that this 
exposes the values to other scalar optimizations.
The generated IR is as follows:

Generated IR:
@g_3461 = internal unnamed_addr global i1 false

define i32 @test(i32 %a) #0 {
entry:
   %.b = load i1* @g_3461
~~~~~~~~~~~~~~~~~~~~~~
   %0 = select i1 %.b, i32 0, i32 -1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 
x i8]* @.str, i32 0, i32 0), i32 %0)
   store i1 true, i1* @g_3461
   ret i32 %a
}

define i32 @main() #0 {
entry:
   %d = alloca i32, align 4
   %call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([4 x 
i8]* @.str1, i32 0, i32 0), i32* %d)
   %.b = load i1* @g_3461
~~~~~~~~~~~~~~~~~~~~~~~
   %0 = select i1 %.b, i32 0, i32 -1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   %1 = load i32* %d, align 4, !tbaa !0
   %add = add i32 %0, %1
   %tobool = icmp ne i32 %add, 0
   br i1 %tobool, label %if.then, label %if.else

if.then:                                          ; preds = %entry
   %call1 = call i32 @test(i32 %0)
   br label %return

if.else:                                          ; preds = %entry
   br label %return

return:                                           ; preds = %if.else, 
%if.then
   %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ]
   ret i32 %retval.0
}

The 'load' instruction is changed and 'select' instruction is inserted.  
After Combine redundant instructions, code is transformed like this.

After Combine redundant instructions:
define i32 @test(i32 %a) #0 {
entry:
   %.b = load i1* @g_3461, align 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   %not..b = xor i1 %.b, true
~~~~~~~~~~~~~~~~~~~~~~~~
   %0 = sext i1 %not..b to i32
~~~~~~~~~~~~~~~~~~~~~~~~~
   %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 
x i8]* @.str, i32 0, i32 0), i32 %0) #2
   store i1 true, i1* @g_3461, align 1
   ret i32 %a
}

define i32 @main() #0 {
entry:
   %d = alloca i32, align 4
   %call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([4 x 
i8]* @.str1, i32 0, i32 0), i32* %d) #2
   %.b = load i1* @g_3461, align 1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   %not..b = xor i1 %.b, true
~~~~~~~~~~~~~~~~~~~~~~~~
   %0 = sext i1 %not..b to i32
~~~~~~~~~~~~~~~~~~~~~~~~~
   %1 = load i32* %d, align 4, !tbaa !0
   %add = sub i32 0, %1
   %tobool = icmp eq i32 %0, %add
   br i1 %tobool, label %if.else, label %if.then

if.then:                                          ; preds = %entry
   %call1 = call i32 @test(i32 %0)
   br label %return

if.else:                                          ; preds = %entry
   br label %return

return:                                           ; preds = %if.else, 
%if.then
   %retval.0 = phi i32 [ 0, %if.then ], [ 1, %if.else ]
   ret i32 %retval.0
}

The 'select' instruction is changed to 'xor' instruction and 'sext' 
instruction. Finally, code generator uses above IR code to make machine 
level code and generates more instruction or pattern, such as 
'sign_extend_inreg',  in order to process 'i1' type value . Could 
someone let me know which cases get advantages from this transformation? 
I think this transformation generates a little bit redundant 
instructions than without this.

Thanks,
JinGu Kang

-- 
JinGu Kang
Codeplay Software Ltd
45 York Place, Edinburgh, EH1 3HP
Tel: 0131 466 0503
Fax: 0131 557 6600
Website: http://www.codeplay.com
Twitter: https://twitter.com/codeplaysoft

This email and any attachments may contain confidential and /or privileged information and is for use by the addressee only. If you are not the intended recipient, please notify Codeplay Software Ltd immediately and delete the message from your computer. You may not copy or forward it,or use or disclose its contents to any other person. Any views or other information in this message which do not relate to our business are not authorized by Codeplay software Ltd, nor does this message form part of any contract unless so stated.
As internet communications are capable of data corruption Codeplay Software Ltd does not accept any responsibility for any changes made to this message after it was sent. Please note that Codeplay Software Ltd does not accept any liability or responsibility for viruses and it is your responsibility to scan any attachments.
Company registered in England and Wales, number: 04567874
Registered office: 81 Linkfield Street, Redhill RH1 6BY




More information about the llvm-dev mailing list