Example #1
0
        protected override Expression VisitBinary(BinaryExpression b)
        {
            sb.Append("(");
            this.Visit(b.Left);
            switch (b.NodeType)
            {
            case ExpressionType.Add:
                LLVMTypeRef[] sumParamTypes = new LLVMTypeRef[] { LLVM.Int32Type(), LLVM.Int32Type() };
                LLVMTypeRef   sumRetType    = LLVM.FunctionType(LLVM.Int32Type(), sumParamTypes, false);
                LLVMValueRef  sumFunc       = LLVM.AddFunction(module, "sum" + functionNumber, sumRetType);

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

                LLVMBuilderRef sumBuilder = LLVM.CreateBuilder();
                LLVM.PositionBuilderAtEnd(sumBuilder, entry);
                LLVMValueRef tmp = LLVM.BuildAdd(sumBuilder, LLVM.GetParam(sumFunc, 0), LLVM.GetParam(sumFunc, 1), "Sum" + functionNumber + "Entry");
                LLVM.BuildRet(sumBuilder, tmp);
                lastLLVMFunctionCalledFromMain = LLVM.BuildCall(mainBuilder, sumFunc, new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), 3, new LLVMBool(0)), LLVM.ConstInt(LLVM.Int32Type(), 2, new LLVMBool(0)) }, "functioncall");

                functionNumber++;
                break;

            default:
                throw new NotSupportedException(string.Format("The binary operator '{0}' is not supported", b.NodeType));
            }

            this.Visit(b.Right);
            sb.Append(")");
            return(b);
        }
Example #2
0
        public void Import()
        {
            FindBasicBlocks();

            try
            {
                ImportBasicBlocks();
            }
            catch
            {
                // Change the function body to trap
                foreach (BasicBlock block in _basicBlocks)
                {
                    if (block != null && block.Block.Pointer != IntPtr.Zero)
                    {
                        LLVM.DeleteBasicBlock(block.Block);
                    }
                }
                LLVMBasicBlockRef trapBlock = LLVM.AppendBasicBlock(_llvmFunction, "Trap");
                LLVM.PositionBuilderAtEnd(_builder, trapBlock);
                if (TrapFunction.Pointer == IntPtr.Zero)
                {
                    TrapFunction = LLVM.AddFunction(Module, "llvm.trap", LLVM.FunctionType(LLVM.VoidType(), Array.Empty <LLVMTypeRef>(), false));
                }
                LLVM.BuildCall(_builder, TrapFunction, Array.Empty <LLVMValueRef>(), String.Empty);
                LLVM.BuildRetVoid(_builder);
                throw;
            }
        }
Example #3
0
        public override LLVMValueRef Emit(EmittingContext pContext)
        {
            pContext.EmitDebugLocation(this);
            var variable = pContext.AllocateVariable("tern_return", Left.Type);

            var cond = Condition.Emit(pContext);

            Utils.LlvmHelper.LoadIfPointer(ref cond, pContext);

            var trueBranch = LLVM.AppendBasicBlock(pContext.CurrentMethod, "tern_true");
            LLVMBasicBlockRef falseBranch = LLVM.AppendBasicBlock(pContext.CurrentMethod, "tern_false");
            var end = LLVM.AppendBasicBlock(pContext.CurrentMethod, "tern_end");

            //Jump to true or false
            LLVM.BuildCondBr(pContext.Builder, cond, trueBranch, falseBranch);

            //Emit true value
            LLVM.PositionBuilderAtEnd(pContext.Builder, trueBranch);
            LLVM.BuildStore(pContext.Builder, Left.Emit(pContext), variable);

            //Jump to end
            LLVM.BuildBr(pContext.Builder, end);

            //Emit false value
            LLVM.PositionBuilderAtEnd(pContext.Builder, falseBranch);
            LLVM.BuildStore(pContext.Builder, Right.Emit(pContext), variable);

            //Jump to end
            LLVM.BuildBr(pContext.Builder, end);

            LLVM.PositionBuilderAtEnd(pContext.Builder, end);

            return(variable);
        }
Example #4
0
        private static void BuildStringFromSliceFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringFromSliceFunction = stringModule.AddFunction(StringFromSliceName, CommonModuleSignatures[StringFromSliceName]);
            LLVMBasicBlockRef entryBlock = stringFromSliceFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringSliceReference   = stringFromSliceFunction.GetParam(0u),
                         stringPtr              = stringFromSliceFunction.GetParam(1u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr          = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            LLVMValueRef sliceAllocationPtr = builder.CreateExtractValue(stringSliceReference, 0u, "sliceAllocationPtr");
            LLVMValueRef sliceSize          = builder.CreateExtractValue(stringSliceReference, 1u, "sliceSize");

            // Get a pointer to a heap allocation big enough for the string
            LLVMValueRef allocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), sliceSize, "allocationPtr");

            builder.CreateStore(allocationPtr, stringAllocationPtrPtr);

            // Copy the data from the string slice to the heap allocation
            LLVMValueRef sizeExtend = builder.CreateSExt(sliceSize, LLVMTypeRef.Int64Type(), "sizeExtend");

            builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { allocationPtr, sliceAllocationPtr, sizeExtend }, string.Empty);

            // Copy actual size into string handle
            builder.CreateStore(sliceSize, stringSizePtr);

            builder.CreateRetVoid();
        }
