Ejemplo n.º 1
0
        private static Function EmitFunction(Module module, MethodBase method)
        {
            var methodInfo = method as MethodInfo;
            var methodConstructor = method as ConstructorInfo;
            var declaringType = method.DeclaringType;
            if (methodInfo == null && methodConstructor == null)
                throw new CudaSharpException("Unknown MethodBase type " + method.GetType().FullName);
            if (declaringType == null)
                throw new CudaSharpException("Could not find the declaring type of " + method.Name.StripNameToValidPtx());

            var parameters = method.GetParameters().Select(p => p.ParameterType);
            if (methodConstructor != null)
                parameters = new[] { declaringType.MakeByRefType() }.Concat(parameters);
            if (methodInfo != null && methodInfo.IsStatic == false)
            {
                if (declaringType.IsValueType == false)
                    throw new CudaSharpException("Cannot compile object instance methods (did you forget to mark the method as static?)");
                parameters = new[] { declaringType.MakeByRefType() }.Concat(parameters);
            }
            var llvmParameters =
                parameters.Select(t => ConvertType(module, t)).ToArray();
            var funcType = new FunctionType(ConvertType(module, methodInfo == null ? typeof(void) : methodInfo.ReturnType), llvmParameters);

            var intrinsic = method.GetCustomAttribute<Gpu.BuiltinAttribute>();
            if (intrinsic != null)
            {
                var name = intrinsic.Intrinsic;
                var preExisting = module.GetFunction(name);
                if (preExisting != null)
                    return preExisting;
                return module.CreateFunction(name, funcType);
            }

            var function = module.CreateFunction(methodConstructor == null ? method.Name.StripNameToValidPtx() : declaringType.Name.StripNameToValidPtx() + "_ctor", funcType);

            var block = new Block("entry", module.Context, function);
            var writer = new InstructionBuilder(module.Context, block);

            var opcodes = method.Disassemble().ToList();
            FindBranchTargets(opcodes, module.Context, function);

            var body = method.GetMethodBody();
            var efo = new EmitFuncObj(module, function, body, writer, null, new Stack<Value>(),
                body == null ? null : new Value[body.LocalVariables.Count], new Value[llvmParameters.Length]);

            PrintHeader(efo);
            foreach (var opcode in opcodes)
            {
                if (EmitFunctions.ContainsKey(opcode.Opcode) == false)
                    throw new CudaSharpException("Unsupported CIL instruction " + opcode.Opcode);
                var func = EmitFunctions[opcode.Opcode];
                efo.Argument = opcode.Parameter;
                func(efo);
            }

            return function;
        }
Ejemplo n.º 2
0
        private static Function EmitFunction(Context context, Module module, MethodInfo method)
        {
            var funcType = new FunctionType(ConvertType(context, method.ReturnType), AnalyzeArguments(context, method.GetParameters()));

            var intrinsic = method.GetCustomAttribute<Gpu.BuiltinAttribute>();
            if (intrinsic != null)
            {
                var name = intrinsic.Intrinsic;
                var preExisting = module.GetFunction(name);
                if (preExisting != null)
                    return preExisting;
                return module.CreateFunction(name, funcType);
            }

            var function = module.CreateFunction(method.Name, funcType);

            var block = new Block("entry", context, function);
            var writer = new InstructionBuilder(context, block);

            var opcodes = method.Decompile().ToList();
            FindBranchTargets(opcodes, context, function);

            var body = method.GetMethodBody();
            var efo = new EmitFuncObj(context, module, function, writer, null, new Stack<Value>(),
                body == null ? null : new Value[body.LocalVariables.Count], new Value[method.GetParameters().Length]);

            foreach (var opcode in opcodes)
            {
                if (EmitFunctions.ContainsKey(opcode.Opcode) == false)
                    throw new Exception("Unsupported CIL instruction " + opcode.Opcode);
                var func = EmitFunctions[opcode.Opcode];
                efo.Argument = opcode.Parameter;
                func(efo);
            }

            return function;
        }