Пример #1
0
		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();
		}
Пример #2
0
        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());
        }
Пример #3
0
		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);
			}
		}
Пример #4
0
 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);
         }
     }
 }
Пример #5
0
        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);
        }
Пример #6
0
        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;
        }
Пример #7
0
		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;
		}
Пример #8
0
        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());
        }