Example #5
0
        private static void BuildStringConcatFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringConcatFunction = stringModule.AddFunction(StringConcatName, CommonModuleSignatures[StringConcatName]);
            LLVMBasicBlockRef entryBlock           = stringConcatFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef slice0                    = stringConcatFunction.GetParam(0u),
                         slice1                    = stringConcatFunction.GetParam(1u),
                         sliceSize0                = builder.CreateExtractValue(slice0, 1u, "sliceSize0"),
                         sliceSize1                = builder.CreateExtractValue(slice1, 1u, "sliceSize1"),
                         concatSize                = builder.CreateAdd(sliceSize0, sliceSize1, "concatSize"),
                         concatAllocationPtr       = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), concatSize, "concatAllocationPtr"),
                         concatAllocationOffsetPtr = builder.CreateGEP(concatAllocationPtr, new LLVMValueRef[] { sliceSize0 }, "concatAllocationOffsetPtr"),
                         stringPtr                 = stringConcatFunction.GetParam(2u),
                         stringAllocationPtrPtr    = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr             = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice0, concatAllocationPtr }, string.Empty);
            builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice1, concatAllocationOffsetPtr }, string.Empty);
            builder.CreateStore(concatAllocationPtr, stringAllocationPtrPtr);
            builder.CreateStore(concatSize, stringSizePtr);
            builder.CreateRetVoid();
        }
        internal static void BuildOptionToPanicResultFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef optionToPanicResultFunction)
        {
            LLVMTypeRef elementLLVMType = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First());

            LLVMBasicBlockRef entryBlock = optionToPanicResultFunction.AppendBasicBlock("entry"),
                              someBlock  = optionToPanicResultFunction.AppendBasicBlock("some"),
                              noneBlock  = optionToPanicResultFunction.AppendBasicBlock("none");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef option = optionToPanicResultFunction.GetParam(0u),
                         isSome = builder.CreateExtractValue(option, 0u, "isSome");
            LLVMValueRef branch = builder.CreateCondBr(isSome, someBlock, noneBlock);
            // TODO: if possible, set metadata that indicates the some branch is more likely to be taken

            LLVMTypeRef panicResultType = moduleContext.LLVMContext.CreateLLVMPanicResultType(elementLLVMType);

            builder.PositionBuilderAtEnd(someBlock);
            LLVMValueRef innerValue          = builder.CreateExtractValue(option, 1u, "innerValue");
            LLVMValueRef panicContinueResult = builder.BuildStructValue(panicResultType, new LLVMValueRef[] { moduleContext.LLVMContext.AsLLVMValue(true), innerValue }, "panicContinueResult");

            builder.CreateStore(panicContinueResult, optionToPanicResultFunction.GetParam(1u));
            builder.CreateRetVoid();

            builder.PositionBuilderAtEnd(noneBlock);
            LLVMValueRef panicResult = LLVMSharp.LLVM.ConstNull(panicResultType);

            builder.CreateStore(panicResult, optionToPanicResultFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
        internal static void BuildOptionDropFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef optionDropFunction)
        {
            NIType innerType;

            signature.GetGenericParameters().First().TryDestructureOptionType(out innerType);

            LLVMBasicBlockRef entryBlock  = optionDropFunction.AppendBasicBlock("entry"),
                              isSomeBlock = optionDropFunction.AppendBasicBlock("isSome"),
                              endBlock    = optionDropFunction.AppendBasicBlock("end");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef optionPtr = optionDropFunction.GetParam(0u),
                         isSomePtr = builder.CreateStructGEP(optionPtr, 0u, "isSomePtr"),
                         isSome    = builder.CreateLoad(isSomePtr, "isSome");

            builder.CreateCondBr(isSome, isSomeBlock, endBlock);

            builder.PositionBuilderAtEnd(isSomeBlock);
            moduleContext.CreateDropCallIfDropFunctionExists(builder, innerType, b => b.CreateStructGEP(optionPtr, 1u, "innerValuePtr"));
            builder.CreateBr(endBlock);

            builder.PositionBuilderAtEnd(endBlock);
            builder.CreateRetVoid();
        }
        private LLVMValueRef BuildInitializeStateFunction(IEnumerable <LLVMTypeRef> parameterTypes)
        {
            LLVMTypeRef initializeStateFunctionType = LLVMTypeRef.FunctionType(
                SharedData.Context.VoidPointerType(),
                parameterTypes.ToArray(),
                false);
            LLVMValueRef      initializeStateFunction = Module.AddFunction(FunctionNames.GetInitializeStateFunctionName(_functionName), initializeStateFunctionType);
            var               builder    = SharedData.Context.CreateIRBuilder();
            LLVMBasicBlockRef entryBlock = initializeStateFunction.AppendBasicBlock("entry");

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef statePtr = SharedData.ModuleContext.CreateMalloc(builder, SharedData.AllocationSet.StateType, "statePtr");

            CurrentState = new OuterFunctionCompilerState(initializeStateFunction, builder)
            {
                StateMalloc = statePtr
            };
            GenerateStoreCompletionState(RuntimeConstants.FunctionNotDoneStatus);

            InitializeParameterAllocations(initializeStateFunction, builder);
            LLVMValueRef bitCastStatePtr = builder.CreateBitCast(statePtr, SharedData.Context.VoidPointerType(), "bitCastStatePtr");

            builder.CreateRet(bitCastStatePtr);

            return(initializeStateFunction);
        }
