コード例 #1
0
        protected override ExprAST VisitPrototypeAST(PrototypeAST node)
        {
            // Make the function type:  double(double,double) etc.
            var argumentCount = (uint)node.Arguments.Count;
            var arguments     = new LLVMTypeRef[Math.Max(argumentCount, 1)];

            var function = LLVM.GetNamedFunction(this.module, node.Name);

            // If F conflicted, there was already something named 'Name'.  If it has a
            // body, don't allow redefinition or reextern.
            if (function.Pointer != IntPtr.Zero)
            {
                // If F already has a body, reject this.
                if (LLVM.CountBasicBlocks(function) != 0)
                {
                    throw new Exception("redefinition of function.");
                }

                // If F took a different number of args, reject.
                if (LLVM.CountParams(function) != argumentCount)
                {
                    throw new Exception("redefinition of function with different # args");
                }
            }
            else
            {
                for (int i = 0; i < argumentCount; ++i)
                {
                    arguments[i] = LLVM.DoubleType();
                }

                function = LLVM.AddFunction(this.module, node.Name, LLVM.FunctionType(LLVM.DoubleType(), arguments, LLVMBoolFalse));
                LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage);
            }

            for (int i = 0; i < argumentCount; ++i)
            {
                var argumentName = node.Arguments[i];

                LLVMValueRef param = LLVM.GetParam(function, (uint)i);
                LLVM.SetValueName(param, argumentName);

                this.namedValues[argumentName] = param;
            }

            this.valueStack.Push(function);
            return(node);
        }
コード例 #2
0
        private void EmitNativeMain()
        {
            LLVMValueRef shadowStackTop = LLVM.GetNamedGlobal(Module, "t_pShadowStackTop");

            LLVMBuilderRef builder        = LLVM.CreateBuilder();
            var            mainSignature  = LLVM.FunctionType(LLVM.Int32Type(), new LLVMTypeRef[] { LLVM.Int32Type(), LLVM.PointerType(LLVM.Int8Type(), 0) }, false);
            var            mainFunc       = LLVM.AddFunction(Module, "__managed__Main", mainSignature);
            var            mainEntryBlock = LLVM.AppendBasicBlock(mainFunc, "entry");

            LLVM.PositionBuilderAtEnd(builder, mainEntryBlock);
            LLVMValueRef managedMain = LLVM.GetNamedFunction(Module, "StartupCodeMain");

            if (managedMain.Pointer == IntPtr.Zero)
            {
                throw new Exception("Main not found");
            }

            LLVMTypeRef  reversePInvokeFrameType = LLVM.StructType(new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int8Type(), 0), LLVM.PointerType(LLVM.Int8Type(), 0) }, false);
            LLVMValueRef reversePinvokeFrame     = LLVM.BuildAlloca(builder, reversePInvokeFrameType, "ReversePInvokeFrame");
            LLVMValueRef RhpReversePInvoke2      = LLVM.GetNamedFunction(Module, "RhpReversePInvoke2");

            if (RhpReversePInvoke2.Pointer == IntPtr.Zero)
            {
                RhpReversePInvoke2 = LLVM.AddFunction(Module, "RhpReversePInvoke2", LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] { LLVM.PointerType(reversePInvokeFrameType, 0) }, false));
            }

            LLVM.BuildCall(builder, RhpReversePInvoke2, new LLVMValueRef[] { reversePinvokeFrame }, "");

            var shadowStack     = LLVM.BuildMalloc(builder, LLVM.ArrayType(LLVM.Int8Type(), 1000000), String.Empty);
            var castShadowStack = LLVM.BuildPointerCast(builder, shadowStack, LLVM.PointerType(LLVM.Int8Type(), 0), String.Empty);

            LLVM.BuildStore(builder, castShadowStack, shadowStackTop);

            // Pass on main arguments
            LLVMValueRef argc = LLVM.GetParam(mainFunc, 0);
            LLVMValueRef argv = LLVM.GetParam(mainFunc, 1);

            LLVMValueRef mainReturn = LLVM.BuildCall(builder, managedMain, new LLVMValueRef[]
            {
                castShadowStack,
                argc,
                argv,
            },
                                                     "returnValue");

            LLVM.BuildRet(builder, mainReturn);
            LLVM.SetLinkage(mainFunc, LLVMLinkage.LLVMExternalLinkage);
        }
コード例 #3
0
ファイル: CudaModule.cs プロジェクト: anthrax3/Flame
        private static LLVMValueRef ReadSReg(string name, IRBuilder builder, LLVMModuleRef module)
        {
            var fName = "llvm.nvvm.read.ptx.sreg." + name;
            var fun   = LLVM.GetNamedFunction(module, name);

            if (fun.Pointer == IntPtr.Zero)
            {
                fun = LLVM.AddFunction(
                    module,
                    fName,
                    LLVM.FunctionType(
                        LLVM.Int32TypeInContext(LLVM.GetModuleContext(module)),
                        EmptyArray <LLVMTypeRef> .Value,
                        false));
            }
            return(builder.CreateCall(fun, EmptyArray <LLVMValueRef> .Value, ""));
        }
コード例 #4
0
        /// <summary>
        /// Creates the declaration for a method.
        /// </summary>
        /// <param name="methodDef">The method definition.</param>
        public void CreateDeclaration(MethodDefinition methodDef)
        {
            string methodName = NameHelper.CreateMethodName(methodDef);
            int    paramCount = methodDef.Parameters.Count;

            // CIL runtime method?
            if (methodDef.IsRuntime && !mRuntimeCompiler.MustHandleMethod(methodDef))
            {
                return;
            }

            // If we expect an instance reference as first argument, then we need to make sure our for loop has an offset.
            int offset = 0;

            if (methodDef.HasThis)
            {
                paramCount++;
                offset = 1;
            }

            // Fill in arguments.
            TypeRef[] argTypes = new TypeRef[paramCount];
            for (int i = offset; i < paramCount; i++)
            {
                TypeReference type = methodDef.Parameters[i - offset].ParameterType;
                argTypes[i] = TypeHelper.GetTypeRefFromType(type);
            }

            // If needed, fill in the instance reference.
            if (methodDef.HasThis)
            {
                argTypes[0] = TypeHelper.GetTypeRefFromType(methodDef.DeclaringType);

                // We need to pass the valuetype as a pointer because we need to modify its contents in the constructor.
                if (methodDef.DeclaringType.IsValueType)
                {
                    argTypes[0] = LLVM.PointerType(argTypes[0], 0);
                }
            }

            // Create LLVM function type and add function to the lookup table.
            TypeRef  functionType = LLVM.FunctionType(TypeHelper.GetTypeRefFromType(methodDef.ReturnType), argTypes, false);
            ValueRef function     = LLVM.AddFunction(mCompiler.Module, methodName, functionType);

            mCompiler.Lookup.AddFunction(methodName, function);
        }
コード例 #5
0
        /// <summary>
        /// Compiles the init cctors method.
        /// </summary>
        private void compileInitCctorsMethod()
        {
            TypeRef    type    = LLVM.FunctionType(TypeHelper.Void, new TypeRef[0], false);
            ValueRef   func    = LLVM.AddFunction(Module, "initCctors", type);
            BuilderRef builder = LLVM.CreateBuilderInContext(ModuleContext);

            LLVM.PositionBuilderAtEnd(builder, LLVM.AppendBasicBlockInContext(ModuleContext, func, string.Empty));

            MethodDefinition[] cctors = Lookup.GetStaticConstructors();
            foreach (MethodDefinition method in cctors)
            {
                LLVM.BuildCall(builder, Lookup.GetFunction(NameHelper.CreateMethodName(method)).Value, new ValueRef[0], string.Empty);
            }

            LLVM.BuildRetVoid(builder);

            LLVM.DisposeBuilder(builder);
        }
