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

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: Fix bug in jump classification. 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++) {
Michael Starzinger 2015/12/16 12:40:12 nit: s/int/size_t/ here and drop the static_cast i
oth 2015/12/16 14:17:06 Done.
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);
Michael Starzinger 2015/12/16 12:40:12 nit: Can we reorder this function so that it follo
oth 2015/12/16 14:17:06 Done.
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 int current_offset = iterator.current_offset();
335 if (analysis.is_reachable(current_offset)) {
336 MergeEnvironmentsOfForwardBranches(current_offset);
337 BuildLoopHeaderForBackwardBranches(current_offset);
338
339 switch (iterator.current_bytecode()) {
253 #define BYTECODE_CASE(name, ...) \ 340 #define BYTECODE_CASE(name, ...) \
254 case interpreter::Bytecode::k##name: \ 341 case interpreter::Bytecode::k##name: \
255 Visit##name(iterator); \ 342 Visit##name(iterator); \
256 break; 343 break;
257 BYTECODE_LIST(BYTECODE_CASE) 344 BYTECODE_LIST(BYTECODE_CASE)
258 #undef BYTECODE_CODE 345 #undef BYTECODE_CODE
346 }
259 } 347 }
260 iterator.Advance(); 348 iterator.Advance();
261 } 349 }
350 set_branch_analysis(nullptr);
351 set_bytecode_iterator(nullptr);
262 } 352 }
263 353
264 354
265 void BytecodeGraphBuilder::VisitLdaZero( 355 void BytecodeGraphBuilder::VisitLdaZero(
266 const interpreter::BytecodeArrayIterator& iterator) { 356 const interpreter::BytecodeArrayIterator& iterator) {
267 Node* node = jsgraph()->ZeroConstant(); 357 Node* node = jsgraph()->ZeroConstant();
268 environment()->BindAccumulator(node); 358 environment()->BindAccumulator(node);
269 } 359 }
270 360
271 361
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 1257
1168 1258
1169 void BytecodeGraphBuilder::VisitToObject( 1259 void BytecodeGraphBuilder::VisitToObject(
1170 const interpreter::BytecodeArrayIterator& iterator) { 1260 const interpreter::BytecodeArrayIterator& iterator) {
1171 BuildCastOperator(javascript()->ToObject(), iterator); 1261 BuildCastOperator(javascript()->ToObject(), iterator);
1172 } 1262 }
1173 1263
1174 1264
1175 void BytecodeGraphBuilder::VisitJump( 1265 void BytecodeGraphBuilder::VisitJump(
1176 const interpreter::BytecodeArrayIterator& iterator) { 1266 const interpreter::BytecodeArrayIterator& iterator) {
1177 UNIMPLEMENTED(); 1267 BuildJump();
1178 } 1268 }
1179 1269
1180 1270
1181 void BytecodeGraphBuilder::VisitJumpConstant( 1271 void BytecodeGraphBuilder::VisitJumpConstant(
1182 const interpreter::BytecodeArrayIterator& iterator) { 1272 const interpreter::BytecodeArrayIterator& iterator) {
1183 UNIMPLEMENTED(); 1273 BuildJump();
1184 } 1274 }
1185 1275
1186 1276
1187 void BytecodeGraphBuilder::VisitJumpIfTrue( 1277 void BytecodeGraphBuilder::VisitJumpIfTrue(
1188 const interpreter::BytecodeArrayIterator& iterator) { 1278 const interpreter::BytecodeArrayIterator& iterator) {
1189 UNIMPLEMENTED(); 1279 Node* condition = BuildCondition(jsgraph()->TrueConstant());
1280 BuildConditionalJump(condition);
1190 } 1281 }
1191 1282
1192 1283
1193 void BytecodeGraphBuilder::VisitJumpIfTrueConstant( 1284 void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
1194 const interpreter::BytecodeArrayIterator& iterator) { 1285 const interpreter::BytecodeArrayIterator& iterator) {
1195 UNIMPLEMENTED(); 1286 Node* condition = BuildCondition(jsgraph()->TrueConstant());
1287 BuildConditionalJump(condition);
1196 } 1288 }
1197 1289
1198 1290
1199 void BytecodeGraphBuilder::VisitJumpIfFalse( 1291 void BytecodeGraphBuilder::VisitJumpIfFalse(
1200 const interpreter::BytecodeArrayIterator& iterator) { 1292 const interpreter::BytecodeArrayIterator& iterator) {
1201 UNIMPLEMENTED(); 1293 Node* condition = BuildCondition(jsgraph()->FalseConstant());
1294 BuildConditionalJump(condition);
1202 } 1295 }
1203 1296
1204 1297
1205 void BytecodeGraphBuilder::VisitJumpIfFalseConstant( 1298 void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
1206 const interpreter::BytecodeArrayIterator& iterator) { 1299 const interpreter::BytecodeArrayIterator& iterator) {
1207 UNIMPLEMENTED(); 1300 Node* condition = BuildCondition(jsgraph()->FalseConstant());
1301 BuildConditionalJump(condition);
1208 } 1302 }
1209 1303
1210 1304
1211 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue( 1305 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
1212 const interpreter::BytecodeArrayIterator& iterator) { 1306 const interpreter::BytecodeArrayIterator& iterator) {
1213 UNIMPLEMENTED(); 1307 Node* condition = BuildToBooleanCondition(jsgraph()->TrueConstant());
1308 BuildConditionalJump(condition);
1214 } 1309 }
1215 1310
1216 1311
1217 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant( 1312 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
1218 const interpreter::BytecodeArrayIterator& iterator) { 1313 const interpreter::BytecodeArrayIterator& iterator) {
1219 UNIMPLEMENTED(); 1314 Node* condition = BuildToBooleanCondition(jsgraph()->TrueConstant());
1315 BuildConditionalJump(condition);
1220 } 1316 }
1221 1317
1222 1318
1223 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse( 1319 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
1224 const interpreter::BytecodeArrayIterator& iterator) { 1320 const interpreter::BytecodeArrayIterator& iterator) {
1225 UNIMPLEMENTED(); 1321 Node* condition = BuildToBooleanCondition(jsgraph()->FalseConstant());
1322 BuildConditionalJump(condition);
1226 } 1323 }
1227 1324
1228 1325
1229 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant( 1326 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
1230 const interpreter::BytecodeArrayIterator& iterator) { 1327 const interpreter::BytecodeArrayIterator& iterator) {
1231 UNIMPLEMENTED(); 1328 Node* condition = BuildToBooleanCondition(jsgraph()->FalseConstant());
1329 BuildConditionalJump(condition);
1232 } 1330 }
1233 1331
1234 1332
1235 void BytecodeGraphBuilder::VisitJumpIfNull( 1333 void BytecodeGraphBuilder::VisitJumpIfNull(
1236 const interpreter::BytecodeArrayIterator& iterator) { 1334 const interpreter::BytecodeArrayIterator& iterator) {
1237 UNIMPLEMENTED(); 1335 Node* condition = BuildCondition(jsgraph()->NullConstant());
1336 BuildConditionalJump(condition);
1238 } 1337 }
1239 1338
1240 1339
1241 void BytecodeGraphBuilder::VisitJumpIfNullConstant( 1340 void BytecodeGraphBuilder::VisitJumpIfNullConstant(
1242 const interpreter::BytecodeArrayIterator& iterator) { 1341 const interpreter::BytecodeArrayIterator& iterator) {
1243 UNIMPLEMENTED(); 1342 Node* condition = BuildCondition(jsgraph()->NullConstant());
1343 BuildConditionalJump(condition);
1244 } 1344 }
1245 1345
1246 1346
1247 void BytecodeGraphBuilder::VisitJumpIfUndefined( 1347 void BytecodeGraphBuilder::VisitJumpIfUndefined(
1248 const interpreter::BytecodeArrayIterator& iterator) { 1348 const interpreter::BytecodeArrayIterator& iterator) {
1249 UNIMPLEMENTED(); 1349 Node* condition = BuildCondition(jsgraph()->UndefinedConstant());
1350 BuildConditionalJump(condition);
1250 } 1351 }
1251 1352
1252 1353
1253 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant( 1354 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
1254 const interpreter::BytecodeArrayIterator& iterator) { 1355 const interpreter::BytecodeArrayIterator& iterator) {
1255 UNIMPLEMENTED(); 1356 Node* condition = BuildCondition(jsgraph()->UndefinedConstant());
1357 BuildConditionalJump(condition);
1256 } 1358 }
1257 1359
1258 1360
1259 void BytecodeGraphBuilder::VisitReturn( 1361 void BytecodeGraphBuilder::VisitReturn(
1260 const interpreter::BytecodeArrayIterator& iterator) { 1362 const interpreter::BytecodeArrayIterator& iterator) {
1261 Node* control = 1363 Node* control =
1262 NewNode(common()->Return(), environment()->LookupAccumulator()); 1364 NewNode(common()->Return(), environment()->LookupAccumulator());
1263 UpdateControlDependencyToLeaveFunction(control); 1365 UpdateControlDependencyToLeaveFunction(control);
1366 set_environment(nullptr);
1264 } 1367 }
1265 1368
1266 1369
1267 void BytecodeGraphBuilder::VisitForInPrepare( 1370 void BytecodeGraphBuilder::VisitForInPrepare(
1268 const interpreter::BytecodeArrayIterator& iterator) { 1371 const interpreter::BytecodeArrayIterator& iterator) {
1269 UNIMPLEMENTED(); 1372 UNIMPLEMENTED();
1270 } 1373 }
1271 1374
1272 1375
1273 void BytecodeGraphBuilder::VisitForInNext( 1376 void BytecodeGraphBuilder::VisitForInNext(
1274 const interpreter::BytecodeArrayIterator& iterator) { 1377 const interpreter::BytecodeArrayIterator& iterator) {
1275 UNIMPLEMENTED(); 1378 UNIMPLEMENTED();
1276 } 1379 }
1277 1380
1278 1381
1279 void BytecodeGraphBuilder::VisitForInDone( 1382 void BytecodeGraphBuilder::VisitForInDone(
1280 const interpreter::BytecodeArrayIterator& iterator) { 1383 const interpreter::BytecodeArrayIterator& iterator) {
1281 UNIMPLEMENTED(); 1384 UNIMPLEMENTED();
1282 } 1385 }
1283 1386
1284 1387
1388 void BytecodeGraphBuilder::MergeEnvironmentsOfBackwardBranches(
1389 int source_offset, int target_offset) {
1390 DCHECK_GE(source_offset, target_offset);
1391 const ZoneVector<int>* back_branches =
1392 branch_analysis()->BackwardBranchesTargetting(target_offset);
1393 if (back_branches->back() == source_offset) {
1394 // The set of back branches is complete, merge them.
1395 Environment* environment = merge_environments_[back_branches->at(0)];
Michael Starzinger 2015/12/16 12:40:12 nit: s/environment/merged/ for readability.
oth 2015/12/16 14:17:06 Done.
1396 for (size_t i = 1; i < back_branches->size(); i++) {
Michael Starzinger 2015/12/16 12:40:12 nit: Would it be possible to have a similar check
oth 2015/12/16 14:17:06 Done.
1397 environment->Merge(merge_environments_[back_branches->at(i)]);
1398 }
1399 // And now merge with loop header environment created when loop
1400 // header was visited.
1401 loop_header_environments_[target_offset]->Merge(environment);
1402 }
1403 }
1404
1405
1406 void BytecodeGraphBuilder::MergeEnvironmentsOfForwardBranches(
1407 int source_offset) {
1408 if (branch_analysis()->forward_branches_target(source_offset)) {
1409 // Merge environments of branches that reach this bytecode.
1410 auto branch_sites =
1411 branch_analysis()->ForwardBranchesTargetting(source_offset);
1412 Environment* merged = merge_environments_[branch_sites->at(0)];
1413 for (size_t i = 1; i < branch_sites->size(); i++) {
1414 DCHECK_LT(branch_sites->at(i), source_offset);
1415 merged->Merge(merge_environments_[branch_sites->at(i)]);
1416 }
1417 if (environment()) {
1418 merged->Merge(environment());
1419 }
1420 set_environment(merged);
1421 }
1422 }
1423
1424
1425 void BytecodeGraphBuilder::BuildLoopHeaderForBackwardBranches(
1426 int source_offset) {
1427 if (branch_analysis()->backward_branches_target(source_offset)) {
1428 // Add loop header and store a copy so we can connect merged back
1429 // edge inputs to the loop header.
1430 loop_header_environments_[source_offset] = environment()->CopyForLoop();
1431 }
1432 }
1433
1434
1435 void BytecodeGraphBuilder::BuildJump(int source_offset, int target_offset) {
1436 DCHECK_NULL(merge_environments_[source_offset]);
1437 merge_environments_[source_offset] = environment();
1438 if (source_offset >= target_offset) {
1439 MergeEnvironmentsOfBackwardBranches(source_offset, target_offset);
1440 }
1441 set_environment(nullptr);
1442 }
1443
1444
1445 void BytecodeGraphBuilder::BuildJump() {
1446 int source_offset = bytecode_iterator()->current_offset();
1447 int target_offset = bytecode_iterator()->GetJumpTargetOffset();
1448 BuildJump(source_offset, target_offset);
1449 }
1450
1451
1452 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1453 int source_offset = bytecode_iterator()->current_offset();
1454 NewBranch(condition);
1455 Environment* if_false_environment = environment()->CopyForConditional();
1456 NewIfTrue();
1457 BuildJump(source_offset, bytecode_iterator()->GetJumpTargetOffset());
1458 set_environment(if_false_environment);
1459 NewIfFalse();
1460 }
1461
1462
1463 Node* BytecodeGraphBuilder::BuildCondition(Node* comperand) {
1464 Node* accumulator = environment()->LookupAccumulator();
1465 return NewNode(javascript()->StrictEqual(), accumulator, comperand);
1466 }
1467
1468
1469 Node* BytecodeGraphBuilder::BuildToBooleanCondition(Node* comperand) {
1470 Node* accumulator = environment()->LookupAccumulator();
1471 Node* to_boolean =
1472 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1473 return NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1474 }
1475
1476
1285 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { 1477 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1286 if (size > input_buffer_size_) { 1478 if (size > input_buffer_size_) {
1287 size = size + kInputBufferSizeIncrement + input_buffer_size_; 1479 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1288 input_buffer_ = local_zone()->NewArray<Node*>(size); 1480 input_buffer_ = local_zone()->NewArray<Node*>(size);
1289 input_buffer_size_ = size; 1481 input_buffer_size_ = size;
1290 } 1482 }
1291 return input_buffer_; 1483 return input_buffer_;
1292 } 1484 }
1293 1485
1294 1486
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 Node* on_success = graph()->NewNode(if_success, result); 1539 Node* on_success = graph()->NewNode(if_success, result);
1348 environment_->UpdateControlDependency(on_success); 1540 environment_->UpdateControlDependency(on_success);
1349 } 1541 }
1350 } 1542 }
1351 } 1543 }
1352 1544
1353 return result; 1545 return result;
1354 } 1546 }
1355 1547
1356 1548
1549 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1550 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1551 Node** buffer = EnsureInputBufferSize(count + 1);
1552 MemsetPointer(buffer, input, count);
1553 buffer[count] = control;
1554 return graph()->NewNode(phi_op, count + 1, buffer, true);
1555 }
1556
1557
1558 // TODO(mstarzinger): Revisit this once we have proper effect states.
Michael Starzinger 2015/12/16 12:40:12 nit: This TODO is outdated, I should remove it fro
oth 2015/12/16 14:17:06 Done.
1559 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1560 Node* control) {
1561 const Operator* phi_op = common()->EffectPhi(count);
1562 Node** buffer = EnsureInputBufferSize(count + 1);
1563 MemsetPointer(buffer, input, count);
1564 buffer[count] = control;
1565 return graph()->NewNode(phi_op, count + 1, buffer, true);
1566 }
1567
1568
1357 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) { 1569 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1358 int inputs = control->op()->ControlInputCount() + 1; 1570 int inputs = control->op()->ControlInputCount() + 1;
1359 if (control->opcode() == IrOpcode::kLoop) { 1571 if (control->opcode() == IrOpcode::kLoop) {
1360 // Control node for loop exists, add input. 1572 // Control node for loop exists, add input.
1361 const Operator* op = common()->Loop(inputs); 1573 const Operator* op = common()->Loop(inputs);
1362 control->AppendInput(graph_zone(), other); 1574 control->AppendInput(graph_zone(), other);
1363 NodeProperties::ChangeOp(control, op); 1575 NodeProperties::ChangeOp(control, op);
1364 } else if (control->opcode() == IrOpcode::kMerge) { 1576 } else if (control->opcode() == IrOpcode::kMerge) {
1365 // Control node for merge exists, add input. 1577 // Control node for merge exists, add input.
1366 const Operator* op = common()->Merge(inputs); 1578 const Operator* op = common()->Merge(inputs);
1367 control->AppendInput(graph_zone(), other); 1579 control->AppendInput(graph_zone(), other);
1368 NodeProperties::ChangeOp(control, op); 1580 NodeProperties::ChangeOp(control, op);
1369 } else { 1581 } else {
1370 // Control node is a singleton, introduce a merge. 1582 // Control node is a singleton, introduce a merge.
1371 const Operator* op = common()->Merge(inputs); 1583 const Operator* op = common()->Merge(inputs);
1372 Node* merge_inputs[] = {control, other}; 1584 Node* merge_inputs[] = {control, other};
1373 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true); 1585 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1374 } 1586 }
1375 return control; 1587 return control;
1376 } 1588 }
1377 1589
1378 1590
1591 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1592 Node* control) {
1593 int inputs = control->op()->ControlInputCount();
1594 if (value->opcode() == IrOpcode::kEffectPhi &&
1595 NodeProperties::GetControlInput(value) == control) {
1596 // Phi already exists, add input.
1597 value->InsertInput(graph_zone(), inputs - 1, other);
1598 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1599 } else if (value != other) {
1600 // Phi does not exist yet, introduce one.
1601 value = NewEffectPhi(inputs, value, control);
1602 value->ReplaceInput(inputs - 1, other);
1603 }
1604 return value;
1605 }
1606
1607
1608 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1609 Node* control) {
1610 int inputs = control->op()->ControlInputCount();
1611 if (value->opcode() == IrOpcode::kPhi &&
1612 NodeProperties::GetControlInput(value) == control) {
1613 // Phi already exists, add input.
1614 value->InsertInput(graph_zone(), inputs - 1, other);
1615 NodeProperties::ChangeOp(
1616 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1617 } else if (value != other) {
1618 // Phi does not exist yet, introduce one.
1619 value = NewPhi(inputs, value, control);
1620
Michael Starzinger 2015/12/16 12:40:12 nit: Stray empty newline.
oth 2015/12/16 14:17:06 Done.
1621 value->ReplaceInput(inputs - 1, other);
1622 }
1623 return value;
1624 }
1625
1626
1379 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 1627 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1380 if (environment()->IsMarkedAsUnreachable()) return; 1628 if (environment()->IsMarkedAsUnreachable()) return;
1381 environment()->MarkAsUnreachable(); 1629 environment()->MarkAsUnreachable();
1382 exit_controls_.push_back(exit); 1630 exit_controls_.push_back(exit);
1383 } 1631 }
1384 1632
1385 } // namespace compiler 1633 } // namespace compiler
1386 } // namespace internal 1634 } // namespace internal
1387 } // namespace v8 1635 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698