Example #9
0
        private static void BuildOpenFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      openFileHandleFunction = fileModule.AddFunction(OpenFileHandleName, CommonModuleSignatures[OpenFileHandleName]);
            LLVMBasicBlockRef entryBlock             = openFileHandleFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef pathSliceRef            = openFileHandleFunction.GetParam(0u),
                         nullTerminatedStringPtr = builder.CreateCall(_createNullTerminatedStringFromSliceFunction, new LLVMValueRef[] { pathSliceRef }, "nullTerminatedStringtPtr"),
                         readWriteAccess         = (0xC0000000u).AsLLVMValue(),
                         noShareMode             = 0u.AsLLVMValue(),
                         openAlways                        = (0x4u).AsLLVMValue(),
                         fileAttributeNormal               = (0x80u).AsLLVMValue(),
                         fileHandleOptionPtr               = openFileHandleFunction.GetParam(1u),
                         fileHandleIsSomePtr               = builder.CreateStructGEP(fileHandleOptionPtr, 0u, "fileHandleIsSomePtr"),
                         fileHandleInnerValuePtr           = builder.CreateStructGEP(fileHandleOptionPtr, 1u, "fileHandleInnerValuePtr"),
                         fileHandleInnerValueFileHandlePtr = builder.CreateStructGEP(fileHandleInnerValuePtr, 0u, "fileHandleInnerValueFileHandlePtr"),
                         fileHandle                        = builder.CreateCall(
                externalFunctions.CreateFileAFunction,
                new LLVMValueRef[] { nullTerminatedStringPtr, readWriteAccess, noShareMode, LLVMExtensions.NullVoidPointer, openAlways, fileAttributeNormal, LLVMExtensions.NullVoidPointer },
                "fileHandle");

            builder.CreateFree(nullTerminatedStringPtr);
            builder.CreateStore(true.AsLLVMValue(), fileHandleIsSomePtr);
            builder.CreateStore(fileHandle, fileHandleInnerValueFileHandlePtr);
            builder.CreateRetVoid();
        }
Example #10
0
        public object Visit(IfStmt stmt)
        {
            LLVMValueRef condition = stmt.Condition.Accept(this);
            LLVMValueRef func      = LLVM.GetBasicBlockParent(LLVM.GetInsertBlock(_builder));

            // Blocks
            LLVMBasicBlockRef thenBB  = LLVM.AppendBasicBlock(func, "then");
            LLVMBasicBlockRef elseBB  = LLVM.AppendBasicBlock(func, "else");
            LLVMBasicBlockRef mergeBB = LLVM.AppendBasicBlock(func, "ifcont");

            // Build condition
            LLVM.BuildCondBr(_builder, condition, thenBB, elseBB);

            // Then branch
            LLVM.PositionBuilderAtEnd(_builder, thenBB); // Position builder at block
            stmt.ThenBranch.Accept(this);                // Generate branch code
            LLVM.BuildBr(_builder, mergeBB);             // Redirect to merge

            // Else branch
            LLVM.PositionBuilderAtEnd(_builder, elseBB); // Position builder at block
            if (stmt.ElseBranch != null)
            {
                stmt.ElseBranch.Accept(this); // Generate branch code if else statement is present
            }
            LLVM.BuildBr(_builder, mergeBB);  // Redirect to merge

            LLVM.PositionBuilderAtEnd(_builder, mergeBB);

            return(null);
        }
Example #11
0
        public SynchronousFunctionModuleBuilder(
            FunctionCompilerSharedData sharedData,
            string functionName,
            IEnumerable <AsyncStateGroup> asyncStateGroups)
            : base(sharedData)
        {
            _functionName     = functionName;
            _asyncStateGroups = asyncStateGroups;

            var         parameterTypes   = GetParameterLLVMTypes();
            LLVMTypeRef syncFunctionType = LLVMSharp.LLVM.FunctionType(SharedData.Context.VoidType, parameterTypes.ToArray(), false);

            SyncFunction           = Module.AddFunction(FunctionNames.GetSynchronousFunctionName(functionName), syncFunctionType);
            SyncFunctionEntryBlock = SyncFunction.AppendBasicBlock("entry");

            foreach (AsyncStateGroup asyncStateGroup in asyncStateGroups)
            {
                LLVMBasicBlockRef groupBasicBlock    = SyncFunction.AppendBasicBlock($"{asyncStateGroup.Label}_begin");
                LLVMBasicBlockRef continueBasicBlock = asyncStateGroup.IsSkippable
                    ? SyncFunction.AppendBasicBlock($"{asyncStateGroup.Label}_continue")
                    : default(LLVMBasicBlockRef);
                LLVMBasicBlockRef endBasicBlock = asyncStateGroup.IsSkippable
                    ? SyncFunction.AppendBasicBlock($"{asyncStateGroup.Label}_end")
                    : default(LLVMBasicBlockRef);
                AsyncStateGroups[asyncStateGroup] = new AsyncStateGroupData(asyncStateGroup, SharedData.Context, SyncFunction, groupBasicBlock, continueBasicBlock, endBasicBlock, null);
            }
        }
