public override IExpression Rewrite(IConditional cond)
 {
     var newCond = new Conditional(cond);
     Switch.On(MutationTarget.PassInfo)
     .Case("to&&", () =>
     {
         newCond.ResultIfTrue = cond.ResultIfFalse;
         newCond.ResultIfFalse = new CompileTimeConstant
         {
             Type = cond.ResultIfTrue.Type,
             Value = false,
         };  
     })
     .Case("to||", () =>
     {
         newCond.ResultIfFalse = cond.ResultIfTrue;
         newCond.ResultIfTrue = new CompileTimeConstant
         {
             Type = cond.ResultIfFalse.Type,
             Value = true,
         };          
     }).ThrowIfNoMatch();
   
     return newCond;
 }
Example #2
0
    private static IExpression InvertConditional(Conditional conditional) {
      Contract.Requires(conditional != null);
      Contract.Ensures(Contract.Result<IExpression>() != null);

      var result = new Conditional() { Type = conditional.Type };
      if (ExpressionHelper.IsIntegralZero(conditional.ResultIfTrue)) {
        result.Condition = conditional.Condition;
        result.ResultIfTrue = InvertCondition(conditional.ResultIfTrue);
        result.ResultIfFalse = InvertCondition(conditional.ResultIfFalse);
      } else {
        result.Condition = InvertCondition(conditional.Condition);
        result.ResultIfTrue = InvertCondition(conditional.ResultIfFalse);
        result.ResultIfFalse = InvertCondition(conditional.ResultIfTrue);
      }
      return result;
    }
 internal static Conditional FixUpType(Conditional conditional) {
   Contract.Requires(conditional != null);
   conditional.Condition = ConvertToBoolean(conditional.Condition);
   var mergedType = conditional.ResultIfTrue.Type;
   if (!TypeHelper.TypesAreEquivalent(conditional.ResultIfTrue.Type, conditional.ResultIfFalse.Type)) {
     mergedType = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
     if (mergedType.TypeCode == PrimitiveTypeCode.Int32) {
       if (conditional.ResultIfTrue.Type.TypeCode == PrimitiveTypeCode.Boolean) {
         conditional.ResultIfFalse = ConvertToBoolean(conditional.ResultIfFalse);
         mergedType = conditional.ResultIfTrue.Type;
       } else if (conditional.ResultIfFalse.Type.TypeCode == PrimitiveTypeCode.Boolean) {
         conditional.ResultIfTrue = ConvertToBoolean(conditional.ResultIfTrue);
         mergedType = conditional.ResultIfFalse.Type;
       }
     }
   }
   conditional.Type = mergedType;
   return conditional;
 }