コード例 #6
0
ファイル: LLVMCodeGenerator.cs プロジェクト: shravanrn/Cleps
        public IMethodRegister CreateMethod(string className, bool isStatic, ClepsType functionType, string functionName)
        {
            string            fullFunctionName  = className + "." + functionName;
            FunctionClepsType functionClepsType = functionType as FunctionClepsType;
            LLVMTypeRef       returnLLVMType    = GetLLVMType(functionClepsType.ReturnType);

            LLVMTypeRef[] parameterLLVMTypes = functionClepsType.ParameterTypes.Select(c => GetLLVMType(c)).ToArray();

            LLVMTypeRef       functionLLVMType = LLVM.FunctionType(returnLLVMType, parameterLLVMTypes, false /* var args */);
            LLVMValueRef      functionRef      = LLVM.AddFunction(Module, fullFunctionName, functionLLVMType);
            LLVMBasicBlockRef block            = LLVM.AppendBasicBlockInContext(Context, functionRef, "entry");

            LLVM.PositionBuilderAtEnd(Builder, block);

            var ret = new LLVMMethod(block);

            return(ret);
        }
コード例 #7
0
        public void FunctionPrototype(Stmt.FunctionDeclaration func)
        {
            uint argc = (uint)func.Parameters.Count;
            var  argv = new LLVMTypeRef[argc];

            var function = LLVM.GetNamedFunction(_module, func.Identifier.Source);

            if (function.Pointer != IntPtr.Zero)
            {
                if (LLVM.CountBasicBlocks(function) != 0)
                {
                    throw new Exception("redefinition of function.");
                }

                if (LLVM.CountParams(function) != argc)
                {
                    throw new Exception("redefinition of function with different # args");
                }
            }
            else
            {
                for (int i = 0; i < argc; i++)
                {
                    argv[i] = GetParameterType(func.Parameters[i].Type);
                }

                function = LLVM.AddFunction(_module, func.Identifier.Source, LLVM.FunctionType(GetParameterType(func.ReturnType), argv, false));
                LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage);
            }

            for (int i = 0; i < argc; i++)
            {
                string argName = func.Parameters[i].Identifier;

                LLVMValueRef param = LLVM.GetParam(function, (uint)i);
                LLVM.SetValueName(param, argName);

                //_namedValues[argName] = new LLVMSymbol { Binding = null, IsFunction = false, KtsType = stmt.Parameters[i].Type, Value = param };
            }

            _functions.Add(func.Identifier.Source, new FunctionSymbol {
                ReturnType = func.ReturnType, Parameters = func.Parameters
            });
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: kaby76/swigged.llvm
        static void Main(string[] args)
        {
            Swigged.LLVM.Helper.Adjust.Path();
            LLVM.InitializeAllTargets();
            LLVM.InitializeAllTargetMCs();
            LLVM.InitializeAllTargetInfos();
            LLVM.InitializeAllAsmPrinters();

            ModuleRef mod = LLVM.ModuleCreateWithName("LLVMSharpIntro");

            TypeRef[]     param_types = { LLVM.Int32Type(), LLVM.Int32Type() };
            TypeRef       ret_type    = LLVM.FunctionType(LLVM.Int32Type(), param_types, false);
            ValueRef      sum         = LLVM.AddFunction(mod, "sum", ret_type);
            BasicBlockRef entry       = LLVM.AppendBasicBlock(sum, "entry");
            BuilderRef    builder     = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder, entry);
            ValueRef tmp = LLVM.BuildAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp");

            LLVM.BuildRet(builder, tmp);
            MyString the_error = new MyString();

            LLVM.VerifyModule(mod, VerifierFailureAction.AbortProcessAction, the_error);
            //LLVM.DisposeMessage(error);
            ExecutionEngineRef   engine;
            MCJITCompilerOptions options = new MCJITCompilerOptions();
            var optionsSize = (4 * sizeof(int)) + IntPtr.Size; // LLVMMCJITCompilerOptions has 4 ints and a pointer

            LLVM.InitializeMCJITCompilerOptions(options, (uint)optionsSize);
            LLVM.CreateMCJITCompilerForModule(out engine, mod, options, (uint)optionsSize, the_error);
            var    ptr       = LLVM.GetPointerToGlobal(engine, sum);
            IntPtr p         = (IntPtr)ptr;
            Add    addMethod = (Add)Marshal.GetDelegateForFunctionPointer(p, typeof(Add));
            int    result    = addMethod(10, 10);

            Console.WriteLine("Result of sum is: " + result);
            if (LLVM.WriteBitcodeToFile(mod, "sum.bc") != 0)
            {
                Console.WriteLine("error writing bitcode to file, skipping");
            }
            LLVM.DumpModule(mod);
            LLVM.DisposeBuilder(builder);
            LLVM.DisposeExecutionEngine(engine);
        }
コード例 #9
0
        private void ImportRawPInvoke(MethodDesc method)
        {
            LLVMValueRef nativeFunc = LLVM.GetNamedFunction(Module, method.Name);

            // Create an import if we haven't already
            if (nativeFunc.Pointer == IntPtr.Zero)
            {
                // Set up native parameter types
                LLVMTypeRef[] paramTypes = new LLVMTypeRef[method.Signature.Length];
                for (int i = 0; i < paramTypes.Length; i++)
                {
                    paramTypes[i] = GetLLVMTypeForTypeDesc(method.Signature[i]);
                }

                // Define the full signature
                LLVMTypeRef nativeFuncType = LLVM.FunctionType(GetLLVMTypeForTypeDesc(method.Signature.ReturnType), paramTypes, LLVMMisc.False);

                nativeFunc = LLVM.AddFunction(Module, method.Name, nativeFuncType);
                LLVM.SetLinkage(nativeFunc, LLVMLinkage.LLVMDLLImportLinkage);
            }

            LLVMValueRef[] arguments = new LLVMValueRef[method.Signature.Length];
            for (int i = 0; i < arguments.Length; i++)
            {
                LLVMValueRef argValue = _stack.Pop().LLVMValue;

                // Arguments are reversed on the stack
                // Coerce pointers to the native type
                TypeDesc     signatureType = method.Signature[arguments.Length - i - 1];
                LLVMValueRef typedValue    = argValue;
                if (signatureType.IsPointer)
                {
                    LLVMTypeRef signatureLlvmType = GetLLVMTypeForTypeDesc(signatureType);
                    typedValue = LLVM.BuildPointerCast(_builder, argValue, signatureLlvmType, String.Empty);
                }
                arguments[arguments.Length - i - 1] = typedValue;
            }

            var returnValue = LLVM.BuildCall(_builder, nativeFunc, arguments, "call");

            // TODO: void returns
            PushExpression(GetStackValueKind(method.Signature.ReturnType), String.Empty, returnValue, method.Signature.ReturnType);
        }
コード例 #10
0
    // Init is the rule that defines our entire program.
    public VisitResult VisitInit([Antlr4.Runtime.Misc.NotNull] BFParser.InitContext context)
    {
        // Create our builder.
        builder = LLVM.CreateBuilder();

        // Define all the functions we need to make a BF program. This includes input, output, and memory management programs to get our initial block of memory.
        outputFunc = LLVM.AddFunction(mod, "putchar", LLVM.FunctionType(LLVM.Int32Type(), new LLVMTypeRef[] { LLVM.Int8Type() }, false));
        inputFunc  = LLVM.AddFunction(mod, "getchar", LLVM.FunctionType(LLVM.Int8Type(), new LLVMTypeRef[] {}, false));
        var malloc = LLVM.AddFunction(mod, "malloc", LLVM.FunctionType(LLVM.PointerType(LLVM.Int32Type(), 0), new LLVMTypeRef[] { LLVM.Int32Type() }, false));
        var memset = LLVM.AddFunction(mod, "memset", LLVM.FunctionType(LLVM.PointerType(LLVM.Int32Type(), 0), new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int32Type(), 0), LLVM.Int32Type(), LLVM.Int32Type() }, false));
        var free   = LLVM.AddFunction(mod, "free", LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int32Type(), 0) }, false));

        main = LLVM.AddFunction(mod, "main", LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] {}, false));

        // Start the entry point.
        var entry = LLVM.AppendBasicBlock(main, "entry");

        LLVM.PositionBuilderAtEnd(builder, entry);

        // Call malloc to get a void* (which is actually a int32*) that points to our program memory. We will just allocate a chunk to play with.
        basePtr = LLVM.BuildCall(builder, malloc, new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), memSize, false) }, "basePtr");

        // Set memory to 0 (otherwise BF would almost never work).
        LLVM.BuildCall(builder, memset, new LLVMValueRef[] { basePtr, LLVM.ConstInt(LLVM.Int32Type(), 0, true), LLVM.ConstInt(LLVM.Int32Type(), memSize, false) }, "callMemset");

        // Due to how LLVM works, once creating pointer we wouldn't be able to use it again. To counter this, we create a pointer to our pointer.
        ptr = LLVM.BuildAlloca(builder, LLVM.PointerType(LLVM.Int8Type(), 0), "ptr");

        // Cast our void* as a int8* and set our pointer value to it.
        SetValue(ptr, LLVM.BuildPointerCast(builder, basePtr, LLVM.PointerType(LLVM.Int8Type(), 0), "tempPtr"));

        // This is where we actually start adding our program instructions.
        for (int i = 0; i < context.ChildCount; i++)
        {
            context.GetChild(i).Accept(visitor);
        }

        // Free our malloc'd memory and return nothing.
        LLVM.BuildFree(builder, basePtr);
        LLVM.BuildRetVoid(builder);
        return(null);
    }