Example #12
0
        /// <summary>
        /// Create a new LLVM block builder and position
        /// it accordingly.
        /// </summary>
        public static LLVMBuilderRef CreateBuilder(this LLVMBasicBlockRef block, bool positionAtEnd = true)
        {
            // Create a new builder.
            LLVMBuilderRef builder = LLVM.CreateBuilder();

            // Position the builder at the beginning of the block.
            if (!positionAtEnd)
            {
                LLVMValueRef lastInstruction = block.GetLastInstruction();

                // No instructions, position at beginning.
                if (lastInstruction.Pointer == IntPtr.Zero)
                {
                    LLVM.PositionBuilderAtEnd(builder, block);
                }
                // Otherwise, position it before the last instruction.
                else
                {
                    LLVM.PositionBuilderBefore(builder, lastInstruction);
                }
            }
            // Otherwise, at the end of the block.
            else
            {
                LLVM.PositionBuilderAtEnd(builder, block);
            }

            // Return the linked builder.
            return(builder);
        }
Example #13
0
        private void ConditionalOrExpression(BinaryExpressionSyntax node)
        {
            LLVMBasicBlockRef incoming = LLVM.GetInsertBlock(this.builder);
            LLVMBasicBlockRef lorRhs   = LLVM.AppendBasicBlock(this.function, "lor.rhs");
            LLVMBasicBlockRef lorEnd   = LLVM.AppendBasicBlock(this.function, "lor.end");

            var lhs = this.Pop(node.Left);

            LLVM.BuildCondBr(this.builder, lhs, lorEnd, lorRhs);

            LLVM.PositionBuilderAtEnd(this.builder, lorRhs);
            var rhs = this.Pop(node.Right);

            LLVM.BuildBr(this.builder, lorEnd);

            LLVM.PositionBuilderAtEnd(this.builder, lorEnd);
            var phi       = LLVM.BuildPhi(this.builder, LLVM.Int1Type(), "phi");
            var trueValue = LLVM.ConstInt(LLVM.Int1Type(), 1, False);

            LLVM.AddIncoming(phi, out trueValue, out incoming, 1);
            LLVM.AddIncoming(phi, out rhs, out lorRhs, 1);

            LLVM.PositionBuilderAtEnd(this.builder, lorEnd);

            this.Push(node, phi);
        }
Example #14
0
        public void AddIncoming(Tuple <Value, BasicBlock> firstIncoming, params Tuple <Value, BasicBlock>[] additionalIncoming)
        {
            if (firstIncoming == null)
            {
                throw new ArgumentNullException(nameof(firstIncoming));
            }

            if (additionalIncoming == null)
            {
                throw new ArgumentNullException(nameof(additionalIncoming));
            }

            LLVMValueRef[] llvmValues = new LLVMValueRef[additionalIncoming.Length + 1];
            llvmValues[0] = firstIncoming.Item1.ValueHandle;
            for (int i = 0; i < additionalIncoming.Length; ++i)
            {
                llvmValues[i + i] = additionalIncoming[i].Item1.ValueHandle;
            }

            LLVMBasicBlockRef[] llvmBlocks = new LLVMBasicBlockRef[additionalIncoming.Length + 1];
            llvmBlocks[0] = firstIncoming.Item2.BlockHandle;
            for (int i = 0; i < additionalIncoming.Length; ++i)
            {
                llvmBlocks[i + i] = additionalIncoming[i].Item2.BlockHandle;
            }

            NativeMethods.AddIncoming(ValueHandle, out llvmValues[0], out llvmBlocks[0], ( uint )llvmValues.Length);
        }
        private void VisitLoopBeforeLeftBorderNodes(Compiler.Nodes.Loop loop)
        {
            LLVMBasicBlockRef startBlock           = _topLevelFunction.AppendBasicBlock($"loop{loop.UniqueId}_start"),
                              interiorBlock        = _topLevelFunction.AppendBasicBlock($"loop{loop.UniqueId}_interior"),
                              endBlock             = _topLevelFunction.AppendBasicBlock($"loop{loop.UniqueId}_end");
            LoopConditionTunnel loopCondition      = loop.BorderNodes.OfType <LoopConditionTunnel>().First();
            Terminal            loopConditionInput = loopCondition.InputTerminals[0];
            var conditionAllocationSource          = (LocalAllocationValueSource)GetTerminalValueSource(loopConditionInput);

            _loopData[loop] = new LoopData(conditionAllocationSource, startBlock, interiorBlock, endBlock);

            if (!loopConditionInput.IsConnected)
            {
                // if loop condition was unwired, initialize it to true
                conditionAllocationSource.UpdateValue(_builder, true.AsLLVMValue());
            }

            // initialize all output tunnels with None values, in case the loop interior does not execute
            foreach (Tunnel outputTunnel in loop.BorderNodes.OfType <Tunnel>().Where(tunnel => tunnel.Direction == Direction.Output))
            {
                VariableReference tunnelOutputVariable = outputTunnel.OutputTerminals[0].GetTrueVariable();
                ValueSource       tunnelOutputSource   = _variableValues[tunnelOutputVariable];
                LLVMTypeRef       tunnelOutputType     = tunnelOutputVariable.Type.AsLLVMType();
                tunnelOutputSource.UpdateValue(_builder, LLVMSharp.LLVM.ConstNull(tunnelOutputType));
            }

            _builder.CreateBr(startBlock);
            _builder.PositionBuilderAtEnd(startBlock);
        }
