Index: lib/CodeGen/CodeGeneration.cpp =================================================================== --- lib/CodeGen/CodeGeneration.cpp +++ lib/CodeGen/CodeGeneration.cpp @@ -92,6 +92,65 @@ return true; } + // createExitingBlockForExitNodePHIs - create a dedicated block for exit node + // PHIs. + // This special block is mode the exiting block so the PHIs become included + // into the region. + // The exit block keeps its identity. + BasicBlock *createExitingBlockForExitNodePHIs(Region *R) { + BasicBlock *ExitBB = R->getExit(); + + SmallVector NonPreds; + for (BasicBlock *P : make_range(pred_begin(ExitBB), pred_end(ExitBB))) + if (!R->contains(P)) + NonPreds.push_back(P); + + /* Preds[0] Preds[1] otherBB */ + /* \ | ________/ */ + /* \ | / */ + /* ExitBB */ + BasicBlock *NewExitBlock = splitBlockNonPredecessors( + ExitBB, NonPreds, ".exit", DT, LI, /*RI,*/ SE); + /* Preds[0] Preds[1] otherBB */ + /* \ / / */ + /* ExitBB / */ + /* \ / */ + /* NewExitBlock */ + + // If there was a region with ExitBB as entry block, change it to + // NewExitBlock + Region *RegionOfExit = RI->getRegionFor(ExitBB); + RI->setRegionFor(NewExitBlock, RegionOfExit); + while (RegionOfExit && !RegionOfExit->isTopLevelRegion() && + RegionOfExit->getEntry() == ExitBB) { + RegionOfExit->replaceEntry(NewExitBlock); + RegionOfExit = RegionOfExit->getParent(); + } + RI->setRegionFor(ExitBB, RegionOfExit); + + // Make NewExitBlock the new exit block + for (BasicBlock *PotentialExiting : + make_range(pred_begin(ExitBB), pred_end(ExitBB))) { + assert(PotentialExiting != NewExitBlock); + Region *OtherR = RI->getRegionFor(PotentialExiting); + while (OtherR && !OtherR->isTopLevelRegion() && + OtherR->getExit() == ExitBB) { + // Do not change exit nodes of subregions as they can keep ExitBB as + // their exit block + if (R == OtherR || !R->contains(OtherR)) { + OtherR->replaceExit(NewExitBlock); + } + OtherR = OtherR->getParent(); + } + } + assert(R->contains(ExitBB)); + assert(!R->contains(NewExitBlock)); + assert(R->getExit() == NewExitBlock); + RI->setRegionFor(ExitBB, R); + + return ExitBB; // The block containing the PHIs + } + // CodeGeneration adds a lot of BBs without updating the RegionInfo // We make all created BBs belong to the scop's parent region without any // nested structure to keep the RegionInfo verifier happy. @@ -125,6 +184,7 @@ Region *R = &S.getRegion(); assert(!R->isTopLevelRegion()); + createExitingBlockForExitNodePHIs(R); simplifyRegion(R, this); assert(R->isSimple()); Index: test/Isl/CodeGen/loop_with_conditional_entry_edge_splitted_hard_case.ll =================================================================== --- test/Isl/CodeGen/loop_with_conditional_entry_edge_splitted_hard_case.ll +++ test/Isl/CodeGen/loop_with_conditional_entry_edge_splitted_hard_case.ll @@ -19,10 +19,10 @@ entry: br label %while.begin -; CHECK-LABEL: while.begin.region_exiting: -; CHECK: br label %polly.merge_new_and_old - ; CHECK-LABEL: while.begin: +; CHECK: br label %polly.merge_new_and_old + +; CHECK-LABEL: while.begin.exit: while.begin: ; CHECK: %call = call i32 @f() %call = call i32 @f() Index: test/Isl/CodeGen/phi_loop_carried_float.ll =================================================================== --- test/Isl/CodeGen/phi_loop_carried_float.ll +++ test/Isl/CodeGen/phi_loop_carried_float.ll @@ -12,10 +12,13 @@ ; CHECK-NOT: %tmp7{{[.*]}} = alloca float ; CHECK-DAG: %tmp.0.phiops = alloca float ; CHECK-NOT: %tmp7{{[.*]}} = alloca float +; +; CHECK-LABEL: polly.merge_new_and_old: +; CHECK-NEXT: br label %exit.exit -; CHECK-LABEL: exit: +; CHECK-LABEL: exit.exit: ; CHECK-NEXT: ret - +; ; CHECK-LABEL: polly.start: ; CHECK-NEXT: store float 0.000000e+00, float* %tmp.0.phiops Index: test/Isl/CodeGen/phi_loop_carried_float_escape.ll =================================================================== --- test/Isl/CodeGen/phi_loop_carried_float_escape.ll +++ test/Isl/CodeGen/phi_loop_carried_float_escape.ll @@ -8,8 +8,11 @@ ; } ; CHECK-LABEL: polly.merge_new_and_old: -; CHECK-NEXT: %tmp.0.merge = phi float [ %tmp.0.final_reload, %polly.merge ], [ %tmp.0, %bb8 ] -; CHECK-NEXT: br label %exit +; CHECK-NEXT: %tmp.0.merge = phi float [ %tmp.0.final_reload, %polly.merge ], [ %tmp.0, %exit ] +; CHECK-NEXT: br label %exit.exit + +; CHECK-LABEL: exit.exit: +; CHECK-NEXT: ret float %tmp.0.merge ; CHECK-LABEL: polly.start: ; CHECK-NEXT: store float 0.000000e+00, float* %tmp.0.phiops Index: test/Isl/CodeGen/phi_scalar_simple_1.ll =================================================================== --- test/Isl/CodeGen/phi_scalar_simple_1.ll +++ test/Isl/CodeGen/phi_scalar_simple_1.ll @@ -22,7 +22,7 @@ br label %for.cond ; CHECK-LABEL: polly.merge_new_and_old: -; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge ], [ %x.addr.0, %for.cond ] +; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge ], [ %x.addr.0, %for.end6 ] ; CHECK: ret i32 %x.addr.0.merge ; CHECK-LABEL: polly.start: Index: test/Isl/CodeGen/phi_scalar_simple_2.ll =================================================================== --- test/Isl/CodeGen/phi_scalar_simple_2.ll +++ test/Isl/CodeGen/phi_scalar_simple_2.ll @@ -24,7 +24,7 @@ br label %for.cond ; CHECK-LABEL: polly.merge_new_and_old: -; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge ], [ %x.addr.0, %for.cond ] +; CHECK: %x.addr.0.merge = phi i32 [ %x.addr.0.final_reload, %polly.merge ], [ %x.addr.0, %for.end7 ] ; CHECK: ret i32 %x.addr.0.merge ; CHECK-LABEL: polly.start: