diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 2a5e7b8c4..003d2ff60 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -168,6 +168,12 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, void visitExpression(Expression* curr) { // we may be able to apply multiple patterns, one may open opportunities that look deeper NB: patterns must not have cycles while (1) { + auto* handOptimized = handOptimize(curr); + if (handOptimized) { + curr = handOptimized; + replaceCurrent(curr); + continue; + } auto iter = database->patternMap.find(curr->_id); if (iter == database->patternMap.end()) return; auto& patterns = iter->second; @@ -184,6 +190,27 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, if (!more) break; } } + + // Optimizations that don't yet fit in the pattern DSL, but could be eventually maybe + Expression* handOptimize(Expression* curr) { + if (auto* binary = curr->dynCast<Binary>()) { + // pattern match a load of 8 bits and a sign extend using a shl of 24 then shr_s of 24 as well, etc. + if (binary->op == BinaryOp::ShrSInt32 && binary->right->is<Const>()) { + auto shifts = binary->right->cast<Const>()->value.geti32(); + if (shifts == 24 || shifts == 16) { + auto* left = binary->left->dynCast<Binary>(); + if (left && left->op == ShlInt32 && left->right->is<Const>() && left->right->cast<Const>()->value.geti32() == shifts) { + auto* load = left->left->dynCast<Load>(); + if (load && ((load->bytes == 1 && shifts == 24) || (load->bytes == 2 && shifts == 16))) { + load->signed_ = true; + return load; + } + } + } + } + } + return nullptr; + } }; Pass *createOptimizeInstructionsPass() { |