private bool ReplacePushDupPushPopPattern(BlockStatement b) { Contract.Requires(b != null); bool replacedPattern = false; var statements = b.Statements; for (int i = 0; i < statements.Count-4; i++) { var push1 = statements[i] as PushStatement; if (push1 == null) continue; var exprS1 = statements[i+1] as ExpressionStatement; if (exprS1 == null) continue; var assign1 = exprS1.Expression as Assignment; if (assign1 == null) continue; if (!(assign1.Source is DupValue) || assign1.Target.Instance != null) continue; var push2 = statements[i+2] as PushStatement; if (push2 == null) continue; var popCounter = new PopCounter(); popCounter.Traverse(push2); if (popCounter.count != 1) continue; if (!this.singleUseExpressionChecker.ExpressionCanBeMovedAndDoesNotReference(push1.ValueToPush, assign1.Target.Definition)) continue; assign1.Source = push1.ValueToPush; var popReplacer = new SinglePopReplacer(this.host, assign1); popReplacer.Rewrite(push2.ValueToPush); statements.RemoveRange(i, 2); replacedPattern = true; } return replacedPattern; }
private bool ReplacePushDupPopPattern(BlockStatement b) { Contract.Requires(b != null); bool replacedPattern = false; var statements = b.Statements; for (int i = 0; i < statements.Count-3; i++) { var push1 = statements[i] as PushStatement; if (push1 == null) continue; var binop1 = push1.ValueToPush as BinaryOperation; if (binop1 == null) continue; var bound1 = binop1.LeftOperand as BoundExpression; if (bound1 == null) continue; var exprS1 = statements[i+1] as ExpressionStatement; if (exprS1 == null) continue; var assign1 = exprS1.Expression as Assignment; if (assign1 == null) continue; if (assign1.Target.Definition != bound1.Definition) continue; if (assign1.Target.Instance != bound1.Instance) { if (!(assign1.Target.Instance is IPopValue && bound1.Instance is IDupValue)) continue; } if (!(assign1.Source is DupValue)) continue; var statement = statements[i+2] as Statement; if (statement == null) continue; var popCounter = new PopCounter(); popCounter.Traverse(statement); if (popCounter.count != 1) continue; binop1.LeftOperand = assign1.Target; var popReplacer = new SinglePopReplacer(this.host, binop1); popReplacer.Rewrite(statement); statements.RemoveRange(i, 2); replacedPattern = true; } return replacedPattern; }