Exemplo n.º 1
0
        private static BasicBlock HandleStatement(
            BasicBlock start,
            BasicBlock enclosing_loop_frontier,
            IList <BasicBlock> bblist,
            Dictionary <BasicBlock, IEnumerable <BasicBlock> > pred,
            Dictionary <BasicBlock, List <BasicBlock> > dom,
            GraphPathFinder path_finder,
            List <TreeStatement> code)
        {
            BasicBlock loop_tail;

            try
            {
                loop_tail = pred[start].Where(bb => dom[bb].Contains(start)).SingleOrDefault();
            }
            catch (InvalidOperationException e)
            {
                throw new IrreducibleCFGException("Loop must have only one route to its header from its body");
            }
            if (loop_tail != null)
            {
                IEnumerable <BasicBlock> loop_insiders = bblist.Where(
                    bb => path_finder.GetPathLength(bb, loop_tail) < (int)short.MaxValue &&
                    !path_finder.GetPath(bb, loop_tail).Contains(start) &&
                    dom[bb].Contains(start)).Add(start);

                BasicBlock loop_frontier;

                try
                {
                    loop_frontier = (from insider in loop_insiders
                                     from adj in new [] { insider.Target, insider.Successor }
                                     where adj != null && !loop_insiders.Contains(adj)
                                     select adj).Single();
                }
                catch (InvalidOperationException e)
                {
                    throw new IrreducibleCFGException("Loop must have only one exit route from its body");
                }

                List <TreeStatement> loop_body        = start.Code.Select(bbi => new InstructionStatement(bbi) as TreeStatement).ToList();
                BasicBlock           statement_cursor = HandleBranch(start.Trailer, loop_frontier, bblist, pred, dom, path_finder, loop_body);
                while (statement_cursor != start)
                {
                    statement_cursor = HandleStatement(statement_cursor, loop_frontier, bblist, pred, dom, path_finder, loop_body);
                }

                code.Add(new InfiniteLoopStatement(loop_body));

                return(loop_frontier);
            }

            code.AddRange(start.Code.Select(bbi => new InstructionStatement(bbi)));
            return(HandleBranch(start.Trailer, enclosing_loop_frontier, bblist, pred, dom, path_finder, code));
        }
Exemplo n.º 2
0
		private static BasicBlock HandleBranch(
			ControlFlowInstruction cfi,
			BasicBlock enclosing_loop_frontier,
			IList<BasicBlock> bblist,
			Dictionary<BasicBlock, IEnumerable<BasicBlock>> pred,
			Dictionary<BasicBlock, List<BasicBlock>> dom,
			GraphPathFinder path_finder,
			List<TreeStatement> code)
		{
			JumpInstruction jump = cfi as JumpInstruction;
			JumpIfInstruction jumpif = cfi as JumpIfInstruction;

			switch (cfi.OpCode)
			{
				case IROpCodes.RET:
					return null;
				case IROpCodes.JMP:
					return jump.Target;
				case IROpCodes.JT:
				case IROpCodes.JF:
				{
					// loop condition check

					if (jumpif.Target == enclosing_loop_frontier)
					{
						// while-do break condition check
						code.Add(new BranchStatement(
							jumpif.Flag,
							cfi.OpCode == IROpCodes.JT ? new TreeStatement[] { new BreakStatement() } : null,
							cfi.OpCode == IROpCodes.JF ? new TreeStatement[] { new BreakStatement() } : null));
						return jumpif.Next;
					}
					if (jumpif.Next == enclosing_loop_frontier)
					{
						// do-while continue condition check
						code.Add(new BranchStatement(
							jumpif.Flag,
							cfi.OpCode == IROpCodes.JF ? new TreeStatement[] { new BreakStatement() } : null,
							cfi.OpCode == IROpCodes.JT ? new TreeStatement[] { new BreakStatement() } : null));
						return jumpif.Target;
					}

					// initialize IF statement frontier with enclosing loop frontier or the last block in CFG
					BasicBlock frontier = (enclosing_loop_frontier != null) ? enclosing_loop_frontier :
						bblist.Single(bb => bb.Trailer.OpCode == IROpCodes.RET);

					// precise IF statement frontier with last common block in reversed paths going 
					// from initial frontier value to both successors of basic block ending with this branch
					IEnumerator<BasicBlock> targetPathRev =
						path_finder.GetPath(jumpif.Target, frontier).Reverse().GetEnumerator();
					IEnumerator<BasicBlock> nextPathRev =
						path_finder.GetPath(jumpif.Next, frontier).Reverse().GetEnumerator();
					while (targetPathRev.MoveNext() && nextPathRev.MoveNext() && targetPathRev.Current == nextPathRev.Current)
						frontier = targetPathRev.Current;

					List<TreeStatement> trueBranchCode = new List<TreeStatement>();
					List<TreeStatement> falseBranchCode = new List<TreeStatement>();

					BasicBlock cursor;

					cursor = cfi.OpCode == IROpCodes.JT ? jumpif.Target : jumpif.Next;
					while (cursor != frontier)
						cursor = HandleStatement(cursor, null, bblist, pred, dom, path_finder, trueBranchCode);

					cursor = cfi.OpCode == IROpCodes.JF ? jumpif.Target : jumpif.Next;
					while (cursor != frontier)
						cursor = HandleStatement(cursor, null, bblist, pred, dom, path_finder, falseBranchCode);

					code.Add(new BranchStatement(jumpif.Flag, trueBranchCode, falseBranchCode));

					return frontier;
				}
				default:
					throw new NotSupportedException(cfi.OpCode.ToString());

			}
		}
