Esempio n. 1
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;
         }
     }
 }
Esempio n. 2
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);
        }
Esempio n. 3
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);
            }
        }