This patch adds checking of code-motion safety before hoisting, Loop rotate considers moving memory instructions as unsafe we used CodeMoverUtils to check code-motion safety of memory instructions and included other pass independent checks, It hoists more memory instructions resulting in less duplication.
LoopRotate:
define void @test(i32 %n, i32* %A) { %cond1 = icmp slt i32 0, %n %0 = load i32, i32* %A %1 = add nsw i32 %0, 5 br i1 %cond1, label %body.lr.ph, label %exit body.lr.ph: ; preds = %entry br label %body body: ; preds = %body.lr.ph, %latch %i2 = phi i32 [ 0, %body.lr.ph ], [ %i.next, %latch ] br label %latch latch: ; preds = %body %i.next = add nsw i32 %i2, 1 %cond = icmp slt i32 %i.next, %n %2 = load i32, i32* %A %3 = add nsw i32 %2, 5 br i1 %cond, label %body, label %for.header.exit_crit_edge for.header.exit_crit_edge: ; preds = %latch br label %exit exit: ; preds = %for.header.exit_crit_edge, %entry ret void }
CodeMoverUtils:
define void @test(i32 %n, i32* %A) { entry: %cond1 = icmp slt i32 0, %n %0 = load i32, i32* %A, align 4 %1 = add nsw i32 %0, 5 br i1 %cond1, label %body.lr.ph, label %exit body.lr.ph: ; preds = %entry br label %body body: ; preds = %body.lr.ph, %latch %i2 = phi i32 [ 0, %body.lr.ph ], [ %i.next, %latch ] br label %latch latch: ; preds = %body %i.next = add nsw i32 %i2, 1 %cond = icmp slt i32 %i.next, %n br i1 %cond, label %body, label %for.header.exit_crit_edge for.header.exit_crit_edge: ; preds = %latch br label %exit exit: ; preds = %for.header.exit_crit_edge, %entry ret void }
This shows more hoisting of instructions and less duplication after using code-motion checks before hoisting.
PS: Some test case are failing. I'm working to fix them.
This makes it easy to misuse the interface. If someone forgets to pass PDT, we skip checking for control flow equivalence and may return "safe" when it's not the case. I think we should pass a separate boolean to make the user explicitly state whether they care about control-flow equivalence or not.