Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Unified Diff: src/hydrogen.cc

Issue 10984057: Replace a set of Hydrogen instructions with rotate instructions on ARM (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc (revision 12582)
+++ src/hydrogen.cc (working copy)
@@ -1021,6 +1021,98 @@
};
+// Help with TryRotate pattern matching by checking if sub is 32 - s. It's okay
+// if the right operand of sub isn't the same HValue as s if both are HChange
+// instructions from the same value. This is called twice to determine whether
+// we do a left or right rotation.
+static bool TryMatchShiftAmountForRotate(HValue* s, HValue* sub) {
+ if (!sub->IsSub())
+ return false;
+ HValue* subl = HSub::cast(sub)->left();
+ HValue* subr = HSub::cast(sub)->right();
+ return subl->representation().IsInteger32() &&
+ subl->IsConstant() &&
+ HConstant::cast(subl)->Integer32Value() == 32 &&
+ (s == subr ||
+ (subr->IsChange() && s->IsChange() &&
+ subr->OperandAt(0) == s->OperandAt(0)));
+}
+
+
+// Attempt to replace one of the following patterns with a rotate instruction:
+// n << s | n >>> (32 - s) ==> rotate left
+// n >>> s | n << (32 - s) ==> rotate right
+bool HGraph::TryRotate(HInstruction* instr) {
+ HBitwise* bor = HBitwise::cast(instr);
+ ASSERT(bor->op() == Token::BIT_OR);
+ HShl* shl;
+ HShr* shr;
+ if (bor->left()->IsShl() && bor->right()->IsShr()) {
+ shl = HShl::cast(bor->left());
+ shr = HShr::cast(bor->right());
+ } else if (bor->left()->IsShr() && bor->right()->IsShl()) {
+ shl = HShl::cast(bor->right());
+ shr = HShr::cast(bor->left());
+ } else {
+ return false;
+ }
+
+ // Neither shift can be used elsewhere (or it is not safe to delete them).
+ // Also, both must have Integer32 representation, since we can't rotate
+ // anything else quickly.
+ if (shl->UseCount() > 1 || !shl->representation().IsInteger32() ||
+ shr->UseCount() > 1 || !shr->representation().IsInteger32() ||
+ !shr->right()->representation().IsInteger32() ||
+ !shr->left()->representation().IsInteger32() ||
+ !shl->right()->representation().IsInteger32() ||
+ !shl->left()->representation().IsInteger32()) {
+ return false;
+ }
+
+ // The value being shifted must be the same.
+ if (shl->left() != shr->left())
+ return false;
+ HValue* number = shl->left();
+
+ // The shift values must be s and 32-s. Whether we have found a left or
+ // right rotate depends on which shift has 32-s. Note that it's okay if the
+ // "s" values on both sides are distinct HChange instructions, as long as
+ // their operands are the same value.
+ HValue* shift_amount = NULL;
+ if (TryMatchShiftAmountForRotate(shl->right(), shr->right()) |
+ TryMatchShiftAmountForRotate(shr->right(), shl->right())) {
+ shift_amount = shr->right();
+ } else {
+ return false;
+ }
+
+ // We have matched all the operands. Do the replacement.
+ HRor* ror = new(zone()) HRor(shr->context(), number, shift_amount);
+ ror->InsertAfter(bor);
+ bor->DeleteAndReplaceWith(ror);
+ shl->DeleteAndReplaceWith(NULL);
+ shr->DeleteAndReplaceWith(NULL);
+
+ return true;
+}
+
+
+void HGraph::ReplaceWithRor() {
+ if (!FLAG_use_replace_with_ror) return;
+ HPhase phase("H_Replace with ror", this);
+ for (int i = 0; i < blocks()->length(); ++i) {
+ HInstruction* instr = blocks()->at(i)->first();
+ while (instr != NULL) {
+ if (instr->IsBitwise() &&
+ HBitwise::cast(instr)->op() == Token::BIT_OR) {
+ TryRotate(instr);
+ }
+ instr = instr->next();
+ }
+ }
+}
+
+
void HGraph::OrderBlocks() {
HPhase phase("H_Block ordering");
BitVector visited(blocks_.length(), zone());
@@ -3402,6 +3494,12 @@
HStackCheckEliminator sce(this);
sce.Process();
+#if defined(V8_TARGET_ARCH_ARM)
+ // TODO: support rotate instructions on other architectures. For now they are
+ // only supported on ARM.
+ ReplaceWithRor();
+#endif
+
EliminateRedundantBoundsChecks();
DehoistSimpleArrayIndexComputations();
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698