hello!
I am writing a pass for LLVM generated by Rust. Basically, I am trying to identify the body of a loop. With clang, it is easy because the basic blocks are labeled (for.cond, for.body, for.inc etc) however rust names basic blocks by numbers. My initial thought was to get the header block with loopinfo and assume that the successor block is the body. However, there can be multiple blocks belonging to the body as well as the header it seems. An example:
let mut arr: [i32; 5] = [1, 2, 3, 4, 5];
for i in 0..arr.len() {
...
}
and the section of the IR:
bb3: ; preds = %bb9, %bb2
%22 = call { i64, i64 } @"_ZN4core4iter5range93_$LT$impl$u20$core..iter..iterator..Iterator$u20$for$u20$core..ops..range..Range$LT$A$GT$$GT$4next17h08af673f70db9933E"({ i64, i64 }* dereferenceable(16) %iter)
store { i64, i64 } %22, { i64, i64 }* %_17, align 8
br label %bb4
bb4: ; preds = %bb3
%23 = bitcast { i64, i64 }* %_17 to i64*
%24 = load i64, i64* %23, align 8
%25 = bitcast { i64, i64 }* %_17 to i64*
%26 = load i64, i64* %25, align 8
switch i64 %26, label %bb6 [
i64 0, label %bb5
i64 1, label %bb7
]
Loopinfo tells me, bb3 is the header and this is what the latch jumps back to. In my understanding this is also the block which is equivalent to the for.inc block where the iterator gets updated to the next value. Then bb4 would be the for.cond block deciding whether to enter the body or the exit block.
So can I then assume bb5 is the body? what if there is a situation where there is another header block before bb4. a custom front end could break up the basic blocks in the header an it would still be correct but my assumption that the 3rd block in the loop is the body would be wrong. Is it even true to say bb3 and bb4 both belong to the header?
thanks!