예제 #1
0
        public ArrayInfo(ArgumentLocation ArrayArgument)
        {
            m_ArrayArgument  = ArrayArgument;
            m_DimensionCount = ArrayArgument.DataType.GetArrayRank();

            m_ScaleNode     = new List <Node>(DimensionCount);
            m_ScaleArgument = new List <ArgumentLocation>(DimensionCount);

            for (int i = 0; i < DimensionCount; i++)
            {
                m_ScaleNode.Add(null);
                m_ScaleArgument.Add(null);
            }
        }
예제 #2
0
 protected ArgumentLocation(ArgumentLocation ex)
     : base(ex)
 {
     m_Index = ex.m_Index;
 }
예제 #3
0
        public void PutArgument(HighLevel.ArgumentLocation Location, object Value)
        {
            int Index = Location.Index;

            System.Diagnostics.Debug.Assert(Index >= 0 && Index < m_Arguments.Count);
            System.Diagnostics.Debug.Assert(m_Arguments[Index] == null);

            InvokeArgument Argument = null;

            if (object.ReferenceEquals(Value, null))
            {
                Argument = new InvokeArgument.Int32Arg(0);
            }
            else if (Value is int)
            {
                Argument = new InvokeArgument.Int32Arg((int)Value);
            }
            else if (Value is uint)
            {
                Argument = new InvokeArgument.UInt32Arg((uint)Value);
            }
            else if (Value is long)
            {
                Argument = new InvokeArgument.Int64Arg((long)Value);
            }
            else if (Value is ulong)
            {
                Argument = new InvokeArgument.UInt64Arg((ulong)Value);
            }
            else if (Value is float)
            {
                Argument = new InvokeArgument.FloatArg((float)Value);
            }
            else if (Value is double)
            {
                Argument = new InvokeArgument.DoubleArg((double)Value);
            }
            else
            {
                Type Type = Value.GetType();
                if (Type.IsArray)
                {
                    bool ForRead = false, ForWrite = false;
                    if ((Location.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                    {
                        ForRead = true;
                    }
                    if ((Location.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                    {
                        ForWrite = true;
                    }

                    if (!ForRead && !ForWrite)
                    {
                        ForRead = ForWrite = true;
                    }

                    Type ElementType = Type.GetElementType();
                    if (ElementType == typeof(byte) || ElementType == typeof(int) || ElementType == typeof(uint) || ElementType == typeof(long) || ElementType == typeof(ulong) ||
                        ElementType == typeof(float) || ElementType == typeof(double))
                    {
                        Argument = new InvokeArgument.PrimitiveArrayArg((System.Array)Value, ForRead, ForWrite);
                    }
                    else if (ValueTypeMap.ContainsKey(ElementType))
                    {
                        Argument = new InvokeArgument.MarshalledArrayArg((System.Array)Value, ForRead, ForWrite);
                    }
                }
            }

            if (Argument == null)
            {
                throw new InvalidOperationException(string.Format("Sorry, argument type '{0}' cannot be marshalled for OpenCL.", Value.GetType()));
            }

            m_Arguments[Index] = Argument;
        }
예제 #4
0
        internal static void WriteOpenCL(HighLevel.HlGraph HLgraph, TextWriter writer)
        {
            writer.WriteLine();
            writer.WriteLine("// OpenCL source for {2} method '{0}' of type '{1}'", HLgraph.MethodBase.ToString(), HLgraph.MethodBase.DeclaringType.ToString(), HLgraph.IsKernel ? "kernel" : "related");
            writer.WriteLine("{2}{0} {1}(", GetOpenClType(HLgraph, ((MethodInfo)HLgraph.MethodBase).ReturnType), HLgraph.MethodName, HLgraph.IsKernel ? "__kernel " : string.Empty);
            for (int i = 0; i < HLgraph.Arguments.Count; i++)
            {
                HighLevel.ArgumentLocation Argument = HLgraph.Arguments[i];

                string AttributeString = string.Empty;
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                {
                    AttributeString += "/*[in";
                }
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[out";
                    }
                    else
                    {
                        AttributeString += ",out";
                    }
                }

                if (AttributeString != string.Empty)
                {
                    AttributeString += "]*/ ";
                }

                if ((Argument.DataType.IsArray || Argument.DataType.IsPointer || Argument.DataType.IsByRef) &&
                    ((Argument.Flags & Hybrid.MsilToOpenCL.HighLevel.LocationFlags.PointerLocal) == 0))
                {
                    AttributeString += "__global ";
                }

                writer.WriteLine("\t{0}{1} {2}{3}", AttributeString, GetOpenClType(HLgraph, Argument.DataType), Argument.Name, i + 1 < HLgraph.Arguments.Count ? "," : string.Empty);
            }
            writer.WriteLine(")");
            writer.WriteLine("/*");
            writer.WriteLine("  Generated by CIL2OpenCL");
            writer.WriteLine("*/");
            writer.WriteLine("{");

            foreach (HighLevel.LocalVariableLocation LocalVariable in HLgraph.LocalVariables)
            {
                string AttributeString = string.Empty;
                if ((LocalVariable.Flags & HighLevel.LocationFlags.Read) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "read";
                }
                if ((LocalVariable.Flags & HighLevel.LocationFlags.Write) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "write";
                }
                if ((LocalVariable.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "deref_read";
                }
                if ((LocalVariable.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                {
                    if (AttributeString == string.Empty)
                    {
                        AttributeString += "/*[";
                    }
                    else
                    {
                        AttributeString += ",";
                    }
                    AttributeString += "deref_write";
                }
                if (AttributeString == string.Empty)
                {
                    AttributeString = "/*UNUSED*/ // ";
                }
                else
                {
                    AttributeString += "]*/ ";
                }
                if ((LocalVariable.Flags & Hybrid.MsilToOpenCL.HighLevel.LocationFlags.PointerGlobal) != 0)
                {
                    AttributeString += "__global ";
                }

                writer.WriteLine("\t{0}{1} {2};", AttributeString, GetOpenClType(HLgraph, LocalVariable.DataType), LocalVariable.Name);
            }

            HighLevel.BasicBlock FallThroughTargetBlock = HLgraph.CanonicalStartBlock;
            for (int i = 0; i < HLgraph.BasicBlocks.Count; i++)
            {
                HighLevel.BasicBlock BB = HLgraph.BasicBlocks[i];

                if (BB == HLgraph.CanonicalEntryBlock || BB == HLgraph.CanonicalExitBlock)
                {
                    continue;
                }

                if (FallThroughTargetBlock != null && FallThroughTargetBlock != BB)
                {
                    writer.WriteLine("\tgoto {0};", FallThroughTargetBlock.LabelName);
                }

                FallThroughTargetBlock = null;

                writer.WriteLine();
                if (BB.LabelNameUsed)
                {
                    writer.WriteLine("{0}:", BB.LabelName);
                }
                else
                {
                    writer.WriteLine("//{0}: (unreferenced block label)", BB.LabelName);
                }

                foreach (HighLevel.Instruction Instruction in BB.Instructions)
                {
                    writer.WriteLine("\t{0}", Instruction.ToString());
                }

                if (BB.Successors.Count == 0)
                {
                    writer.WriteLine("\t// End of block is unreachable");
                }
                else if (BB.Successors[0] == HLgraph.CanonicalExitBlock)
                {
                    writer.WriteLine("\t// End of block is unreachable/canonical routine exit");
                }
                else
                {
                    FallThroughTargetBlock = BB.Successors[0];
                }
            }

            writer.WriteLine("}");
        }
예제 #5
0
            private void TraverseTree(Node Node, bool TopIsDef, bool ArrayDef)
            {
                if (Node == null)
                {
                    return;
                }

                if (TopIsDef)
                {
                    if (Node.NodeType == NodeType.Location)
                    {
                        Location Location = ((LocationNode)Node).Location;
                        if (!DefinedLocations.Contains(Location))
                        {
                            DefinedLocations.Add(Location);
                        }
                    }
                    else if (Node.NodeType == NodeType.ArrayAccess)
                    {
                        TraverseTree(Node, false, true);
                    }
                    else if (Node.NodeType == NodeType.AddressOf)
                    {
                        TraverseTree(((AddressOfNode)Node).SubNodes[0], true, false);
                        TraverseTree(((AddressOfNode)Node).SubNodes[0], false, false);
                    }
                    else if (Node.NodeType == NodeType.Deref)
                    {
                        TraverseTree(((DerefNode)Node).SubNodes[0], false, false);
                    }
                    else if (Node.NodeType == NodeType.InstanceField)
                    {
                        // Do nothing here. ConvertForOpenCl will convert this to an argument location,
                        // so regular analysis treats it as such at a later pass
                    }
                    else if (Node.NodeType == NodeType.NamedField)
                    {
                        TraverseTree(((NamedFieldNode)Node).SubNodes[0], true, false);
                    }
                    else
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                }
                else
                {
                    if (Node.NodeType == NodeType.Location)
                    {
                        Location Location = ((LocationNode)Node).Location;
                        if (!UsedLocations.Contains(Location))
                        {
                            UsedLocations.Add(Location);
                        }
                    }
                    else
                    {
                        HlGraphEntry RelatedGraphEntry;

                        if (Node.NodeType == NodeType.ArrayAccess && Node.SubNodes.Count > 0 && Node.SubNodes[0].NodeType == NodeType.Location)
                        {
                            Location ArrayLocation = ((LocationNode)Node.SubNodes[0]).Location;

                            if (ArrayDef && !IndirectDefinedLocations.Contains(ArrayLocation))
                            {
                                IndirectDefinedLocations.Add(ArrayLocation);
                            }
                            else if (!ArrayDef && !IndirectUsedLocations.Contains(ArrayLocation))
                            {
                                IndirectUsedLocations.Add(ArrayLocation);
                            }
                        }
                        else if (Node.NodeType == NodeType.Call && Node.SubNodes.Count > 0 && !object.ReferenceEquals(RelatedGraphs, null) &&
                                 RelatedGraphs.TryGetValue(((CallNode)Node).MethodInfo, out RelatedGraphEntry))
                        {
                            // Call to other generated method. Propagate indirect usage flags

                            HlGraph HlGraph = RelatedGraphEntry.HlGraph;

                            for (int i = 0; i < Math.Min(Node.SubNodes.Count, HlGraph.Arguments.Count); i++)
                            {
                                ArgumentLocation Argument = HlGraph.Arguments[i];

                                if ((Argument.Flags & (LocationFlags.IndirectRead | LocationFlags.IndirectWrite)) != 0)
                                {
                                    Node SubNode = Node.SubNodes[i];
                                    if (SubNode.NodeType == NodeType.Location)
                                    {
                                        Location ArrayLocation = ((LocationNode)SubNode).Location;
                                        if ((Argument.Flags & LocationFlags.IndirectRead) != 0 && !IndirectUsedLocations.Contains(ArrayLocation))
                                        {
                                            IndirectUsedLocations.Add(ArrayLocation);
                                        }
                                        if ((Argument.Flags & LocationFlags.IndirectWrite) != 0 && !IndirectDefinedLocations.Contains(ArrayLocation))
                                        {
                                            IndirectDefinedLocations.Add(ArrayLocation);
                                        }
                                    }
                                }
                            }
                        }

                        foreach (Node SubNode in Node.SubNodes)
                        {
                            TraverseTree(SubNode, (SubNode.NodeType == NodeType.AddressOf) ? true : false, false);
                        }
                    }
                }
            }
예제 #6
0
        private static void WriteCode(HighLevel.HlGraph HLgraph, TextWriter writer)
        {
            writer.WriteLine("// begin {0}", HLgraph.MethodBase);

            if (HLgraph.MethodBase.IsConstructor)
            {
                writer.Write("constructor {0}::{1} (", ((System.Reflection.ConstructorInfo)HLgraph.MethodBase).DeclaringType, HLgraph.MethodBase.Name);
            }
            else
            {
                writer.Write("{0} {1}(", ((MethodInfo)HLgraph.MethodBase).ReturnType, HLgraph.MethodBase.Name);
            }

            for (int i = 0; i < HLgraph.Arguments.Count; i++)
            {
                if (i > 0)
                {
                    writer.Write(", ");
                }

                HighLevel.ArgumentLocation Argument = HLgraph.Arguments[i];
                string AttributeString = string.Empty;
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectRead) != 0)
                {
                    AttributeString += "__deref_read ";
                }
                if ((Argument.Flags & HighLevel.LocationFlags.IndirectWrite) != 0)
                {
                    AttributeString += "__deref_write ";
                }

                writer.Write("{0}{1} {2}", AttributeString, Argument.DataType, Argument.Name);
            }

            writer.WriteLine(") {");

            foreach (HighLevel.LocalVariableLocation LocalVariable in HLgraph.LocalVariables)
            {
                writer.WriteLine("\t{0} {1};", LocalVariable.DataType, LocalVariable.Name);
            }

            for (int i = 0; i < HLgraph.BasicBlocks.Count; i++)
            {
                HighLevel.BasicBlock BB = HLgraph.BasicBlocks[i];

                if (BB == HLgraph.CanonicalEntryBlock || BB == HLgraph.CanonicalExitBlock)
                {
                    continue;
                }

                writer.WriteLine();
                writer.WriteLine("{0}:", BB.LabelName);
                foreach (HighLevel.Instruction Instruction in BB.Instructions)
                {
                    writer.WriteLine("\t{0}", Instruction.ToString());
                }

                if (BB.Successors.Count == 0)
                {
                    writer.WriteLine("\t// unreachable code");
                }
                else if (i + 1 == HLgraph.BasicBlocks.Count || HLgraph.BasicBlocks[i + 1] != BB.Successors[0])
                {
                    if (BB.Successors[0] == HLgraph.CanonicalExitBlock)
                    {
                        writer.WriteLine("\t// to canonical routine exit");
                    }
                    else
                    {
                        writer.WriteLine("\tgoto {0};", BB.Successors[0].LabelName);
                    }
                }
            }

            writer.WriteLine("}");
            writer.WriteLine("// end");
            writer.WriteLine();
        }