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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 694063005: Introduce Diamond, a helper for building diamond-shaped control patterns. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: newline Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler/select-lowering.cc ('k') | test/cctest/compiler/test-control-reducer.cc » ('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 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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/select-lowering.cc ('k') | test/cctest/compiler/test-control-reducer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698