Example #16
0
        /// <summary>
        /// 8.8.1
        /// </summary>
        public override void VisitWhileStatement(WhileStatementSyntax node)
        {
            LLVMBasicBlockRef condBB = LLVM.AppendBasicBlock(this.function, "while.cond");
            LLVMBasicBlockRef bodyBB = LLVM.AppendBasicBlock(this.function, "while.body");
            LLVMBasicBlockRef endBB  = LLVM.AppendBasicBlock(this.function, "while.end");

            this.controlFlowStack.Push(new ControlFlowTarget(condBB, endBB));

            LLVM.BuildBr(this.builder, condBB);

            // condition
            LLVM.PositionBuilderAtEnd(this.builder, condBB);
            LLVM.BuildCondBr(this.builder, this.Pop(node.Condition), bodyBB, endBB);

            // body
            LLVM.PositionBuilderAtEnd(this.builder, bodyBB);
            this.EnterScope();
            this.Visit(node.Statement);
            this.LeaveScope();
            LLVM.BuildBr(this.builder, condBB);

            // end
            LLVM.PositionBuilderAtEnd(this.builder, endBB);

            this.controlFlowStack.Pop();
        }
Example #17
0
        public override CompilerResult VisitMethod([NotNull] LangParser.MethodContext context)
        {
            var @params = context.parameter_declaration().NAME();

            LLVMTypeRef[] paramTypes = new LLVMTypeRef[@params.Count()];

            for (int i = 0; i < @params.Count(); i++)
            {
                paramTypes[i] = LLVM.Int32Type();
            }

            method = LLVM.AddFunction(module, context.NAME().GetText(), LLVM.FunctionType(LLVM.Int32Type(), paramTypes, false));
            LLVMBasicBlockRef entryBlock = LLVM.AppendBasicBlock(method, "entry");

            builder = LLVM.CreateBuilder();
            LLVM.PositionBuilderAtEnd(builder, entryBlock);

            PushContext();

            for (uint i = 0; i < @params.Count(); i++)
            {
                CurrContext().registerParameter(method, @params[i].GetText(), i);
            }

            base.VisitMethod(context);

            LLVM.RunFunctionPassManager(passManager, method);

            PopContext();

            LLVM.DisposeBuilder(builder);


            return(NullCompilerResult.INSTANCE);
        }
        private void VisitFrameAfterLeftBorderNodes(Frame frame)
        {
            LLVMBasicBlockRef interiorBlock = _frameData[frame].InteriorBlock;

            _builder.CreateBr(interiorBlock);
            _builder.PositionBuilderAtEnd(interiorBlock);
        }
Example #19
0
        private void StartImportingBasicBlock(BasicBlock basicBlock)
        {
            _stack.Clear();

            EvaluationStack <StackEntry> entryStack = basicBlock.EntryStack;

            if (entryStack != null)
            {
                int n = entryStack.Length;
                for (int i = 0; i < n; i++)
                {
                    _stack.Push(entryStack[i].Duplicate());
                }
            }

            bool isFirstBlock = false;

            if (_curBasicBlock.Equals(default(LLVMBasicBlockRef)))
            {
                isFirstBlock = true;
            }
            _curBasicBlock = GetLLVMBasicBlockForBlock(basicBlock);

            LLVM.PositionBuilderAtEnd(_builder, _curBasicBlock);

            if (isFirstBlock)
            {
                GenerateProlog();
            }
        }
Example #20
0
        public object Visit(WhileStmt stmt)
        {
            LLVMValueRef func = LLVM.GetBasicBlockParent(LLVM.GetInsertBlock(_builder));

            // Blocks
            LLVMBasicBlockRef condBB   = LLVM.AppendBasicBlock(func, "cond");
            LLVMBasicBlockRef branchBB = LLVM.AppendBasicBlock(func, "branch");
            LLVMBasicBlockRef mergeBB  = LLVM.AppendBasicBlock(func, "forcont");

            // Build condition
            LLVM.BuildBr(_builder, condBB);
            LLVM.PositionBuilderAtEnd(_builder, condBB);
            LLVMValueRef condition = stmt.Condition.Accept(this);

            LLVM.BuildCondBr(_builder, condition, branchBB, mergeBB);

            // branch
            LLVM.PositionBuilderAtEnd(_builder, branchBB); // Position builder at block
            stmt.Branch.Accept(this);                      // Generate branch code
            LLVM.BuildBr(_builder, condBB);

            LLVM.PositionBuilderAtEnd(_builder, mergeBB);

            return(null);
        }
        internal static void BuildCreateNotifierPairFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef createNotifierPairFunction)
        {
            LLVMTypeRef valueType          = moduleContext.LLVMContext.AsLLVMType(signature.GetGenericParameters().First()),
                        notifierReaderType = moduleContext.LLVMContext.CreateLLVMNotifierReaderType(valueType),
                        notifierWriterType = moduleContext.LLVMContext.CreateLLVMNotifierWriterType(valueType);

            LLVMBasicBlockRef entryBlock = createNotifierPairFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMTypeRef  sharedDataType        = moduleContext.LLVMContext.CreateLLVMNotifierSharedDataType(valueType);
            LLVMTypeRef  refCountType          = moduleContext.LLVMContext.CreateLLVMRefCountType(sharedDataType);
            LLVMValueRef refCountAllocationPtr = moduleContext.CreateMalloc(builder, refCountType, "refCountAllocationPtr"),
                         refCount = builder.BuildStructValue(
                refCountType,
                new LLVMValueRef[] { moduleContext.LLVMContext.AsLLVMValue(2), LLVMSharp.LLVM.ConstNull(sharedDataType) },
                "refCount");

            builder.CreateStore(refCount, refCountAllocationPtr);

            LLVMValueRef notifierReader = builder.BuildStructValue(notifierReaderType, new[] { refCountAllocationPtr });

            builder.CreateStore(notifierReader, createNotifierPairFunction.GetParam(0u));
            LLVMValueRef notifierWriter = builder.BuildStructValue(notifierWriterType, new[] { refCountAllocationPtr });

            builder.CreateStore(notifierWriter, createNotifierPairFunction.GetParam(1u));
            builder.CreateRetVoid();
        }
