Accessors for implicitTrap field
diff --git a/src/ir/drop.cpp b/src/ir/drop.cpp index 0dec8ff..5b10e1a 100644 --- a/src/ir/drop.cpp +++ b/src/ir/drop.cpp
@@ -41,7 +41,7 @@ // Ignore a trap, as the unreachable replacement would trap too. if (last->is<Unreachable>()) { effects.mustTrap = false; - effects.implicitTrap = false; + effects.clearMayTrap(); } keepParent = effects.hasUnremovableSideEffects(); }
diff --git a/src/ir/effects.cpp b/src/ir/effects.cpp index 68e7abc..5c401e5 100644 --- a/src/ir/effects.cpp +++ b/src/ir/effects.cpp
@@ -84,7 +84,7 @@ if (effects.mustTrap) { o << "mustTrap\n"; } - if (effects.implicitTrap) { + if (effects.hasImplicitTrap()) { o << "implicitTrap\n"; } if (effects.readOrder != MemoryOrder::Unordered) {
diff --git a/src/ir/effects.h b/src/ir/effects.h index c7f6a82..0f9b337 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h
@@ -110,14 +110,21 @@ // A trap from an instruction like a load or div/rem, which may trap on corner // cases. If we do not ignore implicit traps then these are counted as a trap. + // Private to enforce using noteMayTrap(). +private: bool implicitTrap : 1; +public: // Whether this code may trap, either because it is a guaranteed mustTrap, // or because it has an implicitTrap and we are not ignoring them. bool mayTrap() const { return mustTrap || (implicitTrap && !ignoreImplicitTraps); } + void noteMayTrap() { implicitTrap = true; } + void clearMayTrap() { implicitTrap = false; } + bool hasImplicitTrap() const { return implicitTrap; } + bool throws_ : 1; // If this expression contains 'pop's that are not enclosed in 'catch' body. @@ -692,7 +699,7 @@ return true; } if (type.isNullable()) { - parent.implicitTrap = true; + parent.noteMayTrap(); } return false; @@ -761,7 +768,7 @@ // Due to index out of bounds. Type-related traps are handled above and // may set either implicitTrap or trap (or neither). - parent.implicitTrap = true; + parent.noteMayTrap(); const EffectAnalyzer* callTargetEffects = nullptr; if (auto it = parent.module.indirectCallEffects.find(curr->heapType); @@ -799,21 +806,21 @@ } void visitLoad(Load* curr) { readsMemory(curr->memory, curr->order); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitStore(Store* curr) { writesMemory(curr->memory, curr->order); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitAtomicRMW(AtomicRMW* curr) { readsMemory(curr->memory, curr->order); writesMemory(curr->memory, curr->order); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitAtomicCmpxchg(AtomicCmpxchg* curr) { readsMemory(curr->memory, curr->order); writesMemory(curr->memory, curr->order); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitAtomicWait(AtomicWait* curr) { // Waits on unshared memories trap. @@ -828,12 +835,12 @@ parent.writesSharedMemory = true; parent.readOrder = parent.writeOrder = MemoryOrder::SeqCst; // Traps on unaligned accesses. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitAtomicNotify(AtomicNotify* curr) { // Notifies on unshared memories just return 0 or trap on unaligned // accesses. - parent.implicitTrap = true; + parent.noteMayTrap(); if (!parent.module.getMemory(curr->memory)->shared) { return; } @@ -868,7 +875,7 @@ void visitSIMDShift(SIMDShift* curr) {} void visitSIMDLoad(SIMDLoad* curr) { readsMemory(curr->memory, MemoryOrder::Unordered); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitSIMDLoadStoreLane(SIMDLoadStoreLane* curr) { if (curr->isLoad()) { @@ -876,27 +883,27 @@ } else { writesMemory(curr->memory, MemoryOrder::Unordered); } - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitMemoryInit(MemoryInit* curr) { writesMemory(curr->memory, MemoryOrder::Unordered); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitDataDrop(DataDrop* curr) { // data.drop does not actually write memory, but it does alter the size of // a segment, which can be noticeable later by memory.init, so we need to // mark it as having a global side effect of some kind. parent.writesMemory = true; - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitMemoryCopy(MemoryCopy* curr) { readsMemory(curr->sourceMemory, MemoryOrder::Unordered); writesMemory(curr->destMemory, MemoryOrder::Unordered); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitMemoryFill(MemoryFill* curr) { writesMemory(curr->memory, MemoryOrder::Unordered); - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitConst(Const* curr) {} void visitUnary(Unary* curr) { @@ -909,7 +916,7 @@ case TruncSFloat64ToInt64: case TruncUFloat64ToInt32: case TruncUFloat64ToInt64: { - parent.implicitTrap = true; + parent.noteMayTrap(); break; } default: { @@ -932,13 +939,13 @@ // divider. if (auto* c = curr->right->dynCast<Const>()) { if (c->value.isZero()) { - parent.implicitTrap = true; + parent.noteMayTrap(); } else if ((curr->op == DivSInt32 || curr->op == DivSInt64) && c->value.getInteger() == -1LL) { - parent.implicitTrap = true; + parent.noteMayTrap(); } } else { - parent.implicitTrap = true; + parent.noteMayTrap(); } break; } @@ -972,11 +979,11 @@ void visitRefEq(RefEq* curr) {} void visitTableGet(TableGet* curr) { parent.readsTable = true; - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitTableSet(TableSet* curr) { parent.writesTable = true; - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitTableSize(TableSize* curr) { parent.readsTable = true; } void visitTableGrow(TableGrow* curr) { @@ -988,16 +995,16 @@ } void visitTableFill(TableFill* curr) { parent.writesTable = true; - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitTableCopy(TableCopy* curr) { parent.readsTable = true; parent.writesTable = true; - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitTableInit(TableInit* curr) { parent.writesTable = true; - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitElemDrop(ElemDrop* curr) { parent.writesTable = true; } void visitTry(Try* curr) { @@ -1046,7 +1053,7 @@ return; } // Traps if the cast fails. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitRefGetDesc(RefGetDesc* curr) { trapOnNull(curr->ref); } void visitBrOn(BrOn* curr) { @@ -1112,12 +1119,12 @@ void visitArrayNewData(ArrayNewData* curr) { // Traps on out of bounds access to segments or access to dropped // segments. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitArrayNewElem(ArrayNewElem* curr) { // Traps on out of bounds access to segments or access to dropped // segments. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitArrayNewFixed(ArrayNewFixed* curr) {} void visitArrayGet(ArrayGet* curr) { @@ -1125,7 +1132,7 @@ return; } // Null refs and OOB access. - parent.implicitTrap = true; + parent.noteMayTrap(); readsArray(curr->ref->type.getHeapType(), curr->order); } void visitArraySet(ArraySet* curr) { @@ -1133,7 +1140,7 @@ return; } // Null refs and OOB access. - parent.implicitTrap = true; + parent.noteMayTrap(); writesArray(curr->ref->type.getHeapType(), curr->order); } void visitArrayLoad(ArrayLoad* curr) { @@ -1141,7 +1148,7 @@ return; } // Null refs and OOB access. - parent.implicitTrap = true; + parent.noteMayTrap(); readsArray(curr->ref->type.getHeapType(), MemoryOrder::Unordered); } @@ -1152,7 +1159,7 @@ } parent.writesArray = true; // traps when the arg is null or the index out of bounds - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitArrayLen(ArrayLen* curr) { trapOnNull(curr->ref); @@ -1165,7 +1172,7 @@ return; } // Null refs and OOB access. - parent.implicitTrap = true; + parent.noteMayTrap(); readsArray(curr->srcRef->type.getHeapType(), MemoryOrder::Unordered); writesArray(curr->destRef->type.getHeapType(), MemoryOrder::Unordered); } @@ -1174,7 +1181,7 @@ return; } // Null refs and OOB access. - parent.implicitTrap = true; + parent.noteMayTrap(); writesArray(curr->ref->type.getHeapType(), MemoryOrder::Unordered); } template<typename ArrayInit> void visitArrayInit(ArrayInit* curr) { @@ -1183,7 +1190,7 @@ } parent.writesArray = true; // OOB access to array or element segment. - parent.implicitTrap = true; + parent.noteMayTrap(); writesArray(curr->ref->type.getHeapType(), MemoryOrder::Unordered); } void visitArrayInitData(ArrayInitData* curr) { visitArrayInit(curr); } @@ -1193,7 +1200,7 @@ return; } // Null refs and OOB access. - parent.implicitTrap = true; + parent.noteMayTrap(); auto heapType = curr->ref->type.getHeapType(); readsArray(heapType, curr->order); writesArray(heapType, curr->order); @@ -1216,12 +1223,12 @@ return; } // OOB access to array. - parent.implicitTrap = true; + parent.noteMayTrap(); parent.readsMutableArray = true; return; case StringNewFromCodePoint: // Invalid code points. - parent.implicitTrap = true; + parent.noteMayTrap(); return; } } @@ -1232,7 +1239,7 @@ return; } // OOB array access. - parent.implicitTrap = true; + parent.noteMayTrap(); parent.writesArray = true; } void visitStringConcat(StringConcat* curr) { @@ -1254,14 +1261,14 @@ return; } // OOB string access. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitStringSliceWTF(StringSliceWTF* curr) { if (trapOnNull(curr->ref)) { return; } // OOB string access. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitContNew(ContNew* curr) { trapOnNull(curr->func); } void visitContBind(ContBind* curr) { @@ -1283,7 +1290,7 @@ } // A suspend may go unhandled and therefore trap. - parent.implicitTrap = true; + parent.noteMayTrap(); } void visitResume(Resume* curr) { if (trapOnNull(curr->cont)) {
diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index 1dbff8e..4e5372c 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp
@@ -485,7 +485,7 @@ // example above has no effect as (ORIGINAL) never has global write // effects. effects.mustTrap = false; - effects.implicitTrap = false; + effects.clearMayTrap(); auto idempotent = isIdempotent(curr, *getModule()); @@ -542,7 +542,7 @@ // determinism, will ensure that either all of the appearances trap, or // none of them.) effects.mustTrap = false; - effects.implicitTrap = false; + effects.clearMayTrap(); // Note that we've already checked above that this has no side effects or // generativity: if we got here, then it is good to go from the