Example #4
0
 private bool ReplaceShortCircuitAnd4(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count-2; i++) {
     var ifStatement1 = statements[i] as ConditionalStatement;
     if (ifStatement1 == null || !(ifStatement1.FalseBranch is EmptyStatement)) continue;
     var goto1 = ifStatement1.TrueBranch as GotoStatement;
     if (goto1 == null) continue;
     var labStat = statements[i+1] as LabeledStatement;
     if (labStat == null) continue;
     var gotos1 =  this.gotosThatTarget[(uint)labStat.Label.UniqueKey];
     if (gotos1 != null && gotos1.Count > 0) continue;
     var ifStatement2 = statements[i+2] as ConditionalStatement;
     if (ifStatement2 == null) continue;
     if (ifStatement2.TrueBranch is EmptyStatement) {
       var goto2 = ifStatement2.FalseBranch as GotoStatement;
       if (goto2 == null) continue;
       if (goto1.TargetStatement != goto2.TargetStatement) continue;
       var gotos = this.gotosThatTarget[(uint)goto1.TargetStatement.Label.UniqueKey];
       if (gotos == null || gotos.Count == 0) continue;
       var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
       var notCond1 = new LogicalNot() { Operand = ifStatement1.Condition, Type = this.host.PlatformType.SystemBoolean };
       var conditional = new Conditional() { Condition = notCond1, ResultIfTrue = ifStatement2.Condition, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(goto1);
       replacedPattern = true;
     } else if (ifStatement2.FalseBranch is EmptyStatement) {
       var goto2 = ifStatement2.TrueBranch as GotoStatement;
       if (goto2 == null) continue;
       if (goto1.TargetStatement != goto2.TargetStatement) continue;
       var gotos = this.gotosThatTarget[(uint)goto1.TargetStatement.Label.UniqueKey];
       if (gotos == null || gotos.Count == 0) continue;
       var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
       var cond1 = ifStatement1.Condition;
       var conditional = new Conditional() { Condition = cond1, ResultIfTrue = trueConst, ResultIfFalse = ifStatement2.Condition, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(goto1);
       replacedPattern = true;
     }
   }
   return replacedPattern;
 }
Example #5
0
 private bool ReplaceShortCircuitAnd2(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count-3; i++) {
     var ifStatement = statements[i] as ConditionalStatement;
     if (ifStatement == null) continue;
     var gotoFalseCase = ifStatement.FalseBranch as GotoStatement;
     if (gotoFalseCase == null) continue;
     Contract.Assume(ifStatement.TrueBranch is EmptyStatement);
     var labeledStatement = statements[i+1] as LabeledStatement;
     if (labeledStatement == null) continue;
     var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey];
     if (gotos != null && gotos.Count > 0) continue;
     var ifStatement2 = statements[i+2] as ConditionalStatement;
     if (ifStatement2 == null) continue;
     var gotoTrueCase = ifStatement2.TrueBranch as GotoStatement;
     if (gotoTrueCase == null) continue;
     Contract.Assume(ifStatement2.FalseBranch is EmptyStatement);
     var labeledStatement2 = statements[i+3] as LabeledStatement;
     if (labeledStatement2 == null) continue;
     if (labeledStatement2 == gotoFalseCase.TargetStatement) {
       gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey];
       Contract.Assume(gotos != null && gotos.Count > 0);
       if (gotos.Count > 1) continue;
       var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
       var conditional = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = ifStatement2.Condition, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(gotoFalseCase);
       replacedPattern = true;
     } else {
       if (gotoFalseCase.TargetStatement != gotoTrueCase.TargetStatement) continue;
       //actually have a short circuit or here
       gotos = this.gotosThatTarget[(uint)gotoFalseCase.TargetStatement.Label.UniqueKey];
       Contract.Assume(gotos != null && gotos.Count > 0);
       var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
       var invertedCond = new LogicalNot() { Operand = ifStatement.Condition, Type = this.host.PlatformType.SystemBoolean };
       var conditional = new Conditional() { Condition = invertedCond, ResultIfTrue = trueConst, ResultIfFalse = ifStatement2.Condition, Type = this.host.PlatformType.SystemBoolean };
       ifStatement2.Condition = conditional;
       statements.RemoveRange(i, 2);
       gotos.Remove(gotoFalseCase);
       replacedPattern = true;
     }
   }
   return replacedPattern;
 }