Example #22
0
        /// <summary>
        /// 8.7.1
        /// </summary>
        public override void VisitIfStatement(IfStatementSyntax node)
        {
            LLVMBasicBlockRef ifThen = LLVM.AppendBasicBlock(this.function, "if.then");
            LLVMBasicBlockRef ifElse = LLVM.AppendBasicBlock(this.function, "if.else");
            LLVMBasicBlockRef end    = LLVM.AppendBasicBlock(this.function, "if.end");

            LLVMBasicBlockRef targtBB = node.Else != null ? ifElse : end;

            LLVM.BuildCondBr(this.builder, this.Pop(node.Condition), ifThen, targtBB);

            // true case
            LLVM.PositionBuilderAtEnd(this.builder, ifThen);
            this.EnterScope();
            this.Visit(node.Statement);
            this.LeaveScope();
            LLVM.BuildBr(this.builder, end);

            // else case
            if (node.Else != null)
            {
                LLVM.PositionBuilderAtEnd(this.builder, ifElse);
                this.EnterScope();
                this.Visit(node.Else.Statement);
                this.LeaveScope();
                LLVM.BuildBr(this.builder, end);
            }

            // end
            LLVM.PositionBuilderAtEnd(this.builder, end);
        }
Example #23
0
        public LlvmBlock AppendBlock(string name)
        {
            // Append the basic block.
            LLVMBasicBlockRef block = LLVM.AppendBasicBlock(this.reference, name);

            // Wrap and return the reference.
            return(new LlvmBlock(this, block));
        }
Example #24
0
 /// <summary>
 /// Tags the given break and continue blocks with the given tag.
 /// </summary>
 /// <param name="Tag">The tag for a flow block.</param>
 /// <param name="BreakBlock">The 'break' basic block for the flow block.</param>
 /// <param name="ContinueBlock">The 'continue' basic block for the flow block.</param>
 public void TagFlowBlock(
     UniqueTag Tag,
     LLVMBasicBlockRef BreakBlock,
     LLVMBasicBlockRef ContinueBlock)
 {
     breakBlocks.Add(Tag, BreakBlock);
     continueBlocks.Add(Tag, ContinueBlock);
 }
Example #25
0
 /// <summary>
 /// Creates a basic block builder from the given arguments.
 /// </summary>
 public BasicBlockBuilder(
     FunctionBodyBuilder FunctionBody,
     LLVMBasicBlockRef Block)
 {
     this.FunctionBody = FunctionBody;
     this.Block        = Block;
     this.Builder      = CreateBuilder();
     PositionBuilderAtEnd(Builder, Block);
 }
