@@ -62,7 +62,7 @@ static bool isBackedgeNode(const CFGBlock &B) {
62
62
63
63
namespace {
64
64
65
- // / Extracts the condition expression.
65
+ // / Extracts the terminator's condition expression.
66
66
class TerminatorVisitor
67
67
: public ConstStmtVisitor<TerminatorVisitor, const Expr *> {
68
68
public:
@@ -200,9 +200,13 @@ class JoinedStateBuilder {
200
200
return Result;
201
201
}
202
202
};
203
-
204
203
} // namespace
205
204
205
+ static const Expr *getTerminatorCondition (const Stmt *TerminatorStmt) {
206
+ return TerminatorStmt == nullptr ? nullptr
207
+ : TerminatorVisitor ().Visit (TerminatorStmt);
208
+ }
209
+
206
210
// / Computes the input state for a given basic block by joining the output
207
211
// / states of its predecessors.
208
212
// /
@@ -273,33 +277,33 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) {
273
277
AC.BlockStates [Pred->getBlockID ()];
274
278
if (!MaybePredState)
275
279
continue ;
280
+
276
281
const TypeErasedDataflowAnalysisState &PredState = *MaybePredState;
282
+ const Expr *Cond = getTerminatorCondition (Pred->getTerminatorStmt ());
283
+ if (Cond == nullptr ) {
284
+ Builder.addUnowned (PredState);
285
+ continue ;
286
+ }
277
287
278
- if (const Stmt *PredTerminatorStmt = Pred->getTerminatorStmt ()) {
279
- bool BranchVal = blockIndexInPredecessor (*Pred, Block) == 0 ;
280
- const Expr *Cond = TerminatorVisitor ().Visit (PredTerminatorStmt);
281
- if (Cond != nullptr ) {
282
- // `transferBranch` may need to mutate the environment to describe the
283
- // dynamic effect of the terminator for a given branch. Copy now.
284
- TypeErasedDataflowAnalysisState Copy = MaybePredState->fork ();
285
- if (AC.Analysis .builtinOptions ()) {
286
- auto *CondVal = Copy.Env .get <BoolValue>(*Cond);
287
- // In transferCFGBlock(), we ensure that we always have a `Value`
288
- // for the terminator condition, so assert this. We consciously
289
- // assert ourselves instead of asserting via `cast()` so that we get
290
- // a more meaningful line number if the assertion fails.
291
- assert (CondVal != nullptr );
292
- BoolValue *AssertedVal =
293
- BranchVal ? CondVal : &Copy.Env .makeNot (*CondVal);
294
- Copy.Env .assume (AssertedVal->formula ());
295
- }
296
- AC.Analysis .transferBranchTypeErased (BranchVal, Cond, Copy.Lattice ,
297
- Copy.Env );
298
- Builder.addOwned (std::move (Copy));
299
- continue ;
300
- }
288
+ bool BranchVal = blockIndexInPredecessor (*Pred, Block) == 0 ;
289
+
290
+ // `transferBranch` may need to mutate the environment to describe the
291
+ // dynamic effect of the terminator for a given branch. Copy now.
292
+ TypeErasedDataflowAnalysisState Copy = MaybePredState->fork ();
293
+ if (AC.Analysis .builtinOptions ()) {
294
+ auto *CondVal = Copy.Env .get <BoolValue>(*Cond);
295
+ // In transferCFGBlock(), we ensure that we always have a `Value`
296
+ // for the terminator condition, so assert this. We consciously
297
+ // assert ourselves instead of asserting via `cast()` so that we get
298
+ // a more meaningful line number if the assertion fails.
299
+ assert (CondVal != nullptr );
300
+ BoolValue *AssertedVal =
301
+ BranchVal ? CondVal : &Copy.Env .makeNot (*CondVal);
302
+ Copy.Env .assume (AssertedVal->formula ());
301
303
}
302
- Builder.addUnowned (PredState);
304
+ AC.Analysis .transferBranchTypeErased (BranchVal, Cond, Copy.Lattice ,
305
+ Copy.Env );
306
+ Builder.addOwned (std::move (Copy));
303
307
}
304
308
return std::move (Builder).take ();
305
309
}
0 commit comments