Friday, 18 November 2016

IR simple example and meaning

Source code:
int a, b;
int fn1() {
  char c;
  if (b)
    return 1;
  c = fn1 == a;
  return c;
}
~

Corresponding IR:

; ModuleID = 'utf8.i'
source_filename = "utf8.i"
target datalayout = "e-m:e-i64:64-n32:64"
target triple = "powerpc64le-unknown-linux-gnu"

 ---> Every global variable begins with @
@b = common local_unnamed_addr global i32 0, align 4  
@a = common local_unnamed_addr global i32 0, align 4

---> clang IR use ';' (semi colon) as comments symbol.
; Function Attrs: norecurse nounwind readonly
define signext i32 @fn1() #0 {  ---> Global function fn1
entry:        ---> label entry, which denotes a start of a block.
 
  %0 = load i32, i32* @b, align 4, !tbaa !1   --> every local variable begins with %
 Here the first i32, means the type of load, it loads as i32, the second i32* @b, means
it loads the value from global variable b, with alignment 4 bytes.


  %tobool = icmp eq i32 %0, 0   ---> compare the result i32 %0 (temp variable) from 
last step with 0 and assign the compared bool result to a temp variable named %tobool.
 The above code correspond to the user code if (b)
 
  br i1 %tobool, label %if.end, label %cleanup
---> branch  according to one bit type (i1) variable %tobool value, if true goto %if.end, else goto label%cleanup.

---> The start of if.end block (label name is if.end)
if.end:                                           ; preds = %entry
  %1 = load i32, i32* @a, align 4, !tbaa !1 ---> Load global variable a to a temp variable %1, i32 type, usually this is put on a virtual register, you can consider %1 as r1.

  %conv = sext i32 %1 to i64   ---> sign extend %1 from i32 to i64 and save it to %conv
  %2 = inttoptr i64 %conv to i32 (...)*            ---> convert int to pointer from last step to i32(...) * 
 , i.e., to a function pointer, save the converted result    to %2
 
  %cmp = icmp eq i32 (...)* %2, bitcast (i32 ()* @fn1 to i32 (...)*)  ---> compare equal, function pointer converted from last step: i32 (...)* %2 with bitcast (i32 ()* @fn1 to i32 (...)*), this corresponds to the fn==a in the user source code

  %conv3 = zext i1 %cmp to i32 --> zero extend bit 1 variable %cmp to i32, i.e. convert bool to int
  br label %cleanup ---> branch to label %cleanup to do some clean up work before exit.  Here %conv3 corresponds to variable c

cleanup:                                          ; preds = %entry, %if.end  ---> some preceding labels
  %retval.0 = phi i32 [ %conv3, %if.end ], [ 1, %entry ] 
  ret i32 %retval.0
the return (ret) value is a phi node (a function of the temp variable %conv3 in block %if.end and the constant value 1 in block %entry. This corresponds to return 1; return c
}

No comments:

Post a Comment