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

Side by Side Diff: src/compiler/change-lowering.cc

Issue 703103003: [turbofan] Combine JSToNumber and ChangeTaggedToFloat64 for fast SMI case. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler/change-lowering.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/change-lowering.h" 5 #include "src/compiler/change-lowering.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/compiler/diamond.h" 8 #include "src/compiler/diamond.h"
9 #include "src/compiler/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
11 #include "src/compiler/machine-operator.h" 11 #include "src/compiler/machine-operator.h"
12 #include "src/compiler/node-properties-inl.h"
12 13
13 namespace v8 { 14 namespace v8 {
14 namespace internal { 15 namespace internal {
15 namespace compiler { 16 namespace compiler {
16 17
17 ChangeLowering::~ChangeLowering() {} 18 ChangeLowering::~ChangeLowering() {}
18 19
19 20
20 Reduction ChangeLowering::Reduce(Node* node) { 21 Reduction ChangeLowering::Reduce(Node* node) {
21 Node* control = graph()->start(); 22 Node* control = graph()->start();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 Node* effect = graph()->NewNode(common()->ValueEffect(1), value); 79 Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
79 Node* heap_number = graph()->NewNode(common()->Call(descriptor), target, 80 Node* heap_number = graph()->NewNode(common()->Call(descriptor), target,
80 context, effect, control); 81 context, effect, control);
81 Node* store = graph()->NewNode( 82 Node* store = graph()->NewNode(
82 machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)), 83 machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
83 heap_number, HeapNumberValueIndexConstant(), value, heap_number, control); 84 heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
84 return graph()->NewNode(common()->Finish(1), heap_number, store); 85 return graph()->NewNode(common()->Finish(1), heap_number, store);
85 } 86 }
86 87
87 88
89 Node* ChangeLowering::ChangeInt32ToFloat64(Node* value) {
90 return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
91 }
92
93
94 Node* ChangeLowering::ChangeSmiToFloat64(Node* value) {
95 return ChangeInt32ToFloat64(ChangeSmiToInt32(value));
96 }
97
98
88 Node* ChangeLowering::ChangeSmiToInt32(Node* value) { 99 Node* ChangeLowering::ChangeSmiToInt32(Node* value) {
89 value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant()); 100 value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
90 if (machine()->Is64()) { 101 if (machine()->Is64()) {
91 value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value); 102 value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
92 } 103 }
93 return value; 104 return value;
94 } 105 }
95 106
96 107
108 Node* ChangeLowering::ChangeUint32ToFloat64(Node* value) {
109 return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
110 }
111
112
113 Node* ChangeLowering::ChangeUint32ToSmi(Node* value) {
114 if (machine()->Is64()) {
115 value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
116 }
117 return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
118 }
119
120
97 Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) { 121 Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
98 return graph()->NewNode(machine()->Load(kMachFloat64), value, 122 return graph()->NewNode(machine()->Load(kMachFloat64), value,
99 HeapNumberValueIndexConstant(), graph()->start(), 123 HeapNumberValueIndexConstant(), graph()->start(),
100 control); 124 control);
101 } 125 }
102 126
103 127
128 Node* ChangeLowering::TestNotSmi(Node* value) {
129 STATIC_ASSERT(kSmiTag == 0);
130 STATIC_ASSERT(kSmiTagMask == 1);
131 return graph()->NewNode(machine()->WordAnd(), value,
132 jsgraph()->IntPtrConstant(kSmiTagMask));
133 }
134
135
136 Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) {
137 return graph()->NewNode(machine()->Uint32LessThanOrEqual(), lhs, rhs);
138 }
139
140
104 Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) { 141 Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
105 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged); 142 MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
106 return Replace(graph()->NewNode(common()->Select(type), val, 143 return Replace(graph()->NewNode(common()->Select(type), val,
107 jsgraph()->TrueConstant(), 144 jsgraph()->TrueConstant(),
108 jsgraph()->FalseConstant())); 145 jsgraph()->FalseConstant()));
109 } 146 }
110 147
111 148
112 Reduction ChangeLowering::ChangeBoolToBit(Node* val) { 149 Reduction ChangeLowering::ChangeBoolToBit(Node* val) {
113 return Replace( 150 return Replace(
114 graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant())); 151 graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant()));
115 } 152 }
116 153
117 154
118 Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) { 155 Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
119 return Replace(AllocateHeapNumberWithValue(val, control)); 156 return Replace(AllocateHeapNumberWithValue(val, control));
120 } 157 }
121 158
122 159
123 Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* control) { 160 Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) {
124 if (machine()->Is64()) { 161 if (machine()->Is64()) {
125 return Replace( 162 return Replace(graph()->NewNode(
126 graph()->NewNode(machine()->Word64Shl(), 163 machine()->Word64Shl(),
127 graph()->NewNode(machine()->ChangeInt32ToInt64(), val), 164 graph()->NewNode(machine()->ChangeInt32ToInt64(), value),
128 SmiShiftBitsConstant())); 165 SmiShiftBitsConstant()));
129 } 166 }
130 167
131 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val, val); 168 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
132 Node* ovf = graph()->NewNode(common()->Projection(1), add); 169 Node* ovf = graph()->NewNode(common()->Projection(1), add);
133 170
134 Diamond d(graph(), common(), ovf, BranchHint::kFalse); 171 Diamond d(graph(), common(), ovf, BranchHint::kFalse);
135 d.Chain(control); 172 d.Chain(control);
136 Node* heap_number = AllocateHeapNumberWithValue( 173 return Replace(
137 graph()->NewNode(machine()->ChangeInt32ToFloat64(), val), d.if_true); 174 d.Phi(kMachAnyTagged,
138 Node* smi = graph()->NewNode(common()->Projection(0), add); 175 AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), d.if_true),
139 return Replace(d.Phi(kMachAnyTagged, heap_number, smi)); 176 graph()->NewNode(common()->Projection(0), add)));
140 } 177 }
141 178
142 179
143 Reduction ChangeLowering::ChangeTaggedToUI32(Node* val, Node* control, 180 Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control,
144 Signedness signedness) { 181 Signedness signedness) {
145 STATIC_ASSERT(kSmiTag == 0); 182 const MachineType type = (signedness == kSigned) ? kMachInt32 : kMachUint32;
146 STATIC_ASSERT(kSmiTagMask == 1);
147
148 Node* tag = graph()->NewNode(machine()->WordAnd(), val,
149 jsgraph()->IntPtrConstant(kSmiTagMask));
150
151 Diamond d(graph(), common(), tag, BranchHint::kFalse);
152 d.Chain(control);
153 const Operator* op = (signedness == kSigned) 183 const Operator* op = (signedness == kSigned)
154 ? machine()->ChangeFloat64ToInt32() 184 ? machine()->ChangeFloat64ToInt32()
155 : machine()->ChangeFloat64ToUint32(); 185 : machine()->ChangeFloat64ToUint32();
156 Node* load = graph()->NewNode(op, LoadHeapNumberValue(val, d.if_true)); 186 Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
157 Node* number = ChangeSmiToInt32(val); 187 d.Chain(control);
158
159 return Replace( 188 return Replace(
160 d.Phi((signedness == kSigned) ? kMachInt32 : kMachUint32, load, number)); 189 d.Phi(type, graph()->NewNode(op, LoadHeapNumberValue(value, d.if_true)),
190 ChangeSmiToInt32(value)));
161 } 191 }
162 192
163 193
164 Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) { 194 namespace {
165 STATIC_ASSERT(kSmiTag == 0);
166 STATIC_ASSERT(kSmiTagMask == 1);
167 195
168 Node* tag = graph()->NewNode(machine()->WordAnd(), val, 196 bool CanCover(Node* value, IrOpcode::Value opcode) {
169 jsgraph()->IntPtrConstant(kSmiTagMask)); 197 if (value->opcode() != opcode) return false;
170 Diamond d(graph(), common(), tag, BranchHint::kFalse); 198 bool first = true;
199 for (auto i = value->uses().begin(); i != value->uses().end(); ++i) {
200 if (NodeProperties::IsEffectEdge(i.edge())) continue;
201 DCHECK(NodeProperties::IsValueEdge(i.edge()));
202 if (!first) return false;
203 first = false;
204 }
205 return true;
206 }
207
208 } // namespace
209
210
211 Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) {
212 if (CanCover(value, IrOpcode::kJSToNumber)) {
213 // ChangeTaggedToFloat64(JSToNumber(x)) =>
214 // if IsSmi(x) then ChangeSmiToFloat64(x)
215 // else let y = JSToNumber(x) in
216 // if IsSmi(y) then ChangeSmiToFloat64(y)
217 // else LoadHeapNumberValue(y)
218 Node* const object = NodeProperties::GetValueInput(value, 0);
219 Node* const context = NodeProperties::GetContextInput(value);
220 Node* const effect = NodeProperties::GetEffectInput(value);
221 Node* const control = NodeProperties::GetControlInput(value);
222
223 Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse);
224 d1.Chain(control);
225
226 Node* number =
227 graph()->NewNode(value->op(), object, context, effect, d1.if_true);
228 Diamond d2(graph(), common(), TestNotSmi(number));
229 d2.Nest(d1, true);
230 Node* phi2 = d2.Phi(kMachFloat64, LoadHeapNumberValue(number, d2.if_true),
231 ChangeSmiToFloat64(number));
232
233 Node* phi1 = d1.Phi(kMachFloat64, phi2, ChangeSmiToFloat64(object));
234 Node* ephi1 = d1.EffectPhi(number, effect);
235
236 for (auto i = value->uses().begin(); i != value->uses().end();) {
237 if (NodeProperties::IsEffectEdge(i.edge())) {
238 i.UpdateToAndIncrement(ephi1);
239 } else {
240 ++i;
241 }
242 }
243 return Replace(phi1);
244 }
245
246 Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
171 d.Chain(control); 247 d.Chain(control);
172 Node* load = LoadHeapNumberValue(val, d.if_true); 248 Node* load = LoadHeapNumberValue(value, d.if_true);
173 Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(), 249 Node* number = ChangeSmiToFloat64(value);
174 ChangeSmiToInt32(val));
175
176 return Replace(d.Phi(kMachFloat64, load, number)); 250 return Replace(d.Phi(kMachFloat64, load, number));
177 } 251 }
178 252
179 253
180 Reduction ChangeLowering::ChangeUint32ToTagged(Node* val, Node* control) { 254 Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) {
181 STATIC_ASSERT(kSmiTag == 0); 255 Diamond d(graph(), common(),
182 STATIC_ASSERT(kSmiTagMask == 1); 256 Uint32LessThanOrEqual(value, SmiMaxValueConstant()),
183 257 BranchHint::kTrue);
184 Node* cmp = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
185 SmiMaxValueConstant());
186 Diamond d(graph(), common(), cmp, BranchHint::kTrue);
187 d.Chain(control); 258 d.Chain(control);
188 Node* smi = graph()->NewNode( 259 return Replace(d.Phi(
189 machine()->WordShl(), 260 kMachAnyTagged, ChangeUint32ToSmi(value),
190 machine()->Is64() 261 AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), d.if_false)));
191 ? graph()->NewNode(machine()->ChangeUint32ToUint64(), val)
192 : val,
193 SmiShiftBitsConstant());
194
195 Node* heap_number = AllocateHeapNumberWithValue(
196 graph()->NewNode(machine()->ChangeUint32ToFloat64(), val), d.if_false);
197
198 return Replace(d.Phi(kMachAnyTagged, smi, heap_number));
199 } 262 }
200 263
201 264
202 Isolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); } 265 Isolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); }
203 266
204 267
205 Graph* ChangeLowering::graph() const { return jsgraph()->graph(); } 268 Graph* ChangeLowering::graph() const { return jsgraph()->graph(); }
206 269
207 270
208 CommonOperatorBuilder* ChangeLowering::common() const { 271 CommonOperatorBuilder* ChangeLowering::common() const {
209 return jsgraph()->common(); 272 return jsgraph()->common();
210 } 273 }
211 274
212 275
213 MachineOperatorBuilder* ChangeLowering::machine() const { 276 MachineOperatorBuilder* ChangeLowering::machine() const {
214 return jsgraph()->machine(); 277 return jsgraph()->machine();
215 } 278 }
216 279
217 } // namespace compiler 280 } // namespace compiler
218 } // namespace internal 281 } // namespace internal
219 } // namespace v8 282 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/change-lowering.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698