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

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

Issue 1394003008: dart2js cps_ir: Unary operator improvements (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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
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 f45de41c118b18a988863d9b17a9cfa16c14ee66..f0aae40fc04a1a2be6b51937d9f9a0e6ef707f3e 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -243,8 +243,15 @@ class ConstantPropagationLattice {
///
/// This method returns `null` if a good result could not be found. In that
/// case, it is best to fall back on interprocedural type information.
- AbstractValue unaryOp(UnaryOperator operator,
- AbstractValue value) {
+ AbstractValue unaryOp(UnaryOperator operator, AbstractValue value) {
+ switch (operator.kind) {
+ case UnaryOperatorKind.COMPLEMENT:
+ return bitNotSpecial(value);
+ case UnaryOperatorKind.NEGATE:
+ return negateSpecial(value);
+ default:
+ break;
+ }
// TODO(asgerf): Also return information about whether this can throw?
if (value.isNothing) {
return nothing;
@@ -334,6 +341,27 @@ class ConstantPropagationLattice {
return null; // The caller will use return type from type inference.
}
+ AbstractValue foldUnary(UnaryOperation operation, AbstractValue value) {
+ if (value.isNothing) return nothing;
+ if (value.isConstant) {
+ ConstantValue result = operation.fold(value.constant);
+ if (result != null) return constant(result);
+ }
+ return null;
+ }
+
+ AbstractValue bitNotSpecial(AbstractValue value) {
+ return foldUnary(constantSystem.bitNot, value);
+ }
+
+ AbstractValue negateSpecial(AbstractValue value) {
+ AbstractValue folded = foldUnary(constantSystem.negate, value);
+ if (folded != null) return folded;
+ if (isDefinitelyInt(value)) return nonConstant(typeSystem.intType);
+ return null;
+ }
+
+
AbstractValue foldBinary(BinaryOperation operation,
AbstractValue left, AbstractValue right) {
if (left.isNothing || right.isNothing) return nothing;
@@ -492,7 +520,6 @@ class ConstantPropagationLattice {
return foldBinary(constantSystem.greaterEqual, left, right);
}
-
AbstractValue stringConstant(String value) {
return constant(new StringConstantValue(new ast.DartString.literal(value)));
}
@@ -938,17 +965,24 @@ class TransformingVisitor extends DeepRecursiveVisitor {
/// Returns `true` if the node was replaced.
bool specializeOperatorCall(InvokeMethod node) {
Continuation cont = node.continuation.definition;
- bool replaceWithBinary(BuiltinOperator operator,
- Primitive left,
- Primitive right) {
- Primitive prim =
- new ApplyBuiltinOperator(operator, <Primitive>[left, right],
- node.sourceInformation);
+ bool replaceWithPrimitive(Primitive prim) {
LetPrim let = makeLetPrimInvoke(prim, cont);
replaceSubtree(node, let);
push(let);
return true; // So returning early is more convenient.
}
+ bool replaceWithBinary(BuiltinOperator operator,
+ Primitive left,
+ Primitive right) {
+ return replaceWithPrimitive(
+ new ApplyBuiltinOperator(
+ operator, <Primitive>[left, right], node.sourceInformation));
+ }
+ bool replaceWithUnary(BuiltinOperator operator, Primitive argument) {
+ return replaceWithPrimitive(
+ new ApplyBuiltinOperator(
+ operator, <Primitive>[argument], node.sourceInformation));
+ }
if (node.selector.isOperator && node.arguments.length == 2) {
Primitive leftArg = getDartReceiver(node);
@@ -1032,6 +1066,20 @@ class TransformingVisitor extends DeepRecursiveVisitor {
}
}
}
+ if (node.selector.isOperator && node.arguments.length == 1) {
+ Primitive argument = getDartReceiver(node);
+ AbstractValue value = getValue(argument);
+
+ if (lattice.isDefinitelyNum(value, allowNull: false)) {
+ String opname = node.selector.name;
+ if (opname == '~') {
+ return replaceWithUnary(BuiltinOperator.NumBitNot, argument);
+ }
+ if (opname == 'unary-') {
+ return replaceWithUnary(BuiltinOperator.NumNegate, argument);
+ }
+ }
+ }
if (node.selector.isCall) {
String name = node.selector.name;
Primitive receiver = getDartReceiver(node);
@@ -2508,6 +2556,12 @@ class TypePropagationVisitor implements Visitor {
void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
+ void unaryOp(AbstractValue operation(AbstractValue argument),
+ TypeMask defaultType) {
+ AbstractValue value = getValue(node.arguments[0].definition);
+ setValue(node, operation(value) ?? nonConstant(defaultType));
+ }
+
void binaryOp(
AbstractValue operation(AbstractValue left, AbstractValue right),
TypeMask defaultType) {
@@ -2649,6 +2703,14 @@ class TypePropagationVisitor implements Visitor {
binaryBoolOp(lattice.greaterEqualSpecial);
break;
+ case BuiltinOperator.NumBitNot:
+ unaryOp(lattice.bitNotSpecial, typeSystem.uint32Type);
+ break;
+
+ case BuiltinOperator.NumNegate:
+ unaryOp(lattice.negateSpecial, typeSystem.numType);
+ break;
+
case BuiltinOperator.StrictNeq:
case BuiltinOperator.LooseNeq:
case BuiltinOperator.IsFalsy:
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/builtin_operator.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698