コード例 #11
0
        /// <summary>
        /// Initializes runtime functions.
        /// </summary>
        /// <param name="module">The module.</param>
        public static void ImportFunctions(ModuleRef module)
        {
            // Newarr.
            TypeRef newarrType = LLVM.FunctionType(TypeHelper.VoidPtr, new TypeRef[] { TypeHelper.Int32, TypeHelper.NativeIntType }, false);

            Newarr = LLVM.AddFunction(module, "newarr", newarrType);
            LLVM.SetLinkage(Newarr, Linkage.ExternalLinkage);

            // Memcpy.
            TypeRef memcpyType = LLVM.FunctionType(TypeHelper.VoidPtr, new TypeRef[] { TypeHelper.VoidPtr, TypeHelper.VoidPtr, TypeHelper.NativeIntType }, false);

            Memcpy = LLVM.AddFunction(module, "memcpy", memcpyType);
            LLVM.SetLinkage(Memcpy, Linkage.ExternalLinkage);

            // Memcpy.
            TypeRef memsetType = LLVM.FunctionType(TypeHelper.VoidPtr, new TypeRef[] { TypeHelper.VoidPtr, TypeHelper.Int32, TypeHelper.NativeIntType }, false);

            Memset = LLVM.AddFunction(module, "memset", memsetType);
            LLVM.SetLinkage(Memset, Linkage.ExternalLinkage);
        }
コード例 #12
0
ファイル: Function.cs プロジェクト: ronthecookie/Ion
        public LLVMValueRef Emit(LLVMModuleRef context)
        {
            // Ensure body was provided or created.
            if (Body == null)
            {
                throw new Exception("Unexpected function body to be null");
            }
            // Ensure prototype is set.
            else if (Prototype == null)
            {
                throw new Exception("Unexpected function prototype to be null");
            }

            // Emit the argument types.
            var args = Prototype.Args.Emit();

            // Emit the return type
            LLVMTypeRef returnType = Prototype.ReturnType.Emit();

            // Emit the function type.
            LLVMTypeRef type = LLVM.FunctionType(returnType, args, Prototype.Args.Continuous);

            // Create the function.
            LLVMValueRef function = LLVM.AddFunction(context, Prototype.Name, type);

            // Apply the body.
            Body.Emit(function);

            // Ensures the function does not already exist
            if (SymbolTable.functions.ContainsKey(Prototype.Name))
            {
                throw new Exception($@"Function with that name ""{Prototype.Name}"" already exists.");
            }
            else
            {
                // Register the function in the symbol table.
                SymbolTable.functions.Add(Prototype.Name, function);
            }

            return(function);
        }
コード例 #13
0
ファイル: CompilerDriver.cs プロジェクト: vishruth/Cleps
        private void AddEntryPoint(ClassManager classManager, CompileStatus status, LLVMContextRef context, LLVMModuleRef module, LLVMBuilderRef builder)
        {
            LLVMTypeRef       functionType  = LLVM.FunctionType(LLVM.Int32TypeInContext(context), new LLVMTypeRef[] { }, false);
            LLVMValueRef      functionValue = LLVM.AddFunction(module, "main", functionType);
            LLVMBasicBlockRef blockValue    = LLVM.AppendBasicBlockInContext(context, functionValue, "entry");

            LLVM.PositionBuilderAtEnd(builder, blockValue);

            LLVMValueRef intRet = LLVM.ConstInt(LLVM.Int32Type(), 0, false);

            if (classManager.MainFunctionFullNames.Count < 1)
            {
                status.AddError(new CompilerError("", 0, 0, "No main functions found in the program"));
            }
            else if (classManager.MainFunctionFullNames.Count > 1)
            {
                status.AddError(new CompilerError("", 0, 0, "Multiple main functions found in the program: " + String.Join(",", classManager.MainFunctionFullNames)));
            }
            else
            {
                LLVMValueRef functionToCall        = LLVM.GetNamedFunction(module, classManager.MainFunctionFullNames.First());
                LLVMValueRef intOrIntMappedTypeRet = LLVM.BuildCall(builder, functionToCall, new LLVMValueRef[0], "entryPointCall");
                LLVMTypeRef  returnType            = LLVM.TypeOf(intOrIntMappedTypeRet);

                if (returnType.TypeKind == LLVMTypeKind.LLVMIntegerTypeKind && returnType.GetIntTypeWidth() == 32)
                {
                    intRet = intOrIntMappedTypeRet;
                }
                else
                {
                    LLVMValueRef intMappedTypeRetPtr = LLVM.BuildAlloca(builder, LLVM.TypeOf(intOrIntMappedTypeRet), "intMappedType");
                    LLVM.BuildStore(builder, intOrIntMappedTypeRet, intMappedTypeRetPtr);
                    //Extract the first field to get the int value from the mapped type
                    //See rawtypemap for more details
                    LLVMValueRef fieldPtr = LLVM.BuildStructGEP(builder, intMappedTypeRetPtr, 0, "returnIntFieldPtr");
                    intRet = LLVM.BuildLoad(builder, fieldPtr, "returnValue");
                }
            }

            LLVM.BuildRet(builder, intRet);
        }
コード例 #14
0
        public void Visit(AST.Module module)
        {
            moduleLLVM = LLVM.ModuleCreateWithName(module.Name);
            var triple = Marshal.PtrToStringAnsi(LLVM.GetDefaultTargetTriple());

            LLVM.SetTarget(moduleLLVM, triple);

            builtIns = new BuiltInsLLVM(builder, moduleLLVM);

            mainFuncLLVM = LLVM.AddFunction(moduleLLVM, "main", LLVM.FunctionType(LLVM.Int32Type(), new LLVMTypeRef[] { }, false));

            var varBlock  = LLVM.AppendBasicBlock(mainFuncLLVM, "var");
            var codeBlock = LLVM.AppendBasicBlock(mainFuncLLVM, "begin");

            varBlocks.Push(varBlock);
            codeBlocks.Push(codeBlock);

            foreach (var statement in module.Statements)
            {
                statement.Accept(this);
                if (returns)
                {
                    break;
                }
            }
            LLVM.PositionBuilderAtEnd(builder, varBlock);
            LLVM.BuildBr(builder, codeBlock);

            if (!returns)
            {
                LLVM.PositionBuilderAtEnd(builder, codeBlocks.Peek());
                LLVM.BuildRet(builder, LLVM.ConstInt(LLVM.Int32Type(), 0, false));
            }

            codeBlocks.Pop();
            varBlocks.Pop();

            LLVM.WriteBitcodeToFile(moduleLLVM, $"{module.Name}.bc");
            LLVM.PrintModuleToFile(moduleLLVM, $"{module.Name}.ll", out var _);
        }
