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

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: Incorporate comments by mstarzinger on patchet 10. 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
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/interpreter/bytecode-array-builder.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 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 (size_t i = 0; i < values_.size(); i++) {
163 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
164 }
165 }
166
167
168 void BytecodeGraphBuilder::Environment::PrepareForLoop() {
169 // Create a control node for the loop header.
170 Node* control = builder()->NewLoop();
171
172 // Create a Phi for external effects.
173 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
174 UpdateEffectDependency(effect);
175
176 // Assume everything in the loop is updated.
177 accumulator_ = builder()->NewPhi(1, accumulator_, control);
178 context_ = builder()->NewPhi(1, context_, control);
179 int size = static_cast<int>(values()->size());
180 for (int i = 0; i < size; i++) {
181 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
182 }
183
184 // Connect to the loop end.
185 Node* terminate = builder()->graph()->NewNode(
186 builder()->common()->Terminate(), effect, control);
187 builder()->exit_controls_.push_back(terminate);
188 }
189
190
110 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 191 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
111 CompilationInfo* compilation_info, 192 CompilationInfo* compilation_info,
112 JSGraph* jsgraph) 193 JSGraph* jsgraph)
113 : local_zone_(local_zone), 194 : local_zone_(local_zone),
114 info_(compilation_info), 195 info_(compilation_info),
115 jsgraph_(jsgraph), 196 jsgraph_(jsgraph),
197 merge_environments_(local_zone),
198 loop_header_environments_(local_zone),
116 input_buffer_size_(0), 199 input_buffer_size_(0),
117 input_buffer_(nullptr), 200 input_buffer_(nullptr),
118 exit_controls_(local_zone) { 201 exit_controls_(local_zone) {
119 bytecode_array_ = handle(info()->shared_info()->bytecode_array()); 202 bytecode_array_ = handle(info()->shared_info()->bytecode_array());
120 } 203 }
121 204
122 205
123 Node* BytecodeGraphBuilder::GetNewTarget() { 206 Node* BytecodeGraphBuilder::GetNewTarget() {
124 if (!new_target_.is_set()) { 207 if (!new_target_.is_set()) {
125 int params = bytecode_array()->parameter_count(); 208 int params = bytecode_array()->parameter_count();
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 323
241 324
242 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) { 325 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
243 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments 326 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
244 // object setup, this function variable if used, tracing hooks. 327 // object setup, this function variable if used, tracing hooks.
245 VisitBytecodes(); 328 VisitBytecodes();
246 } 329 }
247 330
248 331
249 void BytecodeGraphBuilder::VisitBytecodes() { 332 void BytecodeGraphBuilder::VisitBytecodes() {
333 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
334 analysis.Analyze();
335 set_branch_analysis(&analysis);
250 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 336 interpreter::BytecodeArrayIterator iterator(bytecode_array());
337 set_bytecode_iterator(&iterator);
251 while (!iterator.done()) { 338 while (!iterator.done()) {
252 switch (iterator.current_bytecode()) { 339 int current_offset = iterator.current_offset();
340 if (analysis.is_reachable(current_offset)) {
341 MergeEnvironmentsOfForwardBranches(current_offset);
342 BuildLoopHeaderForBackwardBranches(current_offset);
343
344 switch (iterator.current_bytecode()) {
253 #define BYTECODE_CASE(name, ...) \ 345 #define BYTECODE_CASE(name, ...) \
254 case interpreter::Bytecode::k##name: \ 346 case interpreter::Bytecode::k##name: \
255 Visit##name(iterator); \ 347 Visit##name(iterator); \
256 break; 348 break;
257 BYTECODE_LIST(BYTECODE_CASE) 349 BYTECODE_LIST(BYTECODE_CASE)
258 #undef BYTECODE_CODE 350 #undef BYTECODE_CODE
351 }
259 } 352 }
260 iterator.Advance(); 353 iterator.Advance();
261 } 354 }
355 set_branch_analysis(nullptr);
356 set_bytecode_iterator(nullptr);
262 } 357 }
263 358
264 359
265 void BytecodeGraphBuilder::VisitLdaZero( 360 void BytecodeGraphBuilder::VisitLdaZero(
266 const interpreter::BytecodeArrayIterator& iterator) { 361 const interpreter::BytecodeArrayIterator& iterator) {
267 Node* node = jsgraph()->ZeroConstant(); 362 Node* node = jsgraph()->ZeroConstant();
268 environment()->BindAccumulator(node); 363 environment()->BindAccumulator(node);
269 } 364 }
270 365
271 366
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 1262
1168 1263
1169 void BytecodeGraphBuilder::VisitToObject( 1264 void BytecodeGraphBuilder::VisitToObject(
1170 const interpreter::BytecodeArrayIterator& iterator) { 1265 const interpreter::BytecodeArrayIterator& iterator) {
1171 BuildCastOperator(javascript()->ToObject(), iterator); 1266 BuildCastOperator(javascript()->ToObject(), iterator);
1172 } 1267 }
1173 1268
1174 1269
1175 void BytecodeGraphBuilder::VisitJump( 1270 void BytecodeGraphBuilder::VisitJump(
1176 const interpreter::BytecodeArrayIterator& iterator) { 1271 const interpreter::BytecodeArrayIterator& iterator) {
1177 UNIMPLEMENTED(); 1272 BuildJump();
1178 } 1273 }
1179 1274
1180 1275
1181 void BytecodeGraphBuilder::VisitJumpConstant( 1276 void BytecodeGraphBuilder::VisitJumpConstant(
1182 const interpreter::BytecodeArrayIterator& iterator) { 1277 const interpreter::BytecodeArrayIterator& iterator) {
1183 UNIMPLEMENTED(); 1278 BuildJump();
1184 } 1279 }
1185 1280
1186 1281
1187 void BytecodeGraphBuilder::VisitJumpIfTrue( 1282 void BytecodeGraphBuilder::VisitJumpIfTrue(
1188 const interpreter::BytecodeArrayIterator& iterator) { 1283 const interpreter::BytecodeArrayIterator& iterator) {
1189 UNIMPLEMENTED(); 1284 Node* condition = BuildCondition(jsgraph()->TrueConstant());
1285 BuildConditionalJump(condition);
1190 } 1286 }
1191 1287
1192 1288
1193 void BytecodeGraphBuilder::VisitJumpIfTrueConstant( 1289 void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
1194 const interpreter::BytecodeArrayIterator& iterator) { 1290 const interpreter::BytecodeArrayIterator& iterator) {
1195 UNIMPLEMENTED(); 1291 Node* condition = BuildCondition(jsgraph()->TrueConstant());
1292 BuildConditionalJump(condition);
1196 } 1293 }
1197 1294
1198 1295
1199 void BytecodeGraphBuilder::VisitJumpIfFalse( 1296 void BytecodeGraphBuilder::VisitJumpIfFalse(
1200 const interpreter::BytecodeArrayIterator& iterator) { 1297 const interpreter::BytecodeArrayIterator& iterator) {
1201 UNIMPLEMENTED(); 1298 Node* condition = BuildCondition(jsgraph()->FalseConstant());
1299 BuildConditionalJump(condition);
1202 } 1300 }
1203 1301
1204 1302
1205 void BytecodeGraphBuilder::VisitJumpIfFalseConstant( 1303 void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
1206 const interpreter::BytecodeArrayIterator& iterator) { 1304 const interpreter::BytecodeArrayIterator& iterator) {
1207 UNIMPLEMENTED(); 1305 Node* condition = BuildCondition(jsgraph()->FalseConstant());
1306 BuildConditionalJump(condition);
1208 } 1307 }
1209 1308
1210 1309
1211 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue( 1310 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
1212 const interpreter::BytecodeArrayIterator& iterator) { 1311 const interpreter::BytecodeArrayIterator& iterator) {
1213 UNIMPLEMENTED(); 1312 Node* condition = BuildToBooleanCondition(jsgraph()->TrueConstant());
1313 BuildConditionalJump(condition);
1214 } 1314 }
1215 1315
1216 1316
1217 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant( 1317 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
1218 const interpreter::BytecodeArrayIterator& iterator) { 1318 const interpreter::BytecodeArrayIterator& iterator) {
1219 UNIMPLEMENTED(); 1319 Node* condition = BuildToBooleanCondition(jsgraph()->TrueConstant());
1320 BuildConditionalJump(condition);
1220 } 1321 }
1221 1322
1222 1323
1223 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse( 1324 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
1224 const interpreter::BytecodeArrayIterator& iterator) { 1325 const interpreter::BytecodeArrayIterator& iterator) {
1225 UNIMPLEMENTED(); 1326 Node* condition = BuildToBooleanCondition(jsgraph()->FalseConstant());
1327 BuildConditionalJump(condition);
1226 } 1328 }
1227 1329
1228 1330
1229 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant( 1331 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
1230 const interpreter::BytecodeArrayIterator& iterator) { 1332 const interpreter::BytecodeArrayIterator& iterator) {
1231 UNIMPLEMENTED(); 1333 Node* condition = BuildToBooleanCondition(jsgraph()->FalseConstant());
1334 BuildConditionalJump(condition);
1232 } 1335 }
1233 1336
1234 1337
1235 void BytecodeGraphBuilder::VisitJumpIfNull( 1338 void BytecodeGraphBuilder::VisitJumpIfNull(
1236 const interpreter::BytecodeArrayIterator& iterator) { 1339 const interpreter::BytecodeArrayIterator& iterator) {
1237 UNIMPLEMENTED(); 1340 Node* condition = BuildCondition(jsgraph()->NullConstant());
1341 BuildConditionalJump(condition);
1238 } 1342 }
1239 1343
1240 1344
1241 void BytecodeGraphBuilder::VisitJumpIfNullConstant( 1345 void BytecodeGraphBuilder::VisitJumpIfNullConstant(
1242 const interpreter::BytecodeArrayIterator& iterator) { 1346 const interpreter::BytecodeArrayIterator& iterator) {
1243 UNIMPLEMENTED(); 1347 Node* condition = BuildCondition(jsgraph()->NullConstant());
1348 BuildConditionalJump(condition);
1244 } 1349 }
1245 1350
1246 1351
1247 void BytecodeGraphBuilder::VisitJumpIfUndefined( 1352 void BytecodeGraphBuilder::VisitJumpIfUndefined(
1248 const interpreter::BytecodeArrayIterator& iterator) { 1353 const interpreter::BytecodeArrayIterator& iterator) {
1249 UNIMPLEMENTED(); 1354 Node* condition = BuildCondition(jsgraph()->UndefinedConstant());
1355 BuildConditionalJump(condition);
1250 } 1356 }
1251 1357
1252 1358
1253 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant( 1359 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
1254 const interpreter::BytecodeArrayIterator& iterator) { 1360 const interpreter::BytecodeArrayIterator& iterator) {
1255 UNIMPLEMENTED(); 1361 Node* condition = BuildCondition(jsgraph()->UndefinedConstant());
1362 BuildConditionalJump(condition);
1256 } 1363 }
1257 1364
1258 1365
1259 void BytecodeGraphBuilder::VisitReturn( 1366 void BytecodeGraphBuilder::VisitReturn(
1260 const interpreter::BytecodeArrayIterator& iterator) { 1367 const interpreter::BytecodeArrayIterator& iterator) {
1261 Node* control = 1368 Node* control =
1262 NewNode(common()->Return(), environment()->LookupAccumulator()); 1369 NewNode(common()->Return(), environment()->LookupAccumulator());
1263 UpdateControlDependencyToLeaveFunction(control); 1370 UpdateControlDependencyToLeaveFunction(control);
1371 set_environment(nullptr);
1264 } 1372 }
1265 1373
1266 1374
1267 void BytecodeGraphBuilder::VisitForInPrepare( 1375 void BytecodeGraphBuilder::VisitForInPrepare(
1268 const interpreter::BytecodeArrayIterator& iterator) { 1376 const interpreter::BytecodeArrayIterator& iterator) {
1269 UNIMPLEMENTED(); 1377 UNIMPLEMENTED();
1270 } 1378 }
1271 1379
1272 1380
1273 void BytecodeGraphBuilder::VisitForInNext( 1381 void BytecodeGraphBuilder::VisitForInNext(
1274 const interpreter::BytecodeArrayIterator& iterator) { 1382 const interpreter::BytecodeArrayIterator& iterator) {
1275 UNIMPLEMENTED(); 1383 UNIMPLEMENTED();
1276 } 1384 }
1277 1385
1278 1386
1279 void BytecodeGraphBuilder::VisitForInDone( 1387 void BytecodeGraphBuilder::VisitForInDone(
1280 const interpreter::BytecodeArrayIterator& iterator) { 1388 const interpreter::BytecodeArrayIterator& iterator) {
1281 UNIMPLEMENTED(); 1389 UNIMPLEMENTED();
1282 } 1390 }
1283 1391
1284 1392
1393 void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches(
1394 int source_offset, int target_offset) {
1395 DCHECK_GE(source_offset, target_offset);
1396 const ZoneVector<int>* branch_sites =
1397 branch_analysis()->BackwardBranchesTargetting(target_offset);
1398 if (branch_sites->back() == source_offset) {
1399 // The set of back branches is complete, merge them.
1400 DCHECK_GE(branch_sites->at(0), target_offset);
1401 Environment* merged = merge_environments_[branch_sites->at(0)];
1402 for (size_t i = 1; i < branch_sites->size(); i++) {
1403 DCHECK_GE(branch_sites->at(i), target_offset);
1404 merged->Merge(merge_environments_[branch_sites->at(i)]);
1405 }
1406 // And now merge with loop header environment created when loop
1407 // header was visited.
1408 loop_header_environments_[target_offset]->Merge(merged);
1409 }
1410 }
1411
1412
1413 void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches(
1414 int source_offset) {
1415 if (branch_analysis()->forward_branches_target(source_offset)) {
1416 // Merge environments of branches that reach this bytecode.
1417 auto branch_sites =
1418 branch_analysis()->ForwardBranchesTargetting(source_offset);
1419 DCHECK_LT(branch_sites->at(0), source_offset);
1420 Environment* merged = merge_environments_[branch_sites->at(0)];
1421 for (size_t i = 1; i < branch_sites->size(); i++) {
1422 DCHECK_LT(branch_sites->at(i), source_offset);
1423 merged->Merge(merge_environments_[branch_sites->at(i)]);
1424 }
1425 if (environment()) {
1426 merged->Merge(environment());
1427 }
1428 set_environment(merged);
1429 }
1430 }
1431
1432
1433 void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches(
1434 int source_offset) {
1435 if (branch_analysis()->backward_branches_target(source_offset)) {
1436 // Add loop header and store a copy so we can connect merged back
1437 // edge inputs to the loop header.
1438 loop_header_environments_[source_offset] = environment()->CopyForLoop();
1439 }
1440 }
1441
1442
1443 void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
1444 DCHECK_NULL(merge_environments_[source_offset]);
1445 merge_environments_[source_offset] = environment();
1446 if (source_offset >= target_offset) {
1447 MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
1448 }
1449 set_environment(nullptr);
1450 }
1451
1452
1453 void BytecodeGraphBuilder::BuildJump() {
1454 int source_offset = bytecode_iterator()->current_offset();
1455 int target_offset = bytecode_iterator()->GetJumpTargetOffset();
1456 BuildJump(source_offset, target_offset);
1457 }
1458
1459
1460 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1461 int source_offset = bytecode_iterator()->current_offset();
1462 NewBranch(condition);
1463 Environment* if_false_environment = environment()->CopyForConditional();
1464 NewIfTrue();
1465 BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
1466 set_environment(if_false_environment);
1467 NewIfFalse();
1468 }
1469
1470
1471 Node* BytecodeGraphBuilder::BuildCondition(Node* comperand) {
1472 Node* accumulator = environment()->LookupAccumulator();
1473 return NewNode(javascript()->StrictEqual(), accumulator, comperand);
1474 }
1475
1476
1477 Node* BytecodeGraphBuilder::BuildToBooleanCondition(Node* comperand) {
1478 Node* accumulator = environment()->LookupAccumulator();
1479 Node* to_boolean =
1480 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1481 return NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1482 }
1483
1484
1285 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { 1485 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1286 if (size > input_buffer_size_) { 1486 if (size > input_buffer_size_) {
1287 size = size + kInputBufferSizeIncrement + input_buffer_size_; 1487 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1288 input_buffer_ = local_zone()->NewArray<Node*>(size); 1488 input_buffer_ = local_zone()->NewArray<Node*>(size);
1289 input_buffer_size_ = size; 1489 input_buffer_size_ = size;
1290 } 1490 }
1291 return input_buffer_; 1491 return input_buffer_;
1292 } 1492 }
1293 1493
1294 1494
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 Node* on_success = graph()->NewNode(if_success, result); 1547 Node* on_success = graph()->NewNode(if_success, result);
1348 environment_->UpdateControlDependency(on_success); 1548 environment_->UpdateControlDependency(on_success);
1349 } 1549 }
1350 } 1550 }
1351 } 1551 }
1352 1552
1353 return result; 1553 return result;
1354 } 1554 }
1355 1555
1356 1556
1557 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1558 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1559 Node** buffer = EnsureInputBufferSize(count + 1);
1560 MemsetPointer(buffer, input, count);
1561 buffer[count] = control;
1562 return graph()->NewNode(phi_op, count + 1, buffer, true);
1563 }
1564
1565
1566 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1567 Node* control) {
1568 const Operator* phi_op = common()->EffectPhi(count);
1569 Node** buffer = EnsureInputBufferSize(count + 1);
1570 MemsetPointer(buffer, input, count);
1571 buffer[count] = control;
1572 return graph()->NewNode(phi_op, count + 1, buffer, true);
1573 }
1574
1575
1357 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) { 1576 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1358 int inputs = control->op()->ControlInputCount() + 1; 1577 int inputs = control->op()->ControlInputCount() + 1;
1359 if (control->opcode() == IrOpcode::kLoop) { 1578 if (control->opcode() == IrOpcode::kLoop) {
1360 // Control node for loop exists, add input. 1579 // Control node for loop exists, add input.
1361 const Operator* op = common()->Loop(inputs); 1580 const Operator* op = common()->Loop(inputs);
1362 control->AppendInput(graph_zone(), other); 1581 control->AppendInput(graph_zone(), other);
1363 NodeProperties::ChangeOp(control, op); 1582 NodeProperties::ChangeOp(control, op);
1364 } else if (control->opcode() == IrOpcode::kMerge) { 1583 } else if (control->opcode() == IrOpcode::kMerge) {
1365 // Control node for merge exists, add input. 1584 // Control node for merge exists, add input.
1366 const Operator* op = common()->Merge(inputs); 1585 const Operator* op = common()->Merge(inputs);
1367 control->AppendInput(graph_zone(), other); 1586 control->AppendInput(graph_zone(), other);
1368 NodeProperties::ChangeOp(control, op); 1587 NodeProperties::ChangeOp(control, op);
1369 } else { 1588 } else {
1370 // Control node is a singleton, introduce a merge. 1589 // Control node is a singleton, introduce a merge.
1371 const Operator* op = common()->Merge(inputs); 1590 const Operator* op = common()->Merge(inputs);
1372 Node* merge_inputs[] = {control, other}; 1591 Node* merge_inputs[] = {control, other};
1373 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true); 1592 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1374 } 1593 }
1375 return control; 1594 return control;
1376 } 1595 }
1377 1596
1378 1597
1598 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1599 Node* control) {
1600 int inputs = control->op()->ControlInputCount();
1601 if (value->opcode() == IrOpcode::kEffectPhi &&
1602 NodeProperties::GetControlInput(value) == control) {
1603 // Phi already exists, add input.
1604 value->InsertInput(graph_zone(), inputs - 1, other);
1605 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1606 } else if (value != other) {
1607 // Phi does not exist yet, introduce one.
1608 value = NewEffectPhi(inputs, value, control);
1609 value->ReplaceInput(inputs - 1, other);
1610 }
1611 return value;
1612 }
1613
1614
1615 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1616 Node* control) {
1617 int inputs = control->op()->ControlInputCount();
1618 if (value->opcode() == IrOpcode::kPhi &&
1619 NodeProperties::GetControlInput(value) == control) {
1620 // Phi already exists, add input.
1621 value->InsertInput(graph_zone(), inputs - 1, other);
1622 NodeProperties::ChangeOp(
1623 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1624 } else if (value != other) {
1625 // Phi does not exist yet, introduce one.
1626 value = NewPhi(inputs, value, control);
1627 value->ReplaceInput(inputs - 1, other);
1628 }
1629 return value;
1630 }
1631
1632
1379 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 1633 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1380 if (environment()->IsMarkedAsUnreachable()) return; 1634 if (environment()->IsMarkedAsUnreachable()) return;
1381 environment()->MarkAsUnreachable(); 1635 environment()->MarkAsUnreachable();
1382 exit_controls_.push_back(exit); 1636 exit_controls_.push_back(exit);
1383 } 1637 }
1384 1638
1385 } // namespace compiler 1639 } // namespace compiler
1386 } // namespace internal 1640 } // namespace internal
1387 } // namespace v8 1641 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/interpreter/bytecode-array-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698