Example #1
0
 public SwitchBlock(NodeBlock source, ControlBlock defaultCase, List <Case> cases, ControlBlock join)
     : base(source)
 {
     defaultCase_ = defaultCase;
     cases_       = cases;
     join_        = join;
 }
Example #2
0
 public WhileLoop(ControlType type, NodeBlock source, ControlBlock body, ControlBlock join)
     : base(source)
 {
     body_ = body;
     join_ = join;
     type_ = type;
 }
Example #3
0
 public WhileLoop(ControlType type, LogicChain logic, ControlBlock body, ControlBlock join)
     : base(null)
 {
     body_  = body;
     join_  = join;
     logic_ = logic;
     type_  = type;
 }
Example #4
0
 public IfBlock(NodeBlock source, bool invert, ControlBlock trueArm, ControlBlock falseArm, ControlBlock join)
     : base(source)
 {
     trueArm_  = trueArm;
     falseArm_ = falseArm;
     join_     = join;
     invert_   = invert;
 }
Example #5
0
 public void write(ControlBlock root)
 {
     writeSignature(root.source);
     outputLine("{");
     increaseIndent();
     writeBlock(root);
     decreaseIndent();
     outputLine("}");
 }
Example #6
0
 public IfBlock(NodeBlock source, LogicChain chain, ControlBlock trueArm, ControlBlock falseArm, ControlBlock join)
     : base(source)
 {
     trueArm_  = trueArm;
     falseArm_ = falseArm;
     join_     = join;
     invert_   = invert;
     logic_    = logic;
 }
Example #7
0
        private IfBlock traverseIf(NodeBlock block, DJumpCondition jcc)
        {
            if (HasSharedTarget(block, jcc))
            {
                return(traverseComplexIf(block, jcc));
            }

            NodeBlock trueTarget  = (jcc.spop == SPOpcode.jzer) ? jcc.falseTarget : jcc.trueTarget;
            NodeBlock falseTarget = (jcc.spop == SPOpcode.jzer) ? jcc.trueTarget : jcc.falseTarget;
            NodeBlock joinTarget  = findJoinOfSimpleIf(block, jcc);

            // If there is no join block (both arms terminate control flow),
            // eliminate one arm and use the other as a join point.
            if (joinTarget == null)
            {
                joinTarget = falseTarget;
            }

            // If the false target is equivalent to the join point, eliminate
            // it.
            if (BlockAnalysis.EffectiveTarget(falseTarget) == joinTarget)
            {
                falseTarget = null;
            }

            // If the true target is equivalent to the join point, promote
            // the false target to the true target and undo the inversion.
            bool invert = false;

            if (BlockAnalysis.EffectiveTarget(trueTarget) == joinTarget)
            {
                trueTarget  = falseTarget;
                falseTarget = null;
                invert     ^= true;
            }

            // If there is always a true target and a join target.
            pushScope(joinTarget);
            ControlBlock trueArm = traverseBlock(trueTarget);

            popScope();

            ControlBlock joinArm = traverseJoin(joinTarget);

            if (falseTarget == null)
            {
                return(new IfBlock(block, invert, trueArm, joinArm));
            }

            pushScope(joinTarget);
            ControlBlock falseArm = traverseBlock(falseTarget);

            popScope();

            return(new IfBlock(block, invert, trueArm, falseArm, joinArm));
        }
Example #8
0
        private ControlBlock traverseLoop(NodeBlock block)
        {
            DNode last = block.nodes.last;

            NodeBlock  effectiveHeader = block;
            LogicChain chain           = null;

            if (last.type == NodeType.JumpCondition)
            {
                DJumpCondition jcc = (DJumpCondition)last;
                if (HasSharedTarget(block, jcc))
                {
                    chain = buildLogicChain(block, null, out effectiveHeader);
                }
            }

            last = effectiveHeader.nodes.last;
            //Debug.Assert(last.type == NodeType.JumpCondition);

            if (last.type == NodeType.JumpCondition)
            {
                // Assert that the backedge is a straight jump.
                //Debug.Assert(BlockAnalysis.GetSingleTarget(graph_[block.lir.backedge.id]) == block);

                NodeBlock    join, body, cond;
                ControlType  type    = findLoopJoinAndBody(block, effectiveHeader, out join, out body, out cond);
                ControlBlock joinArm = traverseBlock(join);

                ControlBlock bodyArm = null;
                if (body != null)
                {
                    pushScope(block);
                    pushScope(cond);
                    bodyArm = traverseBlockNoLoop(body);
                    popScope();
                    popScope();
                }

                if (chain != null)
                {
                    return(new WhileLoop(type, chain, bodyArm, joinArm));
                }
                return(new WhileLoop(type, cond, bodyArm, joinArm));
            }

            return(null);
        }
