public static Module Translate(Context context, params MethodInfo[] methods)
        {
            var module = new Module("Module", context);

            if (Environment.Is64BitOperatingSystem)
            {
                PInvoke.LLVMSetTarget(module, "nvptx64-nvidia-cuda");
                PInvoke.LLVMSetDataLayout(module, "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64");
            }
            else
            {
                PInvoke.LLVMSetTarget(module, "nvptx-nvidia-cuda");
                PInvoke.LLVMSetDataLayout(module, "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64");
            }

            foreach (var method in methods)
                Translate(context, module, method);
            return module;
        }
Exemple #2
0
 public Module(string name)
     : base(LLVM.ModuleCreateWithName(name))
 {
     _ctx = null;
 }
Exemple #3
0
 public static StructType Get(Context ctx, string name, Type[] types, bool packed = false)
 {
     StructType ty = StructType.Get(ctx, name);
     ty.SetBody(types, packed);
     return ty;
 }
Exemple #4
0
 public static StructType Get(Context ctx, string name)
 {
     StructType ty = new StructType(LLVM.StructCreateNamed(ctx, name));
     return ty;
 }
Exemple #5
0
        private static void FindBranchTargets(IList<OpCodeInstruction> opCodes, Context context, Function function)
        {
            for (var i = 0; i < opCodes.Count; i++)
            {
                var op = opCodes[i];
                var opcode = op.Opcode;
                switch (opcode.FlowControl)
                {
                    case FlowControl.Branch:
                    case FlowControl.Cond_Branch:
                        break;
                    default:
                        continue;
                }

                var target = Convert.ToInt32(op.Parameter);
                target += (int)opCodes[i + 1].InstructionStart;

                var insert = 0;
                while (opCodes[insert].InstructionStart != target)
                    insert++;

                var contBlock = opcode.FlowControl == FlowControl.Cond_Branch ? new Block("", context, function) : null;
                Block block;
                if (opCodes[insert].Opcode == OpCodes.Nop && opCodes[insert].Parameter != null)
                    block = (Block)opCodes[insert].Parameter;
                else
                {
                    opCodes.Insert(insert, new OpCodeInstruction(target, OpCodes.Nop, block = new Block("", context, function)));
                    if (insert < i)
                        i++;
                }
                opCodes[i] = new OpCodeInstruction(op.InstructionStart, op.Opcode, contBlock == null ? (object)block : Tuple.Create(contBlock, block));
            }
        }
        public static void Translate(Context context, Module module, MethodInfo method)
        {
            var function = EmitFunction(context, module, method);

            var metadataArgs = new[]
            {
                function, PInvoke.LLVMMDStringInContext(context, method.Name),
                IntegerType.GetInt32(context).Constant(1, true)
            };
            var metadata = PInvoke.LLVMMDNodeInContext(context, metadataArgs);
            PInvoke.LLVMAddNamedMetadataOperand(module, "nvvm.annotations", metadata);
        }
 public EmitFuncObj(Context context, Module module, Function function, InstructionBuilder instructionBuilder, object argument, Stack<Value> stack, Value[] locals, Value[] parameters)
 {
     Context = context;
     Module = module;
     Function = function;
     Builder = instructionBuilder;
     Argument = argument;
     Stack = stack;
     Locals = locals;
     Parameters = parameters;
 }
        private static Type ConvertType(Context context, System.Type type)
        {
            if (type == typeof(void))
                return Type.GetVoid(context);
            if (type == typeof(bool))
                return IntegerType.Get(context, 1);
            if (type == typeof(byte))
                return IntegerType.Get(context, 8);
            if (type == typeof(short))
                return IntegerType.Get(context, 16);
            if (type == typeof(int))
                return IntegerType.GetInt32(context);
            if (type == typeof(long))
                return IntegerType.Get(context, 64);
            if (type == typeof(float))
                return FloatType.Get(context, 32);
            if (type == typeof(double))
                return FloatType.Get(context, 64);
            if (type.IsArray)
                return PointerType.Get(ConvertType(context, type.GetElementType()), 1);

            throw new Exception("Type cannot be translated to CUDA: " + type.FullName);
        }
 private static Type[] AnalyzeArguments(Context context, IEnumerable<ParameterInfo> parameters)
 {
     return parameters.Select(p => ConvertType(context, p.ParameterType)).ToArray();
 }
        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;
        }