summaryrefslogtreecommitdiff
path: root/src/ir/effects.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir/effects.h')
-rw-r--r--src/ir/effects.h33
1 files changed, 31 insertions, 2 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 2de5c54f6..f5bb0e6cb 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -30,6 +30,7 @@ public:
FeatureSet features,
Expression* ast = nullptr)
: ignoreImplicitTraps(passOptions.ignoreImplicitTraps),
+ trapsNeverHappen(passOptions.trapsNeverHappen),
debugInfo(passOptions.debugInfo), features(features) {
if (ast) {
walk(ast);
@@ -37,6 +38,7 @@ public:
}
bool ignoreImplicitTraps;
+ bool trapsNeverHappen;
bool debugInfo;
FeatureSet features;
@@ -143,10 +145,37 @@ public:
return globalsRead.size() || readsMemory || readsHeap || isAtomic || calls;
}
- bool hasSideEffects() const {
+ bool hasNonTrapSideEffects() const {
return localsWritten.size() > 0 || danglingPop || writesGlobalState() ||
- trap || throws || transfersControlFlow();
+ throws || transfersControlFlow();
}
+
+ bool hasSideEffects() const { return trap || hasNonTrapSideEffects(); }
+
+ // Check if there are side effects, and they are of a kind that cannot be
+ // removed by optimization passes.
+ //
+ // The difference between this and hasSideEffects is subtle, and only related
+ // to trapsNeverHappen - if trapsNeverHappen then any trap we see is removable
+ // by optimizations. In general, you should call hasSideEffects, and only call
+ // this method if you are certain that it is a place that would not perform an
+ // unsafe transformation with a trap. Specifically, if a pass calls this
+ // and gets the result that there are no unremovable side effects, then it
+ // must either
+ //
+ // 1. Remove any side effects present, if any, so they no longer exists.
+ // 2. Keep the code exactly where it is.
+ //
+ // If instead of 1&2 a pass kept the side effect and also reordered the code
+ // with other things, then that could be bad, as the side effect might have
+ // been behind a condition that avoids it occurring.
+ //
+ // TODO: Go through the optimizer and use this in all places that do not move
+ // code around.
+ bool hasUnremovableSideEffects() const {
+ return hasNonTrapSideEffects() || (trap && !trapsNeverHappen);
+ }
+
bool hasAnything() const {
return hasSideEffects() || accessesLocal() || readsMemory ||
accessesGlobal();