예제 #1
0
        // Split critical edges in the graph. A critical edge is an edge which
        // is neither its successor's only predecessor, nor its predecessor's
        // only successor. Critical edges must be split to prevent copy-insertion
        // and code motion from affecting other edges. It is probably not strictly
        // needed here.
        public static void SplitCriticalEdges(LBlock[] blocks)
        {
            for (var i = 0; i < blocks.Length; i++)
            {
                var block = blocks[i];
                if (block.numSuccessors < 2)
                {
                    continue;
                }

                for (var j = 0; j < block.numSuccessors; j++)
                {
                    var target = block.getSuccessor(j);
                    if (target.numPredecessors < 2)
                    {
                        continue;
                    }

                    // Create a new block inheriting from the predecessor.
                    var            split        = new LBlock(block.pc);
                    var            ins          = new LGoto(target);
                    LInstruction[] instructions = { ins };
                    split.setInstructions(instructions);
                    block.replaceSuccessor(j, split);
                    target.replacePredecessor(block, split);
                    split.addPredecessor(block);
                }
            }
        }
예제 #2
0
            public LBlock parse()
            {
                for (int i = 0; i < lir_.instructions.Count; i++)
                {
                    LInstruction ins = lir_.instructions[i];

                    if (lir_.isTarget(ins.pc))
                    {
                        // This instruction is the target of a basic block, so
                        // finish the old one.
                        LBlock next = lir_.blockOfTarget(ins.pc);

                        // Multiple instructions could be at the same pc,
                        // because of decomposition, so make sure we're not
                        // transitioning to the same block.
                        if (block_ != next)
                        {
                            // Add implicit control flow to make further algorithms easier.
                            if (block_ != null)
                            {
                                //Debug.Assert(!pending_[pending_.Count - 1].isControl());
                                pending_.Add(new LGoto(next));
                                next.addPredecessor(block_);
                            }

                            // Fallthrough to the next block.
                            transitionBlocks(next);
                        }
                    }

                    // If there is no block present, we assume this is dead code.
                    if (block_ == null)
                    {
                        continue;
                    }

                    pending_.Add(ins);

                    switch (ins.op)
                    {
                    case Opcode.Return:
                    {
                        // A return terminates the current block.
                        transitionBlocks(null);
                        break;
                    }

                    case Opcode.Jump:
                    {
                        LJump jump = (LJump)ins;
                        jump.target.addPredecessor(block_);
                        transitionBlocks(null);
                        break;
                    }

                    case Opcode.JumpCondition:
                    {
                        LJumpCondition jcc = (LJumpCondition)ins;
                        jcc.trueTarget.addPredecessor(block_);
                        jcc.falseTarget.addPredecessor(block_);

                        // The next iteration will pick the false target up.
                        //Debug.Assert(lir_.instructions[i + 1].pc == jcc.falseTarget.pc);
                        transitionBlocks(null);
                        break;
                    }

                    case Opcode.Switch:
                    {
                        LSwitch switch_ = (LSwitch)ins;
                        for (int j = 0; j < switch_.numSuccessors; j++)
                        {
                            switch_.getSuccessor(j).addPredecessor(block_);
                        }
                        transitionBlocks(null);
                        break;
                    }
                    }
                }
                return(lir_.entry);
            }
예제 #3
0
        // Split critical edges in the graph. A critical edge is an edge which
        // is neither its successor's only predecessor, nor its predecessor's
        // only successor. Critical edges must be split to prevent copy-insertion
        // and code motion from affecting other edges. It is probably not strictly
        // needed here.
        public static void SplitCriticalEdges(LBlock[] blocks)
        {
            for (int i = 0; i < blocks.Length; i++)
            {
                LBlock block = blocks[i];
                if (block.numSuccessors < 2)
                    continue;
                for (int j = 0; j < block.numSuccessors; j++)
                {
                    LBlock target = block.getSuccessor(j);
                    if (target.numPredecessors < 2)
                        continue;

                    // Create a new block inheriting from the predecessor.
                    LBlock split = new LBlock(block.pc);
                    LGoto ins = new LGoto(target);
                    LInstruction[] instructions = { ins };
                    split.setInstructions(instructions);
                    block.replaceSuccessor(j, split);
                    target.replacePredecessor(block, split);
                    split.addPredecessor(block);
                }
            }
        }