public static IntPtr GetBclType(Type type) { // Using the BCL, find the type. Note, Mono has a tendency to list something // in a namespace in which the type's metadata says it has no namespace. // As far as I can tell, this is for generated methods corresponding to the kernels. // Due to the disparity of what the "namespace" means, look up the type from // the top-most declaring type, and use that as context for the sub-class search. Stack <Type> chain = new Stack <Type>(); while (type != null) { chain.Push(type); type = type.DeclaringType; } System.IntPtr result = System.IntPtr.Zero; while (chain.Any()) { var tr = chain.Pop(); var mt = RUNTIME.RewriteType(tr.ToMonoTypeReference()); var assembly_name = tr.Module.Name; var name_space = tr.Namespace; var name = tr.Name; result = BclGetMetaOfType(assembly_name, name_space, name, result); } return(result); }
public static TypeReference FindBCLType(System.Type type) { var runtime = new RUNTIME(); TypeReference result = null; Mono.Cecil.ModuleDefinition md = Mono.Cecil.ModuleDefinition.ReadModule(FindCoreLib()); foreach (var bcl_type in md.GetTypes()) { if (bcl_type.FullName == type.FullName) { return(bcl_type); } } return(result); }
private MethodDefinition Rewrite(MethodReference method_reference) { // Perform any substitution of this method reference. MethodReference new_method_reference = RUNTIME.SubstituteMethod(method_reference); method_reference = new_method_reference != null ? new_method_reference : method_reference; MethodDefinition method_definition = method_reference.Resolve(); // Perform any substitutions of individual instructions. if (!(method_definition == null || method_definition.Body == null)) { RUNTIME.RewriteCilCodeBlock(method_definition.Body); } // Return method definition for further analysis. return(method_definition); }
public static void Initialize() { // Load C# library for BCL, and grab all types and methods. // The tables that this method sets up are: // _substituted_bcl -- maps types in program (represented in Mono.Cecil) into GPU BCL types (represented in Mono.Cecil). // _system_type_to_mono_type_for_bcl -- associates types in GPU BCL with NET Core/NET Framework/... in user program. // Note, there seems to be an underlying bug in System.Type.GetType for certain generics, like System.Collections.Generic.HashSet. // The method returns null. var xx = typeof(System.Collections.Generic.HashSet <>); var x2 = typeof(System.Collections.Generic.HashSet <int>); var yy = System.Type.GetType("System.Collections.Generic.HashSet"); var y2 = System.Type.GetType("System.Collections.Generic.HashSet<>"); var y3 = System.Type.GetType("System.Collections.Generic.HashSet`1"); var y4 = System.Type.GetType("System.Collections.Generic.HashSet<T>"); var y5 = System.Type.GetType(xx.FullName); var y6 = System.Type.GetType(@"System.Collections.Generic.HashSet`1[System.Int32]"); var y7 = System.Type.GetType(@"System.Collections.Generic.Dictionary`2[System.String,System.String]"); var y8 = System.Type.GetType(x2.FullName); // Set up _substituted_bcl. var runtime = new RUNTIME(); // Find corlib.dll. It could be anywhere, but let's check the usual spots. Mono.Cecil.ModuleDefinition md = Mono.Cecil.ModuleDefinition.ReadModule(FindCoreLib()); foreach (var bcl_type in md.GetTypes()) { // Filter out <Module> and <PrivateImplementationDetails>, among possible others. Regex regex = new Regex(@"^[<]\w+[>]"); if (regex.IsMatch(bcl_type.FullName)) { continue; } // Try to map the type into native NET type. Some things just won't. var t_system_type = System.Type.GetType(bcl_type.FullName); if (t_system_type == null) { continue; } var to_mono = t_system_type.ToMonoTypeReference(); // Add entry for converting intrinsic NET BCL type to GPU BCL type. _substituted_bcl.Add(to_mono, bcl_type); foreach (var m in bcl_type.Methods) { var x = m.ImplAttributes; if ((x & MethodImplAttributes.InternalCall) != 0) { if (Campy.Utils.Options.IsOn("runtime_trace")) { System.Console.WriteLine("Internal call set up " + bcl_type + " " + m); } _internalCalls.Add(new BclNativeMethod(bcl_type, m)); } } } // Set up _system_type_to_mono_type_for_bcl. // There really isn't any good way to set this up because NET Core System.Reflection does not work // on .LIB files. So begins the kludge... // Parse PTX files for all "visible" functions, and create LLVM declarations. // For "Internal Calls", these functions appear here, but also on the _internalCalls list. var assembly = Assembly.GetAssembly(typeof(Campy.Compiler.RUNTIME)); var resource_names = assembly.GetManifestResourceNames(); foreach (var resource_name in resource_names) { using (Stream stream = assembly.GetManifestResourceStream(resource_name)) using (StreamReader reader = new StreamReader(stream)) { string gpu_bcl_ptx = reader.ReadToEnd(); // Parse the PTX for ".visible" functions, and enter each in // the runtime table. // This should match ".visible" <spaces> ".func" <spaces> <function-return>? <function-name> // over many lines, many times. Regex regex = new Regex( @"\.visible\s+\.func\s+(?<return>[(][^)]*[)]\s+)?(?<name>\w+)\s*(?<params>[(][^)]*[)]\s+)"); foreach (Match match in regex.Matches(gpu_bcl_ptx)) { Regex space = new Regex(@"\s\s+"); string mangled_name = match.Groups["name"].Value.Trim(); string return_type = match.Groups["return"].Value.Trim(); return_type = space.Replace(return_type, " "); string parameters = match.Groups["params"].Value.Trim(); parameters = space.Replace(parameters, " "); if (Campy.Utils.Options.IsOn("runtime_trace")) { System.Console.WriteLine(mangled_name + " " + return_type + " " + parameters); } if (JITER.functions_in_internal_bcl_layer.ContainsKey(mangled_name)) { continue; } TypeRef llvm_return_type = default(TypeRef); TypeRef[] args; // Construct LLVM extern that corresponds to type of function. // Parse return_type and parameters strings... Regex param_regex = new Regex(@"\.param(\s+\.align\s+\d+)?\s+(?<type>\S+)\s"); { // parse return. if (return_type == "") { llvm_return_type = LLVM.VoidType(); } else { foreach (Match ret in param_regex.Matches(return_type)) { var x = ret.Groups["type"].Value; _ptx_type_to_llvm_typeref.TryGetValue( x, out TypeRef y); if (Campy.Utils.Options.IsOn("runtime_trace")) { System.Console.WriteLine("name " + x + " value " + y.ToString()); } llvm_return_type = y; } } } { // parse parameters. List <TypeRef> args_list = new List <TypeRef>(); foreach (Match ret in param_regex.Matches(parameters)) { var x = ret.Groups["type"].Value; if (!_ptx_type_to_llvm_typeref.TryGetValue( x, out TypeRef y)) { throw new Exception("Unknown type syntax in ptx parameter."); } if (Campy.Utils.Options.IsOn("runtime_trace")) { System.Console.Write("parameter "); System.Console.WriteLine("name " + x + " value " + y.ToString()); } args_list.Add(y); } args = args_list.ToArray(); } var decl = LLVM.AddFunction( JITER.global_llvm_module, mangled_name, LLVM.FunctionType( llvm_return_type, args, false)); PtxFunction ptxf = new PtxFunction(mangled_name, decl); if (Campy.Utils.Options.IsOn("runtime_trace")) { System.Console.WriteLine(ptxf._mangled_name + " " + ptxf._short_name + " " + ptxf._valueref); } JITER.functions_in_internal_bcl_layer.Add(mangled_name, decl); _ptx_functions.Add(ptxf); } } } }