OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
11 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
| 12 #include "src/compiler/diamond.h" |
12 #include "src/compiler/graph-inl.h" | 13 #include "src/compiler/graph-inl.h" |
13 #include "src/compiler/node-matchers.h" | 14 #include "src/compiler/node-matchers.h" |
14 #include "src/compiler/node-properties-inl.h" | 15 #include "src/compiler/node-properties-inl.h" |
15 #include "src/compiler/representation-change.h" | 16 #include "src/compiler/representation-change.h" |
16 #include "src/compiler/simplified-lowering.h" | 17 #include "src/compiler/simplified-lowering.h" |
17 #include "src/compiler/simplified-operator.h" | 18 #include "src/compiler/simplified-operator.h" |
18 #include "src/objects.h" | 19 #include "src/objects.h" |
19 | 20 |
20 namespace v8 { | 21 namespace v8 { |
21 namespace internal { | 22 namespace internal { |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1165 Node* select = graph()->NewNode( | 1166 Node* select = graph()->NewNode( |
1166 common()->Select(kMachIntPtr, BranchHint::kTrue), check, index, | 1167 common()->Select(kMachIntPtr, BranchHint::kTrue), check, index, |
1167 jsgraph()->IntPtrConstant(AddressForOutOfBoundsLoad(output_type) - | 1168 jsgraph()->IntPtrConstant(AddressForOutOfBoundsLoad(output_type) - |
1168 mbase.Value())); | 1169 mbase.Value())); |
1169 | 1170 |
1170 node->set_op(op); | 1171 node->set_op(op); |
1171 node->ReplaceInput(1, select); | 1172 node->ReplaceInput(1, select); |
1172 node->ReplaceInput(2, effect); | 1173 node->ReplaceInput(2, effect); |
1173 node->ReplaceInput(3, graph()->start()); | 1174 node->ReplaceInput(3, graph()->start()); |
1174 } else { | 1175 } else { |
1175 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 1176 Diamond d(graph(), common(), check, BranchHint::kTrue); |
1176 check, graph()->start()); | |
1177 | 1177 |
1178 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1178 Node* load = graph()->NewNode(op, base, index, effect, d.if_true); |
1179 Node* load = graph()->NewNode(op, base, index, effect, if_true); | |
1180 Node* result = load; | 1179 Node* result = load; |
1181 if (output_type & kRepTagged) { | 1180 if (output_type & kRepTagged) { |
1182 // TODO(turbofan): This is ugly as hell! | 1181 // TODO(turbofan): This is ugly as hell! |
1183 SimplifiedOperatorBuilder simplified(graph()->zone()); | 1182 SimplifiedOperatorBuilder simplified(graph()->zone()); |
1184 RepresentationChanger changer(jsgraph(), &simplified, | 1183 RepresentationChanger changer(jsgraph(), &simplified, |
1185 graph()->zone()->isolate()); | 1184 graph()->zone()->isolate()); |
1186 result = | 1185 result = |
1187 changer.GetTaggedRepresentationFor(result, access.machine_type); | 1186 changer.GetTaggedRepresentationFor(result, access.machine_type); |
1188 } | 1187 } |
1189 | 1188 |
1190 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
1191 Node* undefined; | 1189 Node* undefined; |
1192 if (output_type & kRepTagged) { | 1190 if (output_type & kRepTagged) { |
1193 DCHECK_EQ(0, access.machine_type & kRepTagged); | 1191 DCHECK_EQ(0, access.machine_type & kRepTagged); |
1194 undefined = jsgraph()->UndefinedConstant(); | 1192 undefined = jsgraph()->UndefinedConstant(); |
1195 } else if (output_type & kRepFloat32) { | 1193 } else if (output_type & kRepFloat32) { |
1196 undefined = | 1194 undefined = |
1197 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); | 1195 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN()); |
1198 } else if (output_type & kRepFloat64) { | 1196 } else if (output_type & kRepFloat64) { |
1199 undefined = jsgraph()->Float64Constant( | 1197 undefined = jsgraph()->Float64Constant( |
1200 std::numeric_limits<double>::quiet_NaN()); | 1198 std::numeric_limits<double>::quiet_NaN()); |
1201 } else { | 1199 } else { |
1202 undefined = jsgraph()->Int32Constant(0); | 1200 undefined = jsgraph()->Int32Constant(0); |
1203 } | 1201 } |
1204 | 1202 |
1205 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1203 // Replace effect uses of node with the effect phi. |
1206 Node* phi = graph()->NewNode(common()->EffectPhi(2), load, effect, merge); | 1204 NodeProperties::ReplaceWithValue(node, node, d.EffectPhi(load, effect)); |
1207 | 1205 |
1208 // Replace effect uses of node with the effect phi. | 1206 d.OverwriteWithPhi(node, output_type, result, undefined); |
1209 for (UseIter i = node->uses().begin(); i != node->uses().end();) { | |
1210 if (NodeProperties::IsEffectEdge(i.edge())) { | |
1211 i = i.UpdateToAndIncrement(phi); | |
1212 } else { | |
1213 ++i; | |
1214 } | |
1215 } | |
1216 | |
1217 node->set_op(common()->Phi(output_type, 2)); | |
1218 node->ReplaceInput(0, result); | |
1219 node->ReplaceInput(1, undefined); | |
1220 node->ReplaceInput(2, merge); | |
1221 node->TrimInputCount(3); | |
1222 } | 1207 } |
1223 } | 1208 } |
1224 } | 1209 } |
1225 | 1210 |
1226 | 1211 |
1227 void SimplifiedLowering::DoStoreElement(Node* node) { | 1212 void SimplifiedLowering::DoStoreElement(Node* node) { |
1228 const ElementAccess& access = ElementAccessOf(node->op()); | 1213 const ElementAccess& access = ElementAccessOf(node->op()); |
1229 const Operator* op = machine()->Store(StoreRepresentation( | 1214 const Operator* op = machine()->Store(StoreRepresentation( |
1230 access.machine_type, | 1215 access.machine_type, |
1231 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, | 1216 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, |
(...skipping 18 matching lines...) Expand all Loading... |
1250 if (mbase.HasValue()) { | 1235 if (mbase.HasValue()) { |
1251 Node* select = graph()->NewNode( | 1236 Node* select = graph()->NewNode( |
1252 common()->Select(kMachIntPtr, BranchHint::kTrue), check, index, | 1237 common()->Select(kMachIntPtr, BranchHint::kTrue), check, index, |
1253 jsgraph()->IntPtrConstant(AddressForOutOfBoundsStore() - | 1238 jsgraph()->IntPtrConstant(AddressForOutOfBoundsStore() - |
1254 mbase.Value())); | 1239 mbase.Value())); |
1255 | 1240 |
1256 node->set_op(op); | 1241 node->set_op(op); |
1257 node->ReplaceInput(1, select); | 1242 node->ReplaceInput(1, select); |
1258 node->RemoveInput(2); | 1243 node->RemoveInput(2); |
1259 } else { | 1244 } else { |
1260 Node* branch = | 1245 Diamond d(graph(), common(), check, BranchHint::kTrue); |
1261 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 1246 d.Chain(control); |
1262 | 1247 Node* store = graph()->NewNode(op, base, index, value, effect, d.if_true); |
1263 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1248 d.OverwriteWithEffectPhi(node, store, effect); |
1264 Node* store = graph()->NewNode(op, base, index, value, effect, if_true); | |
1265 | |
1266 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
1267 | |
1268 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
1269 | |
1270 node->set_op(common()->EffectPhi(2)); | |
1271 node->ReplaceInput(0, store); | |
1272 node->ReplaceInput(1, effect); | |
1273 node->ReplaceInput(2, merge); | |
1274 node->TrimInputCount(3); | |
1275 } | 1249 } |
1276 } | 1250 } |
1277 } | 1251 } |
1278 | 1252 |
1279 | 1253 |
1280 void SimplifiedLowering::DoStringAdd(Node* node) { | 1254 void SimplifiedLowering::DoStringAdd(Node* node) { |
1281 Callable callable = CodeFactory::StringAdd( | 1255 Callable callable = CodeFactory::StringAdd( |
1282 zone()->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); | 1256 zone()->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED); |
1283 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1257 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1284 CallDescriptor* desc = | 1258 CallDescriptor* desc = |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 Node* const rhs = m.right().node(); | 1292 Node* const rhs = m.right().node(); |
1319 | 1293 |
1320 if (m.right().Is(-1)) { | 1294 if (m.right().Is(-1)) { |
1321 return graph()->NewNode(machine()->Int32Sub(), zero, lhs); | 1295 return graph()->NewNode(machine()->Int32Sub(), zero, lhs); |
1322 } else if (m.right().Is(0)) { | 1296 } else if (m.right().Is(0)) { |
1323 return rhs; | 1297 return rhs; |
1324 } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) { | 1298 } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) { |
1325 return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start()); | 1299 return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start()); |
1326 } | 1300 } |
1327 | 1301 |
1328 Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | 1302 Diamond if_zero(graph(), common(), |
1329 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, | 1303 graph()->NewNode(machine()->Word32Equal(), rhs, zero), |
1330 graph()->start()); | 1304 BranchHint::kFalse); |
1331 | 1305 |
1332 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1306 Diamond if_minus_one(graph(), common(), |
1333 Node* true0 = zero; | 1307 graph()->NewNode(machine()->Word32Equal(), rhs, |
| 1308 jsgraph()->Int32Constant(-1)), |
| 1309 BranchHint::kFalse); |
| 1310 if_minus_one.Nest(if_zero, false); |
| 1311 Node* sub = graph()->NewNode(machine()->Int32Sub(), zero, lhs); |
| 1312 Node* div = |
| 1313 graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_minus_one.if_false); |
1334 | 1314 |
1335 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1315 return if_zero.Phi(kMachInt32, zero, if_minus_one.Phi(kMachInt32, sub, div)); |
1336 Node* false0 = nullptr; | |
1337 { | |
1338 Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs, | |
1339 jsgraph()->Int32Constant(-1)); | |
1340 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
1341 check1, if_false0); | |
1342 | |
1343 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
1344 Node* true1 = graph()->NewNode(machine()->Int32Sub(), zero, lhs); | |
1345 | |
1346 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
1347 Node* false1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_false1); | |
1348 | |
1349 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
1350 false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1, | |
1351 if_false0); | |
1352 } | |
1353 | |
1354 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
1355 return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0, merge0); | |
1356 } | 1316 } |
1357 | 1317 |
1358 | 1318 |
1359 Node* SimplifiedLowering::Int32Mod(Node* const node) { | 1319 Node* SimplifiedLowering::Int32Mod(Node* const node) { |
1360 Int32BinopMatcher m(node); | 1320 Int32BinopMatcher m(node); |
1361 Node* const zero = jsgraph()->Int32Constant(0); | 1321 Node* const zero = jsgraph()->Int32Constant(0); |
1362 Node* const lhs = m.left().node(); | 1322 Node* const lhs = m.left().node(); |
1363 Node* const rhs = m.right().node(); | 1323 Node* const rhs = m.right().node(); |
1364 | 1324 |
1365 if (m.right().Is(-1) || m.right().Is(0)) { | 1325 if (m.right().Is(-1) || m.right().Is(0)) { |
1366 return zero; | 1326 return zero; |
1367 } else if (machine()->Int32ModIsSafe() || m.right().HasValue()) { | 1327 } else if (machine()->Int32ModIsSafe() || m.right().HasValue()) { |
1368 return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start()); | 1328 return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start()); |
1369 } | 1329 } |
1370 | 1330 |
1371 Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | 1331 Diamond if_zero(graph(), common(), |
1372 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0, | 1332 graph()->NewNode(machine()->Word32Equal(), rhs, zero), |
1373 graph()->start()); | 1333 BranchHint::kFalse); |
1374 | 1334 |
1375 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); | 1335 Diamond if_minus_one(graph(), common(), |
1376 Node* true0 = zero; | 1336 graph()->NewNode(machine()->Word32Equal(), rhs, |
| 1337 jsgraph()->Int32Constant(-1)), |
| 1338 BranchHint::kFalse); |
| 1339 if_minus_one.Nest(if_zero, false); |
| 1340 Node* mod = |
| 1341 graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_minus_one.if_false); |
1377 | 1342 |
1378 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); | 1343 return if_zero.Phi(kMachInt32, zero, if_minus_one.Phi(kMachInt32, zero, mod)); |
1379 Node* false0 = nullptr; | |
1380 { | |
1381 Node* check1 = graph()->NewNode(machine()->Word32Equal(), rhs, | |
1382 jsgraph()->Int32Constant(-1)); | |
1383 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), | |
1384 check1, if_false0); | |
1385 | |
1386 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); | |
1387 Node* true1 = zero; | |
1388 | |
1389 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); | |
1390 Node* false1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_false1); | |
1391 | |
1392 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); | |
1393 false0 = graph()->NewNode(common()->Phi(kMachInt32, 2), true1, false1, | |
1394 if_false0); | |
1395 } | |
1396 | |
1397 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); | |
1398 return graph()->NewNode(common()->Phi(kMachInt32, 2), true0, false0, merge0); | |
1399 } | 1344 } |
1400 | 1345 |
1401 | 1346 |
1402 Node* SimplifiedLowering::Uint32Div(Node* const node) { | 1347 Node* SimplifiedLowering::Uint32Div(Node* const node) { |
1403 Uint32BinopMatcher m(node); | 1348 Uint32BinopMatcher m(node); |
1404 Node* const zero = jsgraph()->Uint32Constant(0); | 1349 Node* const zero = jsgraph()->Uint32Constant(0); |
1405 Node* const lhs = m.left().node(); | 1350 Node* const lhs = m.left().node(); |
1406 Node* const rhs = m.right().node(); | 1351 Node* const rhs = m.right().node(); |
1407 | 1352 |
1408 if (m.right().Is(0)) { | 1353 if (m.right().Is(0)) { |
1409 return zero; | 1354 return zero; |
1410 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { | 1355 } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) { |
1411 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); | 1356 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start()); |
1412 } | 1357 } |
1413 | 1358 |
1414 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | 1359 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
1415 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check, | 1360 Diamond d(graph(), common(), check, BranchHint::kFalse); |
1416 graph()->start()); | 1361 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false); |
1417 | 1362 return d.Phi(kMachUint32, zero, div); |
1418 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
1419 Node* vtrue = zero; | |
1420 | |
1421 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
1422 Node* vfalse = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, if_false); | |
1423 | |
1424 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
1425 return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse, merge); | |
1426 } | 1363 } |
1427 | 1364 |
1428 | 1365 |
1429 Node* SimplifiedLowering::Uint32Mod(Node* const node) { | 1366 Node* SimplifiedLowering::Uint32Mod(Node* const node) { |
1430 Uint32BinopMatcher m(node); | 1367 Uint32BinopMatcher m(node); |
1431 Node* const zero = jsgraph()->Uint32Constant(0); | 1368 Node* const zero = jsgraph()->Uint32Constant(0); |
1432 Node* const lhs = m.left().node(); | 1369 Node* const lhs = m.left().node(); |
1433 Node* const rhs = m.right().node(); | 1370 Node* const rhs = m.right().node(); |
1434 | 1371 |
1435 if (m.right().Is(0)) { | 1372 if (m.right().Is(0)) { |
1436 return zero; | 1373 return zero; |
1437 } else if (machine()->Uint32ModIsSafe() || m.right().HasValue()) { | 1374 } else if (machine()->Uint32ModIsSafe() || m.right().HasValue()) { |
1438 return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start()); | 1375 return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start()); |
1439 } | 1376 } |
1440 | 1377 |
1441 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); | 1378 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero); |
1442 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check, | 1379 Diamond d(graph(), common(), check, BranchHint::kFalse); |
1443 graph()->start()); | 1380 Node* mod = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, d.if_false); |
1444 | 1381 return d.Phi(kMachUint32, zero, mod); |
1445 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | |
1446 Node* vtrue = zero; | |
1447 | |
1448 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | |
1449 Node* vfalse = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_false); | |
1450 | |
1451 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); | |
1452 return graph()->NewNode(common()->Phi(kMachUint32, 2), vtrue, vfalse, merge); | |
1453 } | 1382 } |
1454 | 1383 |
1455 | 1384 |
1456 void SimplifiedLowering::DoStringEqual(Node* node) { | 1385 void SimplifiedLowering::DoStringEqual(Node* node) { |
1457 node->set_op(machine()->WordEqual()); | 1386 node->set_op(machine()->WordEqual()); |
1458 node->ReplaceInput(0, StringComparison(node, false)); | 1387 node->ReplaceInput(0, StringComparison(node, false)); |
1459 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1388 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1460 } | 1389 } |
1461 | 1390 |
1462 | 1391 |
1463 void SimplifiedLowering::DoStringLessThan(Node* node) { | 1392 void SimplifiedLowering::DoStringLessThan(Node* node) { |
1464 node->set_op(machine()->IntLessThan()); | 1393 node->set_op(machine()->IntLessThan()); |
1465 node->ReplaceInput(0, StringComparison(node, true)); | 1394 node->ReplaceInput(0, StringComparison(node, true)); |
1466 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1395 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1467 } | 1396 } |
1468 | 1397 |
1469 | 1398 |
1470 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1399 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
1471 node->set_op(machine()->IntLessThanOrEqual()); | 1400 node->set_op(machine()->IntLessThanOrEqual()); |
1472 node->ReplaceInput(0, StringComparison(node, true)); | 1401 node->ReplaceInput(0, StringComparison(node, true)); |
1473 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1402 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1474 } | 1403 } |
1475 | 1404 |
1476 } // namespace compiler | 1405 } // namespace compiler |
1477 } // namespace internal | 1406 } // namespace internal |
1478 } // namespace v8 | 1407 } // namespace v8 |
OLD | NEW |