diff options
Diffstat (limited to 'src/passes/OptimizeInstructions.cpp')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index ef7c17000..90abed825 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -330,6 +330,7 @@ struct OptimizeInstructions // Optimizations that don't yet fit in the pattern DSL, but could be // eventually maybe Expression* handOptimize(Expression* curr) { + FeatureSet features = getModule()->features; // if this contains dead code, don't bother trying to optimize it, the type // might change (if might not be unreachable if just one arm is, for // example). this optimization pass focuses on actually executing code. the @@ -472,7 +473,7 @@ struct OptimizeInstructions if (auto* subZero = sub->left->dynCast<Const>()) { if (subZero->value.geti32() == 0) { if (EffectAnalyzer::canReorder( - getPassOptions(), sub->right, binary->right)) { + getPassOptions(), features, sub->right, binary->right)) { sub->left = binary->right; return sub; } @@ -630,7 +631,8 @@ struct OptimizeInstructions } // finally, try more expensive operations on the binary in // the case that they have no side effects - if (!EffectAnalyzer(getPassOptions(), binary->left).hasSideEffects()) { + if (!EffectAnalyzer(getPassOptions(), features, binary->left) + .hasSideEffects()) { if (ExpressionAnalyzer::equal(binary->left, binary->right)) { return optimizeBinaryWithEqualEffectlessChildren(binary); } @@ -750,7 +752,8 @@ struct OptimizeInstructions // if we can replace the if with one arm, and no side effects in the // condition, do that auto needCondition = - EffectAnalyzer(getPassOptions(), iff->condition).hasSideEffects(); + EffectAnalyzer(getPassOptions(), features, iff->condition) + .hasSideEffects(); auto isSubType = Type::isSubType(iff->ifTrue->type, iff->type); if (isSubType && !needCondition) { return iff->ifTrue; @@ -781,8 +784,8 @@ struct OptimizeInstructions auto* condition = select->condition->dynCast<Unary>(); if (condition && condition->op == EqZInt32) { // flip select to remove eqz, if we can reorder - EffectAnalyzer ifTrue(getPassOptions(), select->ifTrue); - EffectAnalyzer ifFalse(getPassOptions(), select->ifFalse); + EffectAnalyzer ifTrue(getPassOptions(), features, select->ifTrue); + EffectAnalyzer ifFalse(getPassOptions(), features, select->ifFalse); if (!ifTrue.invalidates(ifFalse)) { select->condition = condition->value; std::swap(select->ifTrue, select->ifFalse); @@ -792,7 +795,7 @@ struct OptimizeInstructions // constant condition, we can just pick the right side (barring side // effects) if (c->value.getInteger()) { - if (!EffectAnalyzer(getPassOptions(), select->ifFalse) + if (!EffectAnalyzer(getPassOptions(), features, select->ifFalse) .hasSideEffects()) { return select->ifTrue; } else { @@ -800,7 +803,7 @@ struct OptimizeInstructions // local, which is bad } } else { - if (!EffectAnalyzer(getPassOptions(), select->ifTrue) + if (!EffectAnalyzer(getPassOptions(), features, select->ifTrue) .hasSideEffects()) { return select->ifFalse; } else { @@ -812,7 +815,7 @@ struct OptimizeInstructions } if (ExpressionAnalyzer::equal(select->ifTrue, select->ifFalse)) { // sides are identical, fold - EffectAnalyzer value(getPassOptions(), select->ifTrue); + EffectAnalyzer value(getPassOptions(), features, select->ifTrue); if (value.hasSideEffects()) { // at best we don't need the condition, but need to execute the value // twice. a block is larger than a select by 2 bytes, and @@ -820,7 +823,8 @@ struct OptimizeInstructions // so it's not clear this is worth it, TODO } else { // value has no side effects - EffectAnalyzer condition(getPassOptions(), select->condition); + EffectAnalyzer condition( + getPassOptions(), features, select->condition); if (!condition.hasSideEffects()) { return select->ifTrue; } else { @@ -887,14 +891,15 @@ private: // write more concise pattern matching code elsewhere. void canonicalize(Binary* binary) { assert(Properties::isSymmetric(binary)); + FeatureSet features = getModule()->features; auto swap = [&]() { assert(EffectAnalyzer::canReorder( - getPassOptions(), binary->left, binary->right)); + getPassOptions(), features, binary->left, binary->right)); std::swap(binary->left, binary->right); }; auto maybeSwap = [&]() { if (EffectAnalyzer::canReorder( - getPassOptions(), binary->left, binary->right)) { + getPassOptions(), features, binary->left, binary->right)) { swap(); } }; @@ -1064,6 +1069,7 @@ private: ZeroRemover(PassOptions& passOptions) : passOptions(passOptions) {} void visitBinary(Binary* curr) { + FeatureSet features = getModule()->features; auto* left = curr->left->dynCast<Const>(); auto* right = curr->right->dynCast<Const>(); if (curr->op == AddInt32) { @@ -1086,7 +1092,8 @@ private: // shift has side effects if (((left && left->value.geti32() == 0) || (right && Bits::getEffectiveShifts(right) == 0)) && - !EffectAnalyzer(passOptions, curr->right).hasSideEffects()) { + !EffectAnalyzer(passOptions, features, curr->right) + .hasSideEffects()) { replaceCurrent(curr->left); return; } @@ -1094,12 +1101,14 @@ private: // multiplying by zero is a zero, unless the other side has side // effects if (left && left->value.geti32() == 0 && - !EffectAnalyzer(passOptions, curr->right).hasSideEffects()) { + !EffectAnalyzer(passOptions, features, curr->right) + .hasSideEffects()) { replaceCurrent(left); return; } if (right && right->value.geti32() == 0 && - !EffectAnalyzer(passOptions, curr->left).hasSideEffects()) { + !EffectAnalyzer(passOptions, features, curr->left) + .hasSideEffects()) { replaceCurrent(right); return; } @@ -1107,7 +1116,9 @@ private: } }; Expression* walked = binary; - ZeroRemover(getPassOptions()).walk(walked); + ZeroRemover remover(getPassOptions()); + remover.setModule(getModule()); + remover.walk(walked); if (constant == 0) { return walked; // nothing more to do } @@ -1142,8 +1153,9 @@ private: if (!Properties::emitsBoolean(left) || !Properties::emitsBoolean(right)) { return nullptr; } - auto leftEffects = EffectAnalyzer(getPassOptions(), left); - auto rightEffects = EffectAnalyzer(getPassOptions(), right); + FeatureSet features = getModule()->features; + auto leftEffects = EffectAnalyzer(getPassOptions(), features, left); + auto rightEffects = EffectAnalyzer(getPassOptions(), features, right); auto leftHasSideEffects = leftEffects.hasSideEffects(); auto rightHasSideEffects = rightEffects.hasSideEffects(); if (leftHasSideEffects && rightHasSideEffects) { @@ -1189,13 +1201,16 @@ private: // (x > y) | (x == y) ==> x >= y Expression* combineOr(Binary* binary) { assert(binary->op == OrInt32); + FeatureSet features = getModule()->features; if (auto* left = binary->left->dynCast<Binary>()) { if (auto* right = binary->right->dynCast<Binary>()) { if (left->op != right->op && ExpressionAnalyzer::equal(left->left, right->left) && ExpressionAnalyzer::equal(left->right, right->right) && - !EffectAnalyzer(getPassOptions(), left->left).hasSideEffects() && - !EffectAnalyzer(getPassOptions(), left->right).hasSideEffects()) { + !EffectAnalyzer(getPassOptions(), features, left->left) + .hasSideEffects() && + !EffectAnalyzer(getPassOptions(), features, left->right) + .hasSideEffects()) { switch (left->op) { // (x > y) | (x == y) ==> x >= y case EqInt32: { @@ -1296,6 +1311,7 @@ private: // is a constant // TODO: templatize on type? Expression* optimizeWithConstantOnRight(Binary* binary) { + FeatureSet features = getModule()->features; auto type = binary->right->type; auto* right = binary->right->cast<Const>(); if (type.isInteger()) { @@ -1309,7 +1325,7 @@ private: return binary->left; } else if ((binary->op == Abstract::getBinary(type, Abstract::Mul) || binary->op == Abstract::getBinary(type, Abstract::And)) && - !EffectAnalyzer(getPassOptions(), binary->left) + !EffectAnalyzer(getPassOptions(), features, binary->left) .hasSideEffects()) { return binary->right; } else if (binary->op == EqInt64) { @@ -1323,7 +1339,7 @@ private: if (binary->op == Abstract::getBinary(type, Abstract::And)) { return binary->left; } else if (binary->op == Abstract::getBinary(type, Abstract::Or) && - !EffectAnalyzer(getPassOptions(), binary->left) + !EffectAnalyzer(getPassOptions(), features, binary->left) .hasSideEffects()) { return binary->right; } @@ -1381,7 +1397,9 @@ private: if ((binary->op == Abstract::getBinary(type, Abstract::Shl) || binary->op == Abstract::getBinary(type, Abstract::ShrU) || binary->op == Abstract::getBinary(type, Abstract::ShrS)) && - !EffectAnalyzer(getPassOptions(), binary->right).hasSideEffects()) { + !EffectAnalyzer( + getPassOptions(), getModule()->features, binary->right) + .hasSideEffects()) { return binary->left; } } |