예제 #1
0
        private static BasicBlock InlineIR(this IList <BasicBlockInstruction> code,
                                           ControlFlowInstruction trailer,
                                           Func <Subprogram, bool> permitInline,
                                           Dictionary <VirtualRegister, VirtualRegister> copyRegMap,
                                           Dictionary <Subprogram, Dictionary <VirtualRegister, VirtualRegister> > inlineRegMaps,
                                           IList <Subprogram> subprograms,
                                           out BasicBlock backend)
        {
            List <BasicBlockInstruction> preamble = new List <BasicBlockInstruction>();
            int i = 0;

            while (i < code.Count && !(code[i].OpCode == IROpCodes.CALL &&
                                       permitInline(subprograms.Single(sp => sp.Name == (code[i] as CALLInstruction).Target.Name))))
            {
                preamble.Add(code[i++].MapInstruction(copyRegMap));
            }
            if (i < code.Count)
            {
                CALLInstruction call = code[i++] as CALLInstruction;
                call = new CALLInstruction(subprograms.Single(sp => sp.Name == call.Target.Name),
                                           call.Arguments.Select(op => op.MapOperand(copyRegMap)).ToList());

                List <BasicBlockInstruction> tail = new List <BasicBlockInstruction>();
                while (i < code.Count)
                {
                    tail.Add(code[i++]);
                }

                return(call.InlineIR(preamble, tail.InlineIR(trailer, permitInline, copyRegMap,
                                                             inlineRegMaps, subprograms, out backend), inlineRegMaps));
            }
            else
            {
                backend = new BasicBlock(preamble, trailer);
                return(backend);
            }
        }
예제 #2
0
 public BasicBlock(IList <BasicBlockInstruction> code, ControlFlowInstruction trailer)
 {
     Code    = code;
     Trailer = trailer;
 }
예제 #3
0
파일: Inline.cs 프로젝트: cephdon/gpudotnet
		private static BasicBlock InlineIR(this IList<BasicBlockInstruction> code,
			ControlFlowInstruction trailer,
			Func<Subprogram, bool> permitInline,
			Dictionary<VirtualRegister, VirtualRegister> copyRegMap,
			Dictionary<Subprogram, Dictionary<VirtualRegister, VirtualRegister>> inlineRegMaps,
			IList<Subprogram> subprograms,
			out BasicBlock backend)
		{
			List<BasicBlockInstruction> preamble = new List<BasicBlockInstruction>();
			int i = 0;
			while (i < code.Count && !(code[i].OpCode == IROpCodes.CALL &&
				permitInline(subprograms.Single(sp => sp.Name == (code[i] as CALLInstruction).Target.Name))))
				preamble.Add(code[i++].MapInstruction(copyRegMap));
			if (i < code.Count)
			{
				CALLInstruction call = code[i++] as CALLInstruction;
				call = new CALLInstruction(subprograms.Single(sp => sp.Name == call.Target.Name),
					call.Arguments.Select(op => op.MapOperand(copyRegMap)).ToList());
				
				List<BasicBlockInstruction> tail = new List<BasicBlockInstruction>();
				while (i < code.Count)
					tail.Add(code[i++]);					
				
				return call.InlineIR(preamble, tail.InlineIR(trailer, permitInline, copyRegMap, 
					inlineRegMaps, subprograms, out backend), inlineRegMaps);
			}
			else
			{
				backend = new BasicBlock(preamble, trailer);
				return backend;
			}
		}
예제 #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());

			}
		}
예제 #5
0
		public BasicBlock(IList<BasicBlockInstruction> code, ControlFlowInstruction trailer)
		{
			Code = code;
			Trailer = trailer;
		}
예제 #6
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());
            }
        }