Example #6
0
 private bool ReplaceShortCircuitAnd(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count-6; i++) {
     var ifStatement = statements[i] as ConditionalStatement;
     if (ifStatement == null) continue;
     var gotoFalseCase = ifStatement.FalseBranch as GotoStatement;
     if (gotoFalseCase == null) continue;
     Contract.Assume(ifStatement.TrueBranch is EmptyStatement);
     var labeledStatement = statements[i+1] as LabeledStatement;
     if (labeledStatement == null) continue;
     var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey];
     if (gotos != null && gotos.Count > 0) continue;
     var pushTrueCase = statements[i+2] as PushStatement;
     if (pushTrueCase == null) continue;
     if (pushTrueCase.ValueToPush.Type.TypeCode != PrimitiveTypeCode.Boolean) continue;
     var gotoEnd = statements[i+3] as GotoStatement;
     if (gotoEnd == null) continue;
     var labeledStatement2 = statements[i+4] as LabeledStatement;
     if (labeledStatement2 == null || labeledStatement2 != gotoFalseCase.TargetStatement) continue;
     gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey];
     Contract.Assume(gotos != null && gotos.Count > 0);
     if (gotos.Count > 1) continue;
     var pushFalseCase = statements[i+5] as PushStatement;
     if (pushFalseCase == null) continue;
     var falseCaseVal = pushFalseCase.ValueToPush as CompileTimeConstant;
     if (falseCaseVal == null || !(falseCaseVal.Value is int)) continue;
     var endLabel = statements[i+6] as LabeledStatement;
     if (endLabel == null || gotoEnd.TargetStatement != endLabel) continue;
     Conditional conditional;
     if (((int)falseCaseVal.Value) != 0) {
       var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
       var cond = new LogicalNot() { Operand = ifStatement.Condition, Type = this.host.PlatformType.SystemBoolean };
       conditional = new Conditional() { Condition = cond, ResultIfTrue = trueConst, ResultIfFalse = pushTrueCase.ValueToPush, Type = this.host.PlatformType.SystemBoolean };
     } else {
       var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
       conditional = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = pushTrueCase.ValueToPush, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean };
     }
     pushFalseCase.ValueToPush = conditional;
     statements.RemoveAt(i+6);
     statements.RemoveRange(i, 5);
     replacedPattern = true;
   }
   return replacedPattern;
 }
Example #7
0
 private bool ReplaceConditionalExpressionPattern(BlockStatement b) {
   Contract.Requires(b != null);
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 0; i < statements.Count-6; i++) {
     var ifStatement = statements[i] as ConditionalStatement;
     if (ifStatement == null) continue;
     var gotoTrueCase = ifStatement.TrueBranch as GotoStatement;
     if (gotoTrueCase == null) continue;
     Contract.Assume(ifStatement.FalseBranch is EmptyStatement);
     var labeledStatement = statements[i+1] as LabeledStatement;
     if (labeledStatement == null) continue;
     var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey];
     if (gotos != null && gotos.Count > 0) continue;
     var pushFalseCase = statements[i+2] as PushStatement;
     if (pushFalseCase == null) continue;
     var gotoEnd = statements[i+3] as GotoStatement;
     if (gotoEnd == null) continue;
     var labeledStatement2 = statements[i+4] as LabeledStatement;
     if (labeledStatement2 == null || labeledStatement2 != gotoTrueCase.TargetStatement) continue;
     gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey];
     Contract.Assume(gotos != null && gotos.Count > 0);
     if (gotos.Count > 1) continue;
     var pushTrueCase = statements[i+5] as PushStatement;
     if (pushTrueCase == null) continue;
     var endLabel = statements[i+6] as LabeledStatement;
     if (endLabel == null || gotoEnd.TargetStatement != endLabel) continue;
     var conditional = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = pushTrueCase.ValueToPush, ResultIfFalse = pushFalseCase.ValueToPush };
     pushTrueCase.ValueToPush = TypeInferencer.FixUpType(conditional);
     pushTrueCase.Locations.AddRange(ifStatement.Locations);
     gotos = this.gotosThatTarget[(uint)endLabel.Label.UniqueKey];
     Contract.Assume(gotos != null && gotos.Count > 0);
     gotos.Remove(gotoEnd);
     if (gotos.Count == 0) statements.RemoveAt(i+6);
     statements.RemoveRange(i, 5);
     replacedPattern = true;
   }
   return replacedPattern;
 }
Example #8
0
 /// <summary>
 /// Visits the specified conditional.
 /// </summary>
 /// <param name="conditional">The conditional.</param>
 public override void Visit(IConditional conditional)
 {
     Conditional mutableConditional = conditional as Conditional;
     if (alwaysMakeACopy || mutableConditional == null) mutableConditional = new Conditional(conditional);
     this.resultExpression = this.myCodeMutator.Visit(mutableConditional);
 }
