Ejemplo n.º 1
0
        public static List <BasicBlock> BuildBasicBlocks(List <IInstruction> ops)
        {
            // collect set of branch targets
            HashSet <IInstruction> BranchTargets = new HashSet <IInstruction>();

            foreach (IInstruction op in ops)
            {
                if (op is IJumpInstruction)
                {
                    IJumpInstruction it = op as IJumpInstruction;
                    BranchTargets.Add(it.Target);
                }
                else if (op is IBranchInstruction)
                {
                    IBranchInstruction it = op as IBranchInstruction;
                    BranchTargets.Add(it.IfTarget);
                    BranchTargets.Add(it.ElseTarget);
                }
            }

            // walk instruction list and split off blocks at branches or branch targets
            List <BasicBlock> Blocks = new List <BasicBlock>();
            int nInstructions        = ops.Count;
            int i = 0;

            do
            {
                BasicBlock block = new BasicBlock();
                Blocks.Add(block);

                do
                {
                    IInstruction op = ops[i++];
                    block.AddInstruction(op);
                    op.Block = block;

                    // stop if we just added a branch/jump op
                    if (op is IJumpInstruction || op is IBranchInstruction)
                    {
                        break;
                    }

                    // stop if next instruction is a branch target
                    if (i < nInstructions && BranchTargets.Contains(ops[i]))
                    {
                        break;
                    }
                } while (i < nInstructions);
            } while (i < nInstructions);

            // construct CFG edges
            for (int b = 0; b < Blocks.Count; b++)
            {
                IInstruction op = Blocks[b].LastInstruction;
                if (op is IBranchInstruction)
                {
                    IBranchInstruction branch = op as IBranchInstruction;
                    if (branch.IfTarget != null)
                    {
                        branch.Block.AddSuccessor(branch.IfTarget.Block);
                        branch.IfTarget.Block.AddPredecessor(branch.Block);
                    }
                    if (branch.ElseTarget != null)
                    {
                        branch.Block.AddSuccessor(branch.ElseTarget.Block);
                        branch.ElseTarget.Block.AddPredecessor(branch.Block);
                    }
                }
                else if (op is IJumpInstruction)
                {
                    // unconditional branch or jump, add target as one and only successor
                    IJumpInstruction jmp = op as IJumpInstruction;
                    if (jmp.Target != null)
                    {
                        jmp.Block.AddSuccessor(jmp.Target.Block);
                        jmp.Target.Block.AddPredecessor(jmp.Block);
                    }
                }
                else if (b < Blocks.Count - 1)
                {
                    // Block ends in something other than a branch or jump
                    //  add next block as successor
                    Blocks[b].AddSuccessor(Blocks[b + 1]);
                    Blocks[b + 1].AddPredecessor(Blocks[b]);
                }
            }

            return(Blocks);
        }
Ejemplo n.º 2
0
        public static List<BasicBlock> BuildBasicBlocks(List<IInstruction> ops)
        {
            // collect set of branch targets
            HashSet<IInstruction> BranchTargets = new HashSet<IInstruction>();
            foreach( IInstruction op in ops )
            {
                if( op is IJumpInstruction )
                {
                    IJumpInstruction it = op as IJumpInstruction;
                    BranchTargets.Add( it.Target );
                }
                else if( op is IBranchInstruction )
                {
                    IBranchInstruction it = op as IBranchInstruction;
                    BranchTargets.Add( it.IfTarget );
                    BranchTargets.Add( it.ElseTarget );
                }
            }

            // walk instruction list and split off blocks at branches or branch targets
            List<BasicBlock> Blocks = new List<BasicBlock>();
            int nInstructions = ops.Count;
            int i = 0;
            do
            {
                BasicBlock block = new BasicBlock();
                Blocks.Add(block);

                do
                {
                    IInstruction op = ops[i++];
                    block.AddInstruction(op);
                    op.Block = block;

                    // stop if we just added a branch/jump op
                    if (op is IJumpInstruction || op is IBranchInstruction)
                        break;

                    // stop if next instruction is a branch target
                    if (i<nInstructions && BranchTargets.Contains(ops[i]))
                        break;

                } while (i < nInstructions);

            } while (i < nInstructions);

            // construct CFG edges
            for( int b=0; b<Blocks.Count; b++ )
            {
                IInstruction op = Blocks[b].LastInstruction;
                if (op is IBranchInstruction)
                {
                    IBranchInstruction branch = op as IBranchInstruction;
                    if (branch.IfTarget != null)
                    {
                        branch.Block.AddSuccessor(branch.IfTarget.Block);
                        branch.IfTarget.Block.AddPredecessor(branch.Block);
                    }
                    if (branch.ElseTarget != null)
                    {
                        branch.Block.AddSuccessor(branch.ElseTarget.Block);
                        branch.ElseTarget.Block.AddPredecessor(branch.Block);
                    }
                }
                else if (op is IJumpInstruction)
                {
                    // unconditional branch or jump, add target as one and only successor
                    IJumpInstruction jmp = op as IJumpInstruction;
                    if (jmp.Target != null)
                    {
                        jmp.Block.AddSuccessor(jmp.Target.Block);
                        jmp.Target.Block.AddPredecessor(jmp.Block);
                    }
                }
                else if ( b < Blocks.Count-1 )
                {
                    // Block ends in something other than a branch or jump
                    //  add next block as successor
                    Blocks[b].AddSuccessor(Blocks[b + 1]);
                    Blocks[b + 1].AddPredecessor(Blocks[b]);
                }
            }

            return Blocks;
        }