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); }
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; } }
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); }
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(); }
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); }
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(); }
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); }
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); } }
/// <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); }
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); }
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); }
/// <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(); }
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); }
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(); } }
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(); }
/// <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); }
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)); }
/// <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); }
/// <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); }
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); }
/// <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); }
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; }
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);
public BasicBlock(string name, LLVMBasicBlockRef* handle) : base((LLVMValueRef*) handle) { m_name = name; // base.name, calls LLVM API to fetch Value name }