Example #9
0
 /// <summary>
 /// Finds the following pattern:
 /// i   :  c ? A : B; // either A or B must be an empty statement and the other is "goto L1;"
 /// i+1 :  push x;
 /// i+2 :  goto L2;
 /// i+3 :  Block1
 ///        0  : L1;
 ///        1  : push y;
 ///        2  : goto L2;
 ///        3  : Block2
 ///             0 : whatever (but presumably it is the label L2)
 ///             
 /// Transforms it into:
 /// i   : push d ? X : Y;
 /// i+1 : goto L1;
 /// i+2 : Block 2
 /// 
 /// Where if A is the empty statement,
 ///   d == c, X == x, Y == y
 /// If B is the empty statement and y is zero
 ///   d == !c, X == x, Y == y
 /// If B is the empty statement and y is not zero
 ///   d == c, X == y, Y == x
 /// And Block1 is deleted from the list.
 /// </summary>
 private bool ReplaceShortCircuitPatternCreatedByCCI2(List<IStatement> statements, int i)
 {
     if (i > statements.Count - 4) return false;
       ConditionalStatement/*?*/ conditionalStatement = statements[i] as ConditionalStatement;
       if (conditionalStatement == null) return false;
       PushStatement/*?*/ push1 = statements[i + 1] as PushStatement;
       if (push1 == null) return false;
       GotoStatement/*?*/ Goto = statements[i + 2] as GotoStatement;
       if (Goto == null) return false;
       BasicBlock/*?*/ block1 = statements[i + 3] as BasicBlock;
       if (block1 == null) return false;
       if (block1.Statements.Count < 4) return false;
       LabeledStatement/*?*/ label = block1.Statements[0] as LabeledStatement;
       if (label == null) return false;
       List<IGotoStatement> branchesToThisLabel;
       if (this.predecessors.TryGetValue(label, out branchesToThisLabel)) {
     if (1 < branchesToThisLabel.Count) return false;
       }
       // TODO? Should we make sure that one of the branches in the conditionalStatement is
       // to label?
       PushStatement/*?*/ push2 = block1.Statements[1] as PushStatement;
       if (push2 == null) return false;
       GotoStatement/*?*/ Goto2 = block1.Statements[2] as GotoStatement;
       if (Goto2 == null) return false;
       if (Goto.TargetStatement != Goto2.TargetStatement) return false;
       BasicBlock/*?*/ block2 = block1.Statements[3] as BasicBlock;
       if (block2 == null) return false;
       if (conditionalStatement.TrueBranch is EmptyStatement) {
     Conditional conditional = new Conditional();
     conditional.Condition = conditionalStatement.Condition;
     conditional.ResultIfTrue = push1.ValueToPush;
     conditional.ResultIfFalse = push2.ValueToPush;
     conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
     push1.ValueToPush = conditional;
     push1.Locations = conditionalStatement.Locations;
     statements[i] = push1;
     statements[i + 1] = statements[i + 2]; // move the goto up
     statements[i + 2] = block2;
     statements.RemoveRange(i + 3, 1);
     return true;
       }
       if (conditionalStatement.FalseBranch is EmptyStatement) {
     Conditional conditional = new Conditional();
     if (ExpressionHelper.IsIntegralZero(push2.ValueToPush)) {
       conditional.Condition = InvertCondition(conditionalStatement.Condition);
       conditional.ResultIfTrue = push1.ValueToPush;
       conditional.ResultIfFalse = push2.ValueToPush;
     } else {
       conditional.Condition = conditionalStatement.Condition;
       conditional.ResultIfTrue = push2.ValueToPush;
       conditional.ResultIfFalse = push1.ValueToPush;
     }
     conditional.Locations = conditionalStatement.Locations;
     conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
     push1.ValueToPush = conditional;
     push1.Locations = conditionalStatement.Locations;
     statements[i] = push1;
     statements[i + 1] = statements[i + 2]; // move the goto up
     statements[i + 2] = block2;
     statements.RemoveRange(i + 3, 1);
     return true;
       }
       return false;
 }
