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); } }
protected ArgumentLocation(ArgumentLocation ex) : base(ex) { m_Index = ex.m_Index; }
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; }
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("}"); }
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); } } } }
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(); }