Example #9
0
        private ControlBlock traverseSwitch(NodeBlock block, DSwitch switch_)
        {
            var dominators = new List <LBlock>();

            for (int i = 0; i < block.lir.idominated.Length; i++)
            {
                dominators.Add(block.lir.idominated[i]);
            }

            dominators.Remove(switch_.defaultCase);
            for (int i = 0; i < switch_.numCases; i++)
            {
                dominators.Remove(switch_.getCase(i).target);
            }

            NodeBlock join = null;

            if (dominators.Count > 0)
            {
                //Debug.Assert(dominators.Count == 1);
                join = graph_[dominators[dominators.Count - 1].id];
            }

            ControlBlock joinArm = null;

            if (join != null)
            {
                joinArm = traverseBlock(join);
            }

            pushScope(join);
            var          cases      = new List <SwitchBlock.Case>();
            ControlBlock defaultArm = traverseBlock(graph_[switch_.defaultCase.id]);

            for (int i = 0; i < switch_.numCases; i++)
            {
                ControlBlock arm = traverseBlock(graph_[switch_.getCase(i).target.id]);
                cases.Add(new SwitchBlock.Case(switch_.getCase(i).value, arm));
            }
            popScope();

            return(new SwitchBlock(block, defaultArm, cases, joinArm));
        }
Example #10
0
        private void writeBlock(ControlBlock block)
        {
            if (block == null)
            {
                return;
            }
            switch (block.type)
            {
            case ControlType.If:
                writeIf((IfBlock)block);
                break;

            case ControlType.WhileLoop:
                writeWhileLoop((WhileLoop)block);
                break;

            case ControlType.DoWhileLoop:
                writeDoWhileLoop((WhileLoop)block);
                break;

            case ControlType.Statement:
                writeStatementBlock((StatementBlock)block);
                break;

            case ControlType.Return:
                writeStatements(block.source);
                writeReturn((DReturn)block.source.nodes.last);
                break;

            case ControlType.Switch:
                writeSwitch((SwitchBlock)block);
                break;

            default:
                Debug.Assert(false);
                break;
            }
        }
Example #11
0
        private ControlBlock traverseBlockNoLoop(NodeBlock block)
        {
            if (block == null)
            {
                return(null);
            }

            DNode last = block.nodes.last;

            if (last.type == NodeType.JumpCondition)
            {
                return(traverseIf(block, (DJumpCondition)last));
            }

            if (last.type == NodeType.Jump)
            {
                DJump     jump   = (DJump)last;
                NodeBlock target = BlockAnalysis.EffectiveTarget(jump.target);

                ControlBlock next = null;
                if (!isJoin(target))
                {
                    next = traverseBlock(target);
                }

                return(new StatementBlock(block, next));
            }

            if (last.type == NodeType.Switch)
            {
                return(traverseSwitch(block, (DSwitch)last));
            }

            //Debug.Assert(last.type == NodeType.Return);
            return(new ReturnBlock(block));
        }
Example #12
0
 public void write(ControlBlock root)
 {
     writeSignature(root.source);
     outputLine("{");
     increaseIndent();
     writeBlock(root);
     decreaseIndent();
     outputLine("}");
 }
Example #13
0
 public Case(int value, ControlBlock target)
 {
     value_  = value;
     target_ = target;
 }
Example #14
0
 public StatementBlock(NodeBlock source, ControlBlock next)
     : base(source)
 {
                 next_ = next;
 }
Example #15
0
 public SwitchBlock(NodeBlock source, ControlBlock defaultCase, List<Case> cases, ControlBlock join)
   : base(source)
 {
     defaultCase_ = defaultCase;
     cases_ = cases;
     join_ = join;
 }
Example #16
0
 public Case(int value, ControlBlock target)
 {
     value_ = value;
     target_ = target;
 }
Example #17
0
 public WhileLoop(ControlType type, LogicChain logic, ControlBlock body, ControlBlock join)
     : base(null)
 {
     body_ = body;
     join_ = join;
     logic_ = logic;
     type_ = type;
 }
