예제 #1
0
        public BBLoop(BasicBlock head, BasicBlock tail, IMSet <BasicBlock> body, JST.Identifier label)
        {
            Head  = head;
            Tail  = tail;
            Body  = body;
            Label = label;

            var headEscapes  = false;
            var headbranchbb = head as BranchBasicBlock;

            foreach (var t in head.Targets)
            {
                if (!body.Contains(t))
                {
                    headEscapes = true;
                }
            }

            var tailEscapes  = false;
            var tailbranchbb = tail as BranchBasicBlock;

            foreach (var t in tail.Targets)
            {
                if (!body.Contains(t))
                {
                    tailEscapes = true;
                }
            }

            if (!headEscapes && tailEscapes && tailbranchbb != null)
            {
                if (tailbranchbb.Target.Equals(head))
                {
                    Flavor = LoopFlavor.DoWhile;
                }
                else if (tailbranchbb.Fallthrough.Equals(head))
                {
                    Flavor = LoopFlavor.FlippedDoWhile;
                }
                else
                {
                    throw new InvalidOperationException("invalid loop");
                }
            }
            else if (headEscapes && !tailEscapes && headbranchbb != null)
            {
                if (body.Contains(headbranchbb.Target))
                {
                    Flavor = LoopFlavor.WhileDo;
                }
                else if (body.Contains(headbranchbb.Fallthrough))
                {
                    Flavor = LoopFlavor.FlippedWhileDo;
                }
                else
                {
                    throw new InvalidOperationException("invalid loop");
                }
            }
            else if (!headEscapes && !tailEscapes)
            {
                Flavor = LoopFlavor.Loop;
            }
            else if (headEscapes && tailEscapes && headbranchbb != null && tailbranchbb != null)
            {
                // Could encode as do-while with a break at start, or while-do with a break at end.
                if (body.Contains(headbranchbb.Target))
                {
                    Flavor = LoopFlavor.WhileDo;
                }
                else if (body.Contains(headbranchbb.Fallthrough))
                {
                    Flavor = LoopFlavor.FlippedWhileDo;
                }
                else
                {
                    throw new InvalidOperationException("invalid loop");
                }
            }
            else
            {
                Flavor = LoopFlavor.Unknown;
            }
        }