public static IList<Subprogram> GetCallsRec(Subprogram sp) { List<Subprogram> splist = new List<Subprogram>(); foreach (Subprogram callee in sp.GetCalls()) Enumerate(callee, (x => { }), splist); return splist.AsReadOnly(); }
public static IList <Subprogram> GetCallsRec(Subprogram sp) { List <Subprogram> splist = new List <Subprogram>(); foreach (Subprogram callee in sp.GetCalls()) { Enumerate(callee, (x => { }), splist); } return(splist.AsReadOnly()); }
private static void Enumerate(Subprogram sp, Action<Subprogram> handler, IList<Subprogram> visited) { if (!visited.Contains(sp)) { handler(sp); visited.Add(sp); foreach (Subprogram callee in sp.GetCalls()) Enumerate(callee, handler, visited); } }
private static void Enumerate(Subprogram sp, Action <Subprogram> handler, IList <Subprogram> visited) { if (!visited.Contains(sp)) { handler(sp); visited.Add(sp); foreach (Subprogram callee in sp.GetCalls()) { Enumerate(callee, handler, visited); } } }
private static Subprogram InlineIR(this Subprogram sp, Func <Subprogram, bool> permitInline, IList <Subprogram> subprograms) { List <FormalParameter> formalParameters = sp.FormalParameters.Select(fp => fp.Clone()).ToList(); Dictionary <VirtualRegister, VirtualRegister> copyRegMap = sp.FormalParameters.Zip(formalParameters, (preimage, image) => new KeyValuePair <VirtualRegister, VirtualRegister>(preimage, image)).Concat( sp.LocalVariables.Select(lv => new KeyValuePair <VirtualRegister, VirtualRegister>(lv, new VirtualRegister(lv.UnderlyingType, lv.StateSpace)))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); Subprogram result = sp is Kernel ? new Kernel(formalParameters) : new Subprogram(formalParameters); result.Name = sp.Name; result.CFGRoot = sp.CFGRoot.InlineIR(permitInline, copyRegMap, new Dictionary <Subprogram, Dictionary <VirtualRegister, VirtualRegister> >(), subprograms, new Dictionary <BasicBlock, BasicBlock>()); return(result); }
public CALLInstruction(Subprogram target, IList <GenericOperand> arguments) { if (target == null) { throw new ArgumentNullException("target"); } else if (target is Kernel) { throw new NotSupportedException("Kernels can not be called from device code"); } else { Target = target; } if (arguments == null) { throw new ArgumentNullException("operands"); } else if (arguments.Count != target.FormalParameters.Count) { throw new ArgumentException(string.Format("{0} has {1} formal parameters but {2} actual parameters are provided", target.Name, target.FormalParameters.Count, arguments.Count)); } else { for (int idx = 0; idx < arguments.Count; idx++) { if (arguments[idx] == null) { throw new ArgumentException(string.Format("Argument {0} is null", idx), "operands"); } FormalParameter fp = target.FormalParameters[idx]; if (arguments[idx] is VirtualRegister) { VirtualRegister vr = arguments[idx] as VirtualRegister; if (vr.StateSpace != fp.StateSpace) { throw new ArgumentException(string.Format("Argument {0} is incompatible with {1} state space", idx, fp.StateSpace.ToString()), "operands"); } if (vr.StateSpace != StateSpaces.REG) { if (vr.UnderlyingType != fp.UnderlyingType) { throw new ArgumentException(string.Format("Argument {0} has incompatible underlying type", idx), "operands"); } } else { if (vr.DataType != fp.DataType) { throw new ArgumentException(string.Format("Argument {0} has incompatible data type", idx), "operands"); } } } else if (arguments[idx] is ImmediateValue) { ImmediateValue iv = arguments[idx] as ImmediateValue; if (fp.StateSpace != StateSpaces.REG) { throw new ArgumentException(string.Format("Argument {0} is incompatible with {1} state space", idx, fp.StateSpace.ToString()), "operands"); } if (fp.PassingStyle != PassingStyles.VAL) { throw new ArgumentException(string.Format("Argument {0} can be passed only by value", idx), "operands"); } if (iv.DataType != fp.DataType) { throw new ArgumentException(string.Format("Argument {0} has incompatible data type", idx), "operands"); } } } } this.arguments = arguments; }
public CALLInstruction(Subprogram target, IList<GenericOperand> arguments) { if (target == null) throw new ArgumentNullException("target"); else if (target is Kernel) throw new NotSupportedException("Kernels can not be called from device code"); else Target = target; if (arguments == null) throw new ArgumentNullException("operands"); else if (arguments.Count != target.FormalParameters.Count) throw new ArgumentException(string.Format("{0} has {1} formal parameters but {2} actual parameters are provided", target.Name, target.FormalParameters.Count, arguments.Count)); else { for (int idx = 0; idx < arguments.Count; idx++) { if (arguments[idx] == null) throw new ArgumentException(string.Format("Argument {0} is null", idx), "operands"); FormalParameter fp = target.FormalParameters[idx]; if (arguments[idx] is VirtualRegister) { VirtualRegister vr = arguments[idx] as VirtualRegister; if (vr.StateSpace != fp.StateSpace) throw new ArgumentException(string.Format("Argument {0} is incompatible with {1} state space", idx, fp.StateSpace.ToString()), "operands"); if (vr.StateSpace != StateSpaces.REG) { if (vr.UnderlyingType != fp.UnderlyingType) throw new ArgumentException(string.Format("Argument {0} has incompatible underlying type", idx), "operands"); } else { if (vr.DataType != fp.DataType) throw new ArgumentException(string.Format("Argument {0} has incompatible data type", idx), "operands"); } } else if (arguments[idx] is ImmediateValue) { ImmediateValue iv = arguments[idx] as ImmediateValue; if (fp.StateSpace != StateSpaces.REG) throw new ArgumentException(string.Format("Argument {0} is incompatible with {1} state space", idx, fp.StateSpace.ToString()), "operands"); if (fp.PassingStyle != PassingStyles.VAL) throw new ArgumentException(string.Format("Argument {0} can be passed only by value", idx), "operands"); if (iv.DataType != fp.DataType) throw new ArgumentException(string.Format("Argument {0} has incompatible data type", idx), "operands"); } } } this.arguments = arguments; }
public static IList <TreeStatement> BuildAST(this Subprogram src) { IList <BasicBlock> bblist = src.GetBasicBlocks(); Dictionary <BasicBlock, IEnumerable <BasicBlock> > pred = bblist.Select(bb => new KeyValuePair <BasicBlock, IEnumerable <BasicBlock> >(bb, bblist.Where(bbel => bbel.Successor == bb || bbel.Target == bb))). ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Determine dominators. Dictionary <BasicBlock, List <BasicBlock> > dom = bblist.Select(bb => new KeyValuePair <BasicBlock, List <BasicBlock> >(bb, bb == src.CFGRoot ? new List <BasicBlock> { src.CFGRoot } : bblist.ToList())). ToDictionary(kvp => kvp.Key, kvp => kvp.Value); bool changes = true; while (changes) { changes = false; foreach (BasicBlock n in bblist) { if (n != src.CFGRoot) { IEnumerable <BasicBlock> doms = null; foreach (BasicBlock p in pred[n]) { doms = (doms == null) ? dom[p] : doms.Intersect(dom[p]); } doms = doms.Union(new [] { n }); if (!doms.SequenceEqual(dom[n])) { changes = true; dom[n] = new List <BasicBlock>(doms); } } } } // Perform depth-first enumeration. Dictionary <BasicBlock, int> dfn = bblist.Select(bb => new KeyValuePair <BasicBlock, int>(bb, 0)). ToDictionary(kvp => kvp.Key, kvp => kvp.Value); int c = bblist.Count; NumDepth(src.CFGRoot, dfn, ref c, new List <BasicBlock>()); // Test CFG reducibility: each retreating edge must be back edge. foreach (BasicBlock sbb in bblist) { foreach (BasicBlock tbb in new [] { sbb.Successor, sbb.Target }) { if (tbb != null && dfn[tbb] < dfn[sbb] && !dom[sbb].Contains(tbb)) { throw new IrreducibleCFGException("There is non-back retreating edge"); } } } if (bblist.Where(bb => bb.Trailer.OpCode == IROpCodes.RET).Count() != 1) { throw new IrreducibleCFGException("Control flow graph must have single node with RET ending"); } List <TreeStatement> code = new List <TreeStatement>(); BasicBlock cur = src.CFGRoot; GraphPathFinder path_finder = new GraphPathFinder(bblist); while (cur != null) { cur = HandleStatement(cur, null, bblist, pred, dom, path_finder, code); } return(code.AsReadOnly()); }