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