From 7d2d9ec9f2f936d0a53b7dc60089456a0654d29c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 29 Nov 2016 19:35:55 -0800 Subject: Optimize added factors into load/store offsets (#850) * optimize added factors into load/store offsets, removing the add * optimize offset of load/store of a constant into the constant --- src/passes/OptimizeInstructions.cpp | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'src') diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 1970cf08f..37207ffc7 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -326,7 +326,10 @@ struct OptimizeInstructions : public WalkerPasscondition) { br->condition = optimizeBoolean(br->condition); } + } else if (auto* load = curr->dynCast()) { + optimizeMemoryAccess(load->ptr, load->offset); } else if (auto* store = curr->dynCast()) { + optimizeMemoryAccess(store->ptr, store->offset); // stores of fewer bits truncates anyhow if (auto* binary = store->value->dynCast()) { if (binary->op == AndInt32) { @@ -430,6 +433,43 @@ private: return builder.makeIf(left, right, builder.makeConst(Literal(int32_t(0)))); } } + + // fold constant factors into the offset + void optimizeMemoryAccess(Expression*& ptr, Address& offset) { + while (1) { + auto* add = ptr->dynCast(); + if (!add) break; + if (add->op != AddInt32) break; + auto* left = add->left->dynCast(); + auto* right = add->right->dynCast(); + // note: in optimized code, we shouldn't see an add of two constants, so don't worry about that much + // (precompute would optimize that) + if (left) { + auto value = left->value.geti32(); + if (value >= 0) { + offset = offset + value; + ptr = add->right; + continue; + } + } + if (right) { + auto value = right->value.geti32(); + if (value >= 0) { + offset = offset + value; + ptr = add->left; + continue; + } + } + break; + } + // finally, ptr may be a const, but it isn't worth folding that in (we still have a const); in fact, + // it's better to do the opposite for gzip purposes as well as for readability. + auto* last = ptr->dynCast(); + if (last) { + last->value = Literal(int32_t(last->value.geti32() + offset)); + offset = 0; + } + } }; Pass *createOptimizeInstructionsPass() { -- cgit v1.2.3