コード例 #15
0
        /// <summary>
        /// Declares a method.
        /// </summary>
        /// <param name="methodDef">The CIL method definition</param>
        /// <returns>The LLVM value reference</returns>
        public LLVMValueRef DeclareMethod(MethodDefinition methodDef)
        {
            int offset = methodDef.HasThis ? 1 : 0;

            var paramTypes = new LLVMTypeRef[methodDef.Parameters.Count + offset];

            for (int i = 0; i < paramTypes.Length - offset; ++i)
            {
                paramTypes[i + offset] = typeLookup.GetLLVMTypeRef(methodDef.Parameters[i].ParameterType);
            }

            if (methodDef.HasThis)
            {
                paramTypes[0] = typeLookup.GetLLVMTypeRef(methodDef.DeclaringType);
                if (methodDef.DeclaringType.IsValueType)
                {
                    paramTypes[0] = LLVM.PointerType(paramTypes[0], 0);
                }
            }

            var fnType = LLVM.FunctionType(
                typeLookup.GetLLVMTypeRef(methodDef.MethodReturnType.ReturnType),
                paramTypes,
                false
                );

            var valueRef = LLVM.AddFunction(moduleRef, methodDef.FullName, fnType);

            methodMap.Add(methodDef.FullName, valueRef);

            if (methodDef.IsConstructor && methodDef.IsStatic)
            {
                LLVM.SetLinkage(valueRef, LLVMLinkage.LLVMInternalLinkage);
                LLVM.BuildCall(cctorCallBuilder, valueRef, new LLVMValueRef[0], string.Empty);
            }

            return(valueRef);
        }
コード例 #16
0
        private void createSystemObjectCtor()
        {
            var paramTypes = new LLVMTypeRef[] { LLVM.PointerType(LLVM.VoidType(), 0) };
            var fnType     = LLVM.FunctionType(LLVM.VoidType(), paramTypes, false);
            var valueRef   = LLVM.AddFunction(moduleRef, string.Empty, fnType);

            // TODO: maybe put this somewhere else?
            // TODO: this is somewhat a workaround?

            /*var asmDef = AssemblyDefinition.ReadAssembly(typeof(object).Assembly.Location);
             * var sysObj = asmDef.MainModule.GetTypes().Where(typeDef => typeDef.FullName == "System.Object").Single();
             * var methodDef = sysObj.Methods.Where(methodDef => methodDef.Name == ".ctor").Single();
             * System.Console.WriteLine(methodDef);
             * methodMap.Add(methodDef., valueRef);*/
            methodMap.Add("System.Void System.Object::.ctor()", valueRef);

            var builder = LLVM.CreateBuilder();
            var block   = LLVM.AppendBasicBlock(valueRef, string.Empty);

            LLVM.PositionBuilderAtEnd(builder, block);
            LLVM.BuildRetVoid(builder);
            LLVM.DisposeBuilder(builder);
        }
コード例 #17
0
        private void EmitNativeMain()
        {
            LLVMBuilderRef builder        = LLVM.CreateBuilder();
            var            mainSignature  = LLVM.FunctionType(LLVM.Int32Type(), new LLVMTypeRef[0], false);
            var            mainFunc       = LLVM.AddFunction(Module, "main", mainSignature);
            var            mainEntryBlock = LLVM.AppendBasicBlock(mainFunc, "entry");

            LLVM.PositionBuilderAtEnd(builder, mainEntryBlock);
            LLVMValueRef managedMain = LLVM.GetNamedFunction(Module, "Main");

            var shadowStack     = LLVM.BuildMalloc(builder, LLVM.ArrayType(LLVM.Int8Type(), 1000000), String.Empty);
            var castShadowStack = LLVM.BuildPointerCast(builder, shadowStack, LLVM.PointerType(LLVM.Int8Type(), 0), String.Empty);

            LLVM.BuildCall(builder, managedMain, new LLVMValueRef[]
            {
                castShadowStack,
                LLVM.ConstPointerNull(LLVM.PointerType(LLVM.Int8Type(), 0))
            },
                           String.Empty);

            LLVM.BuildRet(builder, LLVM.ConstInt(LLVM.Int32Type(), 42, LLVMMisc.False));
            LLVM.SetLinkage(mainFunc, LLVMLinkage.LLVMExternalLinkage);
        }
コード例 #18
0
ファイル: Extern.cs プロジェクト: ronthecookie/Ion
        public LLVMValueRef Emit(LLVMModuleRef context)
        {
            // Ensure prototype is set.
            if (Prototype == null)
            {
                throw new Exception("Unexpected external definition's prototype to be null");
            }

            // Emit the formal arguments.
            var args = Prototype.Args.Emit();

            // Emit the return type.
            LLVMTypeRef returnType = Prototype.ReturnType.Emit();

            // Emit the function type.
            LLVMTypeRef type = LLVM.FunctionType(returnType, args, Prototype.Args.Continuous);

            // Emit the external definition to context and capture the LLVM value reference.
            LLVMValueRef external = LLVM.AddFunction(context, Prototype.Name, type);

            // Return the resulting LLVM value reference.
            return(external);
        }
コード例 #19
0
        public LLVMValueRef Emit(PipeContext <Module> context)
        {
            // Ensure prototype is set.
            if (this.Prototype == null)
            {
                throw new Exception("Unexpected external definition's prototype to be null");
            }

            // Emit the formal arguments.
            LLVMTypeRef[] args = this.Prototype.Args.Emit(context);

            // Emit the return type.
            LLVMTypeRef returnType = this.Prototype.ReturnType.Emit();

            // Emit the function type.
            LLVMTypeRef type = LLVM.FunctionType(returnType, args, this.Prototype.Args.Continuous);

            // Emit the external definition to context and capture the LLVM value reference.
            LLVMValueRef external = LLVM.AddFunction(context.Target.Target, this.Prototype.Identifier, type);

            // Determine if should be registered on the symbol table.
            if (!context.SymbolTable.functions.Contains(this.Prototype.Identifier))
            {
                // Register the external definition as a function in the symbol table.
                context.SymbolTable.functions.Add(new FunctionSymbol(this.Prototype.Identifier, external, this.Prototype.Args.Continuous));
            }
            // Otherwise, issue a warning.
            else
            {
                // TODO
                System.Console.WriteLine($"Warning: Extern definition '{this.Prototype.Identifier}' being re-defined");
            }

            // Return the resulting LLVM value reference.
            return(external);
        }
