/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var markedBlock = BasicBlock.FunctionBody.GetOrCreateLabeledBlock(Label); BuildBr(BasicBlock.Builder, markedBlock.Block); return(new BlockCodegen(markedBlock)); }
private Tuple <LLVMValueRef[], BasicBlockBuilder> EmitArguments( BasicBlockBuilder BasicBlock, LLVMValueRef Target, IEnumerable <CodeBlock> Arguments) { int targetArgCount = Target.Pointer == IntPtr.Zero ? 0 : 1; var argArr = Arguments.ToArray <CodeBlock>(); var allArgs = new LLVMValueRef[targetArgCount + argArr.Length]; if (targetArgCount == 1) { allArgs[0] = BuildBitCast( BasicBlock.Builder, Target, PointerType(Int8Type(), 0), "this_tmp"); } for (int i = 0; i < argArr.Length; i++) { var argResult = argArr[i].Emit(BasicBlock); BasicBlock = argResult.BasicBlock; allArgs[targetArgCount + i] = argResult.Value; } return(new Tuple <LLVMValueRef[], BasicBlockBuilder>( allArgs, BasicBlock)); }
private BlockCodegen EmitCall( BasicBlockBuilder BasicBlock, LLVMValueRef Callee, LLVMValueRef[] Arguments) { bool hasVoidRetType = retType == PrimitiveTypes.Void; LLVMValueRef callRef; if (CanThrow && BasicBlock.HasUnwindTarget) { var successBlock = BasicBlock.CreateChildBlock("success"); callRef = BuildInvoke( BasicBlock.Builder, Callee, Arguments, successBlock.Block, BasicBlock.UnwindTarget, hasVoidRetType ? "" : "call_tmp"); BasicBlock = successBlock; } else { callRef = BuildCall( BasicBlock.Builder, Callee, Arguments, hasVoidRetType ? "" : "call_tmp"); } return(hasVoidRetType ? new BlockCodegen(BasicBlock) : new BlockCodegen(BasicBlock, callRef)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var lhsAddrCodegen = DestinationAddress.Emit(BasicBlock); BasicBlock = lhsAddrCodegen.BasicBlock; var rhsValueCodegen = Value.Emit(BasicBlock); BasicBlock = rhsValueCodegen.BasicBlock; // LLVM AtomicRMW instructions always return the *old* value, // but we want the *new* value (with Xchg being the lone // exception). // // We can compute the new value by first performing the RMW // and then computing the new value ourselves. var rmwOp = BuildAtomicRMW( BasicBlock.Builder, Op, lhsAddrCodegen.Value, rhsValueCodegen.Value, LLVMAtomicOrdering.LLVMAtomicOrderingSequentiallyConsistent, false); return(new BlockCodegen( BasicBlock, BuildRMWResult( BasicBlock.Builder, Op, rmwOp, rhsValueCodegen.Value))); }
/// <summary> /// Populates a 'finally' block with instructions. /// </summary> /// <param name="FinallyBlock">The 'finally' block to populate.</param> /// <param name="LeaveBlock"> /// The 'leave' block to which the 'finally' block jumps if no exception was thrown. /// </param> /// <param name="IsPropagatingStorage"> /// A pointer to a Boolean flag that tells if an exception is being propagated. /// </param> private void PopulateFinallyBlock( BasicBlockBuilder FinallyBlock, BasicBlockBuilder LeaveBlock, LLVMValueRef IsPropagatingStorage) { // A finally block is just a normal block that does this: // // finally: // <finally body> // if (is_handling_exception) // { // unwind; // } // else // { // goto leave_try; // } var finallyTail = FinallyBody.Emit(FinallyBlock).BasicBlock; var propagateExceptionBlock = GetManualUnwindTarget(finallyTail); BuildCondBr( finallyTail.Builder, BuildLoad( finallyTail.Builder, IsPropagatingStorage, "is_handling_exception"), propagateExceptionBlock, LeaveBlock.Block); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var destCodegen = Destination.Emit(BasicBlock); BasicBlock = destCodegen.BasicBlock; var valCodegen = Value.Emit(BasicBlock); BasicBlock = valCodegen.BasicBlock; var comparandCodegen = Comparand.Emit(BasicBlock); BasicBlock = comparandCodegen.BasicBlock; var cmpxchg = BuildAtomicCmpXchg( BasicBlock.Builder, destCodegen.Value, comparandCodegen.Value, valCodegen.Value, LLVMAtomicOrdering.LLVMAtomicOrderingSequentiallyConsistent, LLVMAtomicOrdering.LLVMAtomicOrderingSequentiallyConsistent, false); cmpxchg.SetValueName("atomic_cmpxchg"); return(new BlockCodegen( BasicBlock, BuildExtractValue(BasicBlock.Builder, cmpxchg, 0, "old_value"))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { if (CatchClauses.Count == 0) { return(TryBody.Emit(BasicBlock)); } var exceptionDataType = StructType(new[] { PointerType(Int8Type(), 0), Int32Type() }, false); var catchBlock = BasicBlock.CreateChildBlock("catch"); var catchLandingPadBlock = BasicBlock.CreateChildBlock("catch_landingpad"); var leaveBlock = BasicBlock.CreateChildBlock("leave"); // The try block is a regular block that jumps to the 'leave' block. // // try: // <try body> // br label %leave var tryCodegen = TryBody.Emit(BasicBlock.WithUnwindTarget(catchLandingPadBlock, catchBlock)); BuildBr(tryCodegen.BasicBlock.Builder, leaveBlock.Block); PopulateCatchBlock(catchBlock, leaveBlock); ItaniumCxxFinallyBlock.PopulateThunkLandingPadBlock(catchLandingPadBlock, catchBlock.Block, false); return(new BlockCodegen(leaveBlock, tryCodegen.Value)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { return(new BlockCodegen( BasicBlock, BuildAlloca(BasicBlock.Builder, BasicBlock.FunctionBody.Module.Declare(ElementType), "alloca_tmp"))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var markedBlock = BasicBlock.FunctionBody.GetOrCreateLabeledBlock(Label); BuildBr(BasicBlock.Builder, markedBlock.Block); return(new UnreachableBlock(CodeGenerator, Type).Emit(BasicBlock)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var lhsCodegen = address.Emit(BasicBlock); var rhsCodegen = val.Emit(lhsCodegen.BasicBlock); BuildStore(rhsCodegen.BasicBlock.Builder, rhsCodegen.Value, lhsCodegen.Value); return(new BlockCodegen(rhsCodegen.BasicBlock)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var vtableCodegen = VTablePointer.Emit(BasicBlock); BasicBlock = vtableCodegen.BasicBlock; return(new BlockCodegen( BasicBlock, BuildTypeid(BasicBlock.Builder, vtableCodegen.Value))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var firstCodegen = firstBlock.Emit(BasicBlock); var secondCodegen = secondBlock.Emit(firstCodegen.BasicBlock); return(new BlockCodegen( secondCodegen.BasicBlock, secondIsResult ? secondCodegen.Value : firstCodegen.Value)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var lhsCodegen = lhs.Emit(BasicBlock); var rhsCodegen = rhs.Emit(lhsCodegen.BasicBlock); return(new BlockCodegen( rhsCodegen.BasicBlock, build(rhsCodegen.BasicBlock.Builder, lhsCodegen.Value, rhsCodegen.Value, "tmp"))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var targetBlock = IsBreak ? BasicBlock.FunctionBody.GetBreakBlock(Tag) : BasicBlock.FunctionBody.GetContinueBlock(Tag); BuildBr(BasicBlock.Builder, targetBlock); return(new BlockCodegen(BasicBlock.CreateChildBlock())); }
/// <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); }
/// <summary> /// Emits this prologue spec to the given basic block. /// </summary> /// <param name="BasicBlock">The basic block to populate.</param> /// <returns>The next basic block.</returns> public BasicBlockBuilder Emit(BasicBlockBuilder BasicBlock) { for (int i = 0; i < taggedInstructions.Count; i++) { var codegen = taggedInstructions[i].Value.Emit(BasicBlock); BasicBlock = codegen.BasicBlock; BasicBlock.FunctionBody.TagValue(taggedInstructions[i].Key, codegen.Value); } return(BasicBlock); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { BuildUnreachable(BasicBlock.Builder); var newBlock = BasicBlock.CreateChildBlock("post_unreachable"); return(new BlockCodegen( newBlock, PrimitiveTypes.Void == Type ? default(LLVMValueRef) : GetUndef(BasicBlock.FunctionBody.Module.Declare(resultType)))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var result = GetParam(BasicBlock.FunctionBody.Function, (uint)Index); var llvmType = BasicBlock.FunctionBody.Module.Declare(Type); if (result.TypeOf().Pointer != llvmType.Pointer) { result = BuildBitCast(BasicBlock.Builder, result, llvmType, "bitcast_tmp"); } return(new BlockCodegen(BasicBlock, result)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var type = BasicBlock.FunctionBody.Module.Declare(TypeToMeasure); if (!IsReferenceSize) { type = GetElementType(type); } return(new BlockCodegen(BasicBlock, ConstTrunc(SizeOf(type), Int32Type()))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var continueBlock = BasicBlock.CreateChildBlock("continue_block"); var breakBlock = BasicBlock.CreateChildBlock("break_block"); BasicBlock.FunctionBody.TagFlowBlock(Tag, breakBlock.Block, continueBlock.Block); BuildBr(BasicBlock.Builder, continueBlock.Block); var bodyResult = Body.Emit(continueBlock); BuildBr(bodyResult.BasicBlock.Builder, breakBlock.Block); return(new BlockCodegen(breakBlock, bodyResult.Value)); }
/// <summary> /// Generates code for the object that receives a call, if any. /// </summary> /// <param name="BasicBlock">The basic block to generate code in.</param> /// <param name="Target">An object that will receive a call or <c>null</c>.</param> /// <returns>Block codegen.</returns> public static BlockCodegen EmitTarget(BasicBlockBuilder BasicBlock, CodeBlock Target) { if (Target == null) { return(new BlockCodegen(BasicBlock)); } else { var targetResult = Target.Emit(BasicBlock); BasicBlock = targetResult.BasicBlock; return(new BlockCodegen(BasicBlock, targetResult.Value)); } }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var baseAddressResult = ArrayPointer.Emit(BasicBlock); BasicBlock = baseAddressResult.BasicBlock; return(new BlockCodegen( BasicBlock, BuildStructGEP( BasicBlock.Builder, baseAddressResult.Value, (uint)DimensionIndex, "dimension_ptr_tmp"))); }
public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var elements = new LLVMValueRef[structType.InstanceFields.Count]; for (int i = 0; i < elements.Length; i++) { var elemBlock = (CodeBlock)codeGen.EmitDefaultValue(structType.InstanceFields[i].FieldType); var elemResult = elemBlock.Emit(BasicBlock); BasicBlock = elemResult.BasicBlock; elements[i] = elemResult.Value; } return(new BlockCodegen(BasicBlock, ConstStruct(elements, false))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var lhsCodegen = lhs.Emit(BasicBlock); var rhsCodegen = rhs.Emit(lhsCodegen.BasicBlock); return(new BlockCodegen( rhsCodegen.BasicBlock, LLVMSharp.LLVM.BuildFCmp( rhsCodegen.BasicBlock.Builder, predicate, lhsCodegen.Value, rhsCodegen.Value, "tmp"))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var operandCodegen = operand.Emit(BasicBlock); if (buildConst != null && operandCodegen.Value.IsConstant()) { return(new BlockCodegen( operandCodegen.BasicBlock, buildConst(operandCodegen.Value))); } else { return(new BlockCodegen( operandCodegen.BasicBlock, build(operandCodegen.BasicBlock.Builder, operandCodegen.Value, "tmp"))); } }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var exceptionDataType = StructType(new[] { PointerType(Int8Type(), 0), Int32Type() }, false); var isPropagatingStorage = BasicBlock.FunctionBody.CreateEntryPointAlloca( Int1Type(), "exception_value_alloca"); var finallyBlock = BasicBlock.CreateChildBlock("finally"); var finallyLandingPadBlock = BasicBlock.CreateChildBlock("finally_landingpad"); var finallyExceptionBlock = BasicBlock.CreateChildBlock("finally_exception"); var leaveBlock = BasicBlock.CreateChildBlock("leave"); // The try block is a regular block that jumps to the finally block. // // try: // store i1 false, i1* %is_propagating_exception_alloca // <try body> // br label %finally BuildStore( BasicBlock.Builder, ConstInt(Int1Type(), 0, false), isPropagatingStorage); var tryCodegen = TryBody.Emit(BasicBlock.WithUnwindTarget(finallyLandingPadBlock, finallyExceptionBlock)); BuildBr(tryCodegen.BasicBlock.Builder, finallyBlock.Block); PopulateFinallyBlock(finallyBlock, leaveBlock, isPropagatingStorage); PopulateThunkLandingPadBlock(finallyLandingPadBlock, finallyExceptionBlock.Block, true); // The 'finally_exception' block is entered if an exception is propagating from // the 'try' block. It sets the 'is propagating' flag to 'true' and branches // to the finally block. // // finally_exception: // store i1 true, i1* %is_propagating_exception_alloca // br label %finally BuildStore( finallyExceptionBlock.Builder, ConstInt(Int1Type(), 1, false), isPropagatingStorage); BuildBr(finallyExceptionBlock.Builder, finallyBlock.Block); return(new BlockCodegen(leaveBlock, tryCodegen.Value)); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var ptrResult = BaseAddress.Emit(BasicBlock); BasicBlock = ptrResult.BasicBlock; var indexVals = new LLVMValueRef[Indices.Count]; for (int i = 0; i < indexVals.Length; i++) { var indexResult = Indices[i].Emit(BasicBlock); BasicBlock = indexResult.BasicBlock; indexVals[i] = indexResult.Value; } return(new BlockCodegen( BasicBlock, BuildGEP(BasicBlock.Builder, ptrResult.Value, indexVals, "gep_tmp"))); }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { var boxCodegen = Box.Emit(BasicBlock); BasicBlock = boxCodegen.BasicBlock; return(new BlockCodegen( BasicBlock, BuildStructGEP( BasicBlock.Builder, BuildBitCast( BasicBlock.Builder, boxCodegen.Value, BasicBlock.FunctionBody.Module.Declare( elemType.MakePointerType(PointerKind.BoxPointer)), "box_ptr"), 1, "unboxed_ptr"))); }
private BlockCodegen EmitClause( BasicBlockBuilder MergeBlock, CodeBlock Body, string Name, out BasicBlockBuilder ClauseBlock) { if (Body != null) { ClauseBlock = MergeBlock.CreateChildBlock(Name); var clauseResult = Body.Emit(ClauseBlock); BuildBr(clauseResult.BasicBlock.Builder, MergeBlock.Block); return(clauseResult); } else { ClauseBlock = MergeBlock; return(new BlockCodegen(MergeBlock)); } }
/// <inheritdoc/> public override BlockCodegen Emit(BasicBlockBuilder BasicBlock) { if (retVal == null) { return(EmitRetVoid(BasicBlock)); } var retValCodegen = retVal.Emit(BasicBlock); BasicBlock = retValCodegen.BasicBlock; if (retVal.Type == PrimitiveTypes.Void) { return(EmitRetVoid(BasicBlock)); } else { var ret = BuildRet(BasicBlock.Builder, retValCodegen.Value); return(new BlockCodegen(BasicBlock)); } }