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

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

Issue 437583002: TF: Lowering representation changes to machine operators (WIP: need inline allocation for some). Mo… (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
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 "src/compiler/graph-inl.h" 7 #include "src/compiler/graph-inl.h"
8 #include "src/compiler/node-properties-inl.h"
8 #include "src/objects.h" 9 #include "src/objects.h"
9 10
10 namespace v8 { 11 namespace v8 {
11 namespace internal { 12 namespace internal {
12 namespace compiler { 13 namespace compiler {
13 14
14 Node* SimplifiedLowering::DoChangeTaggedToInt32(Node* node, Node* effect, 15 Node* SimplifiedLowering::IsTagged(Node* node) {
15 Node* control) { 16 // TODO(titzer): factor this out to a TaggingScheme abstraction.
16 return node; 17 STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit.
18 return graph()->NewNode(machine()->WordAnd(), node,
19 jsgraph()->Int32Constant(kSmiTagMask));
17 } 20 }
18 21
19 22
20 Node* SimplifiedLowering::DoChangeTaggedToUint32(Node* node, Node* effect, 23 Node* SimplifiedLowering::Untag(Node* node) {
21 Node* control) { 24 // TODO(titzer): factor this out to a TaggingScheme abstraction.
22 return node; 25 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize);
26 return graph()->NewNode(machine()->WordSar(), node, shift_amount);
23 } 27 }
24 28
25 29
26 Node* SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect, 30 Node* SimplifiedLowering::SmiTag(Node* node) {
27 Node* control) { 31 // TODO(titzer): factor this out to a TaggingScheme abstraction.
28 return node; 32 Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize);
33 return graph()->NewNode(machine()->WordShl(), node, shift_amount);
29 } 34 }
30 35
31 36
32 Node* SimplifiedLowering::DoChangeInt32ToTagged(Node* node, Node* effect, 37 Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) {
33 Node* control) { 38 return jsgraph()->Int32Constant(offset - kHeapObjectTag);
34 return node;
35 } 39 }
36 40
37 41
38 Node* SimplifiedLowering::DoChangeUint32ToTagged(Node* node, Node* effect, 42 static void UpdateControlSuccessors(Node* before, Node* node) {
39 Node* control) { 43 ASSERT(IrOpcode::IsControlOpcode(before->opcode()));
40 return node; 44 UseIter iter = before->uses().begin();
45 while (iter != before->uses().end()) {
46 if (IrOpcode::IsControlOpcode((*iter)->opcode()) &&
47 NodeProperties::IsControlEdge(iter.edge())) {
48 iter = iter.UpdateToAndIncrement(node);
49 continue;
50 }
51 ++iter;
52 }
41 } 53 }
42 54
43 55
44 Node* SimplifiedLowering::DoChangeFloat64ToTagged(Node* node, Node* effect, 56 void SimplifiedLowering::DoChangeTaggedToUI32(Node* node, Node* effect,
45 Node* control) { 57 Node* control, bool is_signed) {
46 return node; 58 // if (IsTagged(val))
59 // ConvertFloat64To(Int32|Uint32)(Load[kMachineFloat64](input, #value_offset))
60 // else Untag(val)
61 Node* val = node->InputAt(0);
62 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
63
64 // true branch.
65 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
66 Node* loaded = graph()->NewNode(
67 machine()->Load(kMachineFloat64), val,
68 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
69 Operator* op = is_signed ? machine()->ConvertFloat64ToInt32()
70 : machine()->ConvertFloat64ToUint32();
71 Node* converted = graph()->NewNode(op, loaded);
72
73 // false branch.
74 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
75 Node* untagged = Untag(val);
76
77 // merge.
78 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
79 Node* phi = graph()->NewNode(common()->Phi(2), converted, untagged, merge);
80 UpdateControlSuccessors(control, merge);
81 branch->ReplaceInput(1, control);
82 node->ReplaceUses(phi);
47 } 83 }
48 84
49 85
50 Node* SimplifiedLowering::DoChangeBoolToBit(Node* node, Node* effect, 86 void SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect,
51 Node* control) { 87 Node* control) {
88 // if (IsTagged(input)) Load[kMachineFloat64](input, #value_offset)
89 // else ConvertFloat64(Untag(input))
52 Node* val = node->InputAt(0); 90 Node* val = node->InputAt(0);
53 Operator* op = machine()->WordEqual(); 91 Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
54 return graph()->NewNode(op, val, jsgraph()->TrueConstant()); 92
93 // true branch.
94 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
95 Node* loaded = graph()->NewNode(
96 machine()->Load(kMachineFloat64), val,
97 OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
98
99 // false branch.
100 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
101 Node* untagged = Untag(val);
102 Node* converted =
103 graph()->NewNode(machine()->ConvertInt32ToFloat64(), untagged);
104
105 // merge.
106 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
107 Node* phi = graph()->NewNode(common()->Phi(2), loaded, converted, merge);
108 UpdateControlSuccessors(control, merge);
109 branch->ReplaceInput(1, control);
110 node->ReplaceUses(phi);
55 } 111 }
56 112
57 113
58 Node* SimplifiedLowering::DoChangeBitToBool(Node* node, Node* effect, 114 void SimplifiedLowering::DoChangeUI32ToTagged(Node* node, Node* effect,
59 Node* control) { 115 Node* control, bool is_signed) {
60 return node; 116 Node* val = node->InputAt(0);
117 Node* is_smi = NULL;
118 if (is_signed) {
119 if (SmiValuesAre32Bits()) {
120 // All int32s fit in this case.
121 ASSERT(kPointerSize == 8);
122 return node->ReplaceUses(SmiTag(val));
123 } else {
124 // TODO(turbofan): use an Int32AddWithOverflow to tag and check here.
125 Node* lt = graph()->NewNode(machine()->Int32LessThanOrEqual(), val,
126 jsgraph()->Int32Constant(Smi::kMaxValue));
127 Node* gt =
128 graph()->NewNode(machine()->Int32LessThanOrEqual(),
129 jsgraph()->Int32Constant(Smi::kMinValue), val);
130 is_smi = graph()->NewNode(machine()->Word32And(), lt, gt);
131 }
132 } else {
133 // Check if Uint32 value is in the smi range.
134 is_smi = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
135 jsgraph()->Int32Constant(Smi::kMaxValue));
136 }
137
138 // TODO(turbofan): fold smi test branch eagerly.
139 // if (IsSmi(input)) SmiTag(input);
140 // else InlineAllocAndInitHeapNumber(ConvertToFloat64(input)))
141 Node* branch = graph()->NewNode(common()->Branch(), is_smi, control);
142
143 // true branch.
144 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
145 Node* smi_tagged = SmiTag(val);
146
147 // false branch.
148 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
149 Node* heap_num = jsgraph()->Constant(0.0); // TODO(titzer): alloc and init
150
151 // merge.
152 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
153 Node* phi = graph()->NewNode(common()->Phi(2), smi_tagged, heap_num, merge);
154 UpdateControlSuccessors(control, merge);
155 branch->ReplaceInput(1, control);
156 node->ReplaceUses(phi);
61 } 157 }
62 158
63 159
160 void SimplifiedLowering::DoChangeFloat64ToTagged(Node* node, Node* effect,
161 Node* control) {
162 return; // TODO(titzer): need to call runtime to allocate in one branch
163 }
164
165
166 void SimplifiedLowering::DoChangeBoolToBit(Node* node, Node* effect,
167 Node* control) {
168 Node* val = node->InputAt(0);
169 Operator* op =
170 kPointerSize == 8 ? machine()->Word64Equal() : machine()->Word32Equal();
171 Node* cmp = graph()->NewNode(op, val, jsgraph()->TrueConstant());
172 node->ReplaceUses(cmp);
173 }
174
175
176 void SimplifiedLowering::DoChangeBitToBool(Node* node, Node* effect,
177 Node* control) {
178 Node* val = node->InputAt(0);
179 Node* branch = graph()->NewNode(common()->Branch(), val, control);
180
181 // true branch.
182 Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
183 // false branch.
184 Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
185 // merge.
186 Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
187 Node* phi = graph()->NewNode(common()->Phi(2), jsgraph()->TrueConstant(),
188 jsgraph()->FalseConstant(), merge);
189 UpdateControlSuccessors(control, merge);
190 branch->ReplaceInput(1, control);
191 node->ReplaceUses(phi);
192 }
193
194
64 static WriteBarrierKind ComputeWriteBarrierKind( 195 static WriteBarrierKind ComputeWriteBarrierKind(
65 MachineRepresentation representation, Type* type) { 196 MachineRepresentation representation, Type* type) {
66 // TODO(turbofan): skip write barriers for Smis, etc. 197 // TODO(turbofan): skip write barriers for Smis, etc.
67 if (representation == kMachineTagged) { 198 if (representation == kMachineTagged) {
68 return kFullWriteBarrier; 199 return kFullWriteBarrier;
69 } 200 }
70 return kNoWriteBarrier; 201 return kNoWriteBarrier;
71 } 202 }
72 203
73 204
74 Node* SimplifiedLowering::DoLoadField(Node* node, Node* effect, Node* control) { 205 void SimplifiedLowering::DoLoadField(Node* node, Node* effect, Node* control) {
75 const FieldAccess& access = FieldAccessOf(node->op()); 206 const FieldAccess& access = FieldAccessOf(node->op());
76 node->set_op(machine_.Load(access.representation)); 207 node->set_op(machine_.Load(access.representation));
77 Node* offset = 208 Node* offset =
78 graph()->NewNode(common()->Int32Constant(access.offset - kHeapObjectTag)); 209 graph()->NewNode(common()->Int32Constant(access.offset - kHeapObjectTag));
79 node->InsertInput(zone(), 1, offset); 210 node->InsertInput(zone(), 1, offset);
80 return node;
81 } 211 }
82 212
83 213
84 Node* SimplifiedLowering::DoStoreField(Node* node, Node* effect, 214 void SimplifiedLowering::DoStoreField(Node* node, Node* effect, Node* control) {
85 Node* control) {
86 const FieldAccess& access = FieldAccessOf(node->op()); 215 const FieldAccess& access = FieldAccessOf(node->op());
87 WriteBarrierKind kind = 216 WriteBarrierKind kind =
88 ComputeWriteBarrierKind(access.representation, access.type); 217 ComputeWriteBarrierKind(access.representation, access.type);
89 node->set_op(machine_.Store(access.representation, kind)); 218 node->set_op(machine_.Store(access.representation, kind));
90 Node* offset = 219 Node* offset =
91 graph()->NewNode(common()->Int32Constant(access.offset - kHeapObjectTag)); 220 graph()->NewNode(common()->Int32Constant(access.offset - kHeapObjectTag));
92 node->InsertInput(zone(), 1, offset); 221 node->InsertInput(zone(), 1, offset);
93 return node;
94 } 222 }
95 223
96 224
97 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access, 225 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
98 Node* index) { 226 Node* index) {
99 int element_size = 0; 227 int element_size = 0;
100 switch (access.representation) { 228 switch (access.representation) {
101 case kMachineTagged: 229 case kMachineTagged:
102 element_size = kPointerSize; 230 element_size = kPointerSize;
103 break; 231 break;
(...skipping 20 matching lines...) Expand all
124 graph()->NewNode(common()->Int32Constant(element_size)), index); 252 graph()->NewNode(common()->Int32Constant(element_size)), index);
125 } 253 }
126 int fixed_offset = access.header_size - kHeapObjectTag; 254 int fixed_offset = access.header_size - kHeapObjectTag;
127 if (fixed_offset == 0) return index; 255 if (fixed_offset == 0) return index;
128 return graph()->NewNode( 256 return graph()->NewNode(
129 machine()->Int32Add(), 257 machine()->Int32Add(),
130 graph()->NewNode(common()->Int32Constant(fixed_offset)), index); 258 graph()->NewNode(common()->Int32Constant(fixed_offset)), index);
131 } 259 }
132 260
133 261
134 Node* SimplifiedLowering::DoLoadElement(Node* node, Node* effect, 262 void SimplifiedLowering::DoLoadElement(Node* node, Node* effect,
135 Node* control) { 263 Node* control) {
136 const ElementAccess& access = ElementAccessOf(node->op()); 264 const ElementAccess& access = ElementAccessOf(node->op());
137 node->set_op(machine_.Load(access.representation)); 265 node->set_op(machine_.Load(access.representation));
138 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); 266 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
139 return node;
140 } 267 }
141 268
142 269
143 Node* SimplifiedLowering::DoStoreElement(Node* node, Node* effect, 270 void SimplifiedLowering::DoStoreElement(Node* node, Node* effect,
144 Node* control) { 271 Node* control) {
145 const ElementAccess& access = ElementAccessOf(node->op()); 272 const ElementAccess& access = ElementAccessOf(node->op());
146 WriteBarrierKind kind = 273 WriteBarrierKind kind =
147 ComputeWriteBarrierKind(access.representation, access.type); 274 ComputeWriteBarrierKind(access.representation, access.type);
148 node->set_op(machine_.Store(access.representation, kind)); 275 node->set_op(machine_.Store(access.representation, kind));
149 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); 276 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
150 return node;
151 } 277 }
152 278
153 279
154 void SimplifiedLowering::Lower(Node* node) { 280 void SimplifiedLowering::Lower(Node* node) {
155 Node* start = graph()->start(); 281 Node* start = graph()->start();
156 switch (node->opcode()) { 282 switch (node->opcode()) {
157 case IrOpcode::kBooleanNot: 283 case IrOpcode::kBooleanNot:
158 case IrOpcode::kNumberEqual: 284 case IrOpcode::kNumberEqual:
159 case IrOpcode::kNumberLessThan: 285 case IrOpcode::kNumberLessThan:
160 case IrOpcode::kNumberLessThanOrEqual: 286 case IrOpcode::kNumberLessThanOrEqual:
161 case IrOpcode::kNumberAdd: 287 case IrOpcode::kNumberAdd:
162 case IrOpcode::kNumberSubtract: 288 case IrOpcode::kNumberSubtract:
163 case IrOpcode::kNumberMultiply: 289 case IrOpcode::kNumberMultiply:
164 case IrOpcode::kNumberDivide: 290 case IrOpcode::kNumberDivide:
165 case IrOpcode::kNumberModulus: 291 case IrOpcode::kNumberModulus:
166 case IrOpcode::kNumberToInt32: 292 case IrOpcode::kNumberToInt32:
167 case IrOpcode::kNumberToUint32: 293 case IrOpcode::kNumberToUint32:
168 case IrOpcode::kReferenceEqual: 294 case IrOpcode::kReferenceEqual:
169 case IrOpcode::kStringEqual: 295 case IrOpcode::kStringEqual:
170 case IrOpcode::kStringLessThan: 296 case IrOpcode::kStringLessThan:
171 case IrOpcode::kStringLessThanOrEqual: 297 case IrOpcode::kStringLessThanOrEqual:
172 case IrOpcode::kStringAdd: 298 case IrOpcode::kStringAdd:
173 break; 299 break;
174 case IrOpcode::kChangeTaggedToInt32: 300 case IrOpcode::kChangeTaggedToInt32:
175 DoChangeTaggedToInt32(node, start, start); 301 DoChangeTaggedToUI32(node, start, start, true);
176 break; 302 break;
177 case IrOpcode::kChangeTaggedToUint32: 303 case IrOpcode::kChangeTaggedToUint32:
178 DoChangeTaggedToUint32(node, start, start); 304 DoChangeTaggedToUI32(node, start, start, false);
179 break; 305 break;
180 case IrOpcode::kChangeTaggedToFloat64: 306 case IrOpcode::kChangeTaggedToFloat64:
181 DoChangeTaggedToFloat64(node, start, start); 307 DoChangeTaggedToFloat64(node, start, start);
182 break; 308 break;
183 case IrOpcode::kChangeInt32ToTagged: 309 case IrOpcode::kChangeInt32ToTagged:
184 DoChangeInt32ToTagged(node, start, start); 310 DoChangeUI32ToTagged(node, start, start, true);
185 break; 311 break;
186 case IrOpcode::kChangeUint32ToTagged: 312 case IrOpcode::kChangeUint32ToTagged:
187 DoChangeUint32ToTagged(node, start, start); 313 DoChangeUI32ToTagged(node, start, start, false);
188 break; 314 break;
189 case IrOpcode::kChangeFloat64ToTagged: 315 case IrOpcode::kChangeFloat64ToTagged:
190 DoChangeFloat64ToTagged(node, start, start); 316 DoChangeFloat64ToTagged(node, start, start);
191 break; 317 break;
192 case IrOpcode::kChangeBoolToBit: 318 case IrOpcode::kChangeBoolToBit:
193 node->ReplaceUses(DoChangeBoolToBit(node, start, start)); 319 DoChangeBoolToBit(node, start, start);
194 break; 320 break;
195 case IrOpcode::kChangeBitToBool: 321 case IrOpcode::kChangeBitToBool:
196 DoChangeBitToBool(node, start, start); 322 DoChangeBitToBool(node, start, start);
197 break; 323 break;
198 case IrOpcode::kLoadField: 324 case IrOpcode::kLoadField:
199 DoLoadField(node, start, start); 325 DoLoadField(node, start, start);
200 break; 326 break;
201 case IrOpcode::kStoreField: 327 case IrOpcode::kStoreField:
202 DoStoreField(node, start, start); 328 DoStoreField(node, start, start);
203 break; 329 break;
204 case IrOpcode::kLoadElement: 330 case IrOpcode::kLoadElement:
205 DoLoadElement(node, start, start); 331 DoLoadElement(node, start, start);
206 break; 332 break;
207 case IrOpcode::kStoreElement: 333 case IrOpcode::kStoreElement:
208 DoStoreElement(node, start, start); 334 DoStoreElement(node, start, start);
209 break; 335 break;
210 default: 336 default:
211 break; 337 break;
212 } 338 }
213 } 339 }
214 340
215 } // namespace compiler 341 } // namespace compiler
216 } // namespace internal 342 } // namespace internal
217 } // namespace v8 343 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698