Revision: 24492
Author: bmeu...@chromium.org
Date: Thu Oct 9 12:20:45 2014 UTC
Log: [turbofan] Eliminate redundant masking operations for
word8/word16 stores.
There's no need to apply 0xff when storing 8-bit values or 0xffff when
storing 16-bit values.
TEST=unittests
R=tit...@chromium.org
Review URL: https://codereview.chromium.org/642033002
https://code.google.com/p/v8/source/detail?r=24492
Modified:
/branches/bleeding_edge/src/compiler/machine-operator-reducer.cc
/branches/bleeding_edge/src/compiler/machine-operator.cc
/branches/bleeding_edge/src/compiler/machine-operator.h
/branches/bleeding_edge/test/unittests/compiler/change-lowering-unittest.cc
/branches/bleeding_edge/test/unittests/compiler/graph-unittest.cc
/branches/bleeding_edge/test/unittests/compiler/graph-unittest.h
/branches/bleeding_edge/test/unittests/compiler/machine-operator-reducer-unittest.cc
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator-reducer.cc Wed
Oct 1 10:39:11 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator-reducer.cc Thu
Oct 9 12:20:45 2014 UTC
@@ -473,6 +473,22 @@
if (m.IsChangeFloat32ToFloat64()) return
Replace(m.node()->InputAt(0));
break;
}
+ case IrOpcode::kStore: {
+ Node* const value = node->InputAt(2);
+ // TODO(turbofan): Extend to 64-bit?
+ if (value->opcode() == IrOpcode::kWord32And) {
+ MachineType const rep = static_cast<MachineType>(
+ StoreRepresentationOf(node->op()).machine_type() & kRepMask);
+ Uint32BinopMatcher m(value);
+ if (m.right().HasValue() &&
+ ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
+ (rep == kRepWord16 && (m.right().Value() & 0xffff) ==
0xffff))) {
+ node->ReplaceInput(2, m.left().node());
+ return Changed(node);
+ }
+ }
+ break;
+ }
default:
break;
}
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator.cc Tue Oct 7
13:30:28 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator.cc Thu Oct 9
12:20:45 2014 UTC
@@ -44,6 +44,12 @@
return os << "(" << rep.machine_type() << " : " <<
rep.write_barrier_kind()
<< ")";
}
+
+
+StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
+ DCHECK_EQ(IrOpcode::kStore, op->opcode());
+ return OpParameter<StoreRepresentation>(op);
+}
#define
PURE_OP_LIST(V) \
=======================================
--- /branches/bleeding_edge/src/compiler/machine-operator.h Tue Oct 7
13:30:28 2014 UTC
+++ /branches/bleeding_edge/src/compiler/machine-operator.h Thu Oct 9
12:20:45 2014 UTC
@@ -49,6 +49,8 @@
std::ostream& operator<<(std::ostream&, StoreRepresentation);
+StoreRepresentation const& StoreRepresentationOf(Operator const*);
+
// Interface for building machine-level operators. These operators are
// machine-level but machine-independent and thus define a language
suitable
=======================================
---
/branches/bleeding_edge/test/unittests/compiler/change-lowering-unittest.cc
Wed Oct 1 11:08:37 2014 UTC
+++
/branches/bleeding_edge/test/unittests/compiler/change-lowering-unittest.cc
Thu Oct 9 12:20:45 2014 UTC
@@ -160,7 +160,8 @@
IsFinish(
AllOf(CaptureEq(&heap_number),
IsAllocateHeapNumber(IsValueEffect(val),
graph()->start())),
- IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
+ IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+ CaptureEq(&heap_number),
IsInt32Constant(HeapNumberValueOffset()), val,
CaptureEq(&heap_number), graph()->start())));
}
@@ -202,13 +203,13 @@
EXPECT_THAT(
phi,
IsPhi(kMachAnyTagged,
- IsFinish(
- AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(_, CaptureEq(&if_true))),
- IsStore(kMachFloat64, kNoWriteBarrier,
CaptureEq(&heap_number),
- IsInt32Constant(HeapNumberValueOffset()),
- IsChangeInt32ToFloat64(val),
CaptureEq(&heap_number),
- CaptureEq(&if_true))),
+ IsFinish(AllOf(CaptureEq(&heap_number),
+ IsAllocateHeapNumber(_, CaptureEq(&if_true))),
+ IsStore(StoreRepresentation(kMachFloat64,
kNoWriteBarrier),
+ CaptureEq(&heap_number),
+ IsInt32Constant(HeapNumberValueOffset()),
+ IsChangeInt32ToFloat64(val),
+ CaptureEq(&heap_number),
CaptureEq(&if_true))),
IsProjection(
0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val,
val))),
IsMerge(AllOf(CaptureEq(&if_true),
IsIfTrue(CaptureEq(&branch))),
@@ -308,13 +309,13 @@
phi,
IsPhi(
kMachAnyTagged, IsWord32Shl(val,
IsInt32Constant(SmiShiftAmount())),
- IsFinish(
- AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(_, CaptureEq(&if_false))),
- IsStore(kMachFloat64, kNoWriteBarrier,
CaptureEq(&heap_number),
- IsInt32Constant(HeapNumberValueOffset()),
- IsChangeUint32ToFloat64(val),
CaptureEq(&heap_number),
- CaptureEq(&if_false))),
+ IsFinish(AllOf(CaptureEq(&heap_number),
+ IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+ IsStore(StoreRepresentation(kMachFloat64,
kNoWriteBarrier),
+ CaptureEq(&heap_number),
+ IsInt32Constant(HeapNumberValueOffset()),
+ IsChangeUint32ToFloat64(val),
+ CaptureEq(&heap_number), CaptureEq(&if_false))),
IsMerge(
IsIfTrue(AllOf(CaptureEq(&branch),
IsBranch(IsUint32LessThanOrEqual(
@@ -442,13 +443,13 @@
IsPhi(
kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(val),
IsInt32Constant(SmiShiftAmount())),
- IsFinish(
- AllOf(CaptureEq(&heap_number),
- IsAllocateHeapNumber(_, CaptureEq(&if_false))),
- IsStore(kMachFloat64, kNoWriteBarrier,
CaptureEq(&heap_number),
- IsInt32Constant(HeapNumberValueOffset()),
- IsChangeUint32ToFloat64(val),
CaptureEq(&heap_number),
- CaptureEq(&if_false))),
+ IsFinish(AllOf(CaptureEq(&heap_number),
+ IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+ IsStore(StoreRepresentation(kMachFloat64,
kNoWriteBarrier),
+ CaptureEq(&heap_number),
+ IsInt32Constant(HeapNumberValueOffset()),
+ IsChangeUint32ToFloat64(val),
+ CaptureEq(&heap_number), CaptureEq(&if_false))),
IsMerge(
IsIfTrue(AllOf(CaptureEq(&branch),
IsBranch(IsUint32LessThanOrEqual(
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/graph-unittest.cc Tue
Oct 7 13:30:28 2014 UTC
+++ /branches/bleeding_edge/test/unittests/compiler/graph-unittest.cc Thu
Oct 9 12:20:45 2014 UTC
@@ -654,16 +654,14 @@
class IsStoreMatcher FINAL : public NodeMatcher {
public:
- IsStoreMatcher(const Matcher<MachineType>& type_matcher,
- const Matcher<WriteBarrierKind> write_barrier_matcher,
+ IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
const Matcher<Node*>& value_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher)
: NodeMatcher(IrOpcode::kStore),
- type_matcher_(type_matcher),
- write_barrier_matcher_(write_barrier_matcher),
+ rep_matcher_(rep_matcher),
base_matcher_(base_matcher),
index_matcher_(index_matcher),
value_matcher_(value_matcher),
@@ -672,10 +670,8 @@
virtual void DescribeTo(std::ostream* os) const OVERRIDE {
NodeMatcher::DescribeTo(os);
- *os << " whose type (";
- type_matcher_.DescribeTo(os);
- *os << "), write barrier (";
- write_barrier_matcher_.DescribeTo(os);
+ *os << " whose rep (";
+ rep_matcher_.DescribeTo(os);
*os << "), base (";
base_matcher_.DescribeTo(os);
*os << "), index (";
@@ -692,12 +688,8 @@
virtual bool MatchAndExplain(Node* node,
MatchResultListener* listener) const
OVERRIDE {
return (NodeMatcher::MatchAndExplain(node, listener) &&
- PrintMatchAndExplain(
-
OpParameter<StoreRepresentation>(node).machine_type(), "type",
- type_matcher_, listener) &&
- PrintMatchAndExplain(
-
OpParameter<StoreRepresentation>(node).write_barrier_kind(),
- "write barrier", write_barrier_matcher_, listener) &&
+
PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
+ rep_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetValueInput(node,
0), "base",
base_matcher_, listener) &&
PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
@@ -711,8 +703,7 @@
}
private:
- const Matcher<MachineType> type_matcher_;
- const Matcher<WriteBarrierKind> write_barrier_matcher_;
+ const Matcher<StoreRepresentation> rep_matcher_;
const Matcher<Node*> base_matcher_;
const Matcher<Node*> index_matcher_;
const Matcher<Node*> value_matcher_;
@@ -927,16 +918,15 @@
}
-Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
- const Matcher<WriteBarrierKind>&
write_barrier_matcher,
+Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
const Matcher<Node*>& value_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher) {
- return MakeMatcher(new IsStoreMatcher(
- type_matcher, write_barrier_matcher, base_matcher, index_matcher,
- value_matcher, effect_matcher, control_matcher));
+ return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher,
+ index_matcher, value_matcher,
+ effect_matcher, control_matcher));
}
=======================================
--- /branches/bleeding_edge/test/unittests/compiler/graph-unittest.h Tue
Oct 7 07:36:21 2014 UTC
+++ /branches/bleeding_edge/test/unittests/compiler/graph-unittest.h Thu
Oct 9 12:20:45 2014 UTC
@@ -41,6 +41,9 @@
Node* Float32Constant(volatile float value);
Node* Float64Constant(volatile double value);
Node* Int32Constant(int32_t value);
+ Node* Uint32Constant(uint32_t value) {
+ return Int32Constant(bit_cast<int32_t>(value));
+ }
Node* Int64Constant(int64_t value);
Node* NumberConstant(volatile double value);
Node* HeapConstant(const Handle<HeapObject>& value);
@@ -119,8 +122,7 @@
const Matcher<Node*>& index_matcher,
const Matcher<Node*>& effect_matcher,
const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
- const Matcher<WriteBarrierKind>&
write_barrier_matcher,
+Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
const Matcher<Node*>& base_matcher,
const Matcher<Node*>& index_matcher,
const Matcher<Node*>& value_matcher,
=======================================
---
/branches/bleeding_edge/test/unittests/compiler/machine-operator-reducer-unittest.cc
Wed Oct 1 08:34:25 2014 UTC
+++
/branches/bleeding_edge/test/unittests/compiler/machine-operator-reducer-unittest.cc
Thu Oct 9 12:20:45 2014 UTC
@@ -653,6 +653,54 @@
}
}
}
+
+
+//
-----------------------------------------------------------------------------
+// Store
+
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
+ const StoreRepresentation rep(kRepWord8, kNoWriteBarrier);
+ Node* const base = Parameter(0);
+ Node* const index = Parameter(1);
+ Node* const value = Parameter(2);
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ TRACED_FOREACH(uint32_t, x, kUint32Values) {
+ Node* const node =
+ graph()->NewNode(machine()->Store(rep), base, index,
+ graph()->NewNode(machine()->Word32And(), value,
+ Uint32Constant(x | 0xffu)),
+ effect, control);
+
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsStore(rep, base, index, value, effect, control));
+ }
+}
+
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
+ const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
+ Node* const base = Parameter(0);
+ Node* const index = Parameter(1);
+ Node* const value = Parameter(2);
+ Node* const effect = graph()->start();
+ Node* const control = graph()->start();
+ TRACED_FOREACH(uint32_t, x, kUint32Values) {
+ Node* const node =
+ graph()->NewNode(machine()->Store(rep), base, index,
+ graph()->NewNode(machine()->Word32And(), value,
+ Uint32Constant(x | 0xffffu)),
+ effect, control);
+
+ Reduction r = Reduce(node);
+ ASSERT_TRUE(r.Changed());
+ EXPECT_THAT(r.replacement(),
+ IsStore(rep, base, index, value, effect, control));
+ }
+}
} // namespace compiler
} // namespace internal
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.