コード例 #20
0
ファイル: UnitTest1.cs プロジェクト: kaby76/swigged.llvm
        public void TestMultiModules()
        {
            LLVM.InitializeAllTargets();
            LLVM.InitializeAllTargetMCs();
            LLVM.InitializeAllTargetInfos();
            LLVM.InitializeAllAsmPrinters();

            // First module contains add.
            ModuleRef mod1 = LLVM.ModuleCreateWithName("LLVMSharpIntro");

            TypeRef[]     param_types1 = { LLVM.Int32Type(), LLVM.Int32Type() };
            TypeRef       ret_type1    = LLVM.FunctionType(LLVM.Int32Type(), param_types1, false);
            ValueRef      add          = LLVM.AddFunction(mod1, "add", ret_type1);
            BasicBlockRef entry1       = LLVM.AppendBasicBlock(add, "entry");
            BuilderRef    builder1     = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder1, entry1);
            ValueRef tmp1 = LLVM.BuildAdd(builder1, LLVM.GetParam(add, 0), LLVM.GetParam(add, 1), "tmp");

            LLVM.BuildRet(builder1, tmp1);
            MyString the_error = new MyString();

            LLVM.VerifyModule(mod1, VerifierFailureAction.PrintMessageAction, the_error);
            LLVM.DumpModule(mod1);

            // Second module contains sub.
            ModuleRef mod2 = LLVM.ModuleCreateWithName("LLVMSharpIntro");

            TypeRef[]     param_types2 = { LLVM.Int32Type(), LLVM.Int32Type() };
            TypeRef       ret_type2    = LLVM.FunctionType(LLVM.Int32Type(), param_types2, false);
            ValueRef      sub          = LLVM.AddFunction(mod2, "sub", ret_type2);
            BasicBlockRef entry2       = LLVM.AppendBasicBlock(sub, "entry");
            BuilderRef    builder2     = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder2, entry2);
            ValueRef tmp2 = LLVM.BuildSub(builder2, LLVM.GetParam(sub, 0), LLVM.GetParam(sub, 1), "tmp");

            LLVM.BuildRet(builder2, tmp2);
            LLVM.VerifyModule(mod2, VerifierFailureAction.PrintMessageAction, the_error);
            LLVM.DumpModule(mod2);

            // Third module contains uses of add and sub.
            ModuleRef mod3 = LLVM.ModuleCreateWithName("LLVMSharpIntro");

            TypeRef[]     param_types3 = { };
            TypeRef       ret_type3    = LLVM.FunctionType(LLVM.Int32Type(), param_types3, false);
            ValueRef      comb         = LLVM.AddFunction(mod3, "comb", ret_type3);
            ValueRef      add1         = LLVM.AddFunction(mod3, "add", ret_type1);
            ValueRef      sub2         = LLVM.AddFunction(mod3, "sub", ret_type1);
            BasicBlockRef entry3       = LLVM.AppendBasicBlock(comb, "entry");
            BuilderRef    builder3     = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder3, entry3);
            ValueRef tmpa3 = LLVM.ConstInt(LLVM.Int32Type(), 1, false);
            ValueRef tmpb3 = LLVM.ConstInt(LLVM.Int32Type(), 2, false);
            ValueRef tmpc3 = LLVM.ConstInt(LLVM.Int32Type(), 3, false);
            var      tmpd3 = LLVM.BuildCall(builder3, add1, new ValueRef[] { tmpa3, tmpc3 }, "");
            var      tmpe3 = LLVM.BuildCall(builder3, sub2, new ValueRef[] { tmpd3, tmpb3 }, "");

            LLVM.BuildRet(builder3, tmpe3);

            LLVM.VerifyModule(mod3, VerifierFailureAction.PrintMessageAction, the_error);
            LLVM.DumpModule(mod3);

            //LLVM.DisposeMessage(error);
            TargetRef t2;
            string    tr2      = LLVM.GetDefaultTargetTriple();
            var       b        = LLVM.GetTargetFromTriple(tr2, out t2, the_error);
            string    triple   = "";
            string    cpu      = "";
            string    features = "";

            TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, tr2, cpu, features,
                                                            CodeGenOptLevel.CodeGenLevelDefault,
                                                            RelocMode.RelocDefault,
                                                            CodeModel.CodeModelDefault);

            OrcJITStackRef ojsr = LLVM.OrcCreateInstance(tmr);
            MyString       ms   = new MyString();

            LLVM.OrcGetMangledSymbol(ojsr, ms, "comb");
            IntPtr          ctx  = IntPtr.Zero;
            SharedModuleRef smr1 = LLVM.OrcMakeSharedModule(mod1);
            var             xx   = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh1, smr1, null, ctx);
            SharedModuleRef smr2 = LLVM.OrcMakeSharedModule(mod2);

            xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh2, smr2, null, ctx);
            SharedModuleRef smr3 = LLVM.OrcMakeSharedModule(mod3);

            xx = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh3, smr3, null, ctx);
            var  p          = LLVM.OrcGetSymbolAddress(ojsr, out IntPtr RetAddr, "comb");
            Comb combMethod = (Comb)Marshal.GetDelegateForFunctionPointer(RetAddr, typeof(Comb));
            int  result     = combMethod();

            Console.WriteLine("Result of comb is: " + result);
            if (result != 2)
            {
                throw new Exception();
            }
        }
コード例 #21
0
ファイル: Program.cs プロジェクト: tompinn23/NiLang
        private static void declareCFunctions()
        {
            LLVMTypeRef PutCharType = LLVMTypeRef.FunctionType(LLVM.Int32Type(), new LLVMTypeRef[] { LLVM.Int32Type() }, false);

            LLVM.AddFunction(module, "putchar", PutCharType);
        }
