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

Side by Side Diff: src/compiler/js-intrinsic-lowering.cc

Issue 872363002: [turbofan] Add new JSIntrinsicsLowering reducer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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 unified diff | Download patch
« no previous file with comments | « src/compiler/js-intrinsic-lowering.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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/js-intrinsic-lowering.h"
6
7 #include "src/compiler/access-builder.h"
8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/node-properties-inl.h"
10
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14
15 JSIntrinsicLowering::JSIntrinsicLowering(JSGraph* jsgraph)
16 : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
17
18
19 Reduction JSIntrinsicLowering::Reduce(Node* node) {
20 if (node->opcode() != IrOpcode::kJSCallRuntime) return NoChange();
21 const Runtime::Function* const f =
22 Runtime::FunctionForId(CallRuntimeParametersOf(node->op()).id());
23 if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) return NoChange();
24 switch (f->function_id) {
25 case Runtime::kInlineIsSmi:
26 return ReduceInlineIsSmi(node);
27 case Runtime::kInlineIsNonNegativeSmi:
28 return ReduceInlineIsNonNegativeSmi(node);
29 case Runtime::kInlineIsArray:
30 return ReduceInlineIsInstanceType(node, JS_ARRAY_TYPE);
31 case Runtime::kInlineIsFunction:
32 return ReduceInlineIsInstanceType(node, JS_FUNCTION_TYPE);
33 case Runtime::kInlineIsRegExp:
34 return ReduceInlineIsInstanceType(node, JS_REGEXP_TYPE);
35 case Runtime::kInlineValueOf:
36 return ReduceInlineValueOf(node);
37 default:
38 break;
39 }
40 return NoChange();
41 }
42
43
44 Reduction JSIntrinsicLowering::ReduceInlineIsSmi(Node* node) {
45 return Change(node, simplified()->ObjectIsSmi());
46 }
47
48
49 Reduction JSIntrinsicLowering::ReduceInlineIsNonNegativeSmi(Node* node) {
50 return Change(node, simplified()->ObjectIsNonNegativeSmi());
51 }
52
53
54 Reduction JSIntrinsicLowering::ReduceInlineIsInstanceType(
55 Node* node, InstanceType instance_type) {
56 // if (%_IsSmi(value)) {
57 // return false;
58 // } else {
59 // return %_GetInstanceType(%_GetMap(value)) == instance_type;
60 // }
61 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
62
63 Node* value = NodeProperties::GetValueInput(node, 0);
64 Node* effect = NodeProperties::GetEffectInput(node);
65 Node* control = NodeProperties::GetControlInput(node);
66
67 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), value);
68 Node* branch = graph()->NewNode(common()->Branch(), check, control);
69
70 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
71 Node* etrue = effect;
72 Node* vtrue = jsgraph()->FalseConstant();
73
74 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
75 Node* efalse = graph()->NewNode(
76 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
77 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), value,
78 effect, if_false),
79 effect, if_false);
80 Node* vfalse = graph()->NewNode(machine()->Word32Equal(), efalse,
81 jsgraph()->Int32Constant(instance_type));
82
83 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
84
85 // Replace all effect uses of {node} with the {ephi}.
86 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
87 NodeProperties::ReplaceWithValue(node, node, ephi);
88
89 // Turn the {node} into a Phi.
90 return Change(node, common()->Phi(type, 2), vtrue, vfalse, merge);
91 }
92
93
94 Reduction JSIntrinsicLowering::ReduceInlineValueOf(Node* node) {
95 // if (%_IsSmi(value)) {
96 // return value;
97 // } else if (%_GetInstanceType(%_GetMap(value)) == JS_VALUE_TYPE) {
98 // return %_GetValue(value);
99 // } else {
100 // return value;
101 // }
102 const Operator* const merge_op = common()->Merge(2);
103 const Operator* const ephi_op = common()->EffectPhi(2);
104 const Operator* const phi_op = common()->Phi(kMachAnyTagged, 2);
105
106 Node* value = NodeProperties::GetValueInput(node, 0);
107 Node* effect = NodeProperties::GetEffectInput(node);
108 Node* control = NodeProperties::GetControlInput(node);
109
110 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
111 Node* branch0 = graph()->NewNode(common()->Branch(), check0, control);
112
113 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
114 Node* etrue0 = effect;
115 Node* vtrue0 = value;
116
117 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
118 Node* efalse0;
119 Node* vfalse0;
120 {
121 Node* check1 = graph()->NewNode(
122 machine()->Word32Equal(),
123 graph()->NewNode(
124 simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
125 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
126 value, effect, if_false0),
127 effect, if_false0),
128 jsgraph()->Int32Constant(JS_VALUE_TYPE));
129 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
130
131 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
132 Node* etrue1 =
133 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForValue()),
134 value, effect, if_true1);
135 Node* vtrue1 = etrue1;
136
137 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
138 Node* efalse1 = effect;
139 Node* vfalse1 = value;
140
141 Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1);
142 efalse0 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1);
143 vfalse0 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1);
144 }
145
146 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
147
148
149 // Replace all effect uses of {node} with the {ephi0}.
150 Node* ephi0 = graph()->NewNode(ephi_op, etrue0, efalse0, merge0);
151 NodeProperties::ReplaceWithValue(node, node, ephi0);
152
153 // Turn the {node} into a Phi.
154 return Change(node, phi_op, vtrue0, vfalse0, merge0);
155 }
156
157
158 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op) {
159 // Remove the effects from the node and update its effect usages.
160 NodeProperties::ReplaceWithValue(node, node);
161 // Remove the inputs corresponding to context, effect and control.
162 NodeProperties::RemoveNonValueInputs(node);
163 // Finally update the operator to the new one.
164 node->set_op(op);
165 return Changed(node);
166 }
167
168
169 Reduction JSIntrinsicLowering::Change(Node* node, const Operator* op, Node* a,
170 Node* b, Node* c) {
171 node->set_op(op);
172 node->ReplaceInput(0, a);
173 node->ReplaceInput(1, b);
174 node->ReplaceInput(2, c);
175 node->TrimInputCount(3);
176 return Changed(node);
177 }
178
179
180 Graph* JSIntrinsicLowering::graph() const { return jsgraph()->graph(); }
181
182
183 CommonOperatorBuilder* JSIntrinsicLowering::common() const {
184 return jsgraph()->common();
185 }
186
187
188 MachineOperatorBuilder* JSIntrinsicLowering::machine() const {
189 return jsgraph()->machine();
190 }
191
192 } // namespace compiler
193 } // namespace internal
194 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-intrinsic-lowering.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698