@@ -1144,62 +1144,18 @@ static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock,
1144
1144
using BBPredicates = DenseMap<BasicBlock *, PHINode *>;
1145
1145
using BBSetVector = SetVector<BasicBlock *>;
1146
1146
1147
- // Redirects the terminator of the incoming block to the first guard
1148
- // block in the hub. The condition of the original terminator (if it
1149
- // was conditional) and its original successors are returned as a
1150
- // tuple <condition, succ0, succ1>. The function additionally filters
1151
- // out successors that are not in the set of outgoing blocks.
1147
+ // Collect predicates for each outgoing block. If control reaches the
1148
+ // Hub from an incoming block InBB, then the predicate for each
1149
+ // outgoing block OutBB decides whether control is forwarded to OutBB.
1152
1150
//
1153
- // - condition is non-null iff the branch is conditional.
1154
- // - Succ1 is non-null iff the sole/taken target is an outgoing block.
1155
- // - Succ2 is non-null iff condition is non-null and the fallthrough
1156
- // target is an outgoing block.
1157
- static std::tuple<Value *, BasicBlock *, BasicBlock *>
1158
- redirectToHub (BasicBlock *BB, BasicBlock *FirstGuardBlock,
1159
- const BBSetVector &Outgoing) {
1160
- auto Branch = cast<BranchInst>(BB->getTerminator ());
1161
- auto Condition = Branch->isConditional () ? Branch->getCondition () : nullptr ;
1162
-
1163
- BasicBlock *Succ0 = Branch->getSuccessor (0 );
1164
- BasicBlock *Succ1 = nullptr ;
1165
- Succ0 = Outgoing.count (Succ0) ? Succ0 : nullptr ;
1166
-
1167
- if (Branch->isUnconditional ()) {
1168
- Branch->setSuccessor (0 , FirstGuardBlock);
1169
- assert (Succ0);
1170
- } else {
1171
- Succ1 = Branch->getSuccessor (1 );
1172
- Succ1 = Outgoing.count (Succ1) ? Succ1 : nullptr ;
1173
- assert (Succ0 || Succ1);
1174
- if (Succ0 && !Succ1) {
1175
- Branch->setSuccessor (0 , FirstGuardBlock);
1176
- } else if (Succ1 && !Succ0) {
1177
- Branch->setSuccessor (1 , FirstGuardBlock);
1178
- } else {
1179
- Branch->eraseFromParent ();
1180
- BranchInst::Create (FirstGuardBlock, BB);
1181
- }
1182
- }
1183
-
1184
- assert (Succ0 || Succ1);
1185
- return std::make_tuple (Condition, Succ0, Succ1);
1186
- }
1187
-
1188
- // Capture the existing control flow as guard predicates, and redirect
1189
- // control flow from every incoming block to the first guard block in
1190
- // the hub.
1191
- //
1192
- // There is one guard predicate for each outgoing block OutBB. The
1193
- // predicate is a PHINode with one input for each InBB which
1194
- // represents whether the hub should transfer control flow to OutBB if
1195
- // it arrived from InBB. These predicates are NOT ORTHOGONAL. The Hub
1196
- // evaluates them in the same order as the Outgoing set-vector, and
1197
- // control branches to the first outgoing block whose predicate
1198
- // evaluates to true.
1199
- static void convertToGuardPredicates (
1200
- BasicBlock *FirstGuardBlock, BBPredicates &GuardPredicates,
1201
- SmallVectorImpl<WeakVH> &DeletionCandidates, const BBSetVector &Incoming,
1202
- const BBSetVector &Outgoing) {
1151
+ // These predicates are not orthogonal. The Hub evaluates them in the
1152
+ // same order as the Outgoing set-vector, and control branches to the
1153
+ // first outgoing block whose predicate evaluates to true.
1154
+ static void createGuardPredicates (BasicBlock *FirstGuardBlock,
1155
+ BBPredicates &GuardPredicates,
1156
+ SmallVectorImpl<WeakVH> &DeletionCandidates,
1157
+ const BBSetVector &Incoming,
1158
+ const BBSetVector &Outgoing) {
1203
1159
auto &Context = Incoming.front ()->getContext ();
1204
1160
auto BoolTrue = ConstantInt::getTrue (Context);
1205
1161
auto BoolFalse = ConstantInt::getFalse (Context);
@@ -1216,11 +1172,30 @@ static void convertToGuardPredicates(
1216
1172
}
1217
1173
1218
1174
for (auto In : Incoming) {
1219
- Value *Condition;
1220
- BasicBlock *Succ0;
1221
- BasicBlock *Succ1;
1222
- std::tie (Condition, Succ0, Succ1) =
1223
- redirectToHub (In, FirstGuardBlock, Outgoing);
1175
+ auto Branch = cast<BranchInst>(In->getTerminator ());
1176
+ BasicBlock *Succ0 = Branch->getSuccessor (0 );
1177
+ BasicBlock *Succ1 = nullptr ;
1178
+
1179
+ Succ0 = Outgoing.count (Succ0) ? Succ0 : nullptr ;
1180
+
1181
+ if (Branch->isUnconditional ()) {
1182
+ Branch->setSuccessor (0 , FirstGuardBlock);
1183
+ assert (Succ0);
1184
+ } else {
1185
+ Succ1 = Branch->getSuccessor (1 );
1186
+ Succ1 = Outgoing.count (Succ1) ? Succ1 : nullptr ;
1187
+ assert (Succ0 || Succ1);
1188
+ if (Succ0 && !Succ1) {
1189
+ Branch->setSuccessor (0 , FirstGuardBlock);
1190
+ } else if (Succ1 && !Succ0) {
1191
+ Branch->setSuccessor (1 , FirstGuardBlock);
1192
+ } else {
1193
+ Branch->eraseFromParent ();
1194
+ BranchInst::Create (FirstGuardBlock, In);
1195
+ }
1196
+ }
1197
+
1198
+ assert (Succ0 || Succ1);
1224
1199
1225
1200
// Optimization: Consider an incoming block A with both successors
1226
1201
// Succ0 and Succ1 in the set of outgoing blocks. The predicates
@@ -1230,6 +1205,7 @@ static void convertToGuardPredicates(
1230
1205
// control must reach Succ1, which means that the predicate for
1231
1206
// Succ1 is always true.
1232
1207
bool OneSuccessorDone = false ;
1208
+ auto Condition = Branch->getCondition ();
1233
1209
for (int i = 0 , e = Outgoing.size () - 1 ; i != e; ++i) {
1234
1210
auto Out = Outgoing[i];
1235
1211
auto Phi = GuardPredicates[Out];
@@ -1311,8 +1287,8 @@ BasicBlock *llvm::CreateControlFlowHub(
1311
1287
1312
1288
BBPredicates GuardPredicates;
1313
1289
SmallVector<WeakVH, 8 > DeletionCandidates;
1314
- convertToGuardPredicates (FirstGuardBlock, GuardPredicates, DeletionCandidates,
1315
- Incoming, Outgoing);
1290
+ createGuardPredicates (FirstGuardBlock, GuardPredicates, DeletionCandidates,
1291
+ Incoming, Outgoing);
1316
1292
1317
1293
GuardBlocks.push_back (FirstGuardBlock);
1318
1294
createGuardBlocks (GuardBlocks, F, Outgoing, GuardPredicates, Prefix);
0 commit comments