Exemplo n.º 3
0
		private static BasicBlock HandleStatement(
			BasicBlock start,
			BasicBlock enclosing_loop_frontier,
			IList<BasicBlock> bblist,
			Dictionary<BasicBlock, IEnumerable<BasicBlock>> pred,
			Dictionary<BasicBlock, List<BasicBlock>> dom,
			GraphPathFinder path_finder,
			List<TreeStatement> code)
		{
			BasicBlock loop_tail;
			try
			{
				loop_tail = pred[start].Where(bb => dom[bb].Contains(start)).SingleOrDefault();
			}
			catch (InvalidOperationException e)
			{
				throw new IrreducibleCFGException("Loop must have only one route to its header from its body");
			}
			if (loop_tail != null)
			{
				IEnumerable<BasicBlock> loop_insiders = bblist.Where(
					bb => path_finder.GetPathLength(bb, loop_tail) < (int)short.MaxValue &&
						!path_finder.GetPath(bb, loop_tail).Contains(start) &&
						dom[bb].Contains(start)).Add(start);

				BasicBlock loop_frontier;

				try
				{
					loop_frontier = (from insider in loop_insiders
						from adj in new [] { insider.Target, insider.Successor }
						where adj != null && !loop_insiders.Contains(adj)
						select adj).Single();
				}
				catch (InvalidOperationException e)
				{
					throw new IrreducibleCFGException("Loop must have only one exit route from its body");
				}

				List<TreeStatement> loop_body = start.Code.Select(bbi => new InstructionStatement(bbi) as TreeStatement).ToList();
				BasicBlock statement_cursor = HandleBranch(start.Trailer, loop_frontier, bblist, pred, dom, path_finder, loop_body);
				while (statement_cursor != start)
					statement_cursor = HandleStatement(statement_cursor, loop_frontier, bblist, pred, dom, path_finder, loop_body);

				code.Add(new InfiniteLoopStatement(loop_body));

				return loop_frontier;
			}

			code.AddRange(start.Code.Select(bbi => new InstructionStatement(bbi)));
			return HandleBranch(start.Trailer, enclosing_loop_frontier, bblist, pred, dom, path_finder, code);
		}
Exemplo n.º 4
0
        private static BasicBlock HandleBranch(
            ControlFlowInstruction cfi,
            BasicBlock enclosing_loop_frontier,
            IList <BasicBlock> bblist,
            Dictionary <BasicBlock, IEnumerable <BasicBlock> > pred,
            Dictionary <BasicBlock, List <BasicBlock> > dom,
            GraphPathFinder path_finder,
            List <TreeStatement> code)
        {
            JumpInstruction   jump   = cfi as JumpInstruction;
            JumpIfInstruction jumpif = cfi as JumpIfInstruction;

            switch (cfi.OpCode)
            {
            case IROpCodes.RET:
                return(null);

            case IROpCodes.JMP:
                return(jump.Target);

            case IROpCodes.JT:
            case IROpCodes.JF:
            {
                // loop condition check

                if (jumpif.Target == enclosing_loop_frontier)
                {
                    // while-do break condition check
                    code.Add(new BranchStatement(
                                 jumpif.Flag,
                                 cfi.OpCode == IROpCodes.JT ? new TreeStatement[] { new BreakStatement() } : null,
                                 cfi.OpCode == IROpCodes.JF ? new TreeStatement[] { new BreakStatement() } : null));
                    return(jumpif.Next);
                }
                if (jumpif.Next == enclosing_loop_frontier)
                {
                    // do-while continue condition check
                    code.Add(new BranchStatement(
                                 jumpif.Flag,
                                 cfi.OpCode == IROpCodes.JF ? new TreeStatement[] { new BreakStatement() } : null,
                                 cfi.OpCode == IROpCodes.JT ? new TreeStatement[] { new BreakStatement() } : null));
                    return(jumpif.Target);
                }

                // initialize IF statement frontier with enclosing loop frontier or the last block in CFG
                BasicBlock frontier = (enclosing_loop_frontier != null) ? enclosing_loop_frontier :
                                      bblist.Single(bb => bb.Trailer.OpCode == IROpCodes.RET);

                // precise IF statement frontier with last common block in reversed paths going
                // from initial frontier value to both successors of basic block ending with this branch
                IEnumerator <BasicBlock> targetPathRev =
                    path_finder.GetPath(jumpif.Target, frontier).Reverse().GetEnumerator();
                IEnumerator <BasicBlock> nextPathRev =
                    path_finder.GetPath(jumpif.Next, frontier).Reverse().GetEnumerator();
                while (targetPathRev.MoveNext() && nextPathRev.MoveNext() && targetPathRev.Current == nextPathRev.Current)
                {
                    frontier = targetPathRev.Current;
                }

                List <TreeStatement> trueBranchCode  = new List <TreeStatement>();
                List <TreeStatement> falseBranchCode = new List <TreeStatement>();

                BasicBlock cursor;

                cursor = cfi.OpCode == IROpCodes.JT ? jumpif.Target : jumpif.Next;
                while (cursor != frontier)
                {
                    cursor = HandleStatement(cursor, null, bblist, pred, dom, path_finder, trueBranchCode);
                }

                cursor = cfi.OpCode == IROpCodes.JF ? jumpif.Target : jumpif.Next;
                while (cursor != frontier)
                {
                    cursor = HandleStatement(cursor, null, bblist, pred, dom, path_finder, falseBranchCode);
                }

                code.Add(new BranchStatement(jumpif.Flag, trueBranchCode, falseBranchCode));

                return(frontier);
            }

            default:
                throw new NotSupportedException(cfi.OpCode.ToString());
            }
        }