Example #18
0
 public WhileLoop(ControlType type, NodeBlock source, ControlBlock body, ControlBlock join)
   : base(source)
 {
     body_ = body;
     join_ = join;
     type_ = type;
 }
Example #19
0
 public IfBlock(NodeBlock source, LogicChain chain, ControlBlock trueArm, ControlBlock falseArm, ControlBlock join)
     : base(source)
 {
     trueArm_ = trueArm;
     falseArm_ = falseArm;
     join_ = join;
     invert_ = invert;
     logic_ = logic;
 }
Example #20
0
 public IfBlock(NodeBlock source, bool invert, ControlBlock trueArm, ControlBlock falseArm, ControlBlock join)
   : base(source)
 {
     trueArm_ = trueArm;
     falseArm_ = falseArm;
     join_ = join;
     invert_ = invert;
 }
Example #21
0
 public StatementBlock(NodeBlock source, ControlBlock next)
     : base(source)
 {
     next_ = next;
 }
Example #22
0
 private void writeBlock(ControlBlock block)
 {
     if (block == null)
     {
         return;
     }
     switch (block.type)
     {
         case ControlType.If:
             writeIf((IfBlock)block);
             break;
         case ControlType.WhileLoop:
             writeWhileLoop((WhileLoop)block);
             break;
         case ControlType.DoWhileLoop:
             writeDoWhileLoop((WhileLoop)block);
             break;
         case ControlType.Statement:
             writeStatementBlock((StatementBlock)block);
             break;
         case ControlType.Return:
             writeStatements(block.source);
             writeReturn((DReturn)block.source.nodes.last);
             break;
         case ControlType.Switch:
             writeSwitch((SwitchBlock)block);
             break;
         default:
             Debug.Assert(false);
             break;
     }
 }
Example #23
0
        private IfBlock traverseComplexIf(NodeBlock block, DJumpCondition jcc)
        {
            // Degenerate case: using || or &&, or any combination thereof,
            // will generate a chain of n+1 conditional blocks, where each
            // |n| has a target to a shared "success" block, setting a
            // phony variable. We decompose this giant mess into the intended
            // sequence of expressions.
            NodeBlock  join;
            LogicChain chain = buildLogicChain(block, null, out join);

            DJumpCondition finalJcc = (DJumpCondition)join.nodes.last;
            //Debug.Assert(finalJcc.spop == SPOpcode.jzer);

            // The final conditional should have the normal dominator
            // properties: 2 or 3 idoms, depending on the number of arms.
            // Because of critical edge splitting, we may have 3 idoms
            // even if there are only actually two arms.
            NodeBlock joinBlock = findJoinOfSimpleIf(join, finalJcc);

            // If an AND chain reaches its end, the result is 1. jzer tests
            // for zero, so this is effectively testing (!success).
            // If an OR expression reaches its end, the result is 0. jzer
            // tests for zero, so this is effectively testing if (failure).
            //
            // In both cases, the true target represents a failure, so flip
            // the targets around.
            NodeBlock trueBlock  = finalJcc.falseTarget;
            NodeBlock falseBlock = finalJcc.trueTarget;

            // If there is no join block, both arms terminate control flow,
            // eliminate one arm and use the other as a join point.
            if (joinBlock == null)
            {
                joinBlock = falseBlock;
            }

            if (join.lir.idominated.Length == 2 ||
                BlockAnalysis.EffectiveTarget(falseBlock) == joinBlock)
            {
                if (join.lir.idominated.Length == 3)
                {
                    joinBlock = BlockAnalysis.EffectiveTarget(falseBlock);
                }

                // One-armed structure.
                pushScope(joinBlock);
                ControlBlock trueArm1 = traverseBlock(trueBlock);
                popScope();

                ControlBlock joinArm1 = traverseBlock(joinBlock);
                return(new IfBlock(block, chain, trueArm1, joinArm1));
            }

            //Debug.Assert(join.lir.idominated.Length == 3);

            pushScope(joinBlock);
            ControlBlock trueArm2 = traverseBlock(trueBlock);
            ControlBlock falseArm = traverseBlock(falseBlock);

            popScope();

            ControlBlock joinArm2 = traverseBlock(joinBlock);

            return(new IfBlock(block, chain, trueArm2, falseArm, joinArm2));
        }