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

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

Issue 12051013: Cleanup how we handle side effects in HInstruction and put the right flags for HIs, modulo, truncat… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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: sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/ssa/nodes.dart (revision 17440)
+++ sdk/lib/_internal/compiler/implementation/ssa/nodes.dart (working copy)
@@ -303,12 +303,12 @@
visitInvokeStatic(HInvokeStatic node) => visitInvoke(node);
visitInvokeSuper(HInvokeSuper node) => visitInvoke(node);
visitJump(HJump node) => visitControlFlow(node);
- visitLazyStatic(HLazyStatic node) => visitStatic(node);
+ visitLazyStatic(HLazyStatic node) => visitInstruction(node);
visitLess(HLess node) => visitRelational(node);
visitLessEqual(HLessEqual node) => visitRelational(node);
visitLiteralList(HLiteralList node) => visitInstruction(node);
- visitLocalGet(HLocalGet node) => visitFieldGet(node);
- visitLocalSet(HLocalSet node) => visitFieldSet(node);
+ visitLocalGet(HLocalGet node) => visitFieldAccess(node);
+ visitLocalSet(HLocalSet node) => visitFieldAccess(node);
visitLocalValue(HLocalValue node) => visitInstruction(node);
visitLoopBranch(HLoopBranch node) => visitConditionalBranch(node);
visitNegate(HNegate node) => visitInvokeUnary(node);
@@ -792,9 +792,7 @@
static const int INVOKE_DYNAMIC_GETTER_TYPECODE = 31;
static const int INDEX_TYPECODE = 32;
- HInstruction(this.inputs)
- : id = idCounter++,
- usedBy = <HInstruction>[];
+ HInstruction(this.inputs) : id = idCounter++, usedBy = <HInstruction>[];
int get hashCode => id;
@@ -812,11 +810,6 @@
bool hasSideEffects() => getChangesFlags() != 0;
bool dependsOnSomething() => getDependsOnFlags() != 0;
- void prepareGvn(HTypeMap types) {
- setAllSideEffects();
- setDependsOnSomething();
- }
-
void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); }
void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); }
@@ -824,6 +817,10 @@
int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
flags |= (((1 << count) - 1) << FLAG_CHANGES_COUNT);
}
+ void clearAllDependencies() {
+ int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
+ flags &= ~(((1 << count) - 1) << FLAG_CHANGES_COUNT);
+ }
bool dependsOnStaticPropertyStore() {
return getFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
@@ -1161,8 +1158,7 @@
}
class HBoolify extends HInstruction {
- HBoolify(HInstruction value) : super(<HInstruction>[value]);
- void prepareGvn(HTypeMap types) {
+ HBoolify(HInstruction value) : super(<HInstruction>[value]) {
assert(!hasSideEffects());
setUseGvn();
}
@@ -1183,21 +1179,19 @@
* instruction itself.
*/
abstract class HCheck extends HInstruction {
- HCheck(inputs) : super(inputs);
- HInstruction get checkedInput => inputs[0];
- bool isJsStatement() => true;
- void prepareGvn(HTypeMap types) {
+ HCheck(inputs) : super(inputs) {
assert(!hasSideEffects());
setUseGvn();
}
+ HInstruction get checkedInput => inputs[0];
+ bool isJsStatement() => true;
bool canThrow() => true;
}
class HBailoutTarget extends HInstruction {
final int state;
bool isEnabled = true;
- HBailoutTarget(this.state) : super(<HInstruction>[]);
- void prepareGvn(HTypeMap types) {
+ HBailoutTarget(this.state) : super(<HInstruction>[]) {
assert(!hasSideEffects());
setUseGvn();
}
@@ -1300,9 +1294,6 @@
abstract class HControlFlow extends HInstruction {
HControlFlow(inputs) : super(inputs);
- void prepareGvn(HTypeMap types) {
- // Control flow does not have side-effects.
- }
bool isControlFlow() => true;
bool isJsStatement() => true;
}
@@ -1313,7 +1304,10 @@
* the receiver of a method-call. The remaining inputs are the arguments
* to the invocation.
*/
- HInvoke(List<HInstruction> inputs) : super(inputs);
+ HInvoke(List<HInstruction> inputs) : super(inputs) {
+ setAllSideEffects();
+ setDependsOnSomething();
+ }
static const int ARGUMENTS_OFFSET = 1;
bool canThrow() => true;
}
@@ -1383,13 +1377,8 @@
}
class HInvokeDynamicGetter extends HInvokeDynamicField {
- HInvokeDynamicGetter(
- selector, element, receiver, isSideEffectFree)
- : super(selector, element, [receiver], isSideEffectFree);
- toString() => 'invoke dynamic getter: $selector';
- accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this);
-
- void prepareGvn(HTypeMap types) {
+ HInvokeDynamicGetter(selector, element, receiver, isSideEffectFree)
+ : super(selector, element, [receiver], isSideEffectFree) {
clearAllSideEffects();
if (isSideEffectFree) {
setUseGvn();
@@ -1399,6 +1388,8 @@
setAllSideEffects();
}
}
+ toString() => 'invoke dynamic getter: $selector';
+ accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this);
int typeCode() => HInstruction.INVOKE_DYNAMIC_GETTER_TYPECODE;
bool typeEquals(other) => other is HInvokeDynamicGetter;
@@ -1407,11 +1398,7 @@
class HInvokeDynamicSetter extends HInvokeDynamicField {
HInvokeDynamicSetter(selector, element, receiver, value, isSideEffectFree)
- : super(selector, element, [receiver, value], isSideEffectFree);
- toString() => 'invoke dynamic setter: $selector';
- accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this);
-
- void prepareGvn(HTypeMap types) {
+ : super(selector, element, [receiver, value], isSideEffectFree) {
clearAllSideEffects();
if (isSideEffectFree) {
setChangesInstanceProperty();
@@ -1420,6 +1407,8 @@
setDependsOnSomething();
}
}
+ toString() => 'invoke dynamic setter: $selector';
+ accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this);
}
class HInvokeStatic extends HInvoke {
@@ -1433,20 +1422,6 @@
int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE;
Element get element => target.element;
HStatic get target => inputs[0];
-
- HType computeDesiredTypeForInput(HInstruction input,
- HTypeMap types,
- Compiler compiler) {
- // TODO(floitsch): we want the target to be a function.
- if (input == target) return HType.UNKNOWN;
- return computeDesiredTypeForNonTargetInput(input, types, compiler);
- }
-
- HType computeDesiredTypeForNonTargetInput(HInstruction input,
- HTypeMap types,
- Compiler compiler) {
- return HType.UNKNOWN;
- }
}
class HInvokeSuper extends HInvokeStatic {
@@ -1466,11 +1441,9 @@
final Element element;
HFieldAccess(Element element, List<HInstruction> inputs)
- : this.element = element,
- super(inputs);
+ : this.element = element, super(inputs);
- // TODO(ngeoffray): Only if input can be null.
- bool canThrow() => true;
+ HInstruction get receiver => inputs[0];
}
class HFieldGet extends HFieldAccess {
@@ -1480,20 +1453,19 @@
: this.isAssignable = (isAssignable != null)
? isAssignable
: element.isAssignable(),
- super(element, <HInstruction>[receiver]);
-
- HInstruction get receiver => inputs[0];
-
- accept(HVisitor visitor) => visitor.visitFieldGet(this);
-
- void prepareGvn(HTypeMap types) {
+ super(element, <HInstruction>[receiver]) {
clearAllSideEffects();
setUseGvn();
- if (isAssignable) {
+ if (this.isAssignable) {
setDependsOnInstancePropertyStore();
}
}
+ // TODO(ngeoffray): Only if input can be null.
+ bool canThrow() => true;
+
+ accept(HVisitor visitor) => visitor.visitFieldGet(this);
+
int typeCode() => HInstruction.FIELD_GET_TYPECODE;
bool typeEquals(other) => other is HFieldGet;
bool dataEquals(HFieldGet other) => element == other.element;
@@ -1504,57 +1476,61 @@
HFieldSet(Element element,
HInstruction receiver,
HInstruction value)
- : super(element, <HInstruction>[receiver, value]);
-
- HInstruction get receiver => inputs[0];
- HInstruction get value => inputs[1];
- accept(HVisitor visitor) => visitor.visitFieldSet(this);
-
- void prepareGvn(HTypeMap types) {
+ : super(element, <HInstruction>[receiver, value]) {
clearAllSideEffects();
setChangesInstanceProperty();
}
+ // TODO(ngeoffray): Only if input can be null.
+ bool canThrow() => true;
+
+ HInstruction get value => inputs[1];
+ accept(HVisitor visitor) => visitor.visitFieldSet(this);
+
bool isJsStatement() => true;
String toString() => "FieldSet $element";
}
-class HLocalGet extends HFieldGet {
- HLocalGet(Element element, HLocalValue local) : super(element, local);
+class HLocalGet extends HFieldAccess {
+ // No need to use GVN for a [HLocalGet], it is just a local
+ // access.
+ HLocalGet(Element element, HLocalValue local)
+ : super(element, <HInstruction>[local]);
accept(HVisitor visitor) => visitor.visitLocalGet(this);
HLocalValue get local => inputs[0];
-
- void prepareGvn(HTypeMap types) {
- // No need to use GVN for a [HLocalGet], it is just a local
- // access.
- clearAllSideEffects();
- }
}
-class HLocalSet extends HFieldSet {
+class HLocalSet extends HFieldAccess {
HLocalSet(Element element, HLocalValue local, HInstruction value)
- : super(element, local, value);
+ : super(element, <HInstruction>[local, value]);
accept(HVisitor visitor) => visitor.visitLocalSet(this);
HLocalValue get local => inputs[0];
+ HInstruction get value => inputs[1];
+ bool isJsStatement() => true;
}
class HForeign extends HInstruction {
final DartString code;
final HType foreignType;
- final bool _isStatement;
+ final bool isStatement;
- HForeign(this.code, DartString declaredType, List<HInstruction> inputs)
+ HForeign(this.code,
+ DartString declaredType,
+ List<HInstruction> inputs,
+ {this.isStatement: false})
: foreignType = computeTypeFromDeclaredType(declaredType),
- _isStatement = false,
- super(inputs);
- HForeign.statement(this.code, List<HInstruction> inputs)
- : foreignType = HType.UNKNOWN,
- _isStatement = true,
- super(inputs);
+ super(inputs) {
+ setAllSideEffects();
+ setDependsOnSomething();
+ }
+
+ HForeign.statement(code, List<HInstruction> inputs)
+ : this(code, const LiteralDartString('var'), input, isStatement: true);
+
accept(HVisitor visitor) => visitor.visitForeign(this);
static HType computeTypeFromDeclaredType(DartString declaredType) {
@@ -1569,7 +1545,7 @@
HType get guaranteedType => foreignType;
- bool isJsStatement() => _isStatement;
+ bool isJsStatement() => isStatement;
bool canThrow() => true;
}
@@ -1584,9 +1560,7 @@
abstract class HInvokeBinary extends HInstruction {
HInvokeBinary(HInstruction left, HInstruction right)
- : super(<HInstruction>[left, right]);
-
- void prepareGvn(HTypeMap types) {
+ : super(<HInstruction>[left, right]) {
clearAllSideEffects();
setUseGvn();
}
@@ -1730,15 +1704,13 @@
}
abstract class HInvokeUnary extends HInstruction {
- HInvokeUnary(HInstruction input) : super(<HInstruction>[input]);
-
- HInstruction get operand => inputs[0];
-
- void prepareGvn(HTypeMap types) {
+ HInvokeUnary(HInstruction input) : super(<HInstruction>[input]) {
clearAllSideEffects();
setUseGvn();
}
+ HInstruction get operand => inputs[0];
+
UnaryOperation operation(ConstantSystem constantSystem);
}
@@ -1865,10 +1837,6 @@
HConstant.internal(this.constant, HType this.constantType)
: super(<HInstruction>[]);
- void prepareGvn(HTypeMap types) {
- assert(!hasSideEffects());
- }
-
toString() => 'literal: $constant';
accept(HVisitor visitor) => visitor.visitConstant(this);
@@ -1891,9 +1859,7 @@
}
class HNot extends HInstruction {
- HNot(HInstruction value) : super(<HInstruction>[value]);
- void prepareGvn(HTypeMap types) {
- assert(!hasSideEffects());
+ HNot(HInstruction value) : super(<HInstruction>[value]) {
setUseGvn();
}
@@ -1922,9 +1888,6 @@
sourceElement = element;
}
- void prepareGvn(HTypeMap types) {
- assert(!hasSideEffects());
- }
toString() => 'local ${sourceElement.name}';
accept(HVisitor visitor) => visitor.visitLocalValue(this);
}
@@ -2114,9 +2077,6 @@
HStatic(this.element) : super(<HInstruction>[]) {
assert(element != null);
assert(invariant(this, element.isDeclaration));
- }
-
- void prepareGvn(HTypeMap types) {
clearAllSideEffects();
if (element.isAssignable()) {
setDependsOnStaticPropertyStore();
@@ -2136,16 +2096,14 @@
class HInterceptor extends HInstruction {
Set<ClassElement> interceptedClasses;
HInterceptor(this.interceptedClasses, HInstruction receiver)
- : super(<HInstruction>[receiver]);
+ : super(<HInstruction>[receiver]) {
+ clearAllSideEffects();
+ setUseGvn();
+ }
String toString() => 'interceptor on $interceptedClasses';
accept(HVisitor visitor) => visitor.visitInterceptor(this);
HInstruction get receiver => inputs[0];
- void prepareGvn(HTypeMap types) {
- clearAllSideEffects();
- setUseGvn();
- }
-
HType computeDesiredTypeForInput(HInstruction input,
HTypeMap types,
Compiler compiler) {
@@ -2174,10 +2132,9 @@
}
/** An [HLazyStatic] is a static that is initialized lazily at first read. */
-class HLazyStatic extends HStatic {
- HLazyStatic(Element element) : super(element);
-
- void prepareGvn(HTypeMap types) {
+class HLazyStatic extends HInstruction {
+ final Element element;
+ HLazyStatic(this.element) : super(<HInstruction>[]) {
// TODO(4931): The first access has side-effects, but we afterwards we
// should be able to GVN.
setAllSideEffects();
@@ -2195,7 +2152,11 @@
class HStaticStore extends HInstruction {
Element element;
- HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]);
+ HStaticStore(this.element, HInstruction value)
+ : super(<HInstruction>[value]) {
+ clearAllSideEffects();
+ setChangesStaticProperty();
+ }
toString() => 'static store ${element.name}';
accept(HVisitor visitor) => visitor.visitStaticStore(this);
@@ -2203,11 +2164,6 @@
bool typeEquals(other) => other is HStaticStore;
bool dataEquals(HStaticStore other) => element == other.element;
bool isJsStatement() => true;
-
- void prepareGvn(HTypeMap types) {
- clearAllSideEffects();
- setChangesStaticProperty();
- }
}
class HLiteralList extends HInstruction {
@@ -2216,10 +2172,6 @@
accept(HVisitor visitor) => visitor.visitLiteralList(this);
HType get guaranteedType => HType.EXTENDABLE_ARRAY;
-
- void prepareGvn(HTypeMap types) {
- assert(!hasSideEffects());
- }
}
/**
@@ -2228,16 +2180,15 @@
*/
class HIndex extends HInstruction {
HIndex(HInstruction receiver, HInstruction index)
- : super(<HInstruction>[receiver, index]);
- String toString() => 'index operator';
- accept(HVisitor visitor) => visitor.visitIndex(this);
-
- void prepareGvn(HTypeMap types) {
+ : super(<HInstruction>[receiver, index]) {
clearAllSideEffects();
setDependsOnIndexStore();
setUseGvn();
}
+ String toString() => 'index operator';
+ accept(HVisitor visitor) => visitor.visitIndex(this);
+
HInstruction get receiver => inputs[0];
HInstruction get index => inputs[1];
@@ -2254,33 +2205,27 @@
HIndexAssign(HInstruction receiver,
HInstruction index,
HInstruction value)
- : super(<HInstruction>[receiver, index, value]);
+ : super(<HInstruction>[receiver, index, value]) {
+ clearAllSideEffects();
+ setChangesIndex();
+ }
String toString() => 'index assign operator';
accept(HVisitor visitor) => visitor.visitIndexAssign(this);
HInstruction get receiver => inputs[0];
HInstruction get index => inputs[1];
HInstruction get value => inputs[2];
-
- void prepareGvn(HTypeMap types) {
- clearAllSideEffects();
- setChangesIndex();
- }
}
class HIs extends HInstruction {
final DartType typeExpression;
final bool nullOk;
- HIs.withArgumentChecks(this.typeExpression,
- HInstruction expression,
- List<HInstruction> checks,
- [this.nullOk = false])
- : super(<HInstruction>[expression]..addAll(checks));
+ HIs(this.typeExpression, List<HInstruction> inputs, {this.nullOk: false})
+ : super(inputs) {
+ setUseGvn();
+ }
- HIs(this.typeExpression, HInstruction expression, {this.nullOk: false})
- : super(<HInstruction>[expression]);
-
HInstruction get expression => inputs[0];
HInstruction getCheck(int index) => inputs[index + 1];
int get checkCount => inputs.length - 1;
@@ -2352,7 +2297,10 @@
class HStringConcat extends HInstruction {
final Node node;
HStringConcat(HInstruction left, HInstruction right, this.node)
- : super(<HInstruction>[left, right]);
+ : super(<HInstruction>[left, right]) {
+ setAllSideEffects();
+ setDependsOnSomething();
+ }
HType get guaranteedType => HType.STRING;
HInstruction get left => inputs[0];

Powered by Google App Engine
This is Rietveld 408576698