Example #26
0
        internal static void BuildVectorCloneFunction(FunctionModuleContext moduleContext, NIType signature, LLVMValueRef vectorCloneFunction)
        {
            NIType elementType;

            signature.GetGenericParameters().First().TryDestructureVectorType(out elementType);
            LLVMTypeRef elementLLVMType = moduleContext.LLVMContext.AsLLVMType(elementType);

            LLVMBasicBlockRef entryBlock = vectorCloneFunction.AppendBasicBlock("entry");
            var builder = moduleContext.LLVMContext.CreateIRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);
            LLVMValueRef existingVectorPtr           = vectorCloneFunction.GetParam(0u),
                         existingVector              = builder.CreateLoad(existingVectorPtr, "existingVector"),
                         existingVectorAllocationPtr = builder.CreateExtractValue(existingVector, 0u, "existingVectorAllocationPtr"),
                         existingVectorSize          = builder.CreateExtractValue(existingVector, 1u, "existingVectorSize"),
                         existingVectorCapacity      = builder.CreateExtractValue(existingVector, 2u, "existingVectorCapacity"),
                         newVectorAllocationPtr      = moduleContext.CreateArrayMalloc(builder, elementLLVMType, existingVectorCapacity, "newVectorAllocationPtr");

            LLVMValueRef elementCloneFunction;

            if (moduleContext.TryGetCloneFunction(elementType, out elementCloneFunction))
            {
                LLVMBasicBlockRef loopStartBlock = vectorCloneFunction.AppendBasicBlock("loopStart"),
                                  loopBodyBlock  = vectorCloneFunction.AppendBasicBlock("loopBody"),
                                  loopEndBlock   = vectorCloneFunction.AppendBasicBlock("loopEnd");
                builder.CreateBr(loopStartBlock);

                builder.PositionBuilderAtEnd(loopStartBlock);
                LLVMValueRef index             = builder.CreatePhi(moduleContext.LLVMContext.Int32Type, "index");
                LLVMValueRef indexLessThanSize = builder.CreateICmp(LLVMIntPredicate.LLVMIntSLT, index, existingVectorSize, "indexLessThanSize");
                builder.CreateCondBr(indexLessThanSize, loopBodyBlock, loopEndBlock);

                builder.PositionBuilderAtEnd(loopBodyBlock);
                LLVMValueRef existingElementPtr = builder.CreateGEP(existingVectorAllocationPtr, new LLVMValueRef[] { index }, "existingElementPtr"),
                             newElementPtr      = builder.CreateGEP(newVectorAllocationPtr, new LLVMValueRef[] { index }, "newElementPtr");
                builder.CreateCall(elementCloneFunction, new LLVMValueRef[] { existingElementPtr, newElementPtr }, string.Empty);
                LLVMValueRef incrementIndex = builder.CreateAdd(index, moduleContext.LLVMContext.AsLLVMValue(1), "incrementIndex");
                builder.CreateBr(loopStartBlock);

                index.AddIncoming(moduleContext.LLVMContext.AsLLVMValue(0), entryBlock);
                index.AddIncoming(incrementIndex, loopBodyBlock);

                builder.PositionBuilderAtEnd(loopEndBlock);
            }
            else
            {
                LLVMValueRef existingVectorSizeExtend = builder.CreateSExt(existingVectorSize, moduleContext.LLVMContext.Int64Type, "existingVectorSizeExtend"),
                             bytesToCopy = builder.CreateMul(existingVectorSizeExtend, elementLLVMType.SizeOf(), "bytesToCopy");
                moduleContext.CreateCallToCopyMemory(builder, newVectorAllocationPtr, existingVectorAllocationPtr, bytesToCopy);
            }

            LLVMValueRef newVector    = builder.CreateInsertValue(existingVector, newVectorAllocationPtr, 0u, "newVector"),
                         newVectorPtr = vectorCloneFunction.GetParam(1u);

            builder.CreateStore(newVector, newVectorPtr);
            builder.CreateRetVoid();
        }
 public FrameData(
     LLVMBasicBlockRef interiorBlock,
     LLVMBasicBlockRef unwrapFailedBlock,
     LLVMBasicBlockRef endBlock)
 {
     InteriorBlock     = interiorBlock;
     UnwrapFailedBlock = unwrapFailedBlock;
     EndBlock          = endBlock;
 }
        private void VisitFrameBeforeLeftBorderNodes(Frame frame)
        {
            LLVMBasicBlockRef interiorBlock     = _topLevelFunction.AppendBasicBlock($"frame{frame.UniqueId}_interior");
            LLVMBasicBlockRef unwrapFailedBlock = frame.DoesStructureExecuteConditionally()
                ? _topLevelFunction.AppendBasicBlock($"frame{frame.UniqueId}_unwrapFailed")
                : default(LLVMBasicBlockRef);
            LLVMBasicBlockRef endBlock = _topLevelFunction.AppendBasicBlock($"frame{frame.UniqueId}_end");

            _frameData[frame] = new FrameData(interiorBlock, unwrapFailedBlock, endBlock);
        }
Example #29
0
        /// <summary>
        /// Creates a new basic block builder that appends instructions to
        /// this block, but with a different unwind target.
        /// </summary>
        /// <param name="Target">
        /// The automatic unwind target to which 'invoke' instructions can refer.
        /// </param>
        /// <param name="ManualTarget">
        /// The manual unwind target to which branch instructions can refer.
        /// </param>
        /// <returns>A new basic block builder for the same basic block.</returns>
        public BasicBlockBuilder WithUnwindTarget(
            LLVMBasicBlockRef Target,
            LLVMBasicBlockRef ManualTarget)
        {
            var result = new BasicBlockBuilder(FunctionBody, Block);

            result.UnwindTarget       = Target;
            result.ManualUnwindTarget = ManualTarget;
            return(result);
        }
Example #30
0
        public BasicBlock(string name, LLVMBasicBlockRef* handle)
        {
            if(handle == null)
                throw new ArgumentNullException("handle");

            if(name == null)
                name = Value.GetName((LLVMValueRef*)handle);

            m_handle = handle;
            m_name = name;
        }
