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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/finalize.dart

Issue 1512303002: dart2js cps: Add instruction for bounds checks. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: 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
(Empty)
1 library dart2js.cps_ir.finalize;
2
3 import 'cps_ir_nodes.dart';
4 import 'cps_fragment.dart';
5 import 'optimizers.dart' show Pass;
6 import '../js_backend/js_backend.dart' show JavaScriptBackend;
7 import '../js_backend/backend_helpers.dart';
8
9 /// A transformation pass that must run immediately before the tree IR builder.
10 ///
11 /// This expands [BoundsCheck] nodes into more low-level operations.
12 class Finalize extends TrampolineRecursiveVisitor implements Pass {
13 String get passName => 'Finalize';
14
15 JavaScriptBackend backend;
16 BackendHelpers get helpers => backend.helpers;
17
18 Finalize(this.backend);
19
20 void rewrite(FunctionDefinition node) {
21 visit(node);
22 }
23
24 Expression traverseLetPrim(LetPrim node) {
25 CpsFragment cps = visit(node.primitive);
26 if (cps == null) return node.body;
27 cps.insertBelow(node);
28 Expression next = node.body;
29 node.remove();
30 return next;
31 }
32
33 bool areAdjacent(Primitive first, Primitive second) {
34 return first.parent == second.parent.parent;
35 }
36
37 CpsFragment visitBoundsCheck(BoundsCheck node) {
38 CpsFragment cps = new CpsFragment(node.sourceInformation);
39 if (node.hasNoChecks) {
40 node..replaceUsesWith(node.object.definition)..destroy();
41 return cps;
42 }
43 Continuation fail = cps.letCont();
44 if (node.hasLowerBoundCheck) {
45 cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.NumLt,
46 [node.index.definition, cps.makeZero()]))
47 .invokeContinuation(fail);
48 }
49 if (node.hasUpperBoundCheck) {
50 Primitive length = node.length.definition;
51 if (length is GetLength &&
52 length.hasExactlyOneUse &&
53 areAdjacent(length, node)) {
54 // Rebind the GetLength here, so it does not get stuck outside the
55 // condition, blocked from propagating by the lower bounds check.
56 LetPrim lengthBinding = length.parent;
57 lengthBinding.remove();
58 cps.letPrim(length);
59 }
60 cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.NumGe,
61 [node.index.definition, length]))
62 .invokeContinuation(fail);
63 }
64 if (node.hasEmptinessCheck) {
65 cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.StrictEq,
66 [node.length.definition, cps.makeZero()]))
67 .invokeContinuation(fail);
sra1 2015/12/10 19:09:40 (a.length === 0) I think this could be (!a.length
asgerf 2015/12/11 12:16:31 I had to resolve to micro benchmarking to measure
68 }
69 cps.insideContinuation(fail).invokeStaticThrower(
70 helpers.throwIndexOutOfRangeException,
71 [node.object.definition, node.index.definition]);
72 node..replaceUsesWith(node.object.definition)..destroy();
73 return cps;
74 }
75 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698