OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/compiler/change-lowering.h" | |
6 | |
7 #include "src/compiler/common-node-cache.h" | |
8 #include "src/compiler/graph.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 namespace compiler { | |
13 | |
14 ChangeLoweringBase::ChangeLoweringBase(Graph* graph, Linkage* linkage, | |
15 CommonNodeCache* cache) | |
16 : graph_(graph), | |
17 isolate_(graph->zone()->isolate()), | |
18 linkage_(linkage), | |
19 cache_(cache), | |
20 common_(graph->zone()), | |
21 machine_(graph->zone()) {} | |
22 | |
23 | |
24 ChangeLoweringBase::~ChangeLoweringBase() {} | |
25 | |
26 | |
27 Node* ChangeLoweringBase::ExternalConstant(ExternalReference reference) { | |
titzer
2014/08/13 08:59:47
This is a big duplication of code. Why didn't you
| |
28 Node** loc = cache()->FindExternalConstant(reference); | |
29 if (*loc == NULL) { | |
30 *loc = graph()->NewNode(common()->ExternalConstant(reference)); | |
31 } | |
32 return *loc; | |
33 } | |
34 | |
35 | |
36 Node* ChangeLoweringBase::HeapConstant(PrintableUnique<HeapObject> value) { | |
37 // TODO(bmeurer): Use common node cache. | |
38 return graph()->NewNode(common()->HeapConstant(value)); | |
39 } | |
40 | |
41 | |
42 Node* ChangeLoweringBase::ImmovableHeapConstant(Handle<HeapObject> value) { | |
43 return HeapConstant( | |
44 PrintableUnique<HeapObject>::CreateImmovable(graph()->zone(), value)); | |
45 } | |
46 | |
47 | |
48 Node* ChangeLoweringBase::Int32Constant(int32_t value) { | |
49 Node** loc = cache()->FindInt32Constant(value); | |
50 if (*loc == NULL) { | |
51 *loc = graph()->NewNode(common()->Int32Constant(value)); | |
52 } | |
53 return *loc; | |
54 } | |
55 | |
56 | |
57 Node* ChangeLoweringBase::NumberConstant(double value) { | |
58 Node** loc = cache()->FindNumberConstant(value); | |
59 if (*loc == NULL) { | |
60 *loc = graph()->NewNode(common()->NumberConstant(value)); | |
61 } | |
62 return *loc; | |
63 } | |
64 | |
65 | |
66 Node* ChangeLoweringBase::CEntryStubConstant() { | |
67 if (!c_entry_stub_constant_.is_set()) { | |
68 c_entry_stub_constant_.set( | |
69 ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode())); | |
70 } | |
71 return c_entry_stub_constant_.get(); | |
72 } | |
73 | |
74 | |
75 Node* ChangeLoweringBase::TrueConstant() { | |
76 if (!true_constant_.is_set()) { | |
77 true_constant_.set( | |
78 ImmovableHeapConstant(isolate()->factory()->true_value())); | |
79 } | |
80 return true_constant_.get(); | |
81 } | |
82 | |
83 | |
84 Node* ChangeLoweringBase::FalseConstant() { | |
85 if (!false_constant_.is_set()) { | |
86 false_constant_.set( | |
87 ImmovableHeapConstant(isolate()->factory()->false_value())); | |
88 } | |
89 return false_constant_.get(); | |
90 } | |
91 | |
92 | |
93 Reduction ChangeLoweringBase::ChangeBitToBool(Node* val, Node* control) { | |
94 Node* branch = graph()->NewNode(common()->Branch(), val, control); | |
95 | |
96 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
97 Node* true_value = TrueConstant(); | |
98 | |
99 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
100 Node* false_value = FalseConstant(); | |
101 | |
102 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
103 Node* phi = | |
104 graph()->NewNode(common()->Phi(2), true_value, false_value, merge); | |
105 | |
106 return Replace(phi); | |
107 } | |
108 | |
109 | |
110 template <size_t kPointerSize> | |
111 ChangeLowering<kPointerSize>::ChangeLowering(Graph* graph, Linkage* linkage) | |
112 : ChangeLoweringBase(graph, linkage, | |
113 new (graph->zone()) CommonNodeCache(graph->zone())) {} | |
114 | |
115 | |
116 template <size_t kPointerSize> | |
117 Reduction ChangeLowering<kPointerSize>::Reduce(Node* node) { | |
118 Node* control = graph()->start(); | |
119 Node* effect = control; | |
120 switch (node->opcode()) { | |
121 case IrOpcode::kChangeBitToBool: | |
122 return ChangeBitToBool(node->InputAt(0), control); | |
123 case IrOpcode::kChangeBoolToBit: | |
124 return ChangeBoolToBit(node->InputAt(0)); | |
125 case IrOpcode::kChangeInt32ToTagged: | |
126 return ChangeInt32ToTagged(node->InputAt(0), effect, control); | |
127 case IrOpcode::kChangeTaggedToFloat64: | |
128 return ChangeTaggedToFloat64(node->InputAt(0), effect, control); | |
129 default: | |
130 return NoChange(); | |
131 } | |
132 UNREACHABLE(); | |
133 return NoChange(); | |
134 } | |
135 | |
136 | |
137 template <> | |
138 Reduction ChangeLowering<4>::ChangeBoolToBit(Node* val) { | |
titzer
2014/08/13 08:59:47
This templatization of the changes is unnecessary
Benedikt Meurer
2014/08/13 09:03:41
Before it was simple and not unit testable because
titzer
2014/08/13 09:11:12
You could, e.g. make the pointer size a field on t
Benedikt Meurer
2014/08/13 09:14:12
That's another option, sure. But I decided to do i
| |
139 return Replace( | |
140 graph()->NewNode(machine()->Word32Equal(), val, TrueConstant())); | |
141 } | |
142 | |
143 | |
144 template <> | |
145 Reduction ChangeLowering<8>::ChangeBoolToBit(Node* val) { | |
146 return Replace( | |
147 graph()->NewNode(machine()->Word64Equal(), val, TrueConstant())); | |
148 } | |
149 | |
150 | |
151 template <> | |
152 Reduction ChangeLowering<4>::ChangeInt32ToTagged(Node* val, Node* effect, | |
153 Node* control) { | |
154 Node* context = NumberConstant(0); | |
155 | |
156 Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val, val); | |
157 Node* ovf = graph()->NewNode(common()->Projection(1), add); | |
158 | |
159 Node* branch = graph()->NewNode(common()->Branch(), ovf, control); | |
160 | |
161 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
162 Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(), val); | |
163 | |
164 // TODO(bmeurer): Inline allocation if possible. | |
165 const Runtime::Function* fn = | |
166 Runtime::FunctionForId(Runtime::kAllocateHeapNumber); | |
167 DCHECK_EQ(0, fn->nargs); | |
168 CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor( | |
169 fn->function_id, 0, Operator::kNoProperties); | |
170 Node* heap_number = | |
171 graph()->NewNode(common()->Call(desc), CEntryStubConstant(), | |
172 ExternalConstant(ExternalReference(fn, isolate())), | |
173 Int32Constant(0), context, effect, if_true); | |
174 | |
175 Node* store = graph()->NewNode( | |
176 machine()->Store(kMachineFloat64, kNoWriteBarrier), heap_number, | |
177 Int32Constant(HeapNumber::kValueOffset - kHeapObjectTag), number, effect, | |
178 heap_number); | |
179 | |
180 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
181 Node* smi = graph()->NewNode(common()->Projection(0), add); | |
182 | |
183 Node* merge = graph()->NewNode(common()->Merge(2), store, if_false); | |
184 Node* phi = graph()->NewNode(common()->Phi(2), heap_number, smi, merge); | |
185 | |
186 return Replace(phi); | |
187 } | |
188 | |
189 | |
190 template <> | |
191 Reduction ChangeLowering<8>::ChangeInt32ToTagged(Node* val, Node* effect, | |
192 Node* control) { | |
193 return Replace(graph()->NewNode( | |
194 machine()->Word64Shl(), val, | |
195 Int32Constant(SmiTagging<8>::kSmiShiftSize + kSmiTagSize))); | |
196 } | |
197 | |
198 | |
199 template <> | |
200 Reduction ChangeLowering<4>::ChangeTaggedToFloat64(Node* val, Node* effect, | |
titzer
2014/08/13 08:59:47
ChangeLowering<4> and ChangeLowering<8> of this me
Benedikt Meurer
2014/08/13 09:03:41
Yap, will be refactored once everythings in place.
| |
201 Node* control) { | |
202 Node* branch = graph()->NewNode( | |
203 common()->Branch(), | |
204 graph()->NewNode(machine()->Word32And(), val, Int32Constant(kSmiTagMask)), | |
205 control); | |
206 | |
207 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
208 Node* load = graph()->NewNode( | |
209 machine()->Load(kMachineFloat64), val, | |
210 Int32Constant(HeapNumber::kValueOffset - kHeapObjectTag), if_true); | |
211 | |
212 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
213 Node* number = graph()->NewNode( | |
214 machine()->ChangeInt32ToFloat64(), | |
215 graph()->NewNode( | |
216 machine()->Word32Sar(), val, | |
217 Int32Constant(SmiTagging<4>::kSmiShiftSize + kSmiTagSize))); | |
218 | |
219 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
220 Node* phi = graph()->NewNode(common()->Phi(2), load, number, merge); | |
221 | |
222 return Replace(phi); | |
223 } | |
224 | |
225 | |
226 template <> | |
227 Reduction ChangeLowering<8>::ChangeTaggedToFloat64(Node* val, Node* effect, | |
228 Node* control) { | |
229 Node* branch = graph()->NewNode( | |
230 common()->Branch(), | |
231 graph()->NewNode(machine()->Word64And(), val, Int32Constant(kSmiTagMask)), | |
232 control); | |
233 | |
234 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
235 Node* load = graph()->NewNode( | |
236 machine()->Load(kMachineFloat64), val, | |
237 Int32Constant(HeapNumber::kValueOffset - kHeapObjectTag), if_true); | |
238 | |
239 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
240 Node* number = graph()->NewNode( | |
241 machine()->ChangeInt32ToFloat64(), | |
242 graph()->NewNode( | |
243 machine()->ConvertInt64ToInt32(), | |
244 graph()->NewNode( | |
245 machine()->Word64Sar(), val, | |
246 Int32Constant(SmiTagging<8>::kSmiShiftSize + kSmiTagSize)))); | |
247 | |
248 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
249 Node* phi = graph()->NewNode(common()->Phi(2), load, number, merge); | |
250 | |
251 return Replace(phi); | |
252 } | |
253 | |
254 | |
255 template class ChangeLowering<4>; | |
256 template class ChangeLowering<8>; | |
257 | |
258 } // namespace compiler | |
259 } // namespace internal | |
260 } // namespace v8 | |
OLD | NEW |