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