internal void CheckRemoveJumpOrigin(BasicBlock block)
 {
     if (CecilHelper.IsBranch(block.BranchType))
     {
         var target = GetBlock((Instruction)block.LastInstruction.Operand);
         target.RemoveJumpOrigin(block.LastInstruction);
     }
 }
 void CheckAddJumpOrigin(BasicBlock block)
 {
     if (CecilHelper.IsBranch(block.BranchType))
     {
         // We are adding a new branch instruction.
         var target = _bb_by_instruction [(Instruction)block.LastInstruction.Operand];
         target.AddJumpOrigin(new JumpOrigin(target, block, block.LastInstruction));
     }
 }
        /*
         * The block @block contains a linker conditional that resolves into the
         * boolean constant @condition.  There are @stackDepth extra values on the
         * stack and the block ends with a branch instruction.
         *
         * If @condition is true, then we replace the branch with a direct jump.
         *
         * If @condition is false, then we remove the branch.
         *
         * In either case, we need to make sure to pop the extra @stackDepth values
         * off the stack.
         *
         */
        public void ReplaceWithBranch(ref BasicBlock block, int stackDepth, bool condition)
        {
            if (!CecilHelper.IsBranch(block.BranchType))
            {
                throw new OptimizerAssertionException($"{nameof (ReplaceWithBranch)} used on non-branch block.");
            }

            Instruction branch = null;

            if (condition)
            {
                branch = Instruction.Create(OpCodes.Br, (Instruction)block.LastInstruction.Operand);
            }

            ReplaceWithInstruction(ref block, stackDepth, branch);
        }
        public bool RemoveDeadBlocks()
        {
            Scanner.LogDebug(2, $"REMOVE DEAD BLOCKS: {Method.Name}");
            Scanner.DumpBlocks(2);

            var foundDeadBlocks = false;

            for (int i = 0; i < BlockList.Count; i++)
            {
                var block = BlockList [i];
                if (!block.IsDead)
                {
                    continue;
                }

                Scanner.LogDebug(2, $"  FOUND DEAD BLOCK: {block}");

                if (CecilHelper.IsBranch(block.BranchType))
                {
                    var target = BlockList.GetBlock((Instruction)block.LastInstruction.Operand);
                    target.RemoveJumpOrigin(block.LastInstruction);
                }

                if (block.ExceptionHandlers.Count > 0)
                {
                    CheckRemoveExceptionBlock(ref i);
                }

                foundDeadBlocks = true;
            }

            Scanner.LogDebug(2, $"REMOVE DEAD BLOCKS #1: {Method.Name} {foundDeadBlocks}");

            if (!foundDeadBlocks)
            {
                return(false);
            }

            var removedDeadBlocks = false;

            for (int i = 0; i < BlockList.Count; i++)
            {
                var block = BlockList [i];
                if (!block.IsDead)
                {
                    continue;
                }

                Scanner.LogDebug(2, $"  DELETING DEAD BLOCK: {block}");

                BlockList.DeleteBlock(ref block);
                removedDeadBlocks = true;
                i--;
            }

            if (removedDeadBlocks)
            {
                BlockList.ComputeOffsets();

                Scanner.LogDebug(2, $"REMOVE DEAD BLOCKS DONE: {Method.Name} {foundDeadBlocks}");
                Scanner.DumpBlocks(2);

                Scanner.Context.Options.OptimizerReport?.RemovedDeadBlocks(Method);
            }

            return(removedDeadBlocks);
        }