Пример #1
0
        public static void OptimizeIf(Branch condition)
        {
            Node trueStart = condition.FloatUpToNeighbours(condition.TrueSuccessor);
            Node falseStart = condition.FloatUpToNeighbours(condition.FalseSuccessor);

            NodeCollection trueReachable = trueStart != null ? trueStart.GetReachableNodes() : NodeCollection.Empty;
            NodeCollection falseReachable = falseStart != null ? falseStart.GetReachableNodes() : NodeCollection.Empty;
            NodeCollection commonReachable = NodeCollection.Intersect(trueReachable, falseReachable);

            NodeCollection trueNodes = trueReachable.Clone();
            trueNodes.RemoveRange(commonReachable);
            NodeCollection falseNodes = falseReachable.Clone();
            falseNodes.RemoveRange(commonReachable);

            // Replace the basic block with condition node
            Node conditionParent = condition.Parent;
            int conditionIndex = condition.Index;
            ConditionalNode conditionalNode = new ConditionalNode(condition);
            conditionalNode.MoveTo(conditionParent, conditionIndex);

            // If there are no common nodes, let the 'true' block be the default
            if (commonReachable.Count > 0) {
                trueNodes.MoveTo(conditionalNode.TrueBody);
            }

            falseNodes.MoveTo(conditionalNode.FalseBody);

            // Optimize the created subtrees
            conditionalNode.TrueBody.OptimizeConditions();
            conditionalNode.FalseBody.OptimizeConditions();
        }
Пример #2
0
 Ast.Expression MakeBranchCondition_Internal(Branch branch)
 {
     if (branch is SimpleBranch) {
         List<Ast.Expression> args = TransformExpressionArguments((ILExpression)((SimpleBranch)branch).BasicBlock.Body[0]);
         Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
         Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
         switch(((ILExpression)((SimpleBranch)branch).BasicBlock.Body[0]).OpCode.Code) {
             case Code.Brfalse: return new Ast.UnaryOperatorExpression(arg1, UnaryOperatorType.Not);
             case Code.Brtrue:  return arg1;
             case Code.Beq:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
             case Code.Bge:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2);
             case Code.Bge_Un:  return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2);
             case Code.Bgt:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
             case Code.Bgt_Un:  return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
             case Code.Ble:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2);
             case Code.Ble_Un:  return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2);
             case Code.Blt:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
             case Code.Blt_Un:  return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
             case Code.Bne_Un:  return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
             case Code.Leave:   return new Ast.PrimitiveExpression(true, true.ToString());
             default: throw new Exception("Bad opcode");
         }
     } else if (branch is ShortCircuitBranch) {
         ShortCircuitBranch scBranch = (ShortCircuitBranch)branch;
         switch(scBranch.Operator) {
             case ShortCircuitOperator.LeftAndRight:
                 return new BinaryOperatorExpression(
                     MakeBranchCondition(scBranch.Left),
                     BinaryOperatorType.LogicalAnd,
                     MakeBranchCondition(scBranch.Right)
                 );
             case ShortCircuitOperator.LeftOrRight:
                 return new BinaryOperatorExpression(
                     MakeBranchCondition(scBranch.Left),
                     BinaryOperatorType.LogicalOr,
                     MakeBranchCondition(scBranch.Right)
                 );
             case ShortCircuitOperator.NotLeftAndRight:
                 return new BinaryOperatorExpression(
                     new UnaryOperatorExpression(MakeBranchCondition(scBranch.Left), UnaryOperatorType.Not),
                     BinaryOperatorType.LogicalAnd,
                     MakeBranchCondition(scBranch.Right)
                 );
             case ShortCircuitOperator.NotLeftOrRight:
                 return new BinaryOperatorExpression(
                     new UnaryOperatorExpression(MakeBranchCondition(scBranch.Left), UnaryOperatorType.Not),
                     BinaryOperatorType.LogicalOr,
                     MakeBranchCondition(scBranch.Right)
                 );
             default:
                 throw new Exception("Bad operator");
         }
     } else {
         throw new Exception("Bad type");
     }
 }
Пример #3
0
 Ast.Expression MakeBranchCondition(Branch branch)
 {
     return new ParenthesizedExpression(MakeBranchCondition_Internal(branch));
 }
Пример #4
0
        public ConditionalNode(Branch condition)
        {
            this.condition = condition;

            condition.MoveTo(this);
            trueBody.MoveTo(this);
            falseBody.MoveTo(this);
        }