Example #10
0
 private bool ReplaceShortCircuitPattern3(List<IStatement> statements, int i)
 {
     if (i > statements.Count - 3) return false;
       ConditionalStatement/*?*/ conditionalStatement = statements[i] as ConditionalStatement;
       if (conditionalStatement == null) return false;
       ConditionalStatement/*?*/ conditionalStatement2 = statements[i+1] as ConditionalStatement;
       if (conditionalStatement2 == null) return false;
       if (statements[i+2] is ConditionalStatement) {
     if (!this.ReplaceShortCircuitPattern2(statements, i+1)) return false;
     if (i > statements.Count - 3) return false;
     conditionalStatement2 = statements[i+1] as ConditionalStatement;
     if (conditionalStatement2 == null) return false;
       }
       GotoStatement/*?*/ gotoStatement = conditionalStatement.FalseBranch as GotoStatement;
       if (gotoStatement == null) return false;
       if (!(conditionalStatement.TrueBranch is EmptyStatement)) return false;
       GotoStatement/*?*/ gotoStatement2 = conditionalStatement2.FalseBranch as GotoStatement;
       if (gotoStatement2 == null) {
     gotoStatement2 = conditionalStatement2.TrueBranch as GotoStatement;
     if (gotoStatement2 == null) return false;
     if (!(conditionalStatement2.FalseBranch is EmptyStatement)) return false;
     //brfalse, brtrue, ... could be A && B || C
     BasicBlock/*?*/ bb = statements[i+2] as BasicBlock;
     if (bb == null) return false;
     if (bb.Statements.Count < 1 || !(bb.Statements[0] == gotoStatement.TargetStatement)) return false;
     //we have:
     //i+0: if (cond1) {} else goto lab1;
     //i+1: if (cond2) goto lab2;
     //i+2: {....}
     Conditional conditional = new Conditional();
     conditional.Condition = conditionalStatement.Condition;
     conditional.Locations = conditionalStatement.Locations;
     conditional.ResultIfTrue = conditionalStatement2.Condition;
     conditional.ResultIfFalse = new CompileTimeConstant() { Value = 0, Type = this.sourceMethodBody.MethodDefinition.Type.PlatformType.SystemInt32 };
     conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
     conditionalStatement2.Condition = conditional;
     statements.RemoveAt(i);
     //we now have:
     //i+0: if (cond1 ? cond2 : 0) goto lab2;
     //i+1: {....}
     //which amounts to:
     // if (cond1 && cond2) goto lab2;
     // {...}
     return this.ReplaceShortCircuitPattern2(statements, i);
       }
       if (!(conditionalStatement2.TrueBranch is EmptyStatement)) return false;
       if (gotoStatement.TargetStatement == gotoStatement2.TargetStatement) {
     Conditional conditional = new Conditional();
     conditional.Condition = conditionalStatement.Condition;
     conditional.Locations = conditionalStatement.Locations;
     conditional.ResultIfTrue = conditionalStatement2.Condition;
     conditional.ResultIfFalse = new CompileTimeConstant() { Value = 0, Type = this.sourceMethodBody.MethodDefinition.Type.PlatformType.SystemInt32 };
     conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
     conditionalStatement2.Condition = conditional;
     statements.RemoveAt(i);
     return true;
       }
       return false;
 }
