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

Unified Diff: pkg/compiler/lib/src/ssa/optimize.dart

Issue 1459273002: dart2js load elimination: Look through refinements for locations (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 3 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 | « no previous file | tests/compiler/dart2js_native/load_elim_refinement_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/optimize.dart
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 3ac8e272e90908d5812798de127ec87d154297d9..276631c1bfcf2b9474e1fd354f8efc1cc2c2d2ad 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -2243,9 +2243,9 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
// Assume the argument escapes. All we do with our initial allocation is
// have it escape or store it into an object that escapes.
return false;
- // TODO(sra): Handle more functions. `setRuntimeTypeInfo` does not
- // actually kill it's input, but we don't make use of that elsewhere so
- // there is not point in checking here.
+ // TODO(sra): Handle library functions that we know do not modify or
+ // leak the inputs. For example `setRuntimeTypeInfo` is used to mark
+ // list literals with type information.
}
if (use is HPhi) {
// The initial allocation (it's only alias) gets merged out of the model
@@ -2291,6 +2291,8 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
void visitLiteralList(HLiteralList instruction) {
memorySet.registerAllocation(instruction);
memorySet.killAffectedBy(instruction);
+ // TODO(sra): Set initial keyed values.
+ // TODO(sra): Set initial length.
}
void visitIndex(HIndex instruction) {
@@ -2310,10 +2312,31 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
memorySet.registerKeyedValueUpdate(
receiver, instruction.index, instruction.value);
}
+
+ // Pure operations that do not escape their inputs.
+ void visitBinaryArithmetic(HBinaryArithmetic instruction) {}
+ void visitConstant(HConstant instruction) {}
+ void visitIf(HIf instruction) {}
+ void visitInterceptor(HInterceptor instruction) {}
+ void visitIs(HIs instruction) {}
+ void visitIsViaInterceptor(HIsViaInterceptor instruction) {}
+ void visitNot(HNot instruction) {}
+ void visitParameterValue(HParameterValue instruction) {}
+ void visitRelational(HRelational instruction) {}
+ void visitStringConcat(HStringConcat instruction) {}
+ void visitTypeKnown(HTypeKnown instruction) {}
+ void visitTypeInfoReadRaw(HTypeInfoReadRaw instruction) {}
+ void visitTypeInfoReadVariable(HTypeInfoReadVariable instruction) {}
+ void visitTypeInfoExpression(HTypeInfoExpression instruction) {}
}
/**
* Holds values of memory places.
+ *
+ * Generally, values that name a place (a receiver) have type refinements and
+ * other checks removed to ensure that checks and type refinements do not
+ * confuse aliasing. Values stored into a memory place keep the type
+ * refinements to help further optimizations.
*/
class MemorySet {
final Compiler compiler;
@@ -2379,25 +2402,28 @@ class MemorySet {
* Returns whether [receiver] escapes the current function.
*/
bool escapes(HInstruction receiver) {
+ assert(receiver == null || receiver == receiver.nonCheck());
return !nonEscapingReceivers.contains(receiver);
}
void registerAllocation(HInstruction instruction) {
+ assert(instruction == instruction.nonCheck());
nonEscapingReceivers.add(instruction);
}
/**
- * Sets `receiver.element` to contain [value]. Kills all potential
- * places that may be affected by this update.
+ * Sets `receiver.element` to contain [value]. Kills all potential places that
+ * may be affected by this update.
*/
void registerFieldValueUpdate(
Element element, HInstruction receiver, HInstruction value) {
+ assert(receiver == null || receiver == receiver.nonCheck());
if (backend.isNative(element)) {
return; // TODO(14955): Remove this restriction?
}
// [value] is being set in some place in memory, we remove it from
// the non-escaping set.
- nonEscapingReceivers.remove(value);
+ nonEscapingReceivers.remove(value.nonCheck());
Map<HInstruction, HInstruction> map =
fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{});
map.forEach((key, value) {
@@ -2411,6 +2437,7 @@ class MemorySet {
*/
void registerFieldValue(
Element element, HInstruction receiver, HInstruction value) {
+ assert(receiver == null || receiver == receiver.nonCheck());
if (backend.isNative(element)) {
return; // TODO(14955): Remove this restriction?
}
@@ -2420,27 +2447,26 @@ class MemorySet {
}
/**
- * Returns the value stored in `receiver.element`. Returns null if
- * we don't know.
+ * Returns the value stored in `receiver.element`. Returns `null` if we don't
+ * know.
*/
HInstruction lookupFieldValue(Element element, HInstruction receiver) {
+ assert(receiver == null || receiver == receiver.nonCheck());
Map<HInstruction, HInstruction> map = fieldValues[element];
return (map == null) ? null : map[receiver];
}
/**
- * Kill all places that may be affected by this [instruction]. Also
- * update the set of non-escaping objects in case [instruction] has
- * non-escaping objects in its inputs.
+ * Kill all places that may be affected by this [instruction]. Also update the
+ * set of non-escaping objects in case [instruction] has non-escaping objects
+ * in its inputs.
*/
void killAffectedBy(HInstruction instruction) {
- // Even if [instruction] does not have side effects, it may use
- // non-escaping objects and store them in a new object, which
- // make these objects escaping.
- // TODO(ngeoffray): We need a new side effect flag to know whether
- // an instruction allocates an object.
+ // Even if [instruction] does not have side effects, it may use non-escaping
+ // objects and store them in a new object, which make these objects
+ // escaping.
instruction.inputs.forEach((input) {
- nonEscapingReceivers.remove(input);
+ nonEscapingReceivers.remove(input.nonCheck());
});
if (instruction.sideEffects.changesInstanceProperty() ||
@@ -2491,7 +2517,7 @@ class MemorySet {
*/
void registerKeyedValueUpdate(
HInstruction receiver, HInstruction index, HInstruction value) {
- nonEscapingReceivers.remove(value);
+ nonEscapingReceivers.remove(value.nonCheck());
keyedValues.forEach((key, values) {
if (mayAlias(receiver, key)) {
// Typed arrays that are views of the same buffer may have different
« no previous file with comments | « no previous file | tests/compiler/dart2js_native/load_elim_refinement_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698