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

Side by Side Diff: src/compiler/bytecode-graph-builder.cc

Issue 1502243002: [Interpreter] Local flow control in the bytecode graph builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/bytecode-graph-builder.h" 5 #include "src/compiler/bytecode-graph-builder.h"
6 6
7 #include "src/compiler/bytecode-branch-analysis.h"
7 #include "src/compiler/linkage.h" 8 #include "src/compiler/linkage.h"
8 #include "src/compiler/operator-properties.h" 9 #include "src/compiler/operator-properties.h"
9 #include "src/interpreter/bytecode-array-iterator.h"
10 #include "src/interpreter/bytecodes.h" 10 #include "src/interpreter/bytecodes.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 namespace compiler { 14 namespace compiler {
15 15
16 // Issues: 16 // Issues:
17 // - Need to deal with FrameState / FrameStateBeforeAndAfter / StateValue. 17 // - Need to deal with FrameState / FrameStateBeforeAndAfter / StateValue.
18 // - Scopes - intimately tied to AST. Need to eval what is needed. 18 // - Scopes - intimately tied to AST. Need to eval what is needed.
19 // - Need to resolve closure parameter treatment. 19 // - Need to resolve closure parameter treatment.
(...skipping 28 matching lines...) Expand all
48 // Registers 48 // Registers
49 register_base_ = static_cast<int>(values()->size()); 49 register_base_ = static_cast<int>(values()->size());
50 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); 50 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
51 values()->insert(values()->end(), register_count, undefined_constant); 51 values()->insert(values()->end(), register_count, undefined_constant);
52 52
53 // Accumulator 53 // Accumulator
54 accumulator_ = undefined_constant; 54 accumulator_ = undefined_constant;
55 } 55 }
56 56
57 57
58 BytecodeGraphBuilder::Environment::Environment(
59 const BytecodeGraphBuilder::Environment* other)
60 : builder_(other->builder_),
61 register_count_(other->register_count_),
62 parameter_count_(other->parameter_count_),
63 accumulator_(other->accumulator_),
64 context_(other->context_),
65 control_dependency_(other->control_dependency_),
66 effect_dependency_(other->effect_dependency_),
67 values_(other->zone()),
68 register_base_(other->register_base_) {
69 values_ = other->values_;
70 }
71
72
58 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( 73 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
59 interpreter::Register the_register) const { 74 interpreter::Register the_register) const {
60 if (the_register.is_parameter()) { 75 if (the_register.is_parameter()) {
61 return the_register.ToParameterIndex(parameter_count()); 76 return the_register.ToParameterIndex(parameter_count());
62 } else { 77 } else {
63 return the_register.index() + register_base(); 78 return the_register.index() + register_base();
64 } 79 }
65 } 80 }
66 81
67 82
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const { 115 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
101 return GetControlDependency()->opcode() == IrOpcode::kDead; 116 return GetControlDependency()->opcode() == IrOpcode::kDead;
102 } 117 }
103 118
104 119
105 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { 120 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
106 UpdateControlDependency(builder()->jsgraph()->Dead()); 121 UpdateControlDependency(builder()->jsgraph()->Dead());
107 } 122 }
108 123
109 124
125 BytecodeGraphBuilder::Environment*
126 BytecodeGraphBuilder::Environment::CopyForLoop() {
127 PrepareForLoop();
128 return new (zone()) Environment(this);
129 }
130
131
132 BytecodeGraphBuilder::Environment*
133 BytecodeGraphBuilder::Environment::CopyForConditional() const {
134 return new (zone()) Environment(this);
135 }
136
137
138 void BytecodeGraphBuilder::Environment::Merge(
139 BytecodeGraphBuilder::Environment* other) {
140 // Nothing to do if the other environment is dead.
141 if (other->IsMarkedAsUnreachable()) {
142 return;
143 }
144
145 // Create a merge of the control dependencies of both environments and update
146 // the current environment's control dependency accordingly.
147 Node* control = builder()->MergeControl(GetControlDependency(),
148 other->GetControlDependency());
149 UpdateControlDependency(control);
150
151 // Create a merge of the effect dependencies of both environments and update
152 // the current environment's effect dependency accordingly.
153 Node* effect = builder()->MergeEffect(GetEffectDependency(),
154 other->GetEffectDependency(), control);
155 UpdateEffectDependency(effect);
156
157 // Introduce Phi nodes for values that have differing input at merge points,
158 // potentially extending an existing Phi node if possible.
159 accumulator_ =
160 builder()->MergeValue(accumulator_, other->accumulator_, control);
161 context_ = builder()->MergeValue(context_, other->context_, control);
162 for (int i = 0; i < static_cast<int>(values_.size()); i++) {
163 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
164 }
165 }
166
167
168 void BytecodeGraphBuilder::Environment::PrepareForLoop() {
169 Node* control = builder()->NewLoop();
170 accumulator_ = builder()->NewPhi(1, accumulator_, control);
171 context_ = builder()->NewPhi(1, context_, control);
172
173 int size = static_cast<int>(values()->size());
174 for (int i = 0; i < size; i++) {
175 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
176 }
177 Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
178 UpdateEffectDependency(effect);
179
180 Node* terminate = builder()->graph()->NewNode(
181 builder()->common()->Terminate(), effect, control);
182 builder()->exit_controls_.push_back(terminate);
183 }
184
185
110 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 186 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
111 CompilationInfo* compilation_info, 187 CompilationInfo* compilation_info,
112 JSGraph* jsgraph) 188 JSGraph* jsgraph)
113 : local_zone_(local_zone), 189 : local_zone_(local_zone),
114 info_(compilation_info), 190 info_(compilation_info),
115 jsgraph_(jsgraph), 191 jsgraph_(jsgraph),
192 merge_environments_(local_zone),
193 loop_header_environments_(local_zone),
116 input_buffer_size_(0), 194 input_buffer_size_(0),
117 input_buffer_(nullptr), 195 input_buffer_(nullptr),
118 exit_controls_(local_zone) { 196 exit_controls_(local_zone) {
119 bytecode_array_ = handle(info()->shared_info()->bytecode_array()); 197 bytecode_array_ = handle(info()->shared_info()->bytecode_array());
120 } 198 }
121 199
122 200
123 Node* BytecodeGraphBuilder::GetNewTarget() { 201 Node* BytecodeGraphBuilder::GetNewTarget() {
124 if (!new_target_.is_set()) { 202 if (!new_target_.is_set()) {
125 int params = bytecode_array()->parameter_count(); 203 int params = bytecode_array()->parameter_count();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 318
241 319
242 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) { 320 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
243 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments 321 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
244 // object setup, this function variable if used, tracing hooks. 322 // object setup, this function variable if used, tracing hooks.
245 VisitBytecodes(); 323 VisitBytecodes();
246 } 324 }
247 325
248 326
249 void BytecodeGraphBuilder::VisitBytecodes() { 327 void BytecodeGraphBuilder::VisitBytecodes() {
328 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
329 analysis.Analyze();
330 set_branch_analysis(&analysis);
250 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 331 interpreter::BytecodeArrayIterator iterator(bytecode_array());
332 set_bytecode_iterator(&iterator);
251 while (!iterator.done()) { 333 while (!iterator.done()) {
252 switch (iterator.current_bytecode()) { 334 if (analysis.is_reachable(iterator.current_offset())) {
335 ApplyBranchAnalysis(&analysis);
336
337 switch (iterator.current_bytecode()) {
253 #define BYTECODE_CASE(name, ...) \ 338 #define BYTECODE_CASE(name, ...) \
254 case interpreter::Bytecode::k##name: \ 339 case interpreter::Bytecode::k##name: \
255 Visit##name(iterator); \ 340 Visit##name(iterator); \
256 break; 341 break;
257 BYTECODE_LIST(BYTECODE_CASE) 342 BYTECODE_LIST(BYTECODE_CASE)
258 #undef BYTECODE_CODE 343 #undef BYTECODE_CODE
344 }
259 } 345 }
260 iterator.Advance(); 346 iterator.Advance();
261 } 347 }
348 set_branch_analysis(nullptr);
349 set_bytecode_iterator(nullptr);
262 } 350 }
263 351
264 352
265 void BytecodeGraphBuilder::VisitLdaZero( 353 void BytecodeGraphBuilder::VisitLdaZero(
266 const interpreter::BytecodeArrayIterator& iterator) { 354 const interpreter::BytecodeArrayIterator& iterator) {
267 Node* node = jsgraph()->ZeroConstant(); 355 Node* node = jsgraph()->ZeroConstant();
268 environment()->BindAccumulator(node); 356 environment()->BindAccumulator(node);
269 } 357 }
270 358
271 359
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 1255
1168 1256
1169 void BytecodeGraphBuilder::VisitToObject( 1257 void BytecodeGraphBuilder::VisitToObject(
1170 const interpreter::BytecodeArrayIterator& iterator) { 1258 const interpreter::BytecodeArrayIterator& iterator) {
1171 BuildCastOperator(javascript()->ToObject(), iterator); 1259 BuildCastOperator(javascript()->ToObject(), iterator);
1172 } 1260 }
1173 1261
1174 1262
1175 void BytecodeGraphBuilder::VisitJump( 1263 void BytecodeGraphBuilder::VisitJump(
1176 const interpreter::BytecodeArrayIterator& iterator) { 1264 const interpreter::BytecodeArrayIterator& iterator) {
1177 UNIMPLEMENTED(); 1265 BuildJump();
1178 } 1266 }
1179 1267
1180 1268
1181 void BytecodeGraphBuilder::VisitJumpConstant( 1269 void BytecodeGraphBuilder::VisitJumpConstant(
1182 const interpreter::BytecodeArrayIterator& iterator) { 1270 const interpreter::BytecodeArrayIterator& iterator) {
1183 UNIMPLEMENTED(); 1271 BuildJump();
1184 } 1272 }
1185 1273
1186 1274
1187 void BytecodeGraphBuilder::VisitJumpIfTrue( 1275 void BytecodeGraphBuilder::VisitJumpIfTrue(
1188 const interpreter::BytecodeArrayIterator& iterator) { 1276 const interpreter::BytecodeArrayIterator& iterator) {
1189 UNIMPLEMENTED(); 1277 Node* condition = BuildJumpCondition(jsgraph()->TrueConstant());
1278 BuildConditionalJump(condition);
1190 } 1279 }
1191 1280
1192 1281
1193 void BytecodeGraphBuilder::VisitJumpIfTrueConstant( 1282 void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
1194 const interpreter::BytecodeArrayIterator& iterator) { 1283 const interpreter::BytecodeArrayIterator& iterator) {
1195 UNIMPLEMENTED(); 1284 Node* condition = BuildJumpCondition(jsgraph()->TrueConstant());
1285 BuildConditionalJump(condition);
1196 } 1286 }
1197 1287
1198 1288
1199 void BytecodeGraphBuilder::VisitJumpIfFalse( 1289 void BytecodeGraphBuilder::VisitJumpIfFalse(
1200 const interpreter::BytecodeArrayIterator& iterator) { 1290 const interpreter::BytecodeArrayIterator& iterator) {
1201 UNIMPLEMENTED(); 1291 Node* condition = BuildJumpCondition(jsgraph()->FalseConstant());
1292 BuildConditionalJump(condition);
1202 } 1293 }
1203 1294
1204 1295
1205 void BytecodeGraphBuilder::VisitJumpIfFalseConstant( 1296 void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
1206 const interpreter::BytecodeArrayIterator& iterator) { 1297 const interpreter::BytecodeArrayIterator& iterator) {
1207 UNIMPLEMENTED(); 1298 Node* condition = BuildJumpCondition(jsgraph()->FalseConstant());
1299 BuildConditionalJump(condition);
1208 } 1300 }
1209 1301
1210 1302
1211 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue( 1303 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
1212 const interpreter::BytecodeArrayIterator& iterator) { 1304 const interpreter::BytecodeArrayIterator& iterator) {
1213 UNIMPLEMENTED(); 1305 Node* condition = BuildToBooleanJumpCondition(jsgraph()->TrueConstant());
1306 BuildConditionalJump(condition);
1214 } 1307 }
1215 1308
1216 1309
1217 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant( 1310 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
1218 const interpreter::BytecodeArrayIterator& iterator) { 1311 const interpreter::BytecodeArrayIterator& iterator) {
1219 UNIMPLEMENTED(); 1312 Node* condition = BuildToBooleanJumpCondition(jsgraph()->TrueConstant());
1313 BuildConditionalJump(condition);
1220 } 1314 }
1221 1315
1222 1316
1223 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse( 1317 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
1224 const interpreter::BytecodeArrayIterator& iterator) { 1318 const interpreter::BytecodeArrayIterator& iterator) {
1225 UNIMPLEMENTED(); 1319 Node* condition = BuildToBooleanJumpCondition(jsgraph()->FalseConstant());
1320 BuildConditionalJump(condition);
1226 } 1321 }
1227 1322
1228 1323
1229 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant( 1324 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
1230 const interpreter::BytecodeArrayIterator& iterator) { 1325 const interpreter::BytecodeArrayIterator& iterator) {
1231 UNIMPLEMENTED(); 1326 Node* condition = BuildToBooleanJumpCondition(jsgraph()->FalseConstant());
1327 BuildConditionalJump(condition);
1232 } 1328 }
1233 1329
1234 1330
1235 void BytecodeGraphBuilder::VisitJumpIfNull( 1331 void BytecodeGraphBuilder::VisitJumpIfNull(
1236 const interpreter::BytecodeArrayIterator& iterator) { 1332 const interpreter::BytecodeArrayIterator& iterator) {
1237 UNIMPLEMENTED(); 1333 Node* condition = BuildJumpCondition(jsgraph()->NullConstant());
1334 BuildConditionalJump(condition);
1238 } 1335 }
1239 1336
1240 1337
1241 void BytecodeGraphBuilder::VisitJumpIfNullConstant( 1338 void BytecodeGraphBuilder::VisitJumpIfNullConstant(
1242 const interpreter::BytecodeArrayIterator& iterator) { 1339 const interpreter::BytecodeArrayIterator& iterator) {
1243 UNIMPLEMENTED(); 1340 Node* condition = BuildJumpCondition(jsgraph()->NullConstant());
1341 BuildConditionalJump(condition);
1244 } 1342 }
1245 1343
1246 1344
1247 void BytecodeGraphBuilder::VisitJumpIfUndefined( 1345 void BytecodeGraphBuilder::VisitJumpIfUndefined(
1248 const interpreter::BytecodeArrayIterator& iterator) { 1346 const interpreter::BytecodeArrayIterator& iterator) {
1249 UNIMPLEMENTED(); 1347 Node* condition = BuildJumpCondition(jsgraph()->UndefinedConstant());
1348 BuildConditionalJump(condition);
1250 } 1349 }
1251 1350
1252 1351
1253 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant( 1352 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
1254 const interpreter::BytecodeArrayIterator& iterator) { 1353 const interpreter::BytecodeArrayIterator& iterator) {
1255 UNIMPLEMENTED(); 1354 Node* condition = BuildJumpCondition(jsgraph()->UndefinedConstant());
1355 BuildConditionalJump(condition);
1256 } 1356 }
1257 1357
1258 1358
1259 void BytecodeGraphBuilder::VisitReturn( 1359 void BytecodeGraphBuilder::VisitReturn(
1260 const interpreter::BytecodeArrayIterator& iterator) { 1360 const interpreter::BytecodeArrayIterator& iterator) {
1261 Node* control = 1361 Node* control =
1262 NewNode(common()->Return(), environment()->LookupAccumulator()); 1362 NewNode(common()->Return(), environment()->LookupAccumulator());
1263 UpdateControlDependencyToLeaveFunction(control); 1363 UpdateControlDependencyToLeaveFunction(control);
1364 set_environment(nullptr);
1264 } 1365 }
1265 1366
1266 1367
1267 void BytecodeGraphBuilder::VisitForInPrepare( 1368 void BytecodeGraphBuilder::VisitForInPrepare(
1268 const interpreter::BytecodeArrayIterator& iterator) { 1369 const interpreter::BytecodeArrayIterator& iterator) {
1269 UNIMPLEMENTED(); 1370 UNIMPLEMENTED();
1270 } 1371 }
1271 1372
1272 1373
1273 void BytecodeGraphBuilder::VisitForInNext( 1374 void BytecodeGraphBuilder::VisitForInNext(
1274 const interpreter::BytecodeArrayIterator& iterator) { 1375 const interpreter::BytecodeArrayIterator& iterator) {
1275 UNIMPLEMENTED(); 1376 UNIMPLEMENTED();
1276 } 1377 }
1277 1378
1278 1379
1279 void BytecodeGraphBuilder::VisitForInDone( 1380 void BytecodeGraphBuilder::VisitForInDone(
1280 const interpreter::BytecodeArrayIterator& iterator) { 1381 const interpreter::BytecodeArrayIterator& iterator) {
1281 UNIMPLEMENTED(); 1382 UNIMPLEMENTED();
1282 } 1383 }
1283 1384
1284 1385
1386 void BytecodeGraphBuilder::ApplyBranchAnalysis(
rmcilroy 2015/12/15 17:35:43 Not keen on the name. How about MergeEnvironmentWi
oth 2015/12/15 22:42:17 Done.
1387 const BytecodeBranchAnalysis* analysis) {
1388 int current_offset = bytecode_iterator()->current_offset();
1389 if (analysis->forward_branches_target(current_offset)) {
1390 // Merge environments of branches that reach this bytecode.
1391 auto branch_sites = analysis->ForwardBranchesTargetting(current_offset);
1392 Environment* merged = merge_environments_[branch_sites->at(0)];
1393 for (size_t i = 1; i < branch_sites->size(); i++) {
1394 DCHECK_LT(branch_sites->at(i), current_offset);
1395 merged->Merge(merge_environments_[branch_sites->at(i)]);
1396 }
1397 if (environment()) {
1398 merged->Merge(environment());
1399 set_environment(nullptr);
rmcilroy 2015/12/15 17:35:43 why set nullptr here and set to merged immediately
oth 2015/12/15 22:42:17 Churn, removed.
1400 }
1401 set_environment(merged);
1402 }
1403
1404 if (analysis->backward_branches_target(current_offset)) {
1405 // Add loop header and store a copy so we can connect merged back
1406 // edge inputs to the loop header.
1407 loop_header_environments_[current_offset] = environment()->CopyForLoop();
1408 }
1409 }
1410
1411
1412 void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
1413 DCHECK_NULL(merge_environments_[source_offset]);
1414 merge_environments_[source_offset] = environment();
1415 if (source_offset >= target_offset) {
1416 // Back branch check if all branches to target offset are
1417 // satisfied.
1418 const ZoneVector<int>* back_branches =
1419 branch_analysis()->BackwardBranchesTargetting(target_offset);
1420 if (back_branches->back() == source_offset) {
rmcilroy 2015/12/15 17:35:43 Use IsLastBackwardBranchTo here (or remove that fu
oth 2015/12/15 22:42:17 Removed it, want the branches immediately if true.
1421 // The set of back branches is complete, merge them.
1422 Environment* environment = merge_environments_[back_branches->at(0)];
1423 for (size_t i = 1; i < back_branches->size(); i++) {
1424 environment->Merge(merge_environments_[back_branches->at(i)]);
1425 }
1426 // And now merge with loop header environment created when loop
1427 // header was visited.
1428 loop_header_environments_[target_offset]->Merge(environment);
rmcilroy 2015/12/15 17:35:43 nit - could we pull the back-branch stuff out into
oth 2015/12/15 22:42:17 Done.
1429 }
1430 }
1431 set_environment(nullptr);
1432 }
1433
1434
1435 void BytecodeGraphBuilder::BuildJump() {
1436 int source_offset = bytecode_iterator()->current_offset();
1437 int target_offset = bytecode_iterator()->GetJumpTargetOffset();
1438 BuildJump(source_offset, target_offset);
1439 }
1440
1441
1442 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1443 int source_offset = bytecode_iterator()->current_offset();
1444 NewBranch(condition);
1445 Environment* if_false_environment = environment()->CopyForConditional();
1446 NewIfTrue();
1447 BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
1448 set_environment(if_false_environment);
1449 NewIfFalse();
1450 }
1451
1452
1453 Node* BytecodeGraphBuilder::BuildJumpCondition(Node* comperand) {
1454 Node* accumulator = environment()->LookupAccumulator();
1455 return NewNode(javascript()->StrictEqual(), accumulator, comperand);
1456 }
1457
1458
1459 Node* BytecodeGraphBuilder::BuildToBooleanJumpCondition(Node* comperand) {
1460 Node* accumulator = environment()->LookupAccumulator();
1461 Node* to_boolean =
1462 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1463 return NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1464 }
1465
1466
1285 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { 1467 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1286 if (size > input_buffer_size_) { 1468 if (size > input_buffer_size_) {
1287 size = size + kInputBufferSizeIncrement + input_buffer_size_; 1469 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1288 input_buffer_ = local_zone()->NewArray<Node*>(size); 1470 input_buffer_ = local_zone()->NewArray<Node*>(size);
1289 input_buffer_size_ = size; 1471 input_buffer_size_ = size;
1290 } 1472 }
1291 return input_buffer_; 1473 return input_buffer_;
1292 } 1474 }
1293 1475
1294 1476
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 Node* on_success = graph()->NewNode(if_success, result); 1529 Node* on_success = graph()->NewNode(if_success, result);
1348 environment_->UpdateControlDependency(on_success); 1530 environment_->UpdateControlDependency(on_success);
1349 } 1531 }
1350 } 1532 }
1351 } 1533 }
1352 1534
1353 return result; 1535 return result;
1354 } 1536 }
1355 1537
1356 1538
1539 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1540 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1541 Node** buffer = EnsureInputBufferSize(count + 1);
1542 MemsetPointer(buffer, input, count);
1543 buffer[count] = control;
1544 return graph()->NewNode(phi_op, count + 1, buffer, true);
1545 }
1546
1547
1548 // TODO(mstarzinger): Revisit this once we have proper effect states.
1549 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1550 Node* control) {
1551 const Operator* phi_op = common()->EffectPhi(count);
1552 Node** buffer = EnsureInputBufferSize(count + 1);
1553 MemsetPointer(buffer, input, count);
1554 buffer[count] = control;
1555 return graph()->NewNode(phi_op, count + 1, buffer, true);
1556 }
1557
1558
1357 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) { 1559 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1358 int inputs = control->op()->ControlInputCount() + 1; 1560 int inputs = control->op()->ControlInputCount() + 1;
1359 if (control->opcode() == IrOpcode::kLoop) { 1561 if (control->opcode() == IrOpcode::kLoop) {
1360 // Control node for loop exists, add input. 1562 // Control node for loop exists, add input.
1361 const Operator* op = common()->Loop(inputs); 1563 const Operator* op = common()->Loop(inputs);
1362 control->AppendInput(graph_zone(), other); 1564 control->AppendInput(graph_zone(), other);
1363 NodeProperties::ChangeOp(control, op); 1565 NodeProperties::ChangeOp(control, op);
1364 } else if (control->opcode() == IrOpcode::kMerge) { 1566 } else if (control->opcode() == IrOpcode::kMerge) {
1365 // Control node for merge exists, add input. 1567 // Control node for merge exists, add input.
1366 const Operator* op = common()->Merge(inputs); 1568 const Operator* op = common()->Merge(inputs);
1367 control->AppendInput(graph_zone(), other); 1569 control->AppendInput(graph_zone(), other);
1368 NodeProperties::ChangeOp(control, op); 1570 NodeProperties::ChangeOp(control, op);
1369 } else { 1571 } else {
1370 // Control node is a singleton, introduce a merge. 1572 // Control node is a singleton, introduce a merge.
1371 const Operator* op = common()->Merge(inputs); 1573 const Operator* op = common()->Merge(inputs);
1372 Node* merge_inputs[] = {control, other}; 1574 Node* merge_inputs[] = {control, other};
1373 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true); 1575 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1374 } 1576 }
1375 return control; 1577 return control;
1376 } 1578 }
1377 1579
1378 1580
1581 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1582 Node* control) {
1583 int inputs = control->op()->ControlInputCount();
1584 if (value->opcode() == IrOpcode::kEffectPhi &&
1585 NodeProperties::GetControlInput(value) == control) {
1586 // Phi already exists, add input.
1587 value->InsertInput(graph_zone(), inputs - 1, other);
1588 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1589 } else if (value != other) {
1590 // Phi does not exist yet, introduce one.
1591 value = NewEffectPhi(inputs, value, control);
1592 value->ReplaceInput(inputs - 1, other);
1593 }
1594 return value;
1595 }
1596
1597
1598 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1599 Node* control) {
1600 int inputs = control->op()->ControlInputCount();
1601 if (value->opcode() == IrOpcode::kPhi &&
1602 NodeProperties::GetControlInput(value) == control) {
1603 // Phi already exists, add input.
1604 value->InsertInput(graph_zone(), inputs - 1, other);
1605 NodeProperties::ChangeOp(
1606 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1607 } else if (value != other) {
1608 // Phi does not exist yet, introduce one.
1609 value = NewPhi(inputs, value, control);
1610
1611 value->ReplaceInput(inputs - 1, other);
1612 }
1613 return value;
1614 }
1615
1616
1379 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 1617 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1380 if (environment()->IsMarkedAsUnreachable()) return; 1618 if (environment()->IsMarkedAsUnreachable()) return;
1381 environment()->MarkAsUnreachable(); 1619 environment()->MarkAsUnreachable();
1382 exit_controls_.push_back(exit); 1620 exit_controls_.push_back(exit);
1383 } 1621 }
1384 1622
1385 } // namespace compiler 1623 } // namespace compiler
1386 } // namespace internal 1624 } // namespace internal
1387 } // namespace v8 1625 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698