Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
                        }
                    }
            }
        }