Example #11
0
        private bool ReplaceShortCircuitPattern2(List<IStatement> statements, int i)
        {
            if (i > statements.Count - 3) return false;
              ConditionalStatement/*?*/ conditionalStatement = statements[i] as ConditionalStatement;
              if (conditionalStatement == null) return false;
              ConditionalStatement/*?*/ conditionalStatement2 = statements[i+1] as ConditionalStatement;
              if (conditionalStatement2 == null) return false;
              if (statements[i+2] is ConditionalStatement) {
            if (!ReplaceShortCircuitPattern2(statements, i+1)) return false;
            if (i > statements.Count - 3) return false;
            conditionalStatement2 = statements[i+1] as ConditionalStatement;
            if (conditionalStatement2 == null) return false;
              }
              BasicBlock/*?*/ block = statements[i+2] as BasicBlock;
              if (block == null) {
            return this.ReplaceShortCircuitPattern3(statements, i);
              }
              if (block.Statements.Count < 1) return false;
              GotoStatement/*?*/ gotoStatement = conditionalStatement.TrueBranch as GotoStatement;
              if (gotoStatement == null) {
            return this.ReplaceShortCircuitPattern3(statements, i);
              }
              if (!(conditionalStatement.FalseBranch is EmptyStatement)) return false;
              if (gotoStatement.TargetStatement != block.Statements[0]) return false;
              if (!(conditionalStatement2.TrueBranch is EmptyStatement)) {
            if (!(conditionalStatement2.TrueBranch is GotoStatement)) return false;
            if (!(conditionalStatement2.FalseBranch is EmptyStatement)) return false;
            //Now have:
            //if (cond1) goto lab1;
            //if (cond2) goto lab2;
            //lab1:...
            conditionalStatement2.Condition = InvertCondition(conditionalStatement2.Condition);
            IStatement temp = conditionalStatement2.TrueBranch;
            conditionalStatement2.TrueBranch = conditionalStatement2.FalseBranch;
            conditionalStatement2.FalseBranch = temp;
            //Now have:
            //if (cond1) goto lab1;
            //if (!cond2) {} else goto lab2;
            //lab1:...
              } else {
            if (!(conditionalStatement2.FalseBranch is GotoStatement)) return false;
              }

              //Now have:
              //if (cond1) goto lab1;
              //if (cond2a) {} else goto lab2;
              //lab1:...

              Conditional conditional = new Conditional();
              conditional.Condition = conditionalStatement.Condition;
              conditional.Locations = conditionalStatement.Locations;
              conditional.ResultIfTrue = new CompileTimeConstant() { Value = 1, Type = this.sourceMethodBody.MethodDefinition.Type.PlatformType.SystemInt32 };
              conditional.ResultIfFalse = conditionalStatement2.Condition;
              conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
              conditionalStatement2.Condition = conditional;
              statements.RemoveAt(i);

              //Now have:
              //if (cond1 ? true : cond2a) {} goto lab2;
              //lab1:....
              //
              //Which amounts to
              //if (!(cond1 || cond2a)) goto lab2;
              //lab1:...
              return true;
        }