Example #31
0
        private LLVMRegister VisitFunctionDeclarationBody
        (
            Antlr4.Runtime.ParserRuleContext context,
            ClepsType clepsReturnType,
            ClepsParser.FunctionParametersListContext parametersContext,
            string functionName,
            bool isStatic
        )
        {
            string className = String.Join(".", CurrentNamespaceAndClass);

            if (!ClassManager.DoesClassContainMember(className, functionName, isStatic))
            {
                //if the member was not found in the loaded member stage, then this is probably due to an earlier parsing error, just stop processing this member
                return(null);
            }

            FunctionHierarchy.Add(functionName);
            string fullyQualifiedName = String.Join(".", CurrentNamespaceAndClass.Union(FunctionHierarchy).ToList());

            LLVMValueRef      currFunc   = LLVM.GetNamedFunction(Module, fullyQualifiedName);
            LLVMBasicBlockRef basicBlock = LLVM.GetFirstBasicBlock(currFunc);

            LLVM.PositionBuilderAtEnd(Builder, basicBlock);

            VariableManager.AddBlock();

            List <string>    paramNames          = parametersContext._FunctionParameterNames.Select(p => p.VariableName.Text).ToList();
            List <ClepsType> clepsParameterTypes = parametersContext._FunctionParameterTypes.Select(t => ClepsType.GetBasicType(t)).ToList();

            if (!isStatic)
            {
                ClepsType thisClassType = ClepsType.GetBasicType(className, 1);
                paramNames.Insert(0, "this");
                clepsParameterTypes.Insert(0, thisClassType);
            }

            List <LLVMValueRef> paramValueRegisters = currFunc.GetParams().ToList();

            paramNames.Zip(clepsParameterTypes, (ParamName, ParamType) => new { ParamName, ParamType })
            .Zip(paramValueRegisters, (ParamNameAndType, ParamRegister) => new { ParamNameAndType.ParamName, ParamNameAndType.ParamType, ParamRegister })
            .ToList()
            .ForEach(p => {
                LLVMValueRef functionParamPtr = LLVM.BuildAlloca(Builder, LLVM.TypeOf(p.ParamRegister), p.ParamName);
                LLVM.BuildStore(Builder, p.ParamRegister, functionParamPtr);
                VariableManager.AddLocalVariable(p.ParamName, p.ParamType, functionParamPtr);
            });

            var ret = VisitChildren(context);

            VariableManager.RemoveBlock();
            FunctionHierarchy.RemoveAt(FunctionHierarchy.Count - 1);
            return(ret);
        }
 public static extern void PositionBuilderAtEnd(LLVMBuilderRef* Builder, LLVMBasicBlockRef* Block);
 public static extern LLVMValueRef* GetLastInstruction(LLVMBasicBlockRef* BB);
 public static extern void PositionBuilder(LLVMBuilderRef* Builder, LLVMBasicBlockRef* Block, LLVMValueRef* Instr);
 public static extern LLVMValueRef* BlockAddress(LLVMValueRef* F, LLVMBasicBlockRef* BB);
 public static extern void MoveBasicBlockAfter(LLVMBasicBlockRef* BB, LLVMBasicBlockRef* MovePos);
 public static extern LLVMValueRef* BuildSwitch(LLVMBuilderRef* LLVMBuilderRef, LLVMValueRef* V, LLVMBasicBlockRef* Else, uint NumCases);
 public static extern void AddCase(LLVMValueRef* Switch, LLVMValueRef* OnVal, LLVMBasicBlockRef* Dest);
 public static extern LLVMBasicBlockRef* InsertBasicBlockInContext(LLVMContextRef* C, LLVMBasicBlockRef* BB, [In][MarshalAs(UnmanagedType.LPStr)] string Name);
 public static extern LLVMBasicBlockRef* InsertBasicBlock(LLVMBasicBlockRef* InsertBeforeBB, [In][MarshalAs(UnmanagedType.LPStr)] string Name);
 public static extern LLVMBasicBlockRef* GetNextBasicBlock(LLVMBasicBlockRef* BB);
 public static extern LLVMBasicBlockRef* GetPreviousBasicBlock(LLVMBasicBlockRef* BB);
 public static extern LLVMValueRef* GetBasicBlockTerminator(LLVMBasicBlockRef* BB);
 public static extern LLVMValueRef* GetBasicBlockParent(LLVMBasicBlockRef* BB);
 public static extern LLVMValueRef* BasicBlockAsValue(LLVMBasicBlockRef* BB);
 public static extern LLVMValueRef* BuildBr(LLVMBuilderRef* LLVMBuilderRef, LLVMBasicBlockRef* Dest);
 public static extern void DeleteBasicBlock(LLVMBasicBlockRef* BB);
 public static extern LLVMValueRef* BuildCondBr(LLVMBuilderRef* LLVMBuilderRef, LLVMValueRef* If, LLVMBasicBlockRef* Then, LLVMBasicBlockRef* Else);
 public static extern void RemoveBasicBlockFromParent(LLVMBasicBlockRef* BB);
 public static extern LLVMValueRef* BuildInvoke(LLVMBuilderRef* LLVMBuilderRef, LLVMValueRef* Fn, System.IntPtr[] Args, uint NumArgs, LLVMBasicBlockRef* Then, LLVMBasicBlockRef* Catch, [In][MarshalAs(UnmanagedType.LPStr)] string Name);
 public static extern void MoveBasicBlockBefore(LLVMBasicBlockRef* BB, LLVMBasicBlockRef* MovePos);
 public static extern void AddDestination(LLVMValueRef* IndirectBr, LLVMBasicBlockRef* Dest);
Example #53
0
 public BasicBlock(string name, LLVMBasicBlockRef* handle)
     : base((LLVMValueRef*) handle)
 {
     m_name = name;  // base.name, calls LLVM API to fetch Value name
 }