[polly] r246441 - Always use the branch instructions to model the PHI-node writes

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 31 07:06:23 PDT 2015


On 08/31/2015 03:44 PM, Johannes Doerfert via llvm-commits wrote:
> I don't believe this change was necessary because we have this part:
>
>      Instruction *OpI = dyn_cast<Instruction>(Op);
>      if (OpI) {
>        BasicBlock *OpIBB = OpI->getParent();
>        // As we pretend there is a use (or more precise a write) of OpI in OpBB
>        // we have to insert a scalar dependence from the definition of OpI to
>        // OpBB if the definition is not in OpBB.
>        if (OpIBB != OpBB) {
>          IRAccess ScalarRead(IRAccess::READ, OpI, ZeroOffset, 1, true, OpI);
>          AccFuncMap[OpBB].push_back(std::make_pair(ScalarRead, PHI));
>          IRAccess ScalarWrite(IRAccess::MUST_WRITE, OpI, ZeroOffset, 1, true,
>                                OpI);
>          AccFuncMap[OpIBB].push_back(std::make_pair(ScalarWrite, OpI));
>        }
>      }
>
> Please tell me where I am mistaken?

Input
=====
loop:
   %indvar = phi i64 [0, %entry], [%indvar.next, %backedge]
   %val0 = fadd float 1.0, 2.0
   %val1 = fadd float 1.0, 2.0
   %val2 = fadd float 1.0, 2.0
   br i1 %cond0, label %branch1, label %backedge

branch1:
   br i1 %cond1, label %branch2, label %backedge

branch2:
   br label %backedge

backedge:
   %merge = phi float [%val0, %loop], [%val1, %branch1], [%val2, %branch2]


Before the change
=================

polly.stmt.loop:                                  ; preds = %polly.stmt.loop.entry
   %polly.subregion.iv = phi i32 [ 0, %polly.stmt.loop.entry ]
   %p_val0 = fadd float 1.000000e+00, 2.000000e+00
   %p_val1 = fadd float 1.000000e+00, 2.000000e+00
   %p_val2 = fadd float 1.000000e+00, 2.000000e+00
   store float %p_val0, float* %merge.phiops
   store float %p_val1, float* %val1.s2a
   store float %p_val2, float* %val2.s2a
   store float %p_val1, float* %merge.phiops
   store float %p_val2, float* %merge.phiops
   %polly.subregion.iv.inc = add i32 %polly.subregion.iv, 1
   br i1 %cond0, label %polly.stmt.branch1, label %polly.stmt.backedge.exit

polly.stmt.branch1:                               ; preds = %polly.stmt.loop
   br i1 %cond1, label %polly.stmt.branch2, label %polly.stmt.backedge.exit

polly.stmt.branch2:                               ; preds = %polly.stmt.branch1
   br label %polly.stmt.backedge.exit

polly.stmt.backedge.exit:                         ; preds = %polly.stmt.branch2, %polly.stmt.branch1, %polly.stmt.loop
   br label %polly.stmt.backedge

polly.stmt.backedge:                              ; preds = %polly.stmt.backedge.exit
   %merge.phiops.reload = load float, float* %merge.phiops


After the change
================

polly.stmt.loop:                                  ; preds = %polly.stmt.loop.entry
   %polly.subregion.iv = phi i32 [ 0, %polly.stmt.loop.entry ]
   %p_val0 = fadd float 1.000000e+00, 2.000000e+00
   %p_val1 = fadd float 1.000000e+00, 2.000000e+00
   %p_val2 = fadd float 1.000000e+00, 2.000000e+00
   store float %p_val0, float* %merge.phiops
   store float %p_val1, float* %val1.s2a
   store float %p_val2, float* %val2.s2a
   %polly.subregion.iv.inc = add i32 %polly.subregion.iv, 1
   br i1 %cond0, label %polly.stmt.branch1, label %polly.stmt.backedge.exit

polly.stmt.branch1:                               ; preds = %polly.stmt.loop
   store float %p_val1, float* %merge.phiops
   br i1 %cond1, label %polly.stmt.branch2, label %polly.stmt.backedge.exit

polly.stmt.branch2:                               ; preds = %polly.stmt.branch1
   store float %p_val2, float* %merge.phiops
   br label %polly.stmt.backedge.exit

polly.stmt.backedge.exit:                         ; preds = %polly.stmt.branch2, %polly.stmt.branch1, %polly.stmt.loop
   br label %polly.stmt.backedge

polly.stmt.backedge:                              ; preds = %polly.stmt.backedge.exit
   %merge.phiops.reload = load float, float* %merge.phiops


Before the change, all writes to %merge.phiops have been placed in polly.stmt.loop.
As a result, the last write - in this case 'store float %p_val2, float* %merge.phiops' -
defines the value read by the PHI node independently of any control flow decisions.
After the change, the writes happen in the basic-blocks through which the backedge
block is reached and depending on which control flow is taken, different values will
be written in our phi location.

Best,
Tobias


More information about the llvm-commits mailing list