Reputation: 3454
In LLVM IR, phi nodes are a key component of SSA (Static Single Assignment) form and are used to represent control flow in a program. As far as I know the mem2reg
optimization pass in LLVM is used to convert memory accesses into SSA form by introducing phi nodes.
However when I'm trying to compile the simple app.c
program:
#include <stdio.h>
int main(){
int x = 1;
if(x > 2){
x++;
}else{
x--;
}
printf("%d", x);
}
by running the next commands:
clang -S -emit-llvm -O -Xclang -disable-llvm-passes app.c
opt -S -mem2reg -o opt.ll app.ll
I get the next results.
app.ll
:
define i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, ptr %1, align 4
call void @llvm.lifetime.start.p0(i64 4, ptr %2) #3
store i32 1, ptr %2, align 4, !tbaa !5
%3 = load i32, ptr %2, align 4, !tbaa !5
%4 = icmp sgt i32 %3, 2
br i1 %4, label %5, label %8
5: ; preds = %0
%6 = load i32, ptr %2, align 4, !tbaa !5
%7 = add nsw i32 %6, 1
store i32 %7, ptr %2, align 4, !tbaa !5
br label %11
8: ; preds = %0
%9 = load i32, ptr %2, align 4, !tbaa !5
%10 = add nsw i32 %9, -1
store i32 %10, ptr %2, align 4, !tbaa !5
br label %11
11: ; preds = %8, %5
%12 = load i32, ptr %2, align 4, !tbaa !5
%13 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %12)
call void @llvm.lifetime.end.p0(i64 4, ptr %2) #3
%14 = load i32, ptr %1, align 4
ret i32 %14
}
As you can see, here is no phi nodes and I'm not sure that we can call it SSA form.
After applying mem2reg
optimization (opt.ll
):
define i32 @main() #0 {
%1 = icmp sgt i32 1, 2
br i1 %1, label %2, label %4
2: ; preds = %0
%3 = add nsw i32 1, 1
br label %6
4: ; preds = %0
%5 = add nsw i32 1, -1
br label %6
6: ; preds = %4, %2
%.0 = phi i32 [ %3, %2 ], [ %5, %4 ]
%7 = call i32 (ptr, ...) @printf(ptr noundef @.str, i32 noundef %.0)
ret i32 0
}
and it looks like a SSA form.
Do phi nodes already exist in LLVM IR before the mem2reg
optimization pass is applied? Or are they only introduced by the mem2reg
pass as part of the process of converting memory accesses to SSA form?
I would appreciate any insights or clarifications on this topic. Thank you!
Upvotes: 1
Views: 300
Reputation: 2393
Yes. Phi nodes are generated earlier in CodeGen as part of the AST to IR conversion. This factors the language specific complexities of handling intrinsics, OpenMP, … out of LLVM's language agnostic mem2reg.
You can see examples of this in lib/CodeGen/CGBuiltin.cpp and also in clang/test/CodeGen/ms-intrinsics.c.
Upvotes: 1