コード例 #22
0
        private void VisitStmt(Statement stmt, out bool terminate)
        {
            terminate = false;
            if (stmt == null)
            {
                return;
            }
            LoadTypes(stmt.ScopeSymbols);
            switch (stmt)
            {
            case FunctionDeclarationStmt fd:
            {
                break;
            }

            case FunctionStmt f:
            {
                FunctionSymbol funcSym   = f.Symbol;
                TypeSymbol     returnSym = funcSym.Signature.Return.Symbol;
                LLVMTypeRef    funcTy    = LLVM.FunctionType(
                    ReturnType: m_Types[returnSym],
                    ParamTypes: funcSym.Signature.Arguments.Select(arg => m_Types[arg.Type.Symbol]).ToArray(),
                    IsVarArg: false);
                m_Function = LLVM.AddFunction(m_Module, f.Declaration.Name, funcTy);
                m_FunctionPointers.Add(funcSym, m_Function);
                LLVMBasicBlockRef bb = LLVM.AppendBasicBlock(m_Function, "entry");
                LLVM.PositionBuilderAtEnd(m_Builder, bb);

                int paramIndex = 0;
                foreach (var param in m_Function.GetParams())
                {
                    LLVMValueRef ptrArg = LLVM.BuildAlloca(m_Builder, LLVM.TypeOf(param), "arg");
                    LLVM.BuildStore(m_Builder, param, ptrArg);
                    m_VariablePointers.Add(funcSym.Signature.Arguments[paramIndex].Symbol, ptrArg);
                    paramIndex++;
                }

                VisitStmt(f.Body, out bool term);

                if (!term)
                {
                    if (returnSym.IsPrimitive)
                    {
                        CPrimitiveType prim = returnSym.Primitive.Value;
                        if (prim == CPrimitiveType.Void)
                        {
                            LLVM.BuildRetVoid(m_Builder);
                        }
                        else
                        {
                            LLVM.BuildRet(m_Builder, m_PrimitiveLookup[prim].Default.Value);
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                break;
            }

            case BlockStmt block:
            {
                foreach (var childStmt in block.Statements)
                {
                    VisitStmt(childStmt, out bool term);
                    if (term)
                    {
                        terminate = true;
                        break;
                    }
                }
                break;
            }

            case VariableDeclarationStmt vd:
            {
                if (vd.Symbol.IsGlobal)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    LLVMValueRef ptr = LLVM.BuildAlloca(m_Builder, m_Types[vd.Type.Symbol], vd.Name);
                    m_VariablePointers.Add(vd.Symbol, ptr);
                    if (vd.Assignment != null)
                    {
                        LLVMValueRef value = VisitExpr(vd.Assignment);
                        LLVM.BuildStore(m_Builder, value, ptr);
                    }
                }
                break;
            }

            case IfStmt ifs:
            {
                LLVMValueRef i32  = VisitExpr(ifs.Condition);
                LLVMValueRef cond = I32ToCond(i32);

                LLVMBasicBlockRef bbTrue  = LLVM.AppendBasicBlock(m_Function, "if_true");
                LLVMBasicBlockRef bbFalse = LLVM.AppendBasicBlock(m_Function, "if_false");
                LLVMBasicBlockRef bbSucc  = LLVM.AppendBasicBlock(m_Function, "if_succ");

                LLVM.BuildCondBr(m_Builder, cond, bbTrue, bbFalse);

                LLVM.PositionBuilderAtEnd(m_Builder, bbTrue);
                VisitStmt(ifs.True, out bool termTrue);
                if (!termTrue)
                {
                    LLVM.BuildBr(m_Builder, bbSucc);
                }

                LLVM.PositionBuilderAtEnd(m_Builder, bbFalse);
                VisitStmt(ifs.False, out bool termFalse);
                if (!termFalse)
                {
                    LLVM.BuildBr(m_Builder, bbSucc);
                }

                LLVM.PositionBuilderAtEnd(m_Builder, bbSucc);
                break;
            }

            case ReturnStmt ret:
            {
                if (ret.Value == null)
                {
                    LLVM.BuildRetVoid(m_Builder);
                }
                else
                {
                    LLVMValueRef value = VisitExpr(ret.Value);
                    LLVM.BuildRet(m_Builder, value);
                }
                terminate = true;
                break;
            }

            case WhileStmt wh:
            {
                LLVMBasicBlockRef bbCond = LLVM.AppendBasicBlock(m_Function, "while_cond");
                LLVMBasicBlockRef bbBody = LLVM.AppendBasicBlock(m_Function, "while_body");
                LLVMBasicBlockRef bbSucc = LLVM.AppendBasicBlock(m_Function, "while_succ");
                m_BreakableStatementSuccessor.Add(wh, bbSucc);

                LLVM.BuildBr(m_Builder, bbCond);

                LLVM.PositionBuilderAtEnd(m_Builder, bbCond);
                LLVMValueRef i32  = VisitExpr(wh.Condition);
                LLVMValueRef cond = I32ToCond(i32);
                LLVM.BuildCondBr(m_Builder, cond, bbBody, bbSucc);

                LLVM.PositionBuilderAtEnd(m_Builder, bbBody);
                VisitStmt(wh.Body, out bool term);
                if (!term)
                {
                    LLVM.BuildBr(m_Builder, bbCond);
                }

                LLVM.PositionBuilderAtEnd(m_Builder, bbSucc);
                break;
            }

            case BreakStmt brk:
            {
                terminate = true;
                LLVM.BuildBr(m_Builder, m_BreakableStatementSuccessor[brk.Host]);
                break;
            }

            case ExpressionStmt exprStmt:
            {
                VisitExpr(exprStmt.Expression);
                break;
            }

            default:
            {
                throw new ArgumentException("Unrecognizable statement type.");
            }
            }
        }
コード例 #23
0
ファイル: Compiler.cs プロジェクト: SantiFdezM/SharpLang
        public ModuleRef CompileAssembly(AssemblyDefinition assembly)
        {
            this.assembly = assembly;
            corlib        = assembly.MainModule.Import(typeof(void)).Resolve().Module.Assembly;
            module        = LLVM.ModuleCreateWithName(assembly.Name.Name);

            allocObjectFunction = RuntimeInline.Runtime.define_allocObject(module);

            context       = LLVM.GetModuleContext(module);
            builder       = LLVM.CreateBuilderInContext(context);
            intPtrType    = LLVM.PointerType(LLVM.Int8TypeInContext(context), 0);
            int32Type     = LLVM.Int32TypeInContext(context);
            int64Type     = LLVM.Int64TypeInContext(context);
            intPtrSize    = 4;         // Or 8?
            nativeIntType = int32Type; // Or int64Type?
            builderPhi    = LLVM.CreateBuilderInContext(context);

            intPtr = GetType(corlib.MainModule.GetType(typeof(IntPtr).FullName));
            int32  = GetType(corlib.MainModule.GetType(typeof(int).FullName));
            int64  = GetType(corlib.MainModule.GetType(typeof(long).FullName));

            // struct IMTSlot { i8* functionPtr, i32 functionId, IMTEntry* nextEntry }
            imtEntryType = LLVM.StructCreateNamed(context, "IMTEntry");
            LLVM.StructSetBody(imtEntryType, new[] { intPtrType, int32Type, LLVM.PointerType(imtEntryType, 0) }, false);

            // Process types
            foreach (var assemblyModule in assembly.Modules)
            {
                var typeReferences = assemblyModule.GetTypeReferences();
                foreach (var type in typeReferences)
                {
                    CreateType(type);
                }

                var memberReferences = assemblyModule.GetMemberReferences();
                foreach (var member in memberReferences)
                {
                    var method = member as MethodReference;
                    if (member.DeclaringType.ContainsGenericParameter())
                    {
                        continue;
                    }
                    CreateType(member.DeclaringType);
                    if (method != null)
                    {
                        if (!method.HasGenericParameters)
                        {
                            CreateFunction(method);
                        }
                    }
                }

                foreach (var type in assemblyModule.Types)
                {
                    if (!type.HasGenericParameters && type.FullName != typeof(void).FullName)
                    {
                        GetClass(type);
                    }

                    foreach (var nestedType in type.NestedTypes)
                    {
                        if (!nestedType.HasGenericParameters)
                        {
                            GetClass(nestedType);
                        }
                    }
                }
            }

            // Process methods
            foreach (var @class in classes)
            {
                CompileClassMethods(@class.Value);
            }

            // Generate code
            while (methodsToCompile.Count > 0)
            {
                var methodToCompile = methodsToCompile.Dequeue();
                CompileFunction(methodToCompile.Key, methodToCompile.Value);
            }

            // Emit "main" which will call the assembly entry point (if any)
            Function entryPoint;

            if (assembly.EntryPoint != null && functions.TryGetValue(assembly.EntryPoint, out entryPoint))
            {
                var mainFunctionType = LLVM.FunctionType(int32Type, new TypeRef[0], false);
                var mainFunction     = LLVM.AddFunction(module, "main", mainFunctionType);
                LLVM.SetLinkage(mainFunction, Linkage.ExternalLinkage);
                LLVM.PositionBuilderAtEnd(builder, LLVM.AppendBasicBlockInContext(context, mainFunction, string.Empty));

                var parameters = (entryPoint.ParameterTypes.Length > 0)
                        ? new[] { LLVM.ConstPointerNull(entryPoint.ParameterTypes[0].DefaultType) }
                        : new ValueRef[0];

                LLVM.BuildCall(builder, entryPoint.GeneratedValue, parameters, string.Empty);
                LLVM.BuildRet(builder, LLVM.ConstInt(int32Type, 0, false));
            }

            LLVM.DisposeBuilder(builder);

            // Verify module
#if VERIFY_LLVM
            string message;
            if (LLVM.VerifyModule(module, VerifierFailureAction.PrintMessageAction, out message))
            {
                throw new InvalidOperationException(message);
            }
#endif

            return(module);
        }
コード例 #24
0
        public LLVMValueRef EmitMethodHeader(string pName, Syntax.MethodSyntax pMethod, out string pNewName)
        {
            //Get method return type
            LLVMTypeRef ret;

            if (pMethod.ReturnValues.Count == 0)
            {
                ret = LLVMTypeRef.VoidType();
            }
            else if (pMethod.ReturnValues.Count == 1)
            {
                ret = SmallTypeCache.GetLLVMType(pMethod.Type, this);
            }
            else
            {
                LLVMTypeRef[] types = new LLVMTypeRef[pMethod.ReturnValues.Count];
                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = SmallTypeCache.GetLLVMType(pMethod.ReturnValues[i].Type, this);
                }
                ret = LLVM.StructType(types, false);
                Cache.SetLLVMType(pMethod.Type.Name, ret);
            }

            //If we are emitting a struct method we need to add "self" as a parameter
            SmallType[]   originalTypes = new SmallType[pMethod.Parameters.Count];
            LLVMTypeRef[] parmTypes     = null;
            int           start         = 0;

            if (CurrentStruct != null)
            {
                parmTypes    = new LLVMTypeRef[pMethod.Parameters.Count + 1];
                parmTypes[0] = LLVMTypeRef.PointerType(SmallTypeCache.GetLLVMType(CurrentStruct, this), 0);
                start        = 1;
            }
            else
            {
                parmTypes = new LLVMTypeRef[pMethod.Parameters.Count];
            }

            //Get parameter types
            for (int i = 0; i < pMethod.Parameters.Count; i++)
            {
                var parmType = pMethod.Parameters[i].Type;
                if (parmType.IsGenericParameter)
                {
                    originalTypes[i] = TypeMappings[parmType.Name];
                }
                else
                {
                    originalTypes[i] = parmType;
                }

                //For calling external methods with strings, we only want to pass the character array
                if (pMethod.External && parmType == SmallTypeCache.String)
                {
                    parmType = parmType.GetElementType();
                }

                parmTypes[start + i] = SmallTypeCache.GetLLVMType(parmType, this);
                if (pMethod.Parameters[i].Type.IsStruct || pMethod.Parameters[i].Type.IsArray)
                {
                    parmTypes[start + i] = LLVMTypeRef.PointerType(parmTypes[start + i], 0);
                }
            }

            var result = Cache.FindMethod(out MethodDefinition pDefinition, null, CurrentStruct, pName, originalTypes);

            Debug.Assert(result == Compiler.FindResult.Found);
            pNewName = pDefinition.MangledName;

            //Method header
            var func = LLVM.GetNamedFunction(CurrentModule, pNewName);

            if (func.Pointer == IntPtr.Zero)
            {
                func = LLVM.AddFunction(CurrentModule, pNewName, LLVM.FunctionType(ret, parmTypes, false));
                LLVM.SetLinkage(func, LLVMLinkage.LLVMExternalLinkage);
            }

            if (pMethod.External)
            {
                //Create attribute so we can find it later when executing
                var attribute = LLVM.CreateStringAttribute(_context, "external", 8, pMethod.Annotation.Value, (uint)pMethod.Annotation.Value.Length);
                LLVM.AddAttributeAtIndex(func, LLVMAttributeIndex.LLVMAttributeFunctionIndex, attribute);
            }

            return(func);
        }
コード例 #25
0
        private unsafe static void Main(string[] args)
        {
            LLVMBool      Success = new LLVMBool(0);
            LLVMModuleRef mod     = LLVM.ModuleCreateWithName("LLVMSharpIntro");

            LLVMTypeRef[] param_types = { LLVM.Int32Type(), LLVM.Int32Type() };
            LLVMTypeRef   ret_type    = LLVM.FunctionType(LLVM.Int32Type(), param_types, false);
            LLVMValueRef  sum         = LLVM.AddFunction(mod, "sum", ret_type);

            LLVMBasicBlockRef entry = LLVM.AppendBasicBlock(sum, "entry");

            LLVMBuilderRef builder = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder, entry);
            LLVMValueRef tmp = LLVM.BuildAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp");

            LLVM.BuildRet(builder, tmp);
            LLVM.SetLinkage(sum, LLVMLinkage.LLVMExternalLinkage);
            LLVM.SetDLLStorageClass(sum, LLVMDLLStorageClass.LLVMDLLExportStorageClass);
            if (LLVM.VerifyModule(mod, LLVMVerifierFailureAction.LLVMPrintMessageAction, out var error) != Success)
            {
                Console.WriteLine($"Error: {error}");
            }
            //LLVM.LinkInMCJIT();

            LLVM.InitializeX86TargetMC();
            LLVM.InitializeX86Target();
            LLVM.InitializeX86TargetInfo();
            LLVM.InitializeX86AsmParser();
            LLVM.InitializeX86AsmPrinter();

            /*LLVMMCJITCompilerOptions options = new LLVMMCJITCompilerOptions { NoFramePointerElim = 1 };
             * LLVM.InitializeMCJITCompilerOptions(options);
             * if (LLVM.CreateMCJITCompilerForModule(out var engine, mod, options, out error) != Success)
             * {
             *  Console.WriteLine($"Error: {error}");
             * }
             *
             * var addMethod = (Add)Marshal.GetDelegateForFunctionPointer(LLVM.GetPointerToGlobal(engine, sum), typeof(Add));
             * int result = addMethod(10, 10);
             *
             * Console.WriteLine("Result of sum is: " + result);
             *
             * if (LLVM.WriteBitcodeToFile(mod, "sum.bc") != 0)
             * {
             *  Console.WriteLine("error writing bitcode to file, skipping");
             * }
             *
             * LLVM.DumpModule(mod);
             *
             * LLVM.DisposeBuilder(builder);
             * LLVM.DisposeExecutionEngine(engine);*/
            var aa = LLVM.GetLinkage(sum);

            LLVM.DumpModule(mod);
            if (LLVM.GetTargetFromTriple("x86_64-pc-win32", out var target, out error) == Success)
            {
                var targetMachine = LLVM.CreateTargetMachine(target, "x86_64-pc-win32", "generic", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault);
                var dl            = LLVM.CreateTargetDataLayout(targetMachine);
                LLVM.SetModuleDataLayout(mod, dl);
                LLVM.SetTarget(mod, "x86_64-pc-win32");
                byte[] buffer = System.Text.Encoding.Default.GetBytes("test.o\0");
                fixed(byte *ptr = buffer)
                {
                    LLVM.TargetMachineEmitToFile(targetMachine, mod, new IntPtr(ptr), LLVMCodeGenFileType.LLVMObjectFile, out error);
                }
            }
        }