Example #12
0
        /// <summary>
        /// Finds the following pattern:
        /// i   :  if (c) A else B; // either A or B must be an empty statement and the other is "goto L1;"
        /// i+1 :  push x;
        /// i+2 :  goto L2;
        /// i+3 :  Block1
        ///        0  : L1;
        ///        1  : push y;
        ///        2  : Block2
        ///             0 : L2;
        ///             1 : (rest of statements in Block2)
        ///             
        /// Transforms it into:
        /// i   : push (d ? X : Y);
        /// i+1 : (rest of statements in Block2, preceded by L2 if there are more branches to L2 than just the one that was at i+2)
        /// 
        /// Where if A is the empty statement, then
        ///   d == c, X == x, Y == y
        /// If B is the empty statement, then if y is zero,
        ///   d == !c, X == x, Y == y
        /// If B is the empty statement, then if y is not zero,
        ///   d == c, X == y, Y == x
        /// </summary>
        private bool ReplaceShortCircuitPattern(List<IStatement> statements, int i)
        {
            if (i > statements.Count - 4) return false;
              ConditionalStatement/*?*/ conditionalStatement = statements[i] as ConditionalStatement;
              if (conditionalStatement == null) return false;
              if (statements[i+1] is ConditionalStatement)
            return this.ReplaceChainedShortCircuitBooleanPattern(statements, i);
              GotoStatement/*?*/ gotoL1 = null;
              if (conditionalStatement.TrueBranch is EmptyStatement)
            gotoL1 = conditionalStatement.FalseBranch as GotoStatement;
              else if (conditionalStatement.FalseBranch is EmptyStatement)
            gotoL1 = conditionalStatement.TrueBranch as GotoStatement;
              if (gotoL1 == null) return false;

              PushStatement/*?*/ push = statements[i+1] as PushStatement;
              if (push == null) return false;
              GotoStatement/*?*/ gotoL2 = statements[i+2] as GotoStatement;
              if (gotoL2 == null) return false;

              BasicBlock/*?*/ block = statements[i+3] as BasicBlock;
              if (block == null) return false;
              if (block.Statements.Count < 3) return false;
              LabeledStatement/*?*/ l1 = block.Statements[0] as LabeledStatement;
              if (l1 == null) return false;
              if (l1 != gotoL1.TargetStatement) return false;
              List<IGotoStatement> branchesToThisLabel;
              if (this.predecessors.TryGetValue(l1, out branchesToThisLabel)) {
            if (branchesToThisLabel.Count > 1) return false;
              }
              PushStatement/*?*/ push2 = block.Statements[1] as PushStatement;
              if (push2 == null) return false;

              BasicBlock/*?*/ block2 = block.Statements[2] as BasicBlock;
              if (block2 == null || block2.Statements.Count < 1 || block2.Statements[0] != gotoL2.TargetStatement) return false;

              Conditional conditional = new Conditional();
              if (conditionalStatement.TrueBranch is EmptyStatement) {
            conditional.Condition = conditionalStatement.Condition;
            conditional.ResultIfTrue = push.ValueToPush;
            conditional.ResultIfFalse = push2.ValueToPush;
              } else if (conditionalStatement.FalseBranch is EmptyStatement) {
            if (ExpressionHelper.IsIntegralZero(push2.ValueToPush)) {
              conditional.Condition = InvertCondition(conditionalStatement.Condition);
              conditional.ResultIfTrue = push.ValueToPush;
              conditional.ResultIfFalse = push2.ValueToPush;
            } else {
              conditional.Condition = conditionalStatement.Condition;
              conditional.ResultIfTrue = push2.ValueToPush;
              conditional.ResultIfFalse = push.ValueToPush;
            }
              }
              conditional.Type = TypeHelper.MergedType(TypeHelper.StackType(conditional.ResultIfTrue.Type), TypeHelper.StackType(conditional.ResultIfFalse.Type));
              conditional.Locations = conditionalStatement.Locations;

              push.ValueToPush = conditional;
              push.Locations = conditional.Locations;
              statements[i] = push;
              statements.RemoveRange(i+1, 3);
              var l2 = gotoL2.TargetStatement;
              this.predecessors.TryGetValue(l2, out branchesToThisLabel);
              branchesToThisLabel.Remove(gotoL2);
              if (branchesToThisLabel.Count == 0)
            block2.Statements.RemoveAt(0);
              statements.InsertRange(i+1, block2.Statements);

              return true;
        }
Example #13
0
 /// <summary>
 /// Rewrites the children of the given conditional expression.
 /// </summary>
 public virtual void RewriteChildren(Conditional conditional)
 {
     this.RewriteChildren((Expression)conditional);
       conditional.Condition = this.Rewrite(conditional.Condition);
       conditional.ResultIfTrue = this.Rewrite(conditional.ResultIfTrue);
       conditional.ResultIfFalse = this.Rewrite(conditional.ResultIfFalse);
 }
Example #14
0
 /// <summary>
 /// Visits the specified conditional.
 /// </summary>
 /// <param name="conditional">The conditional.</param>
 public override void Visit(IConditional conditional)
 {
     Conditional mutableConditional = new Conditional(conditional);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableConditional);
 }
