19
19
using namespace swift ;
20
20
using namespace Lowering ;
21
21
22
- void Condition::enterTrue (SILGenFunction &SGF) {
23
- assert (TrueBB && " Cannot call enterTrue without a True block!" );
24
-
25
- // TrueBB has already been inserted somewhere unless there's a
26
- // continuation block.
27
- if (!ContBB) return ;
28
-
29
- SGF.B .emitBlock (TrueBB);
22
+ void Condition::enter (SILGenFunction &SGF, SILBasicBlock *destBB) {
23
+ assert (destBB && " Cannot reenter a finished block." );
24
+ SGF.B .emitBlock (destBB);
30
25
}
31
26
32
27
// / Extract the last SILLocation used in BB.
@@ -36,110 +31,24 @@ static SILLocation getContinuationLoc(SILBasicBlock &BB, SILLocation Fallback) {
36
31
return L;
37
32
return Fallback;
38
33
}
39
- void Condition::exitTrue (SILGenFunction &SGF, ArrayRef<SILValue> Args) {
40
- // If there's no continuation block, it's because the condition was
41
- // folded to true. In that case, we just continue emitting code as
42
- // if we were still in the true case, and we're unreachable iff the
43
- // end of the true case is unreachable. In other words, there's
44
- // nothing to do.
45
- if (!ContBB) {
46
- assert (!FalseBB && " no continuation" );
47
- return ;
48
- }
49
-
50
- // If there is a continuation block, we should branch to it if the
51
- // current point is reachable.
52
- if (!SGF.B .hasValidInsertionPoint ()) {
53
- // If there is no false code, the continuation block has a use
54
- // because the main condition jumps directly to it.
55
- assert (ContBB->pred_empty () || !FalseBB);
34
+ void Condition::exit (SILGenFunction &SGF, SILBasicBlock *destBB,
35
+ ArrayRef<SILValue> Args) {
36
+ // If the current point it reachable, branch to the continuation block.
37
+ if (!SGF.B .hasValidInsertionPoint ())
56
38
return ;
57
- }
58
39
59
- // Otherwise, resume into the continuation block. This branch might
60
- // be folded by exitFalse if it turns out that that point is
61
- // unreachable.
62
40
SGF.B .createBranch (getContinuationLoc (*SGF.B .getInsertionBB (), Loc),
63
41
ContBB, Args);
64
-
65
- // Coming out of exitTrue, we can be in one of three states:
66
- // - a valid non-terminal IP, but only if there is no continuation
67
- // block, which is only possible if there is no false block;
68
- // - a valid terminal IP, if the end of the true block was reachable; or
69
- // - a cleared IP, if the end of the true block was not reachable.
70
- }
71
-
72
- void Condition::enterFalse (SILGenFunction &SGF) {
73
- assert (FalseBB && " entering the false branch when it was not valid" );
74
-
75
- // FalseBB has already been inserted somewhere unless there's a
76
- // continuation block.
77
- if (!ContBB) return ;
78
-
79
- // It's possible to have no insertion point here if the end of the
80
- // true case was unreachable.
81
- SGF.B .emitBlock (FalseBB);
82
- }
83
-
84
- void Condition::exitFalse (SILGenFunction &SGF, ArrayRef<SILValue> Args) {
85
- // If there's no continuation block, it's because the condition was
86
- // folded to false. In that case, we just continue emitting code as
87
- // if we were still in the false case, and we're unreachable iff the
88
- // end of the false case is unreachable. In other words, there's
89
- // nothing to do.
90
- if (!ContBB) return ;
91
-
92
- if (ContBB->pred_empty ()) {
93
- // If the true case didn't need the continuation block, then
94
- // we don't either, regardless of whether the current location
95
- // is reachable. Just keep inserting / being unreachable
96
- // right where we are.
97
- } else if (!SGF.B .hasValidInsertionPoint ()) {
98
- // If the true case did need the continuation block, but the false
99
- // case doesn't, just merge the continuation block back into its
100
- // single predecessor and move the IP there.
101
- //
102
- // Note that doing this tends to strand the false code after
103
- // everything else in the function, so maybe it's not a great idea.
104
- auto PI = ContBB->pred_begin ();
105
- SILBasicBlock *ContPred = *PI;
106
-
107
- // Verify there was only a single predecessor to ContBB.
108
- ++PI;
109
- assert (PI == ContBB->pred_end () && " Only expect one branch to the ContBB" );
110
-
111
- // Insert before the uncond branch and zap it.
112
- auto *Br = cast<BranchInst>(ContPred->getTerminator ());
113
- SGF.B .setInsertionPoint (Br->getParent ());
114
-
115
- Br->eraseFromParent ();
116
- assert (ContBB->pred_empty () &&
117
- " Zapping the branch should make ContBB dead" );
118
- } else {
119
- // Otherwise, branch to the continuation block and start inserting there.
120
- SGF.B .createBranch (getContinuationLoc (*SGF.B .getInsertionBB (), Loc),
121
- ContBB, Args);
122
- }
123
42
}
124
43
125
44
SILBasicBlock *Condition::complete (SILGenFunction &SGF) {
126
- // If there is no continuation block, it's because we
127
- // constant-folded the branch. The case-exit will have left us in a
128
- // normal insertion state (i.e. not a post-terminator IP) with
129
- // nothing to clean up after.
130
- if (!ContBB) {
131
- return SGF. B . getInsertionBB () ;
45
+ assert (!TrueBB && " enterTrue is always called. " );
46
+ if (FalseBB) {
47
+ assert (ContBB-> getNumArguments () == 0 &&
48
+ " block arguments require a non-empty false path. " );
49
+ SILGenBuilder (SGF. B , FalseBB). createBranch (Loc, ContBB);
50
+ FalseBB = nullptr ;
132
51
}
133
-
134
- // Kill the continuation block if it's not being used. Case-exits
135
- // only leave themselves post-terminator if they use the
136
- // continuation block, so we're in an acceptable insertion state.
137
- if (ContBB->pred_empty () && ContBB->args_empty ()) {
138
- SGF.eraseBasicBlock (ContBB);
139
- return SGF.B .hasValidInsertionPoint () ? SGF.B .getInsertionBB () : nullptr ;
140
- }
141
-
142
- // Okay, we need to insert the continuation block.
143
52
SGF.B .emitBlock (ContBB);
144
53
return ContBB;
145
54
}
0 commit comments