Beispiel #1
0
        ICollection <T> GetTargetInstructions(T i)
        {
            List <T> result = new List <T>(1);

            // if there are more multiple branches
            T[] targets = LinearInstructionAdapter <T> .GetOperand(i) as T[];

            if (targets == null)
            {
                T target = LinearInstructionAdapter <T> .GetOperand(i) as T;

                if (target != null)
                {
                    result.Add(target);
                    return(result);
                }
            }
            else
            {
                foreach (T instr in targets)
                {
                    result.Add(instr);
                }

                return(result);
            }

            return(result);
        }
Beispiel #2
0
        bool IsBlockLeader(T i)
        {
            if (LinearInstructionAdapter <T> .GetPrevious(i) == null)
            {
                return(true);
            }

            // Check whether this was a start of an exception protected area
            if (exceptionHandlersStarts.Contains(i))
            {
                return(true);
            }

            if (IsBlockTerminator(LinearInstructionAdapter <T> .GetPrevious(i)))
            {
                return(true);
            }

            // Check whether the instruction has label
            if (HasLabel(i))
            {
                return(true);
            }

            return(false);
        }
Beispiel #3
0
 void ComputeLabels(IEnumerable <T> instructions)
 {
     Debug.Assert(labels == null, "Labels must be null");
     labels = new HashSet <T>();
     foreach (T i in instructions)
     {
         switch (LinearInstructionAdapter <T> .GetFlowControl(i))
         {
         case FlowControl.Cond_Branch:
         case FlowControl.Branch:
             var targets = GetTargetInstructions(i);
             foreach (T target in targets)
             {
                 labels.Add(target);
             }
             break;
         }
     }
 }
Beispiel #4
0
        bool IsBlockTerminator(T i)
        {
            // first instruction in the collection starts a block
            switch (LinearInstructionAdapter <T> .GetFlowControl(i))
            {
            // Ensures leave and endfinally do not create new block in structure CFG
            case FlowControl.Branch:
            case FlowControl.Return:
            case FlowControl.Break:
            case FlowControl.Cond_Branch:
            case FlowControl.Throw:
                return(true);
            }

            T nextInstr = LinearInstructionAdapter <T> .GetNext(i);

            if (nextInstr != null)
            {
                return(HasLabel(nextInstr) || exceptionHandlersStarts.Contains(nextInstr));
            }

            // The next inst is null which means the end of the body.
            return(true);
        }
Beispiel #5
0
        void ConnectBlock(BasicBlock <T> block)
        {
            if (block.Last == null)
            {
                throw new ArgumentException("Undelimited node at " + block.Last);
            }

            T lastInst = block.Last;
            T nextInst = LinearInstructionAdapter <T> .GetNext(lastInst);

            var targets = GetTargetInstructions(lastInst);

            switch (LinearInstructionAdapter <T> .GetFlowControl(lastInst))
            {
            // treat the call as next
            case FlowControl.Call:    // intentional fall through
            case FlowControl.Next:    // intentional fall through
            case FlowControl.Cond_Branch: {
                if (nextInst != null) // in the cases when it is last and there is no inst.Next
                // Add the next instruction as a target to the list of targets.
                {
                    targets.Add(nextInst);
                }
                break;
            }

            case FlowControl.Return: // intentional fall through
            case FlowControl.Branch: // intentional fall through
            case FlowControl.Throw:  // intentional fall through
                break;

            default:
                throw new NotSupportedException(
                          string.Format("Unhandled instruction flow behavior {0}: {1}",
                                        LinearInstructionAdapter <T> .GetFlowControl(lastInst),
                                        lastInst.ToString(),
                                        lastInst.ToString()));
            }

            foreach (var target in targets)
            {
                Debug.Assert(target != null, "Target cannot be null!");
                BasicBlock <T> successor = GetNodeContaining(target);
                // Check whether the successor already exists. Can happen when having branches pointing
                // to one and the same block. Eg. switch with no break.
                if (block.Successors.IndexOf(successor) < 0)
                {
                    block.Successors.Add(successor);
                    successor.Predecessors.Add(block);
                }
            }

            // Nothing to do, everything is already done, exit early.
            if (nextInst == null || targets.Contains(nextInst))
            {
                return;
            }
            // We need to rule out the end of catch, because it ends with a branch and this would end up
            // duplicating the successors
            if (exceptionHandlersEnds.Contains(lastInst))
            {
                BasicBlock <T> successor = GetNodeContaining(nextInst);
                block.Successors.Add(successor);
                successor.Predecessors.Add(block);
            }
        }