コード例 #26
0
        private LLVMValueRef CreateLLVMFunction(string mangledName)
        {
            LLVMTypeRef universalSignature = LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int8Type(), 0), LLVM.PointerType(LLVM.Int8Type(), 0) }, false);

            return(LLVM.AddFunction(Module, mangledName, universalSignature));
        }
コード例 #27
0
ファイル: Visitor.Functions.cs プロジェクト: tompinn23/NiLang
        public PrototypeAST PrototypeASTVisit(PrototypeAST node)
        {
            var argumentCount = (uint)node.Args.Count;
            var arguments     = new LLVMTypeRef[Math.Max(argumentCount, 1)];

            var function = LLVM.GetNamedFunction(this.module, node.Name);

            if (function.Pointer != IntPtr.Zero)
            {
                if (LLVM.CountBasicBlocks(function) != 0)
                {
                    throw new Exception("Redefinition Of Function");
                }

                if (LLVM.CountParams(function) != argumentCount)
                {
                    throw new Exception("Redefinition of function with diff args num.");
                }
                return(node);
            }
            else
            {
                for (int i = 0; i < argumentCount; i++)
                {
                    switch (node.Args[i].Type)
                    {
                    case Type.Bool:
                        arguments[i] = LLVM.Int8Type();
                        break;

                    case Type.Double:
                        arguments[i] = LLVM.DoubleType();
                        break;

                    //Function Type Goes Here!!
                    case Type.Integer:
                        arguments[i] = LLVM.Int64Type();
                        break;

                    case Type.Void:
                        arguments[i] = LLVM.VoidType();
                        break;
                        //String type as well
                        //And the others. :)
                    }
                }
                LLVMTypeRef ret = LLVM.VoidType();
                switch (node.ReturnType)
                {
                case Type.Bool:
                    ret = LLVM.Int8Type();
                    break;

                case Type.Double:
                    ret = LLVM.DoubleType();
                    break;

                //Function Type Goes Here!!
                case Type.Integer:
                    ret = LLVM.Int64Type();
                    break;

                case Type.Void:
                    ret = LLVM.VoidType();
                    break;
                }
                function = LLVM.AddFunction(module, node.Name, LLVM.FunctionType(ret, arguments, LLVMBoolFalse));
                LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage);
                var funcEntry = LLVM.AppendBasicBlock(function, "entry");
                LLVM.PositionBuilderAtEnd(this.builder, funcEntry);

                for (int i = 0; i < argumentCount; i++)
                {
                    string       argumentName = node.Args[i].Name;
                    LLVMValueRef param        = LLVM.GetParam(function, (uint)i);
                    LLVM.SetValueName(param, argumentName);
                    LLVMValueRef Alloca = CreateEntryBlockAlloca(function, arguments[i], argumentName);
                    LLVM.BuildStore(builder, param, Alloca);
                    this.namedValues[argumentName] = Alloca;
                }
                this.valueStack.Push(function);
                return(node);
            }
        }
