Skip to content

Commit 3fb0e2e

Browse files
committed
Update comments and tests for better readability.
1 parent 4741ba2 commit 3fb0e2e

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

lib/SILOptimizer/Mandatory/TFCanonicalizeCFG.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,13 @@ class BasicBlockCloner : public SILClonerWithScopes<BasicBlockCloner> {
420420
"times during SESE cloning.");
421421
}
422422

423-
/// Clone the body of `loop` starting from `startBlock` and nest the cloned
424-
/// fragment into the parent loop. If `startBlock` is the same as the header
425-
/// of `loop`, we clone the entire loop including the back edge. Otherwise,
426-
/// we clone one iteration of the loop body without the back edge.
427-
SILLoop *cloneLoop(SILLoopInfo *LI, SILLoop *loop, SILBasicBlock *startBlock) {
423+
/// Utility to unroll one iteration of the loop or to clone the entire loop.
424+
/// - If `startBlock` is the same as the header of `loop`, we clone the
425+
/// entire loop including the back edge.
426+
/// - Otherwise, we unroll one iteration of the loop body starting from
427+
/// `startBlock' to the latch.
428+
/// The unrolled or cloned version is nested into the parent loop.
429+
SILLoop *cloneOrUnrollLoop(SILLoopInfo *LI, SILLoop *loop, SILBasicBlock *startBlock) {
428430
llvm::DenseMap<SILLoop*, SILLoop*> loopClones;
429431
// This is for convenience as top-level loops have nullptr for parent loop.
430432
loopClones[nullptr] = nullptr;
@@ -515,6 +517,8 @@ class BasicBlockCloner : public SILClonerWithScopes<BasicBlockCloner> {
515517
// A helper class to transform a loop to have a single exit from the header.
516518
class SingleExitLoopTransformer {
517519
public:
520+
// Convert the given loop into a SESE form. Returns false if the loop was
521+
// already in SESE form. Otherwise, returns true.
518522
static bool doIt(GraphFunctionDeviceInfo *deviceInfo, SILLoopInfo *LI,
519523
DominanceInfo *DI, SILLoop *loop, PostDominanceInfo *PDI) {
520524
SingleExitLoopTransformer transformer(deviceInfo, LI, DI, loop, PDI);
@@ -528,7 +532,7 @@ class SingleExitLoopTransformer {
528532
#ifndef NDEBUG
529533
{
530534
// Verify that the loop is OK after all the transformations.
531-
llvm::DenseSet<const SILLoop*> nestedLoops;
535+
llvm::DenseSet<const SILLoop *> nestedLoops;
532536
loop->verifyLoopNest(&nestedLoops);
533537
}
534538
#endif
@@ -742,9 +746,9 @@ void SingleExitLoopTransformer::ensureSingleExitBlock() {
742746
// break;
743747
// }
744748
// }
749+
// The unrelated loops are those that are not contained within each other.
745750
SmallPtrSet<SILBasicBlock *, 32> unrelatedPreheaders;
746751
for (auto *otherLoop : *LI) {
747-
// If loop and otherLoop are not nested into either, remember the preheader.
748752
if (!otherLoop->contains(loop) && !loop->contains(otherLoop)) {
749753
unrelatedPreheaders.insert(otherLoop->getLoopPreheader());
750754
}
@@ -808,8 +812,8 @@ void SingleExitLoopTransformer::ensureSingleExitBlock() {
808812
// If `succ` is a preheader of an unrelated loop, we will have to clone
809813
// the entire loop now so that we can also incrementally update LoopInfo.
810814
if (succBlockLoop) {
811-
SILLoop *clonedLoop =
812-
cloner.cloneLoop(LI, succBlockLoop, succBlockLoop->getHeader());
815+
SILLoop *clonedLoop = cloner.cloneOrUnrollLoop(
816+
LI, succBlockLoop, succBlockLoop->getHeader());
813817
changeBranchTarget(clonedSucc->getTerminator(), 0,
814818
clonedLoop->getHeader(), /*preserveArgs*/ true);
815819
// Note that all the nodes of `clonedLoop` should be moved into the
@@ -1501,7 +1505,7 @@ void SingleExitLoopTransformer::unrollLoopBodyOnce() {
15011505
}
15021506

15031507
// Clone everything starting from the old header.
1504-
cloner.cloneLoop(LI, loop, header);
1508+
cloner.cloneOrUnrollLoop(LI, loop, header);
15051509

15061510
// Get the clone for old header.
15071511
SILBasicBlock *clonedOldHeader = cloner.remapBasicBlock(header);

test/TensorFlow/sese_loop_canonicalization.sil

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -294,17 +294,17 @@ bb3 (%9 : $Builtin.Int32):
294294
// }
295295
// The CFG is shown below:
296296
//
297-
// [0]-----+
297+
// [0]-------+
298298
// | \
299299
// [1] [2]
300-
// | |
301-
// | +--- [4]
302-
// | | / \
303-
// | | [6] [5]
304-
// | +/ \ |
305-
// [3]----[8] |
306-
// | |
307-
// +-->[9]<------+
300+
// | |
301+
// | +--->[4]
302+
// | [7] / \
303+
// | | [6] [5]
304+
// V +-+ \ |
305+
// [3]<-----[8] |
306+
// | |
307+
// +-->[9]<-----+
308308
//
309309
// This is an example where the nodes that lead to the common post dominator of all exit nodes
310310
// is also reachable from nodes outside of the loop. The key issue is that bb9 is the common
@@ -380,8 +380,20 @@ bb9(%18 : $Builtin.Int32):
380380
// reachable from nodes outside of the loop. The only difference in this example
381381
// is that some of these nodes also belong to a loop. Therefore, it is required
382382
// for us to update the LoopInfo in addition to cloning. The loop in question
383-
// consists of the single node bb3.
384-
383+
// consists of the single node bb3. The CFG is shown below:
384+
//
385+
// [0]-------+
386+
// | \
387+
// [1] [2]
388+
// | |
389+
// | +--->[4]
390+
// | [7] / \
391+
// | | [6] [5]
392+
// V +--+ \ |
393+
// +-->[3]<-----[8] |
394+
// | / | |
395+
// + +-->[9]<-----+
396+
//
385397
// CHECK-LABEL:--- XLA CFG Loops Before Canonicalize: $loopThatRequiresNodeAndLoopCloning
386398
//----The following loop will be cloned in the second loop.
387399
// CHECK:Loop at depth 1 containing: {{bb[0-9]+}}<header><latch><exiting>

test/TensorFlow/sese_loop_canonicalization.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,21 @@
55

66
import TensorFlow
77

8-
//expected-warning @+1 {{value implicitly copied to the host}}
8+
// expected-warning @+1 {{value implicitly copied to the host}}
99
public func testLoopMovementFromOutside(_ breakIndex: Int32) -> Tensor<Int32> {
1010
var i: Int32 = 1
1111
var sum = Tensor<Int32>(0)
1212
let maxCount: Int32 = 100
13-
while i <= maxCount {
13+
while i <= maxCount { // expected-note {{value used here}}
1414
sum += i
15-
if (i == breakIndex) {
15+
if i == breakIndex {
1616
var k: Int32 = 0
17-
while (k < i) {
17+
while k < i {
1818
sum += i
1919
k += 1
2020
}
21+
// expected-warning @+1 {{value implicitly copied to the host}}
22+
sum += 1
2123
break // expected-note {{value used here}}
2224
}
2325
i += 1
@@ -27,10 +29,12 @@ public func testLoopMovementFromOutside(_ breakIndex: Int32) -> Tensor<Int32> {
2729

2830
// CHECK-LABEL: --- XLA CFG Loops Before Canonicalize: {{.*}}testLoopMovementFromOutside{{.*}}
2931
// CHECK: Loop at depth 1 containing: {{.*}}
32+
//--- The following loop is the inner while loop, but is unnested in the CFG due to the `break`
3033
// CHECK: Loop at depth 1 containing: {{.*}}
3134

3235
// CHECK-LABEL: --- XLA CFG Loops After Canonicalize: {{.*}}testLoopMovementFromOutside{{.*}}
3336
// CHECK: Loop at depth 1 containing: {{.*}}
37+
//--- The inner while loop gets nested into the outer while loop by SESE canonicalzation.
3438
// CHECK: Loop at depth 2 containing: {{.*}}
3539

3640
// CHECK: --- XLA CFG Canonicalize: {{.*}}testLoopMovementFromOutside{{.*}}

0 commit comments

Comments
 (0)