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

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: Build fix. 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-basic-block-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/bytecode-array-iterator.h"
10 #include "src/interpreter/bytecodes.h" 11 #include "src/interpreter/bytecodes.h"
11 12
12 namespace v8 { 13 namespace v8 {
13 namespace internal { 14 namespace internal {
14 namespace compiler { 15 namespace compiler {
15 16
16 // Issues: 17 // Issues:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 // Registers 49 // Registers
49 register_base_ = static_cast<int>(values()->size()); 50 register_base_ = static_cast<int>(values()->size());
50 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); 51 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
51 values()->insert(values()->end(), register_count, undefined_constant); 52 values()->insert(values()->end(), register_count, undefined_constant);
52 53
53 // Accumulator 54 // Accumulator
54 accumulator_ = undefined_constant; 55 accumulator_ = undefined_constant;
55 } 56 }
56 57
57 58
59 BytecodeGraphBuilder::Environment::Environment(
60 const BytecodeGraphBuilder::Environment* other)
61 : builder_(other->builder_),
62 register_count_(other->register_count_),
63 parameter_count_(other->parameter_count_),
64 accumulator_(other->accumulator_),
65 context_(other->context_),
66 control_dependency_(other->control_dependency_),
67 effect_dependency_(other->effect_dependency_),
68 values_(other->zone()),
69 register_base_(other->register_base_) {
70 values_ = other->values_;
71 }
72
73
58 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( 74 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
59 interpreter::Register the_register) const { 75 interpreter::Register the_register) const {
60 if (the_register.is_parameter()) { 76 if (the_register.is_parameter()) {
61 return the_register.ToParameterIndex(parameter_count()); 77 return the_register.ToParameterIndex(parameter_count());
62 } else { 78 } else {
63 return the_register.index() + register_base(); 79 return the_register.index() + register_base();
64 } 80 }
65 } 81 }
66 82
67 83
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const { 116 bool BytecodeGraphBuilder::Environment::IsMarkedAsUnreachable() const {
101 return GetControlDependency()->opcode() == IrOpcode::kDead; 117 return GetControlDependency()->opcode() == IrOpcode::kDead;
102 } 118 }
103 119
104 120
105 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() { 121 void BytecodeGraphBuilder::Environment::MarkAsUnreachable() {
106 UpdateControlDependency(builder()->jsgraph()->Dead()); 122 UpdateControlDependency(builder()->jsgraph()->Dead());
107 } 123 }
108 124
109 125
126 BytecodeGraphBuilder::Environment*
127 BytecodeGraphBuilder::Environment::CopyForLoop() {
128 PrepareForLoop();
129 return new (zone()) Environment(this);
130 }
131
132
133 BytecodeGraphBuilder::Environment*
134 BytecodeGraphBuilder::Environment::CopyForConditional() const {
135 return new (zone()) Environment(this);
136 }
137
138
139 void BytecodeGraphBuilder::Environment::Merge(
140 BytecodeGraphBuilder::Environment* other) {
141 // Nothing to do if the other environment is dead.
142 if (other->IsMarkedAsUnreachable()) {
143 return;
144 }
145
146 // Create a merge of the control dependencies of both environments and update
147 // the current environment's control dependency accordingly.
148 Node* control = builder()->MergeControl(GetControlDependency(),
149 other->GetControlDependency());
150 UpdateControlDependency(control);
151
152 // Create a merge of the effect dependencies of both environments and update
153 // the current environment's effect dependency accordingly.
154 Node* effect = builder()->MergeEffect(GetEffectDependency(),
155 other->GetEffectDependency(), control);
156 UpdateEffectDependency(effect);
157
158 // Introduce Phi nodes for values that have differing input at merge points,
159 // potentially extending an existing Phi node if possible.
160 accumulator_ =
161 builder()->MergeValue(accumulator_, other->accumulator_, control);
162 context_ = builder()->MergeValue(context_, other->context_, control);
163 for (int i = 0; i < static_cast<int>(values_.size()); i++) {
164 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
165 }
166 }
167
168
169 void BytecodeGraphBuilder::Environment::PrepareForLoop() {
170 Node* control = builder()->NewLoop();
171 accumulator_ = builder()->NewPhi(1, accumulator_, control);
172 context_ = builder()->NewPhi(1, context_, control);
173
174 int size = static_cast<int>(values()->size());
175 for (int i = 0; i < size; i++) {
176 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
177 }
178 Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
179 UpdateEffectDependency(effect);
180
181 Node* terminate = builder()->graph()->NewNode(
182 builder()->common()->Terminate(), effect, control);
183 builder()->exit_controls_.push_back(terminate);
184 }
185
186
110 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, 187 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
111 CompilationInfo* compilation_info, 188 CompilationInfo* compilation_info,
112 JSGraph* jsgraph) 189 JSGraph* jsgraph)
113 : local_zone_(local_zone), 190 : local_zone_(local_zone),
114 info_(compilation_info), 191 info_(compilation_info),
115 jsgraph_(jsgraph), 192 jsgraph_(jsgraph),
193 block_environment_infos_(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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); 312 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
235 graph()->SetEnd(end); 313 graph()->SetEnd(end);
236 314
237 return true; 315 return true;
238 } 316 }
239 317
240 318
241 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) { 319 void BytecodeGraphBuilder::CreateGraphBody(bool stack_check) {
242 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments 320 // TODO(oth): Review ast-graph-builder equivalent, i.e. arguments
243 // object setup, this function variable if used, tracing hooks. 321 // object setup, this function variable if used, tracing hooks.
244 VisitBytecodes(); 322 VisitBasicBlocks();
245 } 323 }
246 324
247 325
248 void BytecodeGraphBuilder::VisitBytecodes() { 326 void BytecodeGraphBuilder::VisitBasicBlocks() {
327 BytecodeBasicBlockAnalysis analyzer(local_zone(), bytecode_array());
328 const ZoneVector<BytecodeBasicBlock*>* blocks = analyzer.Analyze();
329
330 block_environment_infos_.resize(blocks->size());
331 for (auto block_iter = blocks->begin(); block_iter != blocks->end();
332 block_iter++) {
333 VisitBytecodesInBasicBlock(*block_iter);
334 }
335 }
336
337 void BytecodeGraphBuilder::VisitBytecodesInBasicBlock(
338 BytecodeBasicBlock* block) {
339 set_basic_block(block);
340 PrepareForNewBasicBlockVisit();
341
249 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 342 interpreter::BytecodeArrayIterator iterator(bytecode_array());
250 while (!iterator.done()) { 343 iterator.AdvanceToOffset(basic_block()->start());
344 while (!iterator.done() &&
345 iterator.current_offset() != basic_block()->end()) {
251 switch (iterator.current_bytecode()) { 346 switch (iterator.current_bytecode()) {
252 #define BYTECODE_CASE(name, ...) \ 347 #define BYTECODE_CASE(name, ...) \
253 case interpreter::Bytecode::k##name: \ 348 case interpreter::Bytecode::k##name: \
254 Visit##name(iterator); \ 349 Visit##name(iterator); \
255 break; 350 break;
256 BYTECODE_LIST(BYTECODE_CASE) 351 BYTECODE_LIST(BYTECODE_CASE)
257 #undef BYTECODE_CODE 352 #undef BYTECODE_CODE
258 } 353 }
259 iterator.Advance(); 354 iterator.Advance();
260 } 355 }
356 CompleteNewBasicBlockVisit();
261 } 357 }
262 358
263 359
264 void BytecodeGraphBuilder::VisitLdaZero( 360 void BytecodeGraphBuilder::VisitLdaZero(
265 const interpreter::BytecodeArrayIterator& iterator) { 361 const interpreter::BytecodeArrayIterator& iterator) {
266 Node* node = jsgraph()->ZeroConstant(); 362 Node* node = jsgraph()->ZeroConstant();
267 environment()->BindAccumulator(node); 363 environment()->BindAccumulator(node);
268 } 364 }
269 365
270 366
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 1207
1112 1208
1113 void BytecodeGraphBuilder::VisitToObject( 1209 void BytecodeGraphBuilder::VisitToObject(
1114 const interpreter::BytecodeArrayIterator& iterator) { 1210 const interpreter::BytecodeArrayIterator& iterator) {
1115 BuildCastOperator(javascript()->ToObject(), iterator); 1211 BuildCastOperator(javascript()->ToObject(), iterator);
1116 } 1212 }
1117 1213
1118 1214
1119 void BytecodeGraphBuilder::VisitJump( 1215 void BytecodeGraphBuilder::VisitJump(
1120 const interpreter::BytecodeArrayIterator& iterator) { 1216 const interpreter::BytecodeArrayIterator& iterator) {
1121 UNIMPLEMENTED(); 1217 BuildJump();
1122 } 1218 }
1123 1219
1124 1220
1125 void BytecodeGraphBuilder::VisitJumpConstant( 1221 void BytecodeGraphBuilder::VisitJumpConstant(
1126 const interpreter::BytecodeArrayIterator& iterator) { 1222 const interpreter::BytecodeArrayIterator& iterator) {
1127 UNIMPLEMENTED(); 1223 BuildJump();
1128 } 1224 }
1129 1225
1130 1226
1131 void BytecodeGraphBuilder::VisitJumpIfTrue( 1227 void BytecodeGraphBuilder::VisitJumpIfTrue(
1132 const interpreter::BytecodeArrayIterator& iterator) { 1228 const interpreter::BytecodeArrayIterator& iterator) {
1133 UNIMPLEMENTED(); 1229 Node* accumulator = environment()->LookupAccumulator();
1230 Node* comperand = jsgraph()->TrueConstant();
1231 Node* comparison =
1232 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1233 BuildConditionalJump(comparison);
1134 } 1234 }
1135 1235
1136 1236
1137 void BytecodeGraphBuilder::VisitJumpIfTrueConstant( 1237 void BytecodeGraphBuilder::VisitJumpIfTrueConstant(
1138 const interpreter::BytecodeArrayIterator& iterator) { 1238 const interpreter::BytecodeArrayIterator& iterator) {
1139 UNIMPLEMENTED(); 1239 Node* accumulator = environment()->LookupAccumulator();
1240 Node* comperand = jsgraph()->TrueConstant();
1241 Node* comparison =
1242 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1243 BuildConditionalJump(comparison);
rmcilroy 2015/12/08 13:25:07 Please factor out the common code here into a Buil
oth 2015/12/09 11:26:45 I'd like to keep the control flow aspects and cond
1140 } 1244 }
1141 1245
1142 1246
1143 void BytecodeGraphBuilder::VisitJumpIfFalse( 1247 void BytecodeGraphBuilder::VisitJumpIfFalse(
1144 const interpreter::BytecodeArrayIterator& iterator) { 1248 const interpreter::BytecodeArrayIterator& iterator) {
1145 UNIMPLEMENTED(); 1249 Node* accumulator = environment()->LookupAccumulator();
1250 Node* comperand = jsgraph()->FalseConstant();
1251 Node* comparison =
1252 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1253 BuildConditionalJump(comparison);
1146 } 1254 }
1147 1255
1148 1256
1149 void BytecodeGraphBuilder::VisitJumpIfFalseConstant( 1257 void BytecodeGraphBuilder::VisitJumpIfFalseConstant(
1150 const interpreter::BytecodeArrayIterator& iterator) { 1258 const interpreter::BytecodeArrayIterator& iterator) {
1151 UNIMPLEMENTED(); 1259 Node* accumulator = environment()->LookupAccumulator();
1260 Node* comperand = jsgraph()->FalseConstant();
1261 Node* comparison =
1262 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1263 BuildConditionalJump(comparison);
1152 } 1264 }
1153 1265
1154 1266
1155 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue( 1267 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue(
1156 const interpreter::BytecodeArrayIterator& iterator) { 1268 const interpreter::BytecodeArrayIterator& iterator) {
1157 UNIMPLEMENTED(); 1269 Node* accumulator = environment()->LookupAccumulator();
1270 Node* to_boolean =
1271 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1272 Node* comperand = jsgraph()->TrueConstant();
1273 Node* comparison =
1274 NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1275 BuildConditionalJump(comparison);
rmcilroy 2015/12/08 13:25:07 ditto, with a BuildJumpIfToBooleanValueEquals(...)
oth 2015/12/09 11:26:45 Done.
1158 } 1276 }
1159 1277
1160 1278
1161 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant( 1279 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant(
1162 const interpreter::BytecodeArrayIterator& iterator) { 1280 const interpreter::BytecodeArrayIterator& iterator) {
1163 UNIMPLEMENTED(); 1281 Node* accumulator = environment()->LookupAccumulator();
1282 Node* to_boolean =
1283 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1284 Node* comperand = jsgraph()->TrueConstant();
1285 Node* comparison =
1286 NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1287 BuildConditionalJump(comparison);
1164 } 1288 }
1165 1289
1166 1290
1167 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse( 1291 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse(
1168 const interpreter::BytecodeArrayIterator& iterator) { 1292 const interpreter::BytecodeArrayIterator& iterator) {
1169 UNIMPLEMENTED(); 1293 Node* accumulator = environment()->LookupAccumulator();
1294 Node* to_boolean =
1295 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1296 Node* comperand = jsgraph()->FalseConstant();
1297 Node* comparison =
1298 NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1299 BuildConditionalJump(comparison);
1170 } 1300 }
1171 1301
1172 1302
1173 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant( 1303 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant(
1174 const interpreter::BytecodeArrayIterator& iterator) { 1304 const interpreter::BytecodeArrayIterator& iterator) {
1175 UNIMPLEMENTED(); 1305 Node* accumulator = environment()->LookupAccumulator();
1306 Node* to_boolean =
1307 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1308 Node* comperand = jsgraph()->FalseConstant();
1309 Node* comparison =
1310 NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1311 BuildConditionalJump(comparison);
1176 } 1312 }
1177 1313
1178 1314
1179 void BytecodeGraphBuilder::VisitJumpIfNull( 1315 void BytecodeGraphBuilder::VisitJumpIfNull(
1180 const interpreter::BytecodeArrayIterator& iterator) { 1316 const interpreter::BytecodeArrayIterator& iterator) {
1181 UNIMPLEMENTED(); 1317 Node* accumulator = environment()->LookupAccumulator();
1318 Node* comperand = jsgraph()->NullConstant();
1319 Node* comparison =
1320 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1321 BuildConditionalJump(comparison);
1182 } 1322 }
1183 1323
1184 1324
1185 void BytecodeGraphBuilder::VisitJumpIfNullConstant( 1325 void BytecodeGraphBuilder::VisitJumpIfNullConstant(
1186 const interpreter::BytecodeArrayIterator& iterator) { 1326 const interpreter::BytecodeArrayIterator& iterator) {
1187 UNIMPLEMENTED(); 1327 Node* accumulator = environment()->LookupAccumulator();
1328 Node* comperand = jsgraph()->NullConstant();
1329 Node* comparison =
1330 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1331 BuildConditionalJump(comparison);
1188 } 1332 }
1189 1333
1190 1334
1191 void BytecodeGraphBuilder::VisitJumpIfUndefined( 1335 void BytecodeGraphBuilder::VisitJumpIfUndefined(
1192 const interpreter::BytecodeArrayIterator& iterator) { 1336 const interpreter::BytecodeArrayIterator& iterator) {
1193 UNIMPLEMENTED(); 1337 Node* accumulator = environment()->LookupAccumulator();
1338 Node* comperand = jsgraph()->UndefinedConstant();
1339 Node* comparison =
1340 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1341 BuildConditionalJump(comparison);
1194 } 1342 }
1195 1343
1196 1344
1197 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant( 1345 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant(
1198 const interpreter::BytecodeArrayIterator& iterator) { 1346 const interpreter::BytecodeArrayIterator& iterator) {
1199 UNIMPLEMENTED(); 1347 Node* accumulator = environment()->LookupAccumulator();
1348 Node* comperand = jsgraph()->UndefinedConstant();
1349 Node* comparison =
1350 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1351 BuildConditionalJump(comparison);
1200 } 1352 }
1201 1353
1202 1354
1203 void BytecodeGraphBuilder::VisitReturn( 1355 void BytecodeGraphBuilder::VisitReturn(
1204 const interpreter::BytecodeArrayIterator& iterator) { 1356 const interpreter::BytecodeArrayIterator& iterator) {
1205 Node* control = 1357 Node* control =
1206 NewNode(common()->Return(), environment()->LookupAccumulator()); 1358 NewNode(common()->Return(), environment()->LookupAccumulator());
1207 UpdateControlDependencyToLeaveFunction(control); 1359 UpdateControlDependencyToLeaveFunction(control);
1360 BuildReturn();
1208 } 1361 }
1209 1362
1210 1363
1211 void BytecodeGraphBuilder::VisitForInPrepare( 1364 void BytecodeGraphBuilder::VisitForInPrepare(
1212 const interpreter::BytecodeArrayIterator& iterator) { 1365 const interpreter::BytecodeArrayIterator& iterator) {
1213 UNIMPLEMENTED(); 1366 UNIMPLEMENTED();
1214 } 1367 }
1215 1368
1216 1369
1217 void BytecodeGraphBuilder::VisitForInNext( 1370 void BytecodeGraphBuilder::VisitForInNext(
1218 const interpreter::BytecodeArrayIterator& iterator) { 1371 const interpreter::BytecodeArrayIterator& iterator) {
1219 UNIMPLEMENTED(); 1372 UNIMPLEMENTED();
1220 } 1373 }
1221 1374
1222 1375
1223 void BytecodeGraphBuilder::VisitForInDone( 1376 void BytecodeGraphBuilder::VisitForInDone(
1224 const interpreter::BytecodeArrayIterator& iterator) { 1377 const interpreter::BytecodeArrayIterator& iterator) {
1225 UNIMPLEMENTED(); 1378 UNIMPLEMENTED();
1226 } 1379 }
1227 1380
1228 1381
1382 void BytecodeGraphBuilder::PrepareForNewBasicBlockVisit() {
rmcilroy 2015/12/08 13:25:07 nit - I would drop the "new" here, but don't reall
oth 2015/12/09 11:26:45 Done.
1383 int block_id = basic_block()->rpo_id();
1384
1385 DCHECK_NULL(block_environment_infos_[block_id]);
1386 block_environment_infos_[block_id] =
1387 new (local_zone()) BlockEnvironmentInfo();
1388
1389 // Count number of forward and back links to this block
1390 int back_edges = 0;
1391
1392 // Merge forward links and check for backwards edges
1393 bool default_done = false;
1394 for (size_t i = 0; i < basic_block()->incoming_count(); i++) {
1395 const BytecodeBasicBlock* incoming = basic_block()->incoming(i);
1396 if (incoming->is_dominated_by(basic_block())) {
1397 back_edges++;
1398 } else {
1399 Environment* preceding_environment;
1400 if (incoming->if_true() == basic_block()) {
1401 preceding_environment =
1402 block_environment_infos_[incoming->rpo_id()]->if_true_environment();
1403 } else {
1404 DCHECK_EQ(incoming->if_false(), basic_block());
1405 preceding_environment = block_environment_infos_[incoming->rpo_id()]
1406 ->if_false_environment();
1407 }
1408
1409 DCHECK_NOT_NULL(preceding_environment);
1410 if (default_done) {
rmcilroy 2015/12/08 13:25:07 Could you get rid of the default_done boolean by a
oth 2015/12/09 11:26:45 Done.
1411 environment()->Merge(preceding_environment);
1412 } else {
1413 set_environment(preceding_environment);
1414 default_done = true;
1415 }
1416 }
1417 }
1418
1419 if (back_edges) {
rmcilroy 2015/12/08 13:25:07 nit - back_edges != 0
oth 2015/12/09 11:26:45 Done.
1420 Environment* loop_env = environment()->CopyForLoop();
1421 block_environment_infos_[block_id]->set_loop_header_environment(loop_env);
1422 }
1423 }
1424
1425
1426 void BytecodeGraphBuilder::CompleteNewBasicBlockVisit() {
rmcilroy 2015/12/08 13:25:07 ditto
oth 2015/12/09 11:26:45 Done.
1427 if (!basic_block()->is_exit()) {
1428 int last_offset = basic_block()->last_bytecode_offset();
1429 interpreter::Bytecode last_bytecode =
1430 interpreter::Bytecodes::FromByte(bytecode_array()->get(last_offset));
1431 if (!interpreter::Bytecodes::IsLocalControlFlow(last_bytecode)) {
rmcilroy 2015/12/08 13:25:08 Could you do the IsLocalControlFlow check in the b
oth 2015/12/09 11:26:45 Done.
1432 DCHECK_NOT_NULL(basic_block()->if_true());
1433 DCHECK_NULL(basic_block()->if_false());
1434 DCHECK(basic_block()->if_true() != nullptr);
1435 DCHECK_NOT_NULL(environment());
rmcilroy 2015/12/08 13:25:08 Should environment not always be non-null at this
oth 2015/12/09 11:26:45 Change to make the invariant true.
1436 int block_id = basic_block()->rpo_id();
1437 block_environment_infos_[block_id]->set_if_true_environment(
1438 environment());
1439 BuildBackEdgeIfRequired(basic_block()->if_true());
rmcilroy 2015/12/08 13:25:07 Would be good to have a comment here one why what
oth 2015/12/09 11:26:45 Done.
1440 }
1441 }
1442 set_environment(nullptr);
1443 }
1444
1445
1446 void BytecodeGraphBuilder::BuildReturn() {
1447 DCHECK_NOT_NULL(basic_block()->if_true());
1448 DCHECK_NULL(basic_block()->if_false());
1449 int block_id = basic_block()->rpo_id();
1450 block_environment_infos_[block_id]->set_if_true_environment(environment());
1451 set_environment(nullptr);
1452 }
1453
1454
1455 void BytecodeGraphBuilder::BuildBackEdgeIfRequired(BytecodeBasicBlock* target) {
rmcilroy 2015/12/08 13:25:07 nit - move above BuildReturn (group BuildReturn /
oth 2015/12/09 11:26:45 Done.
1456 if (basic_block()->is_dominated_by(target)) {
1457 BytecodeBasicBlock* loop_header = target;
1458 BlockEnvironmentInfo* info =
1459 block_environment_infos_[loop_header->rpo_id()];
1460 info->loop_header_environment()->Merge(environment());
1461 }
1462 }
1463
1464
1465 void BytecodeGraphBuilder::BuildJump() {
1466 DCHECK_NOT_NULL(basic_block()->if_true());
1467 DCHECK_NULL(basic_block()->if_false());
1468 int block_id = basic_block()->rpo_id();
1469 block_environment_infos_[block_id]->set_if_true_environment(environment());
1470 BuildBackEdgeIfRequired(basic_block()->if_true());
1471 set_environment(nullptr);
1472 }
1473
1474
1475 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1476 DCHECK_NOT_NULL(basic_block()->if_true());
1477 DCHECK_NOT_NULL(basic_block()->if_false());
1478 int block_id = basic_block()->rpo_id();
1479 NewBranch(condition);
1480 // Save environment for false branch.
1481 Environment* saved_env = environment()->CopyForConditional();
1482 // Process true branch.
1483 NewIfTrue();
1484 block_environment_infos_[block_id]->set_if_true_environment(environment());
1485 BuildBackEdgeIfRequired(basic_block()->if_true());
1486 // Restore environment and process false branch.
1487 set_environment(saved_env);
1488 NewIfFalse();
1489 block_environment_infos_[block_id]->set_if_false_environment(environment());
1490 BuildBackEdgeIfRequired(basic_block()->if_false());
1491 set_environment(nullptr);
1492 }
1493
1494
1229 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) { 1495 Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1230 if (size > input_buffer_size_) { 1496 if (size > input_buffer_size_) {
1231 size = size + kInputBufferSizeIncrement + input_buffer_size_; 1497 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1232 input_buffer_ = local_zone()->NewArray<Node*>(size); 1498 input_buffer_ = local_zone()->NewArray<Node*>(size);
1233 input_buffer_size_ = size; 1499 input_buffer_size_ = size;
1234 } 1500 }
1235 return input_buffer_; 1501 return input_buffer_;
1236 } 1502 }
1237 1503
1238 1504
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 Node* on_success = graph()->NewNode(if_success, result); 1557 Node* on_success = graph()->NewNode(if_success, result);
1292 environment_->UpdateControlDependency(on_success); 1558 environment_->UpdateControlDependency(on_success);
1293 } 1559 }
1294 } 1560 }
1295 } 1561 }
1296 1562
1297 return result; 1563 return result;
1298 } 1564 }
1299 1565
1300 1566
1567 Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1568 const Operator* phi_op = common()->Phi(kMachAnyTagged, 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
1576 // TODO(mstarzinger): Revisit this once we have proper effect states.
1577 Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1578 Node* control) {
1579 const Operator* phi_op = common()->EffectPhi(count);
1580 Node** buffer = EnsureInputBufferSize(count + 1);
1581 MemsetPointer(buffer, input, count);
1582 buffer[count] = control;
1583 return graph()->NewNode(phi_op, count + 1, buffer, true);
1584 }
1585
1586
1301 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) { 1587 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1302 int inputs = control->op()->ControlInputCount() + 1; 1588 int inputs = control->op()->ControlInputCount() + 1;
1303 if (control->opcode() == IrOpcode::kLoop) { 1589 if (control->opcode() == IrOpcode::kLoop) {
1304 // Control node for loop exists, add input. 1590 // Control node for loop exists, add input.
1305 const Operator* op = common()->Loop(inputs); 1591 const Operator* op = common()->Loop(inputs);
1306 control->AppendInput(graph_zone(), other); 1592 control->AppendInput(graph_zone(), other);
1307 NodeProperties::ChangeOp(control, op); 1593 NodeProperties::ChangeOp(control, op);
1308 } else if (control->opcode() == IrOpcode::kMerge) { 1594 } else if (control->opcode() == IrOpcode::kMerge) {
1309 // Control node for merge exists, add input. 1595 // Control node for merge exists, add input.
1310 const Operator* op = common()->Merge(inputs); 1596 const Operator* op = common()->Merge(inputs);
1311 control->AppendInput(graph_zone(), other); 1597 control->AppendInput(graph_zone(), other);
1312 NodeProperties::ChangeOp(control, op); 1598 NodeProperties::ChangeOp(control, op);
1313 } else { 1599 } else {
1314 // Control node is a singleton, introduce a merge. 1600 // Control node is a singleton, introduce a merge.
1315 const Operator* op = common()->Merge(inputs); 1601 const Operator* op = common()->Merge(inputs);
1316 Node* merge_inputs[] = {control, other}; 1602 Node* merge_inputs[] = {control, other};
1317 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true); 1603 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1318 } 1604 }
1319 return control; 1605 return control;
1320 } 1606 }
1321 1607
1322 1608
1609 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1610 Node* control) {
1611 int inputs = control->op()->ControlInputCount();
1612 if (value->opcode() == IrOpcode::kEffectPhi &&
1613 NodeProperties::GetControlInput(value) == control) {
1614 // Phi already exists, add input.
1615 value->InsertInput(graph_zone(), inputs - 1, other);
1616 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1617 } else if (value != other) {
1618 // Phi does not exist yet, introduce one.
1619 value = NewEffectPhi(inputs, value, control);
1620 value->ReplaceInput(inputs - 1, other);
1621 }
1622 return value;
1623 }
1624
1625
1626 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1627 Node* control) {
1628 int inputs = control->op()->ControlInputCount();
1629 if (value->opcode() == IrOpcode::kPhi &&
1630 NodeProperties::GetControlInput(value) == control) {
1631 // Phi already exists, add input.
1632 value->InsertInput(graph_zone(), inputs - 1, other);
1633 NodeProperties::ChangeOp(value, common()->Phi(kMachAnyTagged, inputs));
1634 } else if (value != other) {
1635 // Phi does not exist yet, introduce one.
1636 value = NewPhi(inputs, value, control);
1637 value->ReplaceInput(inputs - 1, other);
1638 }
1639 return value;
1640 }
1641
1642
1323 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { 1643 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) {
1324 if (environment()->IsMarkedAsUnreachable()) return; 1644 if (environment()->IsMarkedAsUnreachable()) return;
1325 environment()->MarkAsUnreachable(); 1645 environment()->MarkAsUnreachable();
1326 exit_controls_.push_back(exit); 1646 exit_controls_.push_back(exit);
1327 } 1647 }
1328 1648
1329 } // namespace compiler 1649 } // namespace compiler
1330 } // namespace internal 1650 } // namespace internal
1331 } // namespace v8 1651 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698