コード例 #28
0
ファイル: Compiler.Delegate.cs プロジェクト: uppi/SharpLang
        private ValueRef GenerateMulticastInvokeThunk(Class declaringClass)
        {
            // Reuse same signature as Invoke
            var delegateType = corlib.MainModule.GetType(typeof(Delegate).FullName);
            var invokeMethod = declaringClass.Functions.Single(x => x.MethodReference.Name == "Invoke");

            var invokeMethodHelper = LLVM.AddFunction(module, LLVM.GetValueName(invokeMethod.GeneratedValue) + "_MulticastHelper", invokeMethod.FunctionType);

            ApplyFunctionAttributes(invokeMethod.Signature, invokeMethodHelper);
            LLVM.SetLinkage(invokeMethodHelper, declaringClass.Type.Linkage);
            LLVM.PositionBuilderAtEnd(builder, LLVM.AppendBasicBlockInContext(context, invokeMethodHelper, string.Empty));

            var  invokeFunctionType = LLVM.GetElementType(LLVM.TypeOf(invokeMethodHelper));
            bool hasRetValue        = LLVM.GetReturnType(invokeFunctionType) != LLVM.VoidTypeInContext(context);
            var  delegateArrayType  = GetType(new ArrayType(delegateType), TypeState.TypeComplete);

            // Prepare basic blocks
            var forCodeBlock = LLVM.AppendBasicBlockInContext(context, invokeMethodHelper, string.Empty);
            var exitBlock    = LLVM.AppendBasicBlockInContext(context, invokeMethodHelper, string.Empty);

            var stack = new FunctionStack();

            // Load first argument and cast as Delegate[]
            var @this = LLVM.GetParam(invokeMethodHelper, 0);

            @this = LLVM.BuildPointerCast(builder, @this, delegateArrayType.DefaultTypeLLVM, string.Empty);

            // Create index (i = 0)
            var locals = new List <StackValue>();

            locals.Add(new StackValue(StackValueType.Int32, int32, LLVM.BuildAlloca(builder, int32.DefaultTypeLLVM, "i")));
            EmitI4(stack, 0);
            EmitStloc(stack, locals, 0);

            // length = invocationList.Length
            var delegateArray = new StackValue(StackValueType.Object, delegateArrayType, @this);

            stack.Add(delegateArray);
            EmitLdlen(stack);
            EmitConv(stack, Code.Conv_I4);
            var invocationCount = stack.Pop();

            // Iterate over each element in array
            LLVM.BuildBr(builder, forCodeBlock);
            LLVM.PositionBuilderAtEnd(builder, forCodeBlock);

            // Get delegateArray[i]
            stack.Add(delegateArray);
            EmitLdloc(stack, locals, 0);
            EmitLdelem(stack);

            // Call
            var helperArgs = new ValueRef[LLVM.CountParams(invokeMethodHelper)];
            var thisIndex  = invokeMethod.Signature.GetParameterIndexForThis();

            helperArgs[thisIndex] = LLVM.BuildPointerCast(builder, stack.Pop().Value, declaringClass.Type.DefaultTypeLLVM, string.Empty);
            for (int i = 0; i < helperArgs.Length; ++i)
            {
                if (i == thisIndex)
                {
                    continue;
                }
                helperArgs[i] = LLVM.GetParam(invokeMethodHelper, (uint)i);
            }
            var retValue = LLVM.BuildCall(builder, invokeMethod.GeneratedValue, helperArgs, string.Empty);

            ApplyCallAttributes(invokeMethod.Signature, retValue);

            // i++
            EmitLdloc(stack, locals, 0);
            var lastStack        = stack[stack.Count - 1];
            var incrementedValue = LLVM.BuildAdd(builder, lastStack.Value, LLVM.ConstInt(int32LLVM, 1, false), string.Empty);

            lastStack = new StackValue(StackValueType.Int32, int32, incrementedValue);
            stack[stack.Count - 1] = lastStack;
            EmitStloc(stack, locals, 0);

            // if (i < length)
            //     goto forCodeBlock
            // else
            //     return lastReturnValue;
            EmitLdloc(stack, locals, 0);
            stack.Add(invocationCount);
            EmitConditionalBranch(stack, forCodeBlock, exitBlock, Code.Blt_S);

            LLVM.PositionBuilderAtEnd(builder, exitBlock);

            // Return value
            if (hasRetValue)
            {
                LLVM.BuildRet(builder, retValue);
            }
            else
            {
                LLVM.BuildRetVoid(builder);
            }

            return(invokeMethodHelper);
        }
コード例 #29
0
ファイル: CFunction.cs プロジェクト: SplittyDev/LoreLang
        internal void DeclareFunctionPrototype(FunctionDeclaration funcdecl)
        {
            // Prepare argument type array
            var argumentCount = funcdecl.Parameters.Count;
            var arguments     = new LLVMTypeRef [Math.Max(argumentCount, 0)];

            // Check if the function is already defined
            Symbol sym;

            if ((Table.TopScope.IsFunction && Table.TopScope.FindSymbol(funcdecl.Name, out sym)) ||
                (!Table.TopScope.IsFunction && Table.FindSymbol(funcdecl.Name, out sym)))
            {
                var e = LoreException.Create(funcdecl.Location).Describe($"Redefinition of function '{funcdecl.Name}'!");
                e.Describe($"Previous declaration was at {sym.Location}.");
                e.Resolve($"Rename the function to avoid a collision.");
                throw e;
            }

            // Add function parameter types to array
            for (var i = 0; i < funcdecl.Parameters.Count; i++)
            {
                arguments [i] = Helper.GetBuiltinTypeFromString(funcdecl.Parameters [i].Type.Name);
            }

            // Check if the function returns multiple values
            var returnType       = LLVM.VoidType();
            var tupleReturnTypes = new LLVMTypeRef [0];

            if (funcdecl.ReturnsTuple)
            {
                var count = funcdecl.TupleReturnTypes.Count;
                tupleReturnTypes = new LLVMTypeRef [count];
                for (var i = 0; i < count; i++)
                {
                    var current = funcdecl.TupleReturnTypes [i];
                    tupleReturnTypes [i] = Helper.GetBuiltinTypeFromString(current.Name);
                }
                returnType = LLVM.StructType(tupleReturnTypes, true);
            }

            // Create the return type
            else if (funcdecl.HasReturnType)
            {
                returnType = Helper.GetBuiltinTypeFromString(funcdecl.ReturnType.Name);
            }

            // Create the function type
            var functionType = LLVM.FunctionType(
                ReturnType: returnType,
                ParamTypes: arguments,
                IsVarArg: LLVMFalse
                );

            // Create the actual function
            var functionRef = LLVM.AddFunction(LLVMModule, funcdecl.Name, functionType);

            LLVM.SetLinkage(functionRef, LLVMLinkage.LLVMExternalLinkage);

            // Add the function prototype as a symbol
            Table.AddSymbol(Symbol.CreatePrototype(funcdecl.Name, functionRef, funcdecl.Location));
        }
コード例 #30
0
ファイル: Function.cs プロジェクト: BowsiePup/Ion
        public LLVMValueRef Emit(PipeContext <CodeGeneration.Module> context)
        {
            // Ensure body was provided or created.
            if (this.Body == null)
            {
                throw new Exception("Unexpected function body to be null");
            }
            // Ensure prototype is set.
            else if (this.Prototype == null)
            {
                throw new Exception("Unexpected function prototype to be null");
            }
            // Ensure that body returns a value if applicable.
            else if (!this.Prototype.ReturnType.IsVoid && !this.Body.HasReturnExpr)
            {
                throw new Exception("Functions that do not return void must return a value");
            }

            // Emit the argument types.
            LLVMTypeRef[] args = this.Prototype.Args.Emit(context);

            // Emit the return type
            LLVMTypeRef returnType = this.Prototype.ReturnType.Emit();

            // Emit the function type.
            LLVMTypeRef type = LLVM.FunctionType(returnType, args, this.Prototype.Args.Continuous);

            // Create the function.
            LLVMValueRef function = LLVM.AddFunction(context.Target.Target, this.Prototype.Identifier, type);

            // Create the argument index counter.
            uint argIndexCounter = 0;

            // Name arguments.
            foreach (FormalArg arg in this.Prototype.Args.Values)
            {
                // Name the argument.
                LLVM.SetValueName(LLVM.GetParam(function, argIndexCounter), arg.Identifier);

                // Increment the index counter for next iteration.
                argIndexCounter++;
            }

            // Create the function context.
            PipeContext <LLVMValueRef> functionContext = context.Derive <LLVMValueRef>(function);

            // Emit the body to its corresponding context.
            LLVMBasicBlockRef body = this.Body.Emit(functionContext);

            // Create a new builder reference for the body.
            LLVMBuilderRef bodyBuilder = body.CreateBuilder(false);

            // Derive a context for the body's builder.
            PipeContext <LLVMBuilderRef> bodyContext = context.Derive <LLVMBuilderRef>(bodyBuilder);

            // TODO: Missing support for native attribute emission.
            // Emit attributes as first-class instructions if applicable.
            foreach (Attribute attribute in this.Attributes)
            {
                // Emit the attribute onto the body's builder context.
                attribute.Emit(bodyContext);
            }

            // Ensures the function does not already exist
            if (context.SymbolTable.functions.Contains(this.Prototype.Identifier))
            {
                throw new Exception($"A function with the identifier '{this.Prototype.Identifier}' already exists");
            }

            // Register the function on the symbol table.
            context.SymbolTable.functions.Add(new FunctionSymbol(this.Prototype.Identifier, function, this.Prototype.Args.Continuous));

            // Return the function entity.
            return(function);
        }