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

Unified Diff: lib/compiler/implementation/ssa/nodes.dart

Issue 10119010: Start propagating non-primitive types in the backend, and fold instructions that know about the typ… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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 | « lib/compiler/implementation/ssa/codegen.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/ssa/nodes.dart
===================================================================
--- lib/compiler/implementation/ssa/nodes.dart (revision 6727)
+++ lib/compiler/implementation/ssa/nodes.dart (working copy)
@@ -154,6 +154,10 @@
if (constant.isDouble()) return HType.DOUBLE;
if (constant.isString()) return HType.STRING;
if (constant.isList()) return HType.READABLE_ARRAY;
+ if (constant.isMap()) {
+ MapConstant map = constant;
+ return new HNonPrimitiveType(map.type);
+ }
return HType.UNKNOWN;
}
@@ -670,6 +674,7 @@
// FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY.
static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1;
static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1;
+ static final int FLAG_NON_PRIMITIVE = FLAG_DOUBLE << 1;
static final HType CONFLICTING = const HType(FLAG_CONFLICTING);
static final HType UNKNOWN = const HType(FLAG_UNKNOWN);
@@ -695,6 +700,7 @@
bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0;
bool isStringOrArray() =>
(this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0;
+ bool isNonPrimitive() => this.flag === FLAG_NON_PRIMITIVE;
/** A type is useful it is not unknown and not conflicting. */
bool isUseful() => this !== UNKNOWN && this !== CONFLICTING;
@@ -709,7 +715,7 @@
if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY;
if (flag === NUMBER.flag) return NUMBER;
if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY;
- assert(false);
+ unreachable();
}
String toString() {
@@ -733,6 +739,25 @@
}
}
+class HNonPrimitiveType extends HType {
+ final Type type;
+
+ // TODO(ngeoffray): Add a HPrimitiveType to get rid of the flag.
+ const HNonPrimitiveType(Type this.type) : super(HType.FLAG_NON_PRIMITIVE);
+
+ HType combine(HType other) {
+ if (other.isNonPrimitive()) {
+ HNonPrimitiveType temp = other;
+ if (this.type === temp.type) return this;
+ }
+ if (other.isUnknown()) return this;
+ return CONFLICTING;
+ }
+
+ String toString() => type.toString();
+ Element lookupMember(SourceString name) => type.element.lookupMember(name);
+}
+
class HInstruction implements Hashable {
Element sourceElement;
@@ -793,6 +818,7 @@
bool isString() => propagatedType.isString();
bool isTypeUnknown() => propagatedType.isUnknown();
bool isStringOrArray() => propagatedType.isStringOrArray();
+ bool isNonPrimitive() => propagatedType.isNonPrimitive();
/**
* This is the type the instruction is guaranteed to have. It does not
@@ -935,6 +961,8 @@
bool isConstantNull() => false;
bool isConstantNumber() => false;
bool isConstantString() => false;
+ bool isConstantList() => false;
+ bool isConstantMap() => false;
bool isValid() {
HValidator validator = new HValidator();
@@ -1068,9 +1096,11 @@
}
class HInvokeDynamic extends HInvoke {
+ Element element;
SourceString name;
- HInvokeDynamic(Selector selector, this.name, List<HInstruction> inputs)
- : super(selector, inputs);
+ HInvokeDynamic(
+ Selector selector, this.element, this.name, List<HInstruction> inputs)
+ : super(selector, inputs);
toString() => 'invoke dynamic: $name';
HInstruction get receiver() => inputs[0];
@@ -1079,9 +1109,8 @@
}
class HInvokeClosure extends HInvokeDynamic {
- Element element;
HInvokeClosure(Selector selector, List<HInstruction> inputs)
- : super(selector, const SourceString('call'), inputs);
+ : super(selector, null, const SourceString('call'), inputs);
accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
}
@@ -1089,18 +1118,17 @@
HInvokeDynamicMethod(Selector selector,
SourceString methodName,
List<HInstruction> inputs)
- : super(selector, methodName, inputs);
+ : super(selector, null, methodName, inputs);
toString() => 'invoke dynamic method: $name';
accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
}
class HInvokeDynamicField extends HInvokeDynamic {
- Element element;
HInvokeDynamicField(Selector selector,
- Element this.element,
+ Element element,
SourceString name,
List<HInstruction>inputs)
- : super(selector, name, inputs);
+ : super(selector, element, name, inputs);
toString() => 'invoke dynamic field: $name';
// TODO(floitsch): make class abstract instead of adding an abstract method.
@@ -1122,27 +1150,17 @@
}
class HInvokeStatic extends HInvoke {
+ final HType concreteType;
/** The first input must be the target. */
- HInvokeStatic(selector, inputs) : super(selector, inputs);
+ HInvokeStatic(selector, inputs, [this.concreteType = HType.UNKNOWN])
+ : super(selector, inputs);
toString() => 'invoke static: ${element.name}';
accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
Element get element() => target.element;
HStatic get target() => inputs[0];
- bool isArrayConstructor() {
- // TODO(ngeoffray): This is not the right way to do the check,
- // nor the right place. We need to move it to a phase.
- return (element.isFactoryConstructor()
- && element.enclosingElement.name.slowToString() == 'List');
- }
+ HType get guaranteedType() => concreteType;
- HType get guaranteedType() {
- if (isArrayConstructor()) {
- return HType.MUTABLE_ARRAY;
- }
- return HType.UNKNOWN;
- }
-
HType computeDesiredTypeForInput(HInstruction input) {
// TODO(floitsch): we want the target to be a function.
if (input == target) return HType.UNKNOWN;
@@ -1174,9 +1192,12 @@
toString() => 'invoke interceptor: ${element.name}';
accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this);
+ bool isLengthGetter() {
+ return getter && name == const SourceString('length');
+ }
+
bool isLengthGetterOnStringOrArray() {
- return getter
- && name == const SourceString('length')
+ return isLengthGetter()
&& inputs[1].isStringOrArray();
}
@@ -1740,6 +1761,8 @@
bool isConstantNull() => constant.isNull();
bool isConstantNumber() => constant.isNum();
bool isConstantString() => constant.isString();
+ bool isConstantList() => constant.isList();
+ bool isConstantMap() => constant.isMap();
// Maybe avoid this if the literal is big?
bool isCodeMotionInvariant() => true;
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698