diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/effects.h | 12 | ||||
-rw-r--r-- | src/passes/CodePushing.cpp | 20 |
2 files changed, 26 insertions, 6 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h index d3ae9ba20..ad3ab235d 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -881,9 +881,19 @@ public: return effects; } - void ignoreBranches() { + // Ignores all forms of control flow transfers: breaks, returns, and + // exceptions. (Note that traps are not considered relevant here - a trap does + // not just transfer control flow, but can be seen as halting the entire + // program.) + // + // This function matches transfersControlFlow(), that is, after calling this + // method transfersControlFlow() will always return false. + void ignoreControlFlowTransfers() { branchesOut = false; breakTargets.clear(); + throws_ = false; + delegateTargets.clear(); + assert(!transfersControlFlow()); } private: diff --git a/src/passes/CodePushing.cpp b/src/passes/CodePushing.cpp index 682f025c8..5026773d4 100644 --- a/src/passes/CodePushing.cpp +++ b/src/passes/CodePushing.cpp @@ -161,11 +161,21 @@ private: // everything that matters if you want to be pushed past the pushPoint EffectAnalyzer cumulativeEffects(passOptions, module); cumulativeEffects.walk(list[pushPoint]); - // it is ok to ignore the branching here, that is the crucial point of this - // opt - // TODO: it would be ok to ignore thrown exceptions here, if we know they - // could not be caught and must go outside of the function - cumulativeEffects.ignoreBranches(); + // It is ok to ignore branching out of the block here, that is the crucial + // point of this optimization. That is, we are in a situation like this: + // + // { + // x = value; + // if (..) break; + // foo(x); + // } + // + // If the branch is taken, then that's fine, it will jump out of this block + // and reach some outer scope, and in that case we never need x at all + // (since we've proven before that x is not used outside of this block, see + // numGetsSoFar which we use for that). Similarly, control flow could + // transfer away via a return or an exception and that would be ok as well. + cumulativeEffects.ignoreControlFlowTransfers(); std::vector<LocalSet*> toPush; Index i = pushPoint - 1; while (1) { |