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

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

Issue 218993003: Emit read-modify-write of fields as assignment op. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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/codegen_helpers.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart b/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
index f4c895046e6f1d03f9b2d13a489109d6346c5b1d..f76c726664e22a10a2f2d95c05df05ae6eea24bf 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/codegen_helpers.dart
@@ -26,7 +26,7 @@ class SsaInstructionSelection extends HBaseVisitor {
while (instruction != null) {
HInstruction next = instruction.next;
HInstruction replacement = instruction.accept(this);
- if (replacement != instruction) {
+ if (replacement != instruction && replacement != null) {
block.rewrite(instruction, replacement);
// If the replacement instruction does not know its source element, use
@@ -137,6 +137,109 @@ class SsaInstructionSelection extends HBaseVisitor {
return node;
}
+
+ HInstruction visitFieldSet(HFieldSet setter) {
+ // Pattern match
+ // t1 = x.f; t2 = t1 op y; x.f = t2; use(t2) --> x.f op= y
+ // t1 = x.f; t2 = t1 + 1; x.f = t2; use(t2) --> ++x.f
floitsch 2014/04/01 17:28:58 Move that line first. Otherwise the x.f op= y alwa
sra1 2014/04/01 19:51:59 Done.
+ // t1 = x.f; t2 = t1 + 1; x.f = t2; use(t1) --> x.f++
+ HBasicBlock block = setter.block;
+ HInstruction op = setter.value;
+ HInstruction receiver = setter.receiver;
+
+ bool isMatchingRead(HInstruction candidate) {
+ if (candidate is! HFieldGet) return false;
+ if (candidate.element != setter.element) return false;
+ if (candidate.receiver != setter.receiver) return false;
+ // Recognize only three instructions in sequence in the same block. This
+ // could be broadened to allow non-interfereing interleaved instructions.
floitsch 2014/04/01 17:28:58 interfering
sra1 2014/04/01 19:51:59 Done.
+ if (op.block != block) return false;
+ if (candidate.block != block) return false;
+ if (setter.previous != op) return false;
+ if (op.previous != candidate) return false;
+ return true;
+ }
+
+ HInstruction noMatchingRead() {
+ // If we have other HFieldSet optimizations, they go here.
+ return null;
+ }
+
+ HInstruction replaceOp(HInstruction replacement, HInstruction getter) {
+ block.addBefore(setter, replacement);
+ block.remove(setter);
+ block.rewrite(op, replacement);
+ block.remove(op);
+ block.remove(getter);
+ return null;
+ }
+
+ HInstruction plusOrMinus(String assignOp, String incrementOp) {
+ if (isMatchingRead(op.left)) {
+ HFieldGet getter = op.left;
+ HInstruction right = op.right;
+ if (getter.usedBy.length == 1) {
+ if (right is HConstant && right.constant.isOne) {
+ HInstruction rmw = new HReadModifyWrite.preOp(
+ setter.element, incrementOp, receiver, op.instructionType);
+ return replaceOp(rmw, getter);
+ } else {
+ HInstruction rmw = new HReadModifyWrite.assignOp(
+ setter.element,
+ assignOp,
+ receiver, right, op.instructionType);
+ return replaceOp(rmw, getter);
+ }
+ } else if (op.usedBy.length == 1 &&
+ right is HConstant &&
+ right.constant.isOne) {
+ HInstruction rmw = new HReadModifyWrite.postOp(
+ setter.element, incrementOp, receiver, op.instructionType);
+ block.addAfter(getter, rmw);
+ block.remove(setter);
+ block.remove(op);
+ block.rewrite(getter, rmw);
+ block.remove(getter);
+ return null;
+ }
+ }
+ return noMatchingRead();
+ }
+
+ HInstruction simple(String assignOp) {
+ if (isMatchingRead(op.left)) {
+ HFieldGet getter = op.left;
+ if (getter.usedBy.length == 1) {
+ HInstruction rmw = new HReadModifyWrite.assignOp(
+ setter.element,
+ assignOp,
+ receiver, op.right, op.instructionType);
+ return replaceOp(rmw, getter);
+ }
+ }
+ return noMatchingRead();
+ }
+
+ HInstruction bitop(String assignOp) {
+ // HBitAnd, HBitOr etc. are more difficult because HBitAnd(a.x, y)
+ // sometimes needs to be forced to unsigned: a.x = (a.x & y) >>> 0.
+ if (op.isUInt31(compiler)) return simple(assignOp);
+ return noMatchingRead();
+ }
+
+ if (op is HAdd) return plusOrMinus('+', '++');
+ if (op is HSubtract) return plusOrMinus('-', '--');
+
+ if (op is HStringConcat) return simple('+');
+ if (op is HMultiply) return simple('*');
+ if (op is HDivide) return simple('/');
+
+ if (op is HBitAnd) return bitop('&');
+ if (op is HBitOr) return bitop('|');
+ if (op is HBitXor) return bitop('^');
+
+ return noMatchingRead();
+ }
}
/**
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/codegen.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698