OLD | NEW |
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 #ifndef V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_ | 5 #ifndef V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_ |
6 #define V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_ | 6 #define V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 #include "test/cctest/cctest.h" | 9 #include "test/cctest/cctest.h" |
10 | 10 |
11 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
12 #include "src/compiler/graph-builder.h" | 12 #include "src/compiler/graph-builder.h" |
13 #include "src/compiler/linkage.h" | 13 #include "src/compiler/linkage.h" |
14 #include "src/compiler/machine-operator.h" | 14 #include "src/compiler/machine-operator.h" |
| 15 #include "src/compiler/operator-properties.h" |
15 #include "src/compiler/pipeline.h" | 16 #include "src/compiler/pipeline.h" |
16 #include "src/compiler/simplified-operator.h" | 17 #include "src/compiler/simplified-operator.h" |
17 #include "test/cctest/compiler/call-tester.h" | 18 #include "test/cctest/compiler/call-tester.h" |
18 #include "test/cctest/compiler/simplified-graph-builder.h" | |
19 | 19 |
20 namespace v8 { | 20 namespace v8 { |
21 namespace internal { | 21 namespace internal { |
22 namespace compiler { | 22 namespace compiler { |
23 | 23 |
24 class GraphAndBuilders { | 24 class GraphAndBuilders { |
25 public: | 25 public: |
26 explicit GraphAndBuilders(Zone* zone) | 26 explicit GraphAndBuilders(Zone* zone) |
27 : main_graph_(new (zone) Graph(zone)), | 27 : main_graph_(new (zone) Graph(zone)), |
28 main_common_(zone), | 28 main_common_(zone), |
29 main_machine_(zone), | 29 main_machine_(zone), |
30 main_simplified_(zone) {} | 30 main_simplified_(zone) {} |
31 | 31 |
32 protected: | 32 protected: |
33 // Prefixed with main_ to avoid naming conflicts. | 33 // Prefixed with main_ to avoid naming conflicts. |
34 Graph* main_graph_; | 34 Graph* main_graph_; |
35 CommonOperatorBuilder main_common_; | 35 CommonOperatorBuilder main_common_; |
36 MachineOperatorBuilder main_machine_; | 36 MachineOperatorBuilder main_machine_; |
37 SimplifiedOperatorBuilder main_simplified_; | 37 SimplifiedOperatorBuilder main_simplified_; |
38 }; | 38 }; |
39 | 39 |
40 | 40 |
41 template <typename ReturnType> | 41 template <typename ReturnType> |
42 class GraphBuilderTester : public HandleAndZoneScope, | 42 class GraphBuilderTester : public HandleAndZoneScope, |
43 private GraphAndBuilders, | 43 private GraphAndBuilders, |
44 public CallHelper<ReturnType>, | 44 public CallHelper<ReturnType>, |
45 public SimplifiedGraphBuilder { | 45 public GraphBuilder { |
46 public: | 46 public: |
47 explicit GraphBuilderTester(MachineType p0 = kMachNone, | 47 explicit GraphBuilderTester(MachineType p0 = kMachNone, |
48 MachineType p1 = kMachNone, | 48 MachineType p1 = kMachNone, |
49 MachineType p2 = kMachNone, | 49 MachineType p2 = kMachNone, |
50 MachineType p3 = kMachNone, | 50 MachineType p3 = kMachNone, |
51 MachineType p4 = kMachNone) | 51 MachineType p4 = kMachNone) |
52 : GraphAndBuilders(main_zone()), | 52 : GraphAndBuilders(main_zone()), |
53 CallHelper<ReturnType>( | 53 CallHelper<ReturnType>( |
54 main_isolate(), | 54 main_isolate(), |
55 CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1, | 55 CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1, |
56 p2, p3, p4)), | 56 p2, p3, p4)), |
57 SimplifiedGraphBuilder(main_isolate(), main_graph_, &main_common_, | 57 GraphBuilder(main_isolate(), main_graph_), |
58 &main_machine_, &main_simplified_), | 58 effect_(NULL), |
| 59 return_(NULL), |
59 parameters_(main_zone()->template NewArray<Node*>(parameter_count())) { | 60 parameters_(main_zone()->template NewArray<Node*>(parameter_count())) { |
60 Begin(static_cast<int>(parameter_count())); | 61 Begin(static_cast<int>(parameter_count())); |
61 InitParameters(); | 62 InitParameters(); |
62 } | 63 } |
63 virtual ~GraphBuilderTester() {} | 64 virtual ~GraphBuilderTester() {} |
64 | 65 |
65 void GenerateCode() { Generate(); } | 66 void GenerateCode() { Generate(); } |
66 Node* Parameter(size_t index) { | 67 Node* Parameter(size_t index) { |
67 DCHECK(index < parameter_count()); | 68 DCHECK(index < parameter_count()); |
68 return parameters_[index]; | 69 return parameters_[index]; |
69 } | 70 } |
70 | 71 |
| 72 Zone* zone() const { return graph()->zone(); } |
71 Factory* factory() const { return isolate()->factory(); } | 73 Factory* factory() const { return isolate()->factory(); } |
| 74 CommonOperatorBuilder* common() { return &main_common_; } |
| 75 MachineOperatorBuilder* machine() { return &main_machine_; } |
| 76 SimplifiedOperatorBuilder* simplified() { return &main_simplified_; } |
| 77 |
| 78 // Initialize graph and builder. |
| 79 void Begin(int num_parameters) { |
| 80 DCHECK(graph()->start() == NULL); |
| 81 Node* start = graph()->NewNode(common()->Start(num_parameters + 3)); |
| 82 graph()->SetStart(start); |
| 83 effect_ = start; |
| 84 } |
| 85 |
| 86 void Return(Node* value) { |
| 87 return_ = |
| 88 graph()->NewNode(common()->Return(), value, effect_, graph()->start()); |
| 89 effect_ = NULL; |
| 90 } |
| 91 |
| 92 // Close the graph. |
| 93 void End() { |
| 94 Node* end = graph()->NewNode(common()->End(1), return_); |
| 95 graph()->SetEnd(end); |
| 96 } |
| 97 |
| 98 Node* PointerConstant(void* value) { |
| 99 intptr_t intptr_value = reinterpret_cast<intptr_t>(value); |
| 100 return kPointerSize == 8 ? NewNode(common()->Int64Constant(intptr_value)) |
| 101 : Int32Constant(static_cast<int>(intptr_value)); |
| 102 } |
| 103 Node* Int32Constant(int32_t value) { |
| 104 return NewNode(common()->Int32Constant(value)); |
| 105 } |
| 106 Node* HeapConstant(Handle<HeapObject> object) { |
| 107 Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object); |
| 108 return NewNode(common()->HeapConstant(val)); |
| 109 } |
| 110 |
| 111 Node* BooleanNot(Node* a) { return NewNode(simplified()->BooleanNot(), a); } |
| 112 |
| 113 Node* NumberEqual(Node* a, Node* b) { |
| 114 return NewNode(simplified()->NumberEqual(), a, b); |
| 115 } |
| 116 Node* NumberLessThan(Node* a, Node* b) { |
| 117 return NewNode(simplified()->NumberLessThan(), a, b); |
| 118 } |
| 119 Node* NumberLessThanOrEqual(Node* a, Node* b) { |
| 120 return NewNode(simplified()->NumberLessThanOrEqual(), a, b); |
| 121 } |
| 122 Node* NumberAdd(Node* a, Node* b) { |
| 123 return NewNode(simplified()->NumberAdd(), a, b); |
| 124 } |
| 125 Node* NumberSubtract(Node* a, Node* b) { |
| 126 return NewNode(simplified()->NumberSubtract(), a, b); |
| 127 } |
| 128 Node* NumberMultiply(Node* a, Node* b) { |
| 129 return NewNode(simplified()->NumberMultiply(), a, b); |
| 130 } |
| 131 Node* NumberDivide(Node* a, Node* b) { |
| 132 return NewNode(simplified()->NumberDivide(), a, b); |
| 133 } |
| 134 Node* NumberModulus(Node* a, Node* b) { |
| 135 return NewNode(simplified()->NumberModulus(), a, b); |
| 136 } |
| 137 Node* NumberToInt32(Node* a) { |
| 138 return NewNode(simplified()->NumberToInt32(), a); |
| 139 } |
| 140 Node* NumberToUint32(Node* a) { |
| 141 return NewNode(simplified()->NumberToUint32(), a); |
| 142 } |
| 143 |
| 144 Node* StringEqual(Node* a, Node* b) { |
| 145 return NewNode(simplified()->StringEqual(), a, b); |
| 146 } |
| 147 Node* StringLessThan(Node* a, Node* b) { |
| 148 return NewNode(simplified()->StringLessThan(), a, b); |
| 149 } |
| 150 Node* StringLessThanOrEqual(Node* a, Node* b) { |
| 151 return NewNode(simplified()->StringLessThanOrEqual(), a, b); |
| 152 } |
| 153 |
| 154 Node* ChangeTaggedToInt32(Node* a) { |
| 155 return NewNode(simplified()->ChangeTaggedToInt32(), a); |
| 156 } |
| 157 Node* ChangeTaggedToUint32(Node* a) { |
| 158 return NewNode(simplified()->ChangeTaggedToUint32(), a); |
| 159 } |
| 160 Node* ChangeTaggedToFloat64(Node* a) { |
| 161 return NewNode(simplified()->ChangeTaggedToFloat64(), a); |
| 162 } |
| 163 Node* ChangeInt32ToTagged(Node* a) { |
| 164 return NewNode(simplified()->ChangeInt32ToTagged(), a); |
| 165 } |
| 166 Node* ChangeUint32ToTagged(Node* a) { |
| 167 return NewNode(simplified()->ChangeUint32ToTagged(), a); |
| 168 } |
| 169 Node* ChangeFloat64ToTagged(Node* a) { |
| 170 return NewNode(simplified()->ChangeFloat64ToTagged(), a); |
| 171 } |
| 172 Node* ChangeBoolToBit(Node* a) { |
| 173 return NewNode(simplified()->ChangeBoolToBit(), a); |
| 174 } |
| 175 Node* ChangeBitToBool(Node* a) { |
| 176 return NewNode(simplified()->ChangeBitToBool(), a); |
| 177 } |
| 178 |
| 179 Node* LoadField(const FieldAccess& access, Node* object) { |
| 180 return NewNode(simplified()->LoadField(access), object); |
| 181 } |
| 182 Node* StoreField(const FieldAccess& access, Node* object, Node* value) { |
| 183 return NewNode(simplified()->StoreField(access), object, value); |
| 184 } |
| 185 Node* LoadElement(const ElementAccess& access, Node* object, Node* index) { |
| 186 return NewNode(simplified()->LoadElement(access), object, index); |
| 187 } |
| 188 Node* StoreElement(const ElementAccess& access, Node* object, Node* index, |
| 189 Node* value) { |
| 190 return NewNode(simplified()->StoreElement(access), object, index, value); |
| 191 } |
72 | 192 |
73 protected: | 193 protected: |
| 194 virtual Node* MakeNode(const Operator* op, int value_input_count, |
| 195 Node** value_inputs, bool incomplete) final { |
| 196 DCHECK(op->ValueInputCount() == value_input_count); |
| 197 |
| 198 DCHECK(!OperatorProperties::HasContextInput(op)); |
| 199 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); |
| 200 bool has_control = op->ControlInputCount() == 1; |
| 201 bool has_effect = op->EffectInputCount() == 1; |
| 202 |
| 203 DCHECK(op->ControlInputCount() < 2); |
| 204 DCHECK(op->EffectInputCount() < 2); |
| 205 |
| 206 Node* result = NULL; |
| 207 if (!has_control && !has_effect) { |
| 208 result = |
| 209 graph()->NewNode(op, value_input_count, value_inputs, incomplete); |
| 210 } else { |
| 211 int input_count_with_deps = value_input_count; |
| 212 if (has_control) ++input_count_with_deps; |
| 213 if (has_effect) ++input_count_with_deps; |
| 214 Node** buffer = zone()->template NewArray<Node*>(input_count_with_deps); |
| 215 memcpy(buffer, value_inputs, kPointerSize * value_input_count); |
| 216 Node** current_input = buffer + value_input_count; |
| 217 if (has_effect) { |
| 218 *current_input++ = effect_; |
| 219 } |
| 220 if (has_control) { |
| 221 *current_input++ = graph()->start(); |
| 222 } |
| 223 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); |
| 224 if (has_effect) { |
| 225 effect_ = result; |
| 226 } |
| 227 // This graph builder does not support control flow. |
| 228 CHECK_EQ(0, op->ControlOutputCount()); |
| 229 } |
| 230 |
| 231 return result; |
| 232 } |
| 233 |
74 virtual byte* Generate() { | 234 virtual byte* Generate() { |
75 if (!Pipeline::SupportedBackend()) return NULL; | 235 if (!Pipeline::SupportedBackend()) return NULL; |
76 if (code_.is_null()) { | 236 if (code_.is_null()) { |
77 Zone* zone = graph()->zone(); | 237 Zone* zone = graph()->zone(); |
78 CallDescriptor* desc = | 238 CallDescriptor* desc = |
79 Linkage::GetSimplifiedCDescriptor(zone, this->csig_); | 239 Linkage::GetSimplifiedCDescriptor(zone, this->csig_); |
80 code_ = Pipeline::GenerateCodeForTesting(main_isolate(), desc, graph()); | 240 code_ = Pipeline::GenerateCodeForTesting(main_isolate(), desc, graph()); |
81 } | 241 } |
82 return code_.ToHandleChecked()->entry(); | 242 return code_.ToHandleChecked()->entry(); |
83 } | 243 } |
84 | 244 |
85 void InitParameters() { | 245 void InitParameters() { |
86 int param_count = static_cast<int>(parameter_count()); | 246 int param_count = static_cast<int>(parameter_count()); |
87 for (int i = 0; i < param_count; ++i) { | 247 for (int i = 0; i < param_count; ++i) { |
88 parameters_[i] = this->NewNode(common()->Parameter(i), graph()->start()); | 248 parameters_[i] = this->NewNode(common()->Parameter(i), graph()->start()); |
89 } | 249 } |
90 } | 250 } |
91 | 251 |
92 size_t parameter_count() const { return this->csig_->parameter_count(); } | 252 size_t parameter_count() const { return this->csig_->parameter_count(); } |
93 | 253 |
94 private: | 254 private: |
| 255 Node* effect_; |
| 256 Node* return_; |
95 Node** parameters_; | 257 Node** parameters_; |
96 MaybeHandle<Code> code_; | 258 MaybeHandle<Code> code_; |
97 }; | 259 }; |
98 | 260 |
99 } // namespace compiler | 261 } // namespace compiler |
100 } // namespace internal | 262 } // namespace internal |
101 } // namespace v8 | 263 } // namespace v8 |
102 | 264 |
103 #endif // V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_ | 265 #endif // V8_CCTEST_COMPILER_GRAPH_BUILDER_TESTER_H_ |
OLD | NEW |