Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/compiler/graph-inl.h" | |
| 6 #include "src/compiler/js-builtin-reducer.h" | |
| 7 #include "src/compiler/node-matchers.h" | |
| 8 #include "src/compiler/node-properties-inl.h" | |
| 9 #include "src/types.h" | |
| 10 | |
| 11 namespace v8 { | |
| 12 namespace internal { | |
| 13 namespace compiler { | |
| 14 | |
| 15 | |
| 16 // Helper method that assumes replacement nodes are pure values that don't | |
| 17 // produce an effect. Replaces {node} with {reduction} and relaxes effects. | |
| 18 static Reduction ReplaceWithPureReduction(Node* node, Reduction reduction) { | |
| 19 if (reduction.Changed()) { | |
| 20 NodeProperties::ReplaceWithValue(node, reduction.replacement()); | |
| 21 return reduction; | |
| 22 } | |
| 23 return Reducer::NoChange(); | |
| 24 } | |
| 25 | |
| 26 | |
| 27 // Helper class to access JSCallFunction nodes that are potential candidates | |
| 28 // for reduction when they have a BuiltinFunctionId associated with them. | |
| 29 class JSCallReduction { | |
| 30 public: | |
| 31 explicit JSCallReduction(Node* node) : node_(node) {} | |
| 32 | |
| 33 // Determines whether the node is a JSCallFunction operation that targets a | |
| 34 // constant callee being a well-known builtin with a BuiltinFunctionId. | |
| 35 bool HasBuiltinFunctionId() { | |
| 36 if (node_->opcode() != IrOpcode::kJSCallFunction) return false; | |
| 37 HeapObjectMatcher<JSFunction> m(NodeProperties::GetValueInput(node_, 0)); | |
| 38 return m.HasValue() && m.Value().handle()->shared()->HasBuiltinFunctionId(); | |
| 39 } | |
| 40 | |
| 41 // Retrieves the BuiltinFunctionId as described above. | |
| 42 BuiltinFunctionId GetBuiltinFunctionId() { | |
| 43 DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode()); | |
| 44 HeapObjectMatcher<JSFunction> m(NodeProperties::GetValueInput(node_, 0)); | |
| 45 return m.Value().handle()->shared()->builtin_function_id(); | |
| 46 } | |
| 47 | |
| 48 // Determines whether the call takes one input of the given type. | |
| 49 bool InputsMatch(Type* t1) { | |
| 50 return GetJSCallArity() == 1 && | |
| 51 NodeProperties::GetBounds(GetJSCallInput(0)).upper->Is(t1); | |
| 52 } | |
| 53 | |
| 54 // Determines whether the call takes two inputs of the given types. | |
| 55 bool InputsMatch(Type* t1, Type* t2) { | |
| 56 return GetJSCallArity() == 2 && | |
| 57 NodeProperties::GetBounds(GetJSCallInput(0)).upper->Is(t1) && | |
| 58 NodeProperties::GetBounds(GetJSCallInput(1)).upper->Is(t2); | |
| 59 } | |
| 60 | |
| 61 Node* left() { return GetJSCallInput(0); } | |
| 62 Node* right() { return GetJSCallInput(1); } | |
| 63 | |
| 64 protected: | |
| 65 int GetJSCallArity() { | |
| 66 DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode()); | |
| 67 return OperatorProperties::GetValueInputCount(node_->op()) - 2; | |
|
titzer
2014/09/19 11:06:15
+/- magic numbers should be documented.
Michael Starzinger
2014/09/19 11:18:30
Done.
| |
| 68 } | |
| 69 | |
| 70 Node* GetJSCallInput(int index) { | |
| 71 DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode()); | |
| 72 DCHECK_LT(index, GetJSCallArity()); | |
| 73 return NodeProperties::GetValueInput(node_, index + 2); | |
| 74 } | |
| 75 | |
| 76 private: | |
| 77 Node* node_; | |
| 78 }; | |
| 79 | |
| 80 | |
| 81 // ES6 draft 08-24-14, section 20.2.2.19. | |
| 82 Reduction JSBuiltinReducer::ReduceMathImul(Node* node) { | |
| 83 JSCallReduction r(node); | |
| 84 if (r.InputsMatch(Type::Integral32(), Type::Integral32())) { | |
| 85 // Math.imul(a:int32, b:int32) -> Int32Mul(a, b) | |
| 86 Node* value = graph()->NewNode(machine()->Int32Mul(), r.left(), r.right()); | |
| 87 return Replace(value); | |
| 88 } | |
| 89 return NoChange(); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 Reduction JSBuiltinReducer::Reduce(Node* node) { | |
| 94 JSCallReduction r(node); | |
| 95 | |
| 96 // Dispatch according to the BuiltinFunctionId if present. | |
| 97 if (!r.HasBuiltinFunctionId()) return NoChange(); | |
| 98 switch (r.GetBuiltinFunctionId()) { | |
| 99 case kMathImul: | |
| 100 return ReplaceWithPureReduction(node, ReduceMathImul(node)); | |
| 101 default: | |
| 102 break; | |
| 103 } | |
| 104 return NoChange(); | |
| 105 } | |
| 106 | |
| 107 } // namespace compiler | |
| 108 } // namespace internal | |
| 109 } // namespace v8 | |
| OLD | NEW |