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

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

Issue 470593002: Unify MachineType and RepType. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler/representation-change.h ('k') | src/compiler/simplified-operator.h » ('j') | 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/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <deque> 7 #include <deque>
8 #include <queue> 8 #include <queue>
9 9
10 #include "src/compiler/common-operator.h" 10 #include "src/compiler/common-operator.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 // representation changes between uses that demand a particular 47 // representation changes between uses that demand a particular
48 // representation and nodes that produce a different representation. 48 // representation and nodes that produce a different representation.
49 LOWER 49 LOWER
50 }; 50 };
51 51
52 52
53 class RepresentationSelector { 53 class RepresentationSelector {
54 public: 54 public:
55 // Information for each node tracked during the fixpoint. 55 // Information for each node tracked during the fixpoint.
56 struct NodeInfo { 56 struct NodeInfo {
57 RepTypeUnion use : 14; // Union of all usages for the node. 57 MachineTypeUnion use : 14; // Union of all usages for the node.
58 bool queued : 1; // Bookkeeping for the traversal. 58 bool queued : 1; // Bookkeeping for the traversal.
59 bool visited : 1; // Bookkeeping for the traversal. 59 bool visited : 1; // Bookkeeping for the traversal.
60 RepTypeUnion output : 14; // Output type of the node. 60 MachineTypeUnion output : 14; // Output type of the node.
61 }; 61 };
62 62
63 RepresentationSelector(JSGraph* jsgraph, Zone* zone, 63 RepresentationSelector(JSGraph* jsgraph, Zone* zone,
64 RepresentationChanger* changer) 64 RepresentationChanger* changer)
65 : jsgraph_(jsgraph), 65 : jsgraph_(jsgraph),
66 count_(jsgraph->graph()->NodeCount()), 66 count_(jsgraph->graph()->NodeCount()),
67 info_(zone->NewArray<NodeInfo>(count_)), 67 info_(zone->NewArray<NodeInfo>(count_)),
68 nodes_(NodeVector::allocator_type(zone)), 68 nodes_(NodeVector::allocator_type(zone)),
69 replacements_(NodeVector::allocator_type(zone)), 69 replacements_(NodeVector::allocator_type(zone)),
70 contains_js_nodes_(false), 70 contains_js_nodes_(false),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 for (NodeVector::iterator i = replacements_.begin(); 108 for (NodeVector::iterator i = replacements_.begin();
109 i != replacements_.end(); ++i) { 109 i != replacements_.end(); ++i) {
110 Node* node = *i; 110 Node* node = *i;
111 Node* replacement = *(++i); 111 Node* replacement = *(++i);
112 node->ReplaceUses(replacement); 112 node->ReplaceUses(replacement);
113 } 113 }
114 } 114 }
115 115
116 // Enqueue {node} if the {use} contains new information for that node. 116 // Enqueue {node} if the {use} contains new information for that node.
117 // Add {node} to {nodes_} if this is the first time it's been visited. 117 // Add {node} to {nodes_} if this is the first time it's been visited.
118 void Enqueue(Node* node, RepTypeUnion use = 0) { 118 void Enqueue(Node* node, MachineTypeUnion use = 0) {
119 if (phase_ != PROPAGATE) return; 119 if (phase_ != PROPAGATE) return;
120 NodeInfo* info = GetInfo(node); 120 NodeInfo* info = GetInfo(node);
121 if (!info->visited) { 121 if (!info->visited) {
122 // First visit of this node. 122 // First visit of this node.
123 info->visited = true; 123 info->visited = true;
124 info->queued = true; 124 info->queued = true;
125 nodes_.push_back(node); 125 nodes_.push_back(node);
126 queue_.push(node); 126 queue_.push(node);
127 TRACE((" initial: ")); 127 TRACE((" initial: "));
128 info->use |= use; 128 info->use |= use;
(...skipping 11 matching lines...) Expand all
140 } else { 140 } else {
141 TRACE((" inqueue: ")); 141 TRACE((" inqueue: "));
142 } 142 }
143 info->use |= use; 143 info->use |= use;
144 PrintUseInfo(node); 144 PrintUseInfo(node);
145 } 145 }
146 } 146 }
147 147
148 bool lower() { return phase_ == LOWER; } 148 bool lower() { return phase_ == LOWER; }
149 149
150 void Enqueue(Node* node, RepType use) { 150 void Enqueue(Node* node, MachineType use) {
151 Enqueue(node, static_cast<RepTypeUnion>(use)); 151 Enqueue(node, static_cast<MachineTypeUnion>(use));
152 } 152 }
153 153
154 void SetOutput(Node* node, RepTypeUnion output) { 154 void SetOutput(Node* node, MachineTypeUnion output) {
155 // Every node should have at most one output representation. Note that 155 // Every node should have at most one output representation. Note that
156 // phis can have 0, if they have not been used in a representation-inducing 156 // phis can have 0, if they have not been used in a representation-inducing
157 // instruction. 157 // instruction.
158 DCHECK((output & rMask) == 0 || IsPowerOf2(output & rMask)); 158 DCHECK((output & kRepMask) == 0 || IsPowerOf2(output & kRepMask));
159 GetInfo(node)->output = output; 159 GetInfo(node)->output = output;
160 } 160 }
161 161
162 bool BothInputsAre(Node* node, Type* type) { 162 bool BothInputsAre(Node* node, Type* type) {
163 DCHECK_EQ(2, node->InputCount()); 163 DCHECK_EQ(2, node->InputCount());
164 return NodeProperties::GetBounds(node->InputAt(0)).upper->Is(type) && 164 return NodeProperties::GetBounds(node->InputAt(0)).upper->Is(type) &&
165 NodeProperties::GetBounds(node->InputAt(1)).upper->Is(type); 165 NodeProperties::GetBounds(node->InputAt(1)).upper->Is(type);
166 } 166 }
167 167
168 void ProcessInput(Node* node, int index, RepTypeUnion use) { 168 void ProcessInput(Node* node, int index, MachineTypeUnion use) {
169 Node* input = node->InputAt(index); 169 Node* input = node->InputAt(index);
170 if (phase_ == PROPAGATE) { 170 if (phase_ == PROPAGATE) {
171 // In the propagate phase, propagate the usage information backward. 171 // In the propagate phase, propagate the usage information backward.
172 Enqueue(input, use); 172 Enqueue(input, use);
173 } else { 173 } else {
174 // In the change phase, insert a change before the use if necessary. 174 // In the change phase, insert a change before the use if necessary.
175 if ((use & rMask) == 0) return; // No input requirement on the use. 175 if ((use & kRepMask) == 0) return; // No input requirement on the use.
176 RepTypeUnion output = GetInfo(input)->output; 176 MachineTypeUnion output = GetInfo(input)->output;
177 if ((output & rMask & use) == 0) { 177 if ((output & kRepMask & use) == 0) {
178 // Output representation doesn't match usage. 178 // Output representation doesn't match usage.
179 TRACE((" change: #%d:%s(@%d #%d:%s) ", node->id(), 179 TRACE((" change: #%d:%s(@%d #%d:%s) ", node->id(),
180 node->op()->mnemonic(), index, input->id(), 180 node->op()->mnemonic(), index, input->id(),
181 input->op()->mnemonic())); 181 input->op()->mnemonic()));
182 TRACE((" from ")); 182 TRACE((" from "));
183 PrintInfo(output); 183 PrintInfo(output);
184 TRACE((" to ")); 184 TRACE((" to "));
185 PrintInfo(use); 185 PrintInfo(use);
186 TRACE(("\n")); 186 TRACE(("\n"));
187 Node* n = changer_->GetRepresentationFor(input, output, use); 187 Node* n = changer_->GetRepresentationFor(input, output, use);
188 node->ReplaceInput(index, n); 188 node->ReplaceInput(index, n);
189 } 189 }
190 } 190 }
191 } 191 }
192 192
193 static const RepTypeUnion kFloat64 = rFloat64 | tNumber;
194 static const RepTypeUnion kInt32 = rWord32 | tInt32;
195 static const RepTypeUnion kUint32 = rWord32 | tUint32;
196 static const RepTypeUnion kInt64 = rWord64 | tInt64;
197 static const RepTypeUnion kUint64 = rWord64 | tUint64;
198 static const RepTypeUnion kAnyTagged = rTagged | tAny;
199
200 // The default, most general visitation case. For {node}, process all value, 193 // The default, most general visitation case. For {node}, process all value,
201 // context, effect, and control inputs, assuming that value inputs should have 194 // context, effect, and control inputs, assuming that value inputs should have
202 // {rTagged} representation and can observe all output values {tAny}. 195 // {kRepTagged} representation and can observe all output values {kTypeAny}.
203 void VisitInputs(Node* node) { 196 void VisitInputs(Node* node) {
204 InputIter i = node->inputs().begin(); 197 InputIter i = node->inputs().begin();
205 for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0; 198 for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0;
206 ++i, j--) { 199 ++i, j--) {
207 ProcessInput(node, i.index(), kAnyTagged); // Value inputs 200 ProcessInput(node, i.index(), kMachAnyTagged); // Value inputs
208 } 201 }
209 for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0; 202 for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0;
210 ++i, j--) { 203 ++i, j--) {
211 ProcessInput(node, i.index(), kAnyTagged); // Context inputs 204 ProcessInput(node, i.index(), kMachAnyTagged); // Context inputs
212 } 205 }
213 for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0; 206 for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0;
214 ++i, j--) { 207 ++i, j--) {
215 Enqueue(*i); // Effect inputs: just visit 208 Enqueue(*i); // Effect inputs: just visit
216 } 209 }
217 for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0; 210 for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0;
218 ++i, j--) { 211 ++i, j--) {
219 Enqueue(*i); // Control inputs: just visit 212 Enqueue(*i); // Control inputs: just visit
220 } 213 }
221 SetOutput(node, kAnyTagged); 214 SetOutput(node, kMachAnyTagged);
222 } 215 }
223 216
224 // Helper for binops of the I x I -> O variety. 217 // Helper for binops of the I x I -> O variety.
225 void VisitBinop(Node* node, RepTypeUnion input_use, RepTypeUnion output) { 218 void VisitBinop(Node* node, MachineTypeUnion input_use,
219 MachineTypeUnion output) {
226 DCHECK_EQ(2, node->InputCount()); 220 DCHECK_EQ(2, node->InputCount());
227 ProcessInput(node, 0, input_use); 221 ProcessInput(node, 0, input_use);
228 ProcessInput(node, 1, input_use); 222 ProcessInput(node, 1, input_use);
229 SetOutput(node, output); 223 SetOutput(node, output);
230 } 224 }
231 225
232 // Helper for unops of the I -> O variety. 226 // Helper for unops of the I -> O variety.
233 void VisitUnop(Node* node, RepTypeUnion input_use, RepTypeUnion output) { 227 void VisitUnop(Node* node, MachineTypeUnion input_use,
228 MachineTypeUnion output) {
234 DCHECK_EQ(1, node->InputCount()); 229 DCHECK_EQ(1, node->InputCount());
235 ProcessInput(node, 0, input_use); 230 ProcessInput(node, 0, input_use);
236 SetOutput(node, output); 231 SetOutput(node, output);
237 } 232 }
238 233
239 // Helper for leaf nodes. 234 // Helper for leaf nodes.
240 void VisitLeaf(Node* node, RepTypeUnion output) { 235 void VisitLeaf(Node* node, MachineTypeUnion output) {
241 DCHECK_EQ(0, node->InputCount()); 236 DCHECK_EQ(0, node->InputCount());
242 SetOutput(node, output); 237 SetOutput(node, output);
243 } 238 }
244 239
245 // Helpers for specific types of binops. 240 // Helpers for specific types of binops.
246 void VisitFloat64Binop(Node* node) { VisitBinop(node, kFloat64, kFloat64); } 241 void VisitFloat64Binop(Node* node) {
247 void VisitInt32Binop(Node* node) { VisitBinop(node, kInt32, kInt32); } 242 VisitBinop(node, kMachFloat64, kMachFloat64);
248 void VisitUint32Binop(Node* node) { VisitBinop(node, kUint32, kUint32); } 243 }
249 void VisitInt64Binop(Node* node) { VisitBinop(node, kInt64, kInt64); } 244 void VisitInt32Binop(Node* node) { VisitBinop(node, kMachInt32, kMachInt32); }
250 void VisitUint64Binop(Node* node) { VisitBinop(node, kUint64, kUint64); } 245 void VisitUint32Binop(Node* node) {
251 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kFloat64, rBit); } 246 VisitBinop(node, kMachUint32, kMachUint32);
252 void VisitInt32Cmp(Node* node) { VisitBinop(node, kInt32, rBit); } 247 }
253 void VisitUint32Cmp(Node* node) { VisitBinop(node, kUint32, rBit); } 248 void VisitInt64Binop(Node* node) { VisitBinop(node, kMachInt64, kMachInt64); }
254 void VisitInt64Cmp(Node* node) { VisitBinop(node, kInt64, rBit); } 249 void VisitUint64Binop(Node* node) {
255 void VisitUint64Cmp(Node* node) { VisitBinop(node, kUint64, rBit); } 250 VisitBinop(node, kMachUint64, kMachUint64);
251 }
252 void VisitFloat64Cmp(Node* node) { VisitBinop(node, kMachFloat64, kRepBit); }
253 void VisitInt32Cmp(Node* node) { VisitBinop(node, kMachInt32, kRepBit); }
254 void VisitUint32Cmp(Node* node) { VisitBinop(node, kMachUint32, kRepBit); }
255 void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); }
256 void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); }
256 257
257 // Helper for handling phis. 258 // Helper for handling phis.
258 void VisitPhi(Node* node, RepTypeUnion use) { 259 void VisitPhi(Node* node, MachineTypeUnion use) {
259 // First, propagate the usage information to inputs of the phi. 260 // First, propagate the usage information to inputs of the phi.
260 int values = OperatorProperties::GetValueInputCount(node->op()); 261 int values = OperatorProperties::GetValueInputCount(node->op());
261 Node::Inputs inputs = node->inputs(); 262 Node::Inputs inputs = node->inputs();
262 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); 263 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
263 ++iter, --values) { 264 ++iter, --values) {
264 // Propagate {use} of the phi to value inputs, and 0 to control. 265 // Propagate {use} of the phi to value inputs, and 0 to control.
265 // TODO(titzer): it'd be nice to have distinguished edge kinds here. 266 // TODO(titzer): it'd be nice to have distinguished edge kinds here.
266 ProcessInput(node, iter.index(), values > 0 ? use : 0); 267 ProcessInput(node, iter.index(), values > 0 ? use : 0);
267 } 268 }
268 // Phis adapt to whatever output representation their uses demand, 269 // Phis adapt to whatever output representation their uses demand,
269 // pushing representation changes to their inputs. 270 // pushing representation changes to their inputs.
270 RepTypeUnion use_rep = GetUseInfo(node) & rMask; 271 MachineTypeUnion use_rep = GetUseInfo(node) & kRepMask;
271 RepTypeUnion use_type = GetUseInfo(node) & tMask; 272 MachineTypeUnion use_type = GetUseInfo(node) & kTypeMask;
272 RepTypeUnion rep = 0; 273 MachineTypeUnion rep = 0;
273 if (use_rep & rTagged) { 274 if (use_rep & kRepTagged) {
274 rep = rTagged; // Tagged overrides everything. 275 rep = kRepTagged; // Tagged overrides everything.
275 } else if (use_rep & rFloat64) { 276 } else if (use_rep & kRepFloat64) {
276 rep = rFloat64; 277 rep = kRepFloat64;
277 } else if (use_rep & rWord64) { 278 } else if (use_rep & kRepWord64) {
278 rep = rWord64; 279 rep = kRepWord64;
279 } else if (use_rep & rWord32) { 280 } else if (use_rep & kRepWord32) {
280 rep = rWord32; 281 rep = kRepWord32;
281 } else if (use_rep & rBit) { 282 } else if (use_rep & kRepBit) {
282 rep = rBit; 283 rep = kRepBit;
283 } else { 284 } else {
284 // There was no representation associated with any of the uses. 285 // There was no representation associated with any of the uses.
285 // TODO(titzer): Select the best rep using phi's type, not the usage type? 286 // TODO(titzer): Select the best rep using phi's type, not the usage type?
286 if (use_type & tAny) { 287 if (use_type & kTypeAny) {
287 rep = rTagged; 288 rep = kRepTagged;
288 } else if (use_type & tNumber) { 289 } else if (use_type & kTypeNumber) {
289 rep = rFloat64; 290 rep = kRepFloat64;
290 } else if (use_type & tInt64 || use_type & tUint64) { 291 } else if (use_type & kTypeInt64 || use_type & kTypeUint64) {
291 rep = rWord64; 292 rep = kRepWord64;
292 } else if (use_type & tInt32 || use_type & tUint32) { 293 } else if (use_type & kTypeInt32 || use_type & kTypeUint32) {
293 rep = rWord32; 294 rep = kRepWord32;
294 } else if (use_type & tBool) { 295 } else if (use_type & kTypeBool) {
295 rep = rBit; 296 rep = kRepBit;
296 } else { 297 } else {
297 UNREACHABLE(); // should have at least a usage type! 298 UNREACHABLE(); // should have at least a usage type!
298 } 299 }
299 } 300 }
300 // Preserve the usage type, but set the representation. 301 // Preserve the usage type, but set the representation.
301 Type* upper = NodeProperties::GetBounds(node).upper; 302 Type* upper = NodeProperties::GetBounds(node).upper;
302 SetOutput(node, rep | changer_->TypeFromUpperBound(upper)); 303 SetOutput(node, rep | changer_->TypeFromUpperBound(upper));
303 } 304 }
304 305
305 Operator* Int32Op(Node* node) { 306 Operator* Int32Op(Node* node) {
306 return changer_->Int32OperatorFor(node->opcode()); 307 return changer_->Int32OperatorFor(node->opcode());
307 } 308 }
308 309
309 Operator* Uint32Op(Node* node) { 310 Operator* Uint32Op(Node* node) {
310 return changer_->Uint32OperatorFor(node->opcode()); 311 return changer_->Uint32OperatorFor(node->opcode());
311 } 312 }
312 313
313 Operator* Float64Op(Node* node) { 314 Operator* Float64Op(Node* node) {
314 return changer_->Float64OperatorFor(node->opcode()); 315 return changer_->Float64OperatorFor(node->opcode());
315 } 316 }
316 317
317 // Dispatching routine for visiting the node {node} with the usage {use}. 318 // Dispatching routine for visiting the node {node} with the usage {use}.
318 // Depending on the operator, propagate new usage info to the inputs. 319 // Depending on the operator, propagate new usage info to the inputs.
319 void VisitNode(Node* node, RepTypeUnion use, SimplifiedLowering* lowering) { 320 void VisitNode(Node* node, MachineTypeUnion use,
321 SimplifiedLowering* lowering) {
320 switch (node->opcode()) { 322 switch (node->opcode()) {
321 //------------------------------------------------------------------ 323 //------------------------------------------------------------------
322 // Common operators. 324 // Common operators.
323 //------------------------------------------------------------------ 325 //------------------------------------------------------------------
324 case IrOpcode::kStart: 326 case IrOpcode::kStart:
325 case IrOpcode::kDead: 327 case IrOpcode::kDead:
326 return VisitLeaf(node, 0); 328 return VisitLeaf(node, 0);
327 case IrOpcode::kParameter: { 329 case IrOpcode::kParameter: {
328 // TODO(titzer): use representation from linkage. 330 // TODO(titzer): use representation from linkage.
329 Type* upper = NodeProperties::GetBounds(node).upper; 331 Type* upper = NodeProperties::GetBounds(node).upper;
330 ProcessInput(node, 0, 0); 332 ProcessInput(node, 0, 0);
331 SetOutput(node, rTagged | changer_->TypeFromUpperBound(upper)); 333 SetOutput(node, kRepTagged | changer_->TypeFromUpperBound(upper));
332 return; 334 return;
333 } 335 }
334 case IrOpcode::kInt32Constant: 336 case IrOpcode::kInt32Constant:
335 return VisitLeaf(node, rWord32); 337 return VisitLeaf(node, kRepWord32);
336 case IrOpcode::kInt64Constant: 338 case IrOpcode::kInt64Constant:
337 return VisitLeaf(node, rWord64); 339 return VisitLeaf(node, kRepWord64);
338 case IrOpcode::kFloat64Constant: 340 case IrOpcode::kFloat64Constant:
339 return VisitLeaf(node, rFloat64); 341 return VisitLeaf(node, kRepFloat64);
340 case IrOpcode::kExternalConstant: 342 case IrOpcode::kExternalConstant:
341 return VisitLeaf(node, rPtr); 343 return VisitLeaf(node, kMachPtr);
342 case IrOpcode::kNumberConstant: 344 case IrOpcode::kNumberConstant:
343 return VisitLeaf(node, rTagged); 345 return VisitLeaf(node, kRepTagged);
344 case IrOpcode::kHeapConstant: 346 case IrOpcode::kHeapConstant:
345 return VisitLeaf(node, rTagged); 347 return VisitLeaf(node, kRepTagged);
346 348
347 case IrOpcode::kEnd: 349 case IrOpcode::kEnd:
348 case IrOpcode::kIfTrue: 350 case IrOpcode::kIfTrue:
349 case IrOpcode::kIfFalse: 351 case IrOpcode::kIfFalse:
350 case IrOpcode::kReturn: 352 case IrOpcode::kReturn:
351 case IrOpcode::kMerge: 353 case IrOpcode::kMerge:
352 case IrOpcode::kThrow: 354 case IrOpcode::kThrow:
353 return VisitInputs(node); // default visit for all node inputs. 355 return VisitInputs(node); // default visit for all node inputs.
354 356
355 case IrOpcode::kBranch: 357 case IrOpcode::kBranch:
356 ProcessInput(node, 0, rBit); 358 ProcessInput(node, 0, kRepBit);
357 Enqueue(NodeProperties::GetControlInput(node, 0)); 359 Enqueue(NodeProperties::GetControlInput(node, 0));
358 break; 360 break;
359 case IrOpcode::kPhi: 361 case IrOpcode::kPhi:
360 return VisitPhi(node, use); 362 return VisitPhi(node, use);
361 363
362 //------------------------------------------------------------------ 364 //------------------------------------------------------------------
363 // JavaScript operators. 365 // JavaScript operators.
364 //------------------------------------------------------------------ 366 //------------------------------------------------------------------
365 // For now, we assume that all JS operators were too complex to lower 367 // For now, we assume that all JS operators were too complex to lower
366 // to Simplified and that they will always require tagged value inputs 368 // to Simplified and that they will always require tagged value inputs
367 // and produce tagged value outputs. 369 // and produce tagged value outputs.
368 // TODO(turbofan): it might be possible to lower some JSOperators here, 370 // TODO(turbofan): it might be possible to lower some JSOperators here,
369 // but that responsibility really lies in the typed lowering phase. 371 // but that responsibility really lies in the typed lowering phase.
370 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: 372 #define DEFINE_JS_CASE(x) case IrOpcode::k##x:
371 JS_OP_LIST(DEFINE_JS_CASE) 373 JS_OP_LIST(DEFINE_JS_CASE)
372 #undef DEFINE_JS_CASE 374 #undef DEFINE_JS_CASE
373 contains_js_nodes_ = true; 375 contains_js_nodes_ = true;
374 VisitInputs(node); 376 VisitInputs(node);
375 return SetOutput(node, rTagged); 377 return SetOutput(node, kRepTagged);
376 378
377 //------------------------------------------------------------------ 379 //------------------------------------------------------------------
378 // Simplified operators. 380 // Simplified operators.
379 //------------------------------------------------------------------ 381 //------------------------------------------------------------------
380 case IrOpcode::kBooleanNot: { 382 case IrOpcode::kBooleanNot: {
381 if (lower()) { 383 if (lower()) {
382 RepTypeUnion input = GetInfo(node->InputAt(0))->output; 384 MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
383 if (input & rBit) { 385 if (input & kRepBit) {
384 // BooleanNot(x: rBit) => WordEqual(x, #0) 386 // BooleanNot(x: kRepBit) => WordEqual(x, #0)
385 node->set_op(lowering->machine()->WordEqual()); 387 node->set_op(lowering->machine()->WordEqual());
386 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); 388 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
387 } else { 389 } else {
388 // BooleanNot(x: rTagged) => WordEqual(x, #false) 390 // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
389 node->set_op(lowering->machine()->WordEqual()); 391 node->set_op(lowering->machine()->WordEqual());
390 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); 392 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
391 } 393 }
392 } else { 394 } else {
393 // No input representation requirement; adapt during lowering. 395 // No input representation requirement; adapt during lowering.
394 ProcessInput(node, 0, tBool); 396 ProcessInput(node, 0, kTypeBool);
395 SetOutput(node, rBit); 397 SetOutput(node, kRepBit);
396 } 398 }
397 break; 399 break;
398 } 400 }
399 case IrOpcode::kNumberEqual: 401 case IrOpcode::kNumberEqual:
400 case IrOpcode::kNumberLessThan: 402 case IrOpcode::kNumberLessThan:
401 case IrOpcode::kNumberLessThanOrEqual: { 403 case IrOpcode::kNumberLessThanOrEqual: {
402 // Number comparisons reduce to integer comparisons for integer inputs. 404 // Number comparisons reduce to integer comparisons for integer inputs.
403 if (BothInputsAre(node, Type::Signed32())) { 405 if (BothInputsAre(node, Type::Signed32())) {
404 // => signed Int32Cmp 406 // => signed Int32Cmp
405 VisitInt32Cmp(node); 407 VisitInt32Cmp(node);
406 if (lower()) node->set_op(Int32Op(node)); 408 if (lower()) node->set_op(Int32Op(node));
407 } else if (BothInputsAre(node, Type::Unsigned32())) { 409 } else if (BothInputsAre(node, Type::Unsigned32())) {
408 // => unsigned Int32Cmp 410 // => unsigned Int32Cmp
409 VisitUint32Cmp(node); 411 VisitUint32Cmp(node);
410 if (lower()) node->set_op(Uint32Op(node)); 412 if (lower()) node->set_op(Uint32Op(node));
411 } else { 413 } else {
412 // => Float64Cmp 414 // => Float64Cmp
413 VisitFloat64Cmp(node); 415 VisitFloat64Cmp(node);
414 if (lower()) node->set_op(Float64Op(node)); 416 if (lower()) node->set_op(Float64Op(node));
415 } 417 }
416 break; 418 break;
417 } 419 }
418 case IrOpcode::kNumberAdd: 420 case IrOpcode::kNumberAdd:
419 case IrOpcode::kNumberSubtract: { 421 case IrOpcode::kNumberSubtract: {
420 // Add and subtract reduce to Int32Add/Sub if the inputs 422 // Add and subtract reduce to Int32Add/Sub if the inputs
421 // are already integers and all uses are truncating. 423 // are already integers and all uses are truncating.
422 if (BothInputsAre(node, Type::Signed32()) && 424 if (BothInputsAre(node, Type::Signed32()) &&
423 (use & (tUint32 | tNumber | tAny)) == 0) { 425 (use & (kTypeUint32 | kTypeNumber | kTypeAny)) == 0) {
424 // => signed Int32Add/Sub 426 // => signed Int32Add/Sub
425 VisitInt32Binop(node); 427 VisitInt32Binop(node);
426 if (lower()) node->set_op(Int32Op(node)); 428 if (lower()) node->set_op(Int32Op(node));
427 } else if (BothInputsAre(node, Type::Unsigned32()) && 429 } else if (BothInputsAre(node, Type::Unsigned32()) &&
428 (use & (tInt32 | tNumber | tAny)) == 0) { 430 (use & (kTypeInt32 | kTypeNumber | kTypeAny)) == 0) {
429 // => unsigned Int32Add/Sub 431 // => unsigned Int32Add/Sub
430 VisitUint32Binop(node); 432 VisitUint32Binop(node);
431 if (lower()) node->set_op(Uint32Op(node)); 433 if (lower()) node->set_op(Uint32Op(node));
432 } else { 434 } else {
433 // => Float64Add/Sub 435 // => Float64Add/Sub
434 VisitFloat64Binop(node); 436 VisitFloat64Binop(node);
435 if (lower()) node->set_op(Float64Op(node)); 437 if (lower()) node->set_op(Float64Op(node));
436 } 438 }
437 break; 439 break;
438 } 440 }
439 case IrOpcode::kNumberMultiply: 441 case IrOpcode::kNumberMultiply:
440 case IrOpcode::kNumberDivide: 442 case IrOpcode::kNumberDivide:
441 case IrOpcode::kNumberModulus: { 443 case IrOpcode::kNumberModulus: {
442 // Float64Mul/Div/Mod 444 // Float64Mul/Div/Mod
443 VisitFloat64Binop(node); 445 VisitFloat64Binop(node);
444 if (lower()) node->set_op(Float64Op(node)); 446 if (lower()) node->set_op(Float64Op(node));
445 break; 447 break;
446 } 448 }
447 case IrOpcode::kNumberToInt32: { 449 case IrOpcode::kNumberToInt32: {
448 RepTypeUnion use_rep = use & rMask; 450 MachineTypeUnion use_rep = use & kRepMask;
449 if (lower()) { 451 if (lower()) {
450 RepTypeUnion in = GetInfo(node->InputAt(0))->output; 452 MachineTypeUnion in = GetInfo(node->InputAt(0))->output;
451 if ((in & tMask) == tInt32 || (in & rMask) == rWord32) { 453 if ((in & kTypeMask) == kTypeInt32 || (in & kRepMask) == kRepWord32) {
452 // If the input has type int32, or is already a word32, just change 454 // If the input has type int32, or is already a word32, just change
453 // representation if necessary. 455 // representation if necessary.
454 VisitUnop(node, tInt32 | use_rep, tInt32 | use_rep); 456 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
455 DeferReplacement(node, node->InputAt(0)); 457 DeferReplacement(node, node->InputAt(0));
456 } else { 458 } else {
457 // Require the input in float64 format and perform truncation. 459 // Require the input in float64 format and perform truncation.
458 // TODO(turbofan): could also avoid the truncation with a tag check. 460 // TODO(turbofan): could also avoid the truncation with a tag check.
459 VisitUnop(node, tInt32 | rFloat64, tInt32 | rWord32); 461 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
460 // TODO(titzer): should be a truncation. 462 // TODO(titzer): should be a truncation.
461 node->set_op(lowering->machine()->ChangeFloat64ToInt32()); 463 node->set_op(lowering->machine()->ChangeFloat64ToInt32());
462 } 464 }
463 } else { 465 } else {
464 // Propagate a type to the input, but pass through representation. 466 // Propagate a type to the input, but pass through representation.
465 VisitUnop(node, tInt32, tInt32 | use_rep); 467 VisitUnop(node, kTypeInt32, kTypeInt32 | use_rep);
466 } 468 }
467 break; 469 break;
468 } 470 }
469 case IrOpcode::kNumberToUint32: { 471 case IrOpcode::kNumberToUint32: {
470 RepTypeUnion use_rep = use & rMask; 472 MachineTypeUnion use_rep = use & kRepMask;
471 if (lower()) { 473 if (lower()) {
472 RepTypeUnion in = GetInfo(node->InputAt(0))->output; 474 MachineTypeUnion in = GetInfo(node->InputAt(0))->output;
473 if ((in & tMask) == tUint32 || (in & rMask) == rWord32) { 475 if ((in & kTypeMask) == kTypeUint32 ||
476 (in & kRepMask) == kRepWord32) {
474 // The input has type int32, just change representation. 477 // The input has type int32, just change representation.
475 VisitUnop(node, tUint32 | use_rep, tUint32 | use_rep); 478 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
476 DeferReplacement(node, node->InputAt(0)); 479 DeferReplacement(node, node->InputAt(0));
477 } else { 480 } else {
478 // Require the input in float64 format to perform truncation. 481 // Require the input in float64 format to perform truncation.
479 // TODO(turbofan): could also avoid the truncation with a tag check. 482 // TODO(turbofan): could also avoid the truncation with a tag check.
480 VisitUnop(node, tUint32 | rFloat64, tUint32 | rWord32); 483 VisitUnop(node, kTypeUint32 | kRepFloat64,
484 kTypeUint32 | kRepWord32);
481 // TODO(titzer): should be a truncation. 485 // TODO(titzer): should be a truncation.
482 node->set_op(lowering->machine()->ChangeFloat64ToUint32()); 486 node->set_op(lowering->machine()->ChangeFloat64ToUint32());
483 } 487 }
484 } else { 488 } else {
485 // Propagate a type to the input, but pass through representation. 489 // Propagate a type to the input, but pass through representation.
486 VisitUnop(node, tUint32, tUint32 | use_rep); 490 VisitUnop(node, kTypeUint32, kTypeUint32 | use_rep);
487 } 491 }
488 break; 492 break;
489 } 493 }
490 case IrOpcode::kReferenceEqual: { 494 case IrOpcode::kReferenceEqual: {
491 VisitBinop(node, kAnyTagged, rBit); 495 VisitBinop(node, kMachAnyTagged, kRepBit);
492 if (lower()) node->set_op(lowering->machine()->WordEqual()); 496 if (lower()) node->set_op(lowering->machine()->WordEqual());
493 break; 497 break;
494 } 498 }
495 case IrOpcode::kStringEqual: { 499 case IrOpcode::kStringEqual: {
496 VisitBinop(node, kAnyTagged, rBit); 500 VisitBinop(node, kMachAnyTagged, kRepBit);
497 // TODO(titzer): lower StringEqual to stub/runtime call. 501 // TODO(titzer): lower StringEqual to stub/runtime call.
498 break; 502 break;
499 } 503 }
500 case IrOpcode::kStringLessThan: { 504 case IrOpcode::kStringLessThan: {
501 VisitBinop(node, kAnyTagged, rBit); 505 VisitBinop(node, kMachAnyTagged, kRepBit);
502 // TODO(titzer): lower StringLessThan to stub/runtime call. 506 // TODO(titzer): lower StringLessThan to stub/runtime call.
503 break; 507 break;
504 } 508 }
505 case IrOpcode::kStringLessThanOrEqual: { 509 case IrOpcode::kStringLessThanOrEqual: {
506 VisitBinop(node, kAnyTagged, rBit); 510 VisitBinop(node, kMachAnyTagged, kRepBit);
507 // TODO(titzer): lower StringLessThanOrEqual to stub/runtime call. 511 // TODO(titzer): lower StringLessThanOrEqual to stub/runtime call.
508 break; 512 break;
509 } 513 }
510 case IrOpcode::kStringAdd: { 514 case IrOpcode::kStringAdd: {
511 VisitBinop(node, kAnyTagged, kAnyTagged); 515 VisitBinop(node, kMachAnyTagged, kMachAnyTagged);
512 // TODO(titzer): lower StringAdd to stub/runtime call. 516 // TODO(titzer): lower StringAdd to stub/runtime call.
513 break; 517 break;
514 } 518 }
515 case IrOpcode::kLoadField: { 519 case IrOpcode::kLoadField: {
516 FieldAccess access = FieldAccessOf(node->op()); 520 FieldAccess access = FieldAccessOf(node->op());
517 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 521 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
518 SetOutput(node, changer_->TypeForField(access)); 522 SetOutput(node, access.machine_type);
519 if (lower()) lowering->DoLoadField(node); 523 if (lower()) lowering->DoLoadField(node);
520 break; 524 break;
521 } 525 }
522 case IrOpcode::kStoreField: { 526 case IrOpcode::kStoreField: {
523 FieldAccess access = FieldAccessOf(node->op()); 527 FieldAccess access = FieldAccessOf(node->op());
524 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 528 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
525 ProcessInput(node, 1, changer_->TypeForField(access)); 529 ProcessInput(node, 1, access.machine_type);
526 SetOutput(node, 0); 530 SetOutput(node, 0);
527 if (lower()) lowering->DoStoreField(node); 531 if (lower()) lowering->DoStoreField(node);
528 break; 532 break;
529 } 533 }
530 case IrOpcode::kLoadElement: { 534 case IrOpcode::kLoadElement: {
531 ElementAccess access = ElementAccessOf(node->op()); 535 ElementAccess access = ElementAccessOf(node->op());
532 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 536 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
533 ProcessInput(node, 1, kInt32); // element index 537 ProcessInput(node, 1, kMachInt32); // element index
534 SetOutput(node, changer_->TypeForElement(access)); 538 SetOutput(node, access.machine_type);
535 if (lower()) lowering->DoLoadElement(node); 539 if (lower()) lowering->DoLoadElement(node);
536 break; 540 break;
537 } 541 }
538 case IrOpcode::kStoreElement: { 542 case IrOpcode::kStoreElement: {
539 ElementAccess access = ElementAccessOf(node->op()); 543 ElementAccess access = ElementAccessOf(node->op());
540 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 544 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
541 ProcessInput(node, 1, kInt32); // element index 545 ProcessInput(node, 1, kMachInt32); // element index
542 ProcessInput(node, 2, changer_->TypeForElement(access)); 546 ProcessInput(node, 2, access.machine_type);
543 SetOutput(node, 0); 547 SetOutput(node, 0);
544 if (lower()) lowering->DoStoreElement(node); 548 if (lower()) lowering->DoStoreElement(node);
545 break; 549 break;
546 } 550 }
547 551
548 //------------------------------------------------------------------ 552 //------------------------------------------------------------------
549 // Machine-level operators. 553 // Machine-level operators.
550 //------------------------------------------------------------------ 554 //------------------------------------------------------------------
551 case IrOpcode::kLoad: { 555 case IrOpcode::kLoad: {
552 // TODO(titzer): machine loads/stores need to know BaseTaggedness!? 556 // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
553 RepType tBase = rTagged; 557 MachineType tBase = kRepTagged;
554 MachineType rep = OpParameter<MachineType>(node); 558 MachineType machine_type = OpParameter<MachineType>(node);
555 ProcessInput(node, 0, tBase); // pointer or object 559 ProcessInput(node, 0, tBase); // pointer or object
556 ProcessInput(node, 1, kInt32); // index 560 ProcessInput(node, 1, kMachInt32); // index
557 SetOutput(node, changer_->TypeForMachineType(rep)); 561 SetOutput(node, machine_type);
558 break; 562 break;
559 } 563 }
560 case IrOpcode::kStore: { 564 case IrOpcode::kStore: {
561 // TODO(titzer): machine loads/stores need to know BaseTaggedness!? 565 // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
562 RepType tBase = rTagged; 566 MachineType tBase = kRepTagged;
563 StoreRepresentation rep = OpParameter<StoreRepresentation>(node); 567 StoreRepresentation rep = OpParameter<StoreRepresentation>(node);
564 ProcessInput(node, 0, tBase); // pointer or object 568 ProcessInput(node, 0, tBase); // pointer or object
565 ProcessInput(node, 1, kInt32); // index 569 ProcessInput(node, 1, kMachInt32); // index
566 ProcessInput(node, 2, changer_->TypeForMachineType(rep.rep)); 570 ProcessInput(node, 2, rep.machine_type);
567 SetOutput(node, 0); 571 SetOutput(node, 0);
568 break; 572 break;
569 } 573 }
570 case IrOpcode::kWord32Shr: 574 case IrOpcode::kWord32Shr:
571 // We output unsigned int32 for shift right because JavaScript. 575 // We output unsigned int32 for shift right because JavaScript.
572 return VisitBinop(node, rWord32, rWord32 | tUint32); 576 return VisitBinop(node, kRepWord32, kRepWord32 | kTypeUint32);
573 case IrOpcode::kWord32And: 577 case IrOpcode::kWord32And:
574 case IrOpcode::kWord32Or: 578 case IrOpcode::kWord32Or:
575 case IrOpcode::kWord32Xor: 579 case IrOpcode::kWord32Xor:
576 case IrOpcode::kWord32Shl: 580 case IrOpcode::kWord32Shl:
577 case IrOpcode::kWord32Sar: 581 case IrOpcode::kWord32Sar:
578 // We use signed int32 as the output type for these word32 operations, 582 // We use signed int32 as the output type for these word32 operations,
579 // though the machine bits are the same for either signed or unsigned, 583 // though the machine bits are the same for either signed or unsigned,
580 // because JavaScript considers the result from these operations signed. 584 // because JavaScript considers the result from these operations signed.
581 return VisitBinop(node, rWord32, rWord32 | tInt32); 585 return VisitBinop(node, kRepWord32, kRepWord32 | kTypeInt32);
582 case IrOpcode::kWord32Equal: 586 case IrOpcode::kWord32Equal:
583 return VisitBinop(node, rWord32, rBit); 587 return VisitBinop(node, kRepWord32, kRepBit);
584 588
585 case IrOpcode::kInt32Add: 589 case IrOpcode::kInt32Add:
586 case IrOpcode::kInt32Sub: 590 case IrOpcode::kInt32Sub:
587 case IrOpcode::kInt32Mul: 591 case IrOpcode::kInt32Mul:
588 case IrOpcode::kInt32Div: 592 case IrOpcode::kInt32Div:
589 case IrOpcode::kInt32Mod: 593 case IrOpcode::kInt32Mod:
590 return VisitInt32Binop(node); 594 return VisitInt32Binop(node);
591 case IrOpcode::kInt32UDiv: 595 case IrOpcode::kInt32UDiv:
592 case IrOpcode::kInt32UMod: 596 case IrOpcode::kInt32UMod:
593 return VisitUint32Binop(node); 597 return VisitUint32Binop(node);
(...skipping 18 matching lines...) Expand all
612 case IrOpcode::kInt64UDiv: 616 case IrOpcode::kInt64UDiv:
613 case IrOpcode::kInt64UMod: 617 case IrOpcode::kInt64UMod:
614 return VisitUint64Binop(node); 618 return VisitUint64Binop(node);
615 619
616 case IrOpcode::kWord64And: 620 case IrOpcode::kWord64And:
617 case IrOpcode::kWord64Or: 621 case IrOpcode::kWord64Or:
618 case IrOpcode::kWord64Xor: 622 case IrOpcode::kWord64Xor:
619 case IrOpcode::kWord64Shl: 623 case IrOpcode::kWord64Shl:
620 case IrOpcode::kWord64Shr: 624 case IrOpcode::kWord64Shr:
621 case IrOpcode::kWord64Sar: 625 case IrOpcode::kWord64Sar:
622 return VisitBinop(node, rWord64, rWord64); 626 return VisitBinop(node, kRepWord64, kRepWord64);
623 case IrOpcode::kWord64Equal: 627 case IrOpcode::kWord64Equal:
624 return VisitBinop(node, rWord64, rBit); 628 return VisitBinop(node, kRepWord64, kRepBit);
625 629
626 case IrOpcode::kConvertInt32ToInt64: 630 case IrOpcode::kConvertInt32ToInt64:
627 return VisitUnop(node, tInt32 | rWord32, tInt32 | rWord64); 631 return VisitUnop(node, kTypeInt32 | kRepWord32,
632 kTypeInt32 | kRepWord64);
628 case IrOpcode::kConvertInt64ToInt32: 633 case IrOpcode::kConvertInt64ToInt32:
629 return VisitUnop(node, tInt64 | rWord64, tInt32 | rWord32); 634 return VisitUnop(node, kTypeInt64 | kRepWord64,
635 kTypeInt32 | kRepWord32);
630 636
631 case IrOpcode::kChangeInt32ToFloat64: 637 case IrOpcode::kChangeInt32ToFloat64:
632 return VisitUnop(node, tInt32 | rWord32, tInt32 | rFloat64); 638 return VisitUnop(node, kTypeInt32 | kRepWord32,
639 kTypeInt32 | kRepFloat64);
633 case IrOpcode::kChangeUint32ToFloat64: 640 case IrOpcode::kChangeUint32ToFloat64:
634 return VisitUnop(node, tUint32 | rWord32, tUint32 | rFloat64); 641 return VisitUnop(node, kTypeUint32 | kRepWord32,
642 kTypeUint32 | kRepFloat64);
635 case IrOpcode::kChangeFloat64ToInt32: 643 case IrOpcode::kChangeFloat64ToInt32:
636 return VisitUnop(node, tInt32 | rFloat64, tInt32 | rWord32); 644 return VisitUnop(node, kTypeInt32 | kRepFloat64,
645 kTypeInt32 | kRepWord32);
637 case IrOpcode::kChangeFloat64ToUint32: 646 case IrOpcode::kChangeFloat64ToUint32:
638 return VisitUnop(node, tUint32 | rFloat64, tUint32 | rWord32); 647 return VisitUnop(node, kTypeUint32 | kRepFloat64,
648 kTypeUint32 | kRepWord32);
639 649
640 case IrOpcode::kFloat64Add: 650 case IrOpcode::kFloat64Add:
641 case IrOpcode::kFloat64Sub: 651 case IrOpcode::kFloat64Sub:
642 case IrOpcode::kFloat64Mul: 652 case IrOpcode::kFloat64Mul:
643 case IrOpcode::kFloat64Div: 653 case IrOpcode::kFloat64Div:
644 case IrOpcode::kFloat64Mod: 654 case IrOpcode::kFloat64Mod:
645 return VisitFloat64Binop(node); 655 return VisitFloat64Binop(node);
646 case IrOpcode::kFloat64Equal: 656 case IrOpcode::kFloat64Equal:
647 case IrOpcode::kFloat64LessThan: 657 case IrOpcode::kFloat64LessThan:
648 case IrOpcode::kFloat64LessThanOrEqual: 658 case IrOpcode::kFloat64LessThanOrEqual:
(...skipping 18 matching lines...) Expand all
667 } 677 }
668 // TODO(titzer) node->RemoveAllInputs(); // Node is now dead. 678 // TODO(titzer) node->RemoveAllInputs(); // Node is now dead.
669 } 679 }
670 680
671 void PrintUseInfo(Node* node) { 681 void PrintUseInfo(Node* node) {
672 TRACE(("#%d:%-20s ", node->id(), node->op()->mnemonic())); 682 TRACE(("#%d:%-20s ", node->id(), node->op()->mnemonic()));
673 PrintInfo(GetUseInfo(node)); 683 PrintInfo(GetUseInfo(node));
674 TRACE(("\n")); 684 TRACE(("\n"));
675 } 685 }
676 686
677 void PrintInfo(RepTypeUnion info) { 687 void PrintInfo(MachineTypeUnion info) {
678 if (FLAG_trace_representation) { 688 if (FLAG_trace_representation) {
679 char buf[REP_TYPE_STRLEN]; 689 OFStream os(stdout);
680 RenderRepTypeUnion(buf, info); 690 os << static_cast<MachineType>(info);
681 TRACE(("%s", buf));
682 } 691 }
683 } 692 }
684 693
685 private: 694 private:
686 JSGraph* jsgraph_; 695 JSGraph* jsgraph_;
687 int count_; // number of nodes in the graph 696 int count_; // number of nodes in the graph
688 NodeInfo* info_; // node id -> usage information 697 NodeInfo* info_; // node id -> usage information
689 NodeVector nodes_; // collected nodes 698 NodeVector nodes_; // collected nodes
690 NodeVector replacements_; // replacements to be done after lowering 699 NodeVector replacements_; // replacements to be done after lowering
691 bool contains_js_nodes_; // {true} if a JS operator was seen 700 bool contains_js_nodes_; // {true} if a JS operator was seen
692 Phase phase_; // current phase of algorithm 701 Phase phase_; // current phase of algorithm
693 RepresentationChanger* changer_; // for inserting representation changes 702 RepresentationChanger* changer_; // for inserting representation changes
694 703
695 std::queue<Node*, std::deque<Node*, NodePtrZoneAllocator> > queue_; 704 std::queue<Node*, std::deque<Node*, NodePtrZoneAllocator> > queue_;
696 705
697 NodeInfo* GetInfo(Node* node) { 706 NodeInfo* GetInfo(Node* node) {
698 DCHECK(node->id() >= 0); 707 DCHECK(node->id() >= 0);
699 DCHECK(node->id() < count_); 708 DCHECK(node->id() < count_);
700 return &info_[node->id()]; 709 return &info_[node->id()];
701 } 710 }
702 711
703 RepTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } 712 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; }
704 }; 713 };
705 714
706 715
707 Node* SimplifiedLowering::IsTagged(Node* node) { 716 Node* SimplifiedLowering::IsTagged(Node* node) {
708 // TODO(titzer): factor this out to a TaggingScheme abstraction. 717 // TODO(titzer): factor this out to a TaggingScheme abstraction.
709 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. 718 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit.
710 return graph()->NewNode(machine()->WordAnd(), node, 719 return graph()->NewNode(machine()->WordAnd(), node,
711 jsgraph()->Int32Constant(kSmiTagMask)); 720 jsgraph()->Int32Constant(kSmiTagMask));
712 } 721 }
713 722
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 continue; 761 continue;
753 } 762 }
754 ++iter; 763 ++iter;
755 } 764 }
756 } 765 }
757 766
758 767
759 void SimplifiedLowering::DoChangeTaggedToUI32(Node* node, Node* effect, 768 void SimplifiedLowering::DoChangeTaggedToUI32(Node* node, Node* effect,
760 Node* control, bool is_signed) { 769 Node* control, bool is_signed) {
761 // if (IsTagged(val)) 770 // if (IsTagged(val))
762 // ConvertFloat64To(Int32|Uint32)(Load[kMachineFloat64](input, #value_offset)) 771 // ConvertFloat64To(Int32|Uint32)(Load[kMachFloat64](input, #value_offset))
763 // else Untag(val) 772 // else Untag(val)
764 Node* val = node->InputAt(0); 773 Node* val = node->InputAt(0);
765 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control); 774 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
766 775
767 // true branch. 776 // true branch.
768 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch); 777 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
769 Node* loaded = graph()->NewNode( 778 Node* loaded = graph()->NewNode(
770 machine()->Load(kMachineFloat64), val, 779 machine()->Load(kMachFloat64), val,
771 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect); 780 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
772 Operator* op = is_signed ? machine()->ChangeFloat64ToInt32() 781 Operator* op = is_signed ? machine()->ChangeFloat64ToInt32()
773 : machine()->ChangeFloat64ToUint32(); 782 : machine()->ChangeFloat64ToUint32();
774 Node* converted = graph()->NewNode(op, loaded); 783 Node* converted = graph()->NewNode(op, loaded);
775 784
776 // false branch. 785 // false branch.
777 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch); 786 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
778 Node* untagged = Untag(val); 787 Node* untagged = Untag(val);
779 788
780 // merge. 789 // merge.
781 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch); 790 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
782 Node* phi = graph()->NewNode(common()->Phi(2), converted, untagged, merge); 791 Node* phi = graph()->NewNode(common()->Phi(2), converted, untagged, merge);
783 UpdateControlSuccessors(control, merge); 792 UpdateControlSuccessors(control, merge);
784 branch->ReplaceInput(1, control); 793 branch->ReplaceInput(1, control);
785 node->ReplaceUses(phi); 794 node->ReplaceUses(phi);
786 } 795 }
787 796
788 797
789 void SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect, 798 void SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect,
790 Node* control) { 799 Node* control) {
791 // if (IsTagged(input)) Load[kMachineFloat64](input, #value_offset) 800 // if (IsTagged(input)) Load[kMachFloat64](input, #value_offset)
792 // else ConvertFloat64(Untag(input)) 801 // else ConvertFloat64(Untag(input))
793 Node* val = node->InputAt(0); 802 Node* val = node->InputAt(0);
794 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control); 803 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
795 804
796 // true branch. 805 // true branch.
797 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch); 806 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
798 Node* loaded = graph()->NewNode( 807 Node* loaded = graph()->NewNode(
799 machine()->Load(kMachineFloat64), val, 808 machine()->Load(kMachFloat64), val,
800 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect); 809 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
801 810
802 // false branch. 811 // false branch.
803 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch); 812 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
804 Node* untagged = Untag(val); 813 Node* untagged = Untag(val);
805 Node* converted = 814 Node* converted =
806 graph()->NewNode(machine()->ChangeInt32ToFloat64(), untagged); 815 graph()->NewNode(machine()->ChangeInt32ToFloat64(), untagged);
807 816
808 // merge. 817 // merge.
809 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch); 818 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 UpdateControlSuccessors(control, merge); 899 UpdateControlSuccessors(control, merge);
891 branch->ReplaceInput(1, control); 900 branch->ReplaceInput(1, control);
892 node->ReplaceUses(phi); 901 node->ReplaceUses(phi);
893 } 902 }
894 903
895 904
896 static WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged, 905 static WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
897 MachineType representation, 906 MachineType representation,
898 Type* type) { 907 Type* type) {
899 // TODO(turbofan): skip write barriers for Smis, etc. 908 // TODO(turbofan): skip write barriers for Smis, etc.
900 if (base_is_tagged == kTaggedBase && representation == kMachineTagged) { 909 if (base_is_tagged == kTaggedBase &&
910 RepresentationOf(representation) == kRepTagged) {
901 // Write barriers are only for writes into heap objects (i.e. tagged base). 911 // Write barriers are only for writes into heap objects (i.e. tagged base).
902 return kFullWriteBarrier; 912 return kFullWriteBarrier;
903 } 913 }
904 return kNoWriteBarrier; 914 return kNoWriteBarrier;
905 } 915 }
906 916
907 917
908 void SimplifiedLowering::DoLoadField(Node* node) { 918 void SimplifiedLowering::DoLoadField(Node* node) {
909 const FieldAccess& access = FieldAccessOf(node->op()); 919 const FieldAccess& access = FieldAccessOf(node->op());
910 node->set_op(machine_.Load(access.representation)); 920 node->set_op(machine_.Load(access.machine_type));
911 Node* offset = jsgraph()->Int32Constant(access.offset - access.tag()); 921 Node* offset = jsgraph()->Int32Constant(access.offset - access.tag());
912 node->InsertInput(zone(), 1, offset); 922 node->InsertInput(zone(), 1, offset);
913 } 923 }
914 924
915 925
916 void SimplifiedLowering::DoStoreField(Node* node) { 926 void SimplifiedLowering::DoStoreField(Node* node) {
917 const FieldAccess& access = FieldAccessOf(node->op()); 927 const FieldAccess& access = FieldAccessOf(node->op());
918 WriteBarrierKind kind = ComputeWriteBarrierKind( 928 WriteBarrierKind kind = ComputeWriteBarrierKind(
919 access.base_is_tagged, access.representation, access.type); 929 access.base_is_tagged, access.machine_type, access.type);
920 node->set_op(machine_.Store(access.representation, kind)); 930 node->set_op(machine_.Store(access.machine_type, kind));
921 Node* offset = jsgraph()->Int32Constant(access.offset - access.tag()); 931 Node* offset = jsgraph()->Int32Constant(access.offset - access.tag());
922 node->InsertInput(zone(), 1, offset); 932 node->InsertInput(zone(), 1, offset);
923 } 933 }
924 934
925 935
926 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access, 936 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
927 Node* index) { 937 Node* index) {
928 int element_size = 0; 938 int element_size = ElementSizeOf(access.machine_type);
929 switch (access.representation) {
930 case kMachineTagged:
931 element_size = kPointerSize;
932 break;
933 case kMachineWord8:
934 element_size = 1;
935 break;
936 case kMachineWord16:
937 element_size = 2;
938 break;
939 case kMachineWord32:
940 element_size = 4;
941 break;
942 case kMachineWord64:
943 case kMachineFloat64:
944 element_size = 8;
945 break;
946 case kMachineLast:
947 UNREACHABLE();
948 break;
949 }
950 if (element_size != 1) { 939 if (element_size != 1) {
951 index = graph()->NewNode(machine()->Int32Mul(), 940 index = graph()->NewNode(machine()->Int32Mul(),
952 jsgraph()->Int32Constant(element_size), index); 941 jsgraph()->Int32Constant(element_size), index);
953 } 942 }
954 int fixed_offset = access.header_size - access.tag(); 943 int fixed_offset = access.header_size - access.tag();
955 if (fixed_offset == 0) return index; 944 if (fixed_offset == 0) return index;
956 return graph()->NewNode(machine()->Int32Add(), index, 945 return graph()->NewNode(machine()->Int32Add(), index,
957 jsgraph()->Int32Constant(fixed_offset)); 946 jsgraph()->Int32Constant(fixed_offset));
958 } 947 }
959 948
960 949
961 void SimplifiedLowering::DoLoadElement(Node* node) { 950 void SimplifiedLowering::DoLoadElement(Node* node) {
962 const ElementAccess& access = ElementAccessOf(node->op()); 951 const ElementAccess& access = ElementAccessOf(node->op());
963 node->set_op(machine_.Load(access.representation)); 952 node->set_op(machine_.Load(access.machine_type));
964 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); 953 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
965 } 954 }
966 955
967 956
968 void SimplifiedLowering::DoStoreElement(Node* node) { 957 void SimplifiedLowering::DoStoreElement(Node* node) {
969 const ElementAccess& access = ElementAccessOf(node->op()); 958 const ElementAccess& access = ElementAccessOf(node->op());
970 WriteBarrierKind kind = ComputeWriteBarrierKind( 959 WriteBarrierKind kind = ComputeWriteBarrierKind(
971 access.base_is_tagged, access.representation, access.type); 960 access.base_is_tagged, access.machine_type, access.type);
972 node->set_op(machine_.Store(access.representation, kind)); 961 node->set_op(machine_.Store(access.machine_type, kind));
973 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); 962 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
974 } 963 }
975 964
976 965
977 void SimplifiedLowering::Lower(Node* node) {} 966 void SimplifiedLowering::Lower(Node* node) {}
978 967
979 968
980 void SimplifiedLowering::LowerChange(Node* node, Node* effect, Node* control) { 969 void SimplifiedLowering::LowerChange(Node* node, Node* effect, Node* control) {
981 switch (node->opcode()) { 970 switch (node->opcode()) {
982 case IrOpcode::kChangeTaggedToInt32: 971 case IrOpcode::kChangeTaggedToInt32:
(...skipping 22 matching lines...) Expand all
1005 break; 994 break;
1006 default: 995 default:
1007 UNREACHABLE(); 996 UNREACHABLE();
1008 break; 997 break;
1009 } 998 }
1010 } 999 }
1011 1000
1012 } // namespace compiler 1001 } // namespace compiler
1013 } // namespace internal 1002 } // namespace internal
1014 } // namespace v8 1003 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698