Example #15
0
    private bool ReplaceShortCircuitAnd6(BlockStatement b) {
      Contract.Requires(b != null);
      bool replacedPattern = false;
      var statements = b.Statements;
      for (int i = 0; i < statements.Count-8; i++) {
        var ifStatement = statements[i] as ConditionalStatement;
        if (ifStatement == null) continue;
        var gotoFalseCase = ifStatement.FalseBranch as GotoStatement;
        if (gotoFalseCase == null) continue;
        Contract.Assume(ifStatement.TrueBranch is EmptyStatement);
        var labeledStatement = statements[i+1] as LabeledStatement;
        if (labeledStatement == null) continue;
        var gotos = this.gotosThatTarget[(uint)labeledStatement.Label.UniqueKey];
        if (gotos != null && gotos.Count > 0) continue;
        var ifStatement2 = statements[i+2] as ConditionalStatement;
        if (ifStatement2 == null) continue;
        var gotoTrueCase = ifStatement2.FalseBranch as GotoStatement;
        if (gotoTrueCase == null) continue;
        if (!(ifStatement2.TrueBranch is EmptyStatement)) continue;
        var labeledStatement2 = statements[i+3] as LabeledStatement;
        if (labeledStatement2 == null || labeledStatement2 != gotoFalseCase.TargetStatement) continue;
        gotos = this.gotosThatTarget[(uint)labeledStatement2.Label.UniqueKey];
        Contract.Assume(gotos != null && gotos.Count > 0);
        if (gotos.Count > 1) continue;
        Contract.Assume(gotos[0] == gotoFalseCase);
        var pushFalseCase = statements[i+4] as PushStatement;
        if (pushFalseCase == null) continue;
        if (pushFalseCase.ValueToPush.Type.TypeCode != PrimitiveTypeCode.Boolean) continue;
        var gotoEnd = statements[i+5] as GotoStatement;
        if (gotoEnd == null) continue;
        var labeledStatement3 = statements[i+6] as LabeledStatement;
        if (labeledStatement3 == null || labeledStatement3 != gotoTrueCase.TargetStatement) continue;
        gotos = this.gotosThatTarget[(uint)labeledStatement3.Label.UniqueKey];
        Contract.Assume(gotos != null && gotos.Count > 0);
        if (gotos.Count > 1) continue;
        Contract.Assume(gotos[0] == gotoTrueCase);
        var pushTrueCase = statements[i+7] as PushStatement;
        if (pushTrueCase == null) continue;
        if (pushTrueCase.ValueToPush.Type.TypeCode != PrimitiveTypeCode.Int32) continue;
        var pushTrueVal = pushTrueCase.ValueToPush as CompileTimeConstant;
        if (pushTrueVal == null || !(pushTrueVal.Value is int)) continue;
        if (1 != (int)pushTrueVal.Value) continue;
        var endLabel = statements[i+8] as LabeledStatement;
        if (endLabel == null || gotoEnd.TargetStatement != endLabel) continue;
        gotos = this.gotosThatTarget[(uint)endLabel.Label.UniqueKey];
        Contract.Assume(gotos != null && gotos.Count > 0);
        if (gotos.Count > 1) continue;
        Contract.Assume(gotos[0] == gotoEnd);

        var falseConst = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean };
        var invertedCond1 = IfThenElseReplacer.InvertCondition(ifStatement2.Condition);
        var conditional1 = new Conditional() { Condition = ifStatement.Condition, ResultIfTrue = invertedCond1, ResultIfFalse = falseConst, Type = this.host.PlatformType.SystemBoolean };
        var trueConst = new CompileTimeConstant() { Value = true, Type = this.host.PlatformType.SystemBoolean };
        var invertedCond2 = IfThenElseReplacer.InvertCondition(pushFalseCase.ValueToPush);
        var conditional2 = new Conditional() { Condition = conditional1, ResultIfTrue = trueConst, ResultIfFalse = invertedCond2, Type = this.host.PlatformType.SystemBoolean };
        pushTrueCase.ValueToPush = conditional2;
        statements.RemoveAt(i+8);
        statements.RemoveRange(i, 7);
        replacedPattern = true;
      }
      return replacedPattern;
    }
Example #16
0
 /// <summary>
 /// Visits the specified conditional.
 /// </summary>
 /// <param name="conditional">The conditional.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(Conditional conditional)
 {
     conditional.Condition = Substitute(conditional.Condition);
       conditional.ResultIfTrue = Substitute(conditional.ResultIfTrue);
       conditional.ResultIfFalse = Substitute(conditional.ResultIfFalse);
       conditional.Type = this.Substitute(conditional.Type);
       return conditional;
 }
Example #17
0
 /// <summary>
 /// Visits the specified conditional.
 /// </summary>
 /// <param name="conditional">The conditional.</param>
 /// <returns></returns>
 public virtual IExpression Visit(Conditional conditional)
 {
     conditional.Condition = Visit(conditional.Condition);
       conditional.ResultIfTrue = Visit(conditional.ResultIfTrue);
       conditional.ResultIfFalse = Visit(conditional.ResultIfFalse);
       conditional.Type = this.Visit(conditional.Type);
       return conditional;
 }