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

Unified Diff: pkg/compiler/lib/src/cps_ir/type_propagation.dart

Issue 1188253006: dart2js cps: Replace getter/setter calls with direct field access. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix test case Created 5 years, 6 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart ('k') | tests/language/dead_field_access_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 7ae47a5c134e79a5ad369d2a07259bf3dd9c03d7..099e2a699026603bc570f58f041ddf4ac34bbd45 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -12,12 +12,12 @@ import '../dart_types.dart' as types;
import '../dart2jslib.dart' as dart2js;
import '../tree/tree.dart' show LiteralDartString;
import 'cps_ir_nodes.dart';
-import '../types/types.dart' show TypeMask, TypesTask;
+import '../types/types.dart';
import '../types/constants.dart' show computeTypeMask;
-import '../elements/elements.dart' show ClassElement, Element, Entity,
- FieldElement, FunctionElement, ParameterElement;
-import '../dart2jslib.dart' show ClassWorld;
+import '../elements/elements.dart';
+import '../dart2jslib.dart' show ClassWorld, World;
import '../universe/universe.dart';
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
enum AbstractBool {
True, False, Maybe, Nothing
@@ -25,7 +25,7 @@ enum AbstractBool {
class TypeMaskSystem {
final TypesTask inferrer;
- final ClassWorld classWorld;
+ final World classWorld;
TypeMask get dynamicType => inferrer.dynamicType;
TypeMask get typeType => inferrer.typeType;
@@ -50,6 +50,10 @@ class TypeMaskSystem {
classWorld);
}
+ Element locateSingleElement(TypeMask mask, Selector selector) {
+ return mask.locateSingleElement(selector, classWorld.compiler);
+ }
+
TypeMask getParameterType(ParameterElement parameter) {
return inferrer.getGuaranteedTypeOfElement(parameter);
}
@@ -355,6 +359,7 @@ class ConstantPropagationLattice {
class TypePropagator extends Pass {
String get passName => 'Sparse constant propagation';
+ final dart2js.Compiler _compiler;
// The constant system is used for evaluation of expressions with constant
// arguments.
final ConstantPropagationLattice _lattice;
@@ -362,7 +367,8 @@ class TypePropagator extends Pass {
final Map<Definition, AbstractValue> _values = <Definition, AbstractValue>{};
TypePropagator(dart2js.Compiler compiler)
- : _internalError = compiler.internalError,
+ : _compiler = compiler,
+ _internalError = compiler.internalError,
_lattice = new ConstantPropagationLattice(
new TypeMaskSystem(compiler),
compiler.backend.constantSystem,
@@ -389,6 +395,7 @@ class TypePropagator extends Pass {
// replace branches with fixed targets and side-effect-free expressions
// with constant results or existing values that are in scope.
TransformingVisitor transformer = new TransformingVisitor(
+ _compiler,
_lattice,
analyzer.reachableNodes,
analyzer.values,
@@ -423,13 +430,16 @@ class TransformingVisitor extends RecursiveVisitor {
final Map<Node, AbstractValue> values;
final Map<Expression, ConstantValue> replacements;
final ConstantPropagationLattice lattice;
+ final dart2js.Compiler compiler;
+ JavaScriptBackend get backend => compiler.backend;
TypeMaskSystem get typeSystem => lattice.typeSystem;
types.DartTypes get dartTypes => lattice.dartTypes;
final dart2js.InternalErrorFunction internalError;
- TransformingVisitor(this.lattice,
+ TransformingVisitor(this.compiler,
+ this.lattice,
this.reachable,
this.values,
this.replacements,
@@ -635,10 +645,64 @@ class TransformingVisitor extends RecursiveVisitor {
return false;
}
+ bool isInterceptedSelector(Selector selector) {
+ return backend.isInterceptedSelector(selector);
+ }
+
+ Primitive getDartReceiver(InvokeMethod node) {
+ if (isInterceptedSelector(node.selector)) {
+ return node.arguments[0].definition;
+ } else {
+ return node.receiver.definition;
+ }
+ }
+
+ Primitive getDartArgument(InvokeMethod node, int n) {
+ if (isInterceptedSelector(node.selector)) {
+ return node.arguments[n+1].definition;
+ } else {
+ return node.arguments[n].definition;
+ }
+ }
+
+ /// If [node] is a getter or setter invocation, tries to replace the
+ /// invocation with a direct access to a field.
+ ///
+ /// Returns `true` if the node was replaced.
+ bool inlineFieldAccess(InvokeMethod node) {
+ if (!node.selector.isGetter && !node.selector.isSetter) return false;
+ AbstractValue receiver = getValue(getDartReceiver(node));
+ if (receiver.isNothing) return false;
+ Element target =
+ typeSystem.locateSingleElement(receiver.type, node.selector);
+ if (target is! FieldElement) return false;
+ Continuation cont = node.continuation.definition;
+ if (node.selector.isGetter) {
+ GetField get = new GetField(getDartReceiver(node), target);
+ get.objectIsNotNull = receiver.isDefinitelyNotNull;
+ LetPrim let = makeLetPrimInvoke(get, cont);
+ replaceSubtree(node, let);
+ visitLetPrim(let);
+ return true;
+ } else {
+ if (target.isFinal) return false;
+ assert(cont.parameters.single.hasNoUses);
+ cont.parameters.clear();
+ SetField set = new SetField(getDartReceiver(node),
sra1 2015/06/19 18:21:00 This is not valid in checked mode unless we can pr
asgerf 2015/06/22 09:31:58 Nicely spotted, although we are not at all trying
+ target,
+ getDartArgument(node, 0));
+ set.body = new InvokeContinuation(cont, <Primitive>[]);
+ replaceSubtree(node, set);
+ visitSetField(set);
+ return true;
+ }
+ }
+
void visitInvokeMethod(InvokeMethod node) {
Continuation cont = node.continuation.definition;
if (constifyExpression(node, cont)) return;
if (specializeInvoke(node)) return;
+ if (inlineFieldAccess(node)) return;
AbstractValue receiver = getValue(node.receiver.definition);
node.receiverIsNotNull = receiver.isDefinitelyNotNull;
@@ -721,6 +785,10 @@ class TransformingVisitor extends RecursiveVisitor {
return null;
}
+ void visitGetField(GetField node) {
+ node.objectIsNotNull = getValue(node.object.definition).isDefinitelyNotNull;
+ }
+
void visitLetPrim(LetPrim node) {
AbstractValue value = getValue(node.primitive);
if (node.primitive is! Constant && value.isConstant) {
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart ('k') | tests/language/dead_field_access_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698