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; }
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; }