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 EmulatedStateValue(LLVMBuilderRef builder, BasicBlock origin, EmulatedStateValue otherValue) { TypeInfo = otherValue.TypeInfo; LLVMValueRef value = otherValue.Value; Value = LLVM.BuildPhi(builder, LLVM.TypeOf(value), string.Empty); LLVMValueRef[] incoming = { value }; LLVMBasicBlockRef[] basicBlocks = { origin.LLVMBlock }; LLVM.AddIncoming(Value, incoming, basicBlocks, 1); }
protected override ExprAST VisitIfExprAST(IfExpAST node) { this.Visit(node.Condition); var condv = LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealONE, this.valueStack.Pop(), LLVM.ConstReal(LLVM.DoubleType(), 0.0), "ifcond"); LLVMValueRef func = LLVM.GetBasicBlockParent(LLVM.GetInsertBlock(builder)); // Create blocks for the then and else cases. Insert the 'then' block at the // end of the function. LLVMBasicBlockRef thenBB = LLVM.AppendBasicBlock(func, "then"); LLVMBasicBlockRef elseBB = LLVM.AppendBasicBlock(func, "else"); LLVMBasicBlockRef mergeBB = LLVM.AppendBasicBlock(func, "ifcont"); LLVM.BuildCondBr(this.builder, condv, thenBB, elseBB); // Emit then value. LLVM.PositionBuilderAtEnd(this.builder, thenBB); this.Visit(node.Then); var thenV = this.valueStack.Pop(); LLVM.BuildBr(this.builder, mergeBB); // Codegen of 'Then' can change the current block, update ThenBB for the PHI. thenBB = LLVM.GetInsertBlock(this.builder); // Emit else block. LLVM.PositionBuilderAtEnd(this.builder, elseBB); this.Visit(node.Else); var elseV = this.valueStack.Pop(); LLVM.BuildBr(this.builder, mergeBB); // Codegen of 'Else' can change the current block, update ElseBB for the PHI. elseBB = LLVM.GetInsertBlock(this.builder); // Emit merge block. LLVM.PositionBuilderAtEnd(this.builder, mergeBB); var phi = LLVM.BuildPhi(this.builder, LLVM.DoubleType(), "iftmp"); LLVM.AddIncoming(phi, new [] { thenV }, new [] { thenBB }, 1); LLVM.AddIncoming(phi, new [] { elseV }, new [] { elseBB }, 1); this.valueStack.Push(phi); return(node); }
public void Branch(string block, LLVMValueRef[] vals) { LLVM.BuildBr(_codeGenerator.Builder, _namedBlocks[block]); if (vals == null) { return; } LLVMValueRef[] phis = _blockPhis[block]; LLVMBasicBlockRef blockref = _namedBlocks[CurrentBlock]; for (int i = 0; i < vals.Length; i++) { LLVM.AddIncoming(phis[i], new[] { vals[i] }, new[] { blockref }, 1); } }
/// <summary> /// 7.14 Conditional operator /// /// Type Conversion : /// GC Root : N/A /// Sign Extension : N/A /// Stack Balance : +1 /// </summary> public override void VisitConditionalExpression(ConditionalExpressionSyntax node) { LLVMBasicBlockRef condTrue = LLVM.AppendBasicBlock(this.function, "cond.true"); LLVMBasicBlockRef condFalse = LLVM.AppendBasicBlock(this.function, "cond.false"); LLVMBasicBlockRef condEnd = LLVM.AppendBasicBlock(this.function, "cond.end"); LLVM.BuildCondBr(this.builder, this.Pop(node.Condition), condTrue, condFalse); // true case LLVM.PositionBuilderAtEnd(this.builder, condTrue); this.EnterScope(); var trueValue = this.Pop(node.WhenTrue); this.LeaveScope(); LLVM.BuildBr(this.builder, condEnd); condTrue = LLVM.GetInsertBlock(this.builder); // false case LLVM.PositionBuilderAtEnd(this.builder, condFalse); this.EnterScope(); var falseValue = this.Pop(node.WhenFalse); this.LeaveScope(); LLVM.BuildBr(this.builder, condEnd); condFalse = LLVM.GetInsertBlock(this.builder); // end LLVM.PositionBuilderAtEnd(this.builder, condEnd); var phi = LLVM.BuildPhi(this.builder, this.semanticModel.GetTypeInfo(node).LLVMTypeRef(), "cond"); LLVM.AddIncoming(phi, out trueValue, out condTrue, 1); LLVM.AddIncoming(phi, out falseValue, out condFalse, 1); this.Push(node, phi); }
protected override ExprAST VisitForExprAST(ForExprAST node) { // Output this as: // ... // start = startexpr // goto loop // loop: // variable = phi [start, loopheader], [nextvariable, loopend] // ... // bodyexpr // ... // loopend: // step = stepexpr // nextvariable = variable + step // endcond = endexpr // br endcond, loop, endloop // outloop: // Emit the start code first, without 'variable' in scope. this.Visit(node.Start); var startVal = this.valueStack.Pop(); // Make the new basic block for the loop header, inserting after current // block. var preheaderBB = LLVM.GetInsertBlock(this.builder); var function = LLVM.GetBasicBlockParent(preheaderBB); var loopBB = LLVM.AppendBasicBlock(function, "loop"); // Insert an explicit fall through from the current block to the LoopBB. LLVM.BuildBr(this.builder, loopBB); // Start insertion in LoopBB. LLVM.PositionBuilderAtEnd(this.builder, loopBB); // Start the PHI node with an entry for Start. var variable = LLVM.BuildPhi(builder, LLVM.DoubleType(), node.VarName); LLVM.AddIncoming(variable, new [] { startVal }, new [] { preheaderBB }, 1); // Within the loop, the variable is defined equal to the PHI node. If it // shadows an existing variable, we have to restore it, so save it now. LLVMValueRef oldVal; if (this.namedValues.TryGetValue(node.VarName, out oldVal)) { this.namedValues[node.VarName] = variable; } else { this.namedValues.Add(node.VarName, variable); } // Emit the body of the loop. This, like any other expr, can change the // current BB. Note that we ignore the value computed by the body, but don't // allow an error. Visit(node.Body); // Emit the step value. LLVMValueRef stepVal; if (node.Step != null) { Visit(node.Step); stepVal = valueStack.Pop(); } else { // If not specified, use 1.0. stepVal = LLVM.ConstReal(LLVM.DoubleType(), 1.0); } LLVMValueRef nextVar = LLVM.BuildFAdd(builder, variable, stepVal, "nextvar"); // Compute the end condition. Visit(node.End); LLVMValueRef endCond = LLVM.BuildFCmp(builder, LLVMRealPredicate.LLVMRealONE, valueStack.Pop(), LLVM.ConstReal(LLVM.DoubleType(), 0.0), "loopcond"); // Create the "after loop" block and insert it. var loopEndBB = LLVM.GetInsertBlock(builder); var afterBB = LLVM.AppendBasicBlock(function, "afterloop"); // Insert the conditional branch into the end of LoopEndBB. LLVM.BuildCondBr(builder, endCond, loopBB, afterBB); // Any new code will be inserted in AfterBB. LLVM.PositionBuilderAtEnd(builder, afterBB); // Add a new entry to the PHI node for the backedge. LLVM.AddIncoming(variable, new [] { nextVar }, new [] { loopEndBB }, 1); // Restore the unshadowed variable. if (oldVal.Pointer != IntPtr.Zero) { namedValues[node.VarName] = oldVal; } else { namedValues.Remove(node.VarName); } valueStack.Push(LLVM.ConstReal(LLVM.DoubleType(), 0.0)); return(node); }
public void Merge(LLVMBuilderRef builder, BasicBlock origin, EmulatedStateValue other) { LLVMValueRef[] incoming = { other.Value }; LLVMBasicBlockRef[] basicBlocks = { origin.LLVMBlock }; LLVM.AddIncoming(Value, incoming, basicBlocks, 1); }
public void TestFact() { ModuleRef Module = LLVM.ModuleCreateWithName("fac_module"); TypeRef[] fac_args = { LLVM.Int32Type() }; ValueRef fac = LLVM.AddFunction(Module, "fac", LLVM.FunctionType(LLVM.Int32Type(), fac_args, false)); LLVM.SetFunctionCallConv(fac, (uint)Swigged.LLVM.CallConv.CCallConv); ValueRef n = LLVM.GetParam(fac, 0); BasicBlockRef entry = LLVM.AppendBasicBlock(fac, "entry"); BasicBlockRef iftrue = LLVM.AppendBasicBlock(fac, "iftrue"); BasicBlockRef iffalse = LLVM.AppendBasicBlock(fac, "iffalse"); BasicBlockRef end = LLVM.AppendBasicBlock(fac, "end"); BuilderRef builder = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(builder, entry); ValueRef If = LLVM.BuildICmp(builder, Swigged.LLVM.IntPredicate.IntEQ, n, LLVM.ConstInt(LLVM.Int32Type(), 0, false), "n == 0"); LLVM.BuildCondBr(builder, If, iftrue, iffalse); LLVM.PositionBuilderAtEnd(builder, iftrue); ValueRef res_iftrue = LLVM.ConstInt(LLVM.Int32Type(), 1, false); LLVM.BuildBr(builder, end); LLVM.PositionBuilderAtEnd(builder, iffalse); ValueRef n_minus = LLVM.BuildSub(builder, n, LLVM.ConstInt(LLVM.Int32Type(), 1, false), "n - 1"); ValueRef[] call_fac_args = { n_minus }; ValueRef call_fac = LLVM.BuildCall(builder, fac, call_fac_args, "fac(n - 1)"); ValueRef res_iffalse = LLVM.BuildMul(builder, n, call_fac, "n * fac(n - 1)"); LLVM.BuildBr(builder, end); LLVM.PositionBuilderAtEnd(builder, end); ValueRef res = LLVM.BuildPhi(builder, LLVM.Int32Type(), "result"); ValueRef[] phi_vals = { res_iftrue, res_iffalse }; BasicBlockRef[] phi_blocks = { iftrue, iffalse }; LLVM.AddIncoming(res, phi_vals, phi_blocks); LLVM.BuildRet(builder, res); MyString error = new MyString(); LLVM.VerifyModule(Module, VerifierFailureAction.PrintMessageAction, error); if (error.ToString() != "") { throw new Exception("Failed"); } ExecutionEngineRef engine; ModuleProviderRef provider = LLVM.CreateModuleProviderForExistingModule(Module); LLVM.CreateJITCompilerForModule(out engine, Module, 0, error); PassManagerRef pass = LLVM.CreatePassManager(); // LLVM.AddTargetData(LLVM.GetExecutionEngineTargetData(engine), pass); LLVM.AddConstantPropagationPass(pass); LLVM.AddInstructionCombiningPass(pass); LLVM.AddPromoteMemoryToRegisterPass(pass); // LLVMAddDemoteMemoryToRegisterPass(pass); // Demotes every possible value to memory LLVM.AddGVNPass(pass); LLVM.AddCFGSimplificationPass(pass); LLVM.RunPassManager(pass, Module); LLVM.DumpModule(Module); ulong input = 10; for (ulong i = 0; i < input; ++i) { GenericValueRef exec_args = LLVM.CreateGenericValueOfInt(LLVM.Int32Type(), input, false); GenericValueRef exec_res = LLVM.RunFunction(engine, fac, 1, out exec_args); var result_of_function = LLVM.GenericValueToInt(exec_res, false); var result_of_csharp_function = Factorial(input); if (result_of_csharp_function != result_of_function) { throw new Exception("Results not the same."); } } LLVM.DisposePassManager(pass); LLVM.DisposeBuilder(builder); LLVM.DisposeExecutionEngine(engine); }
public void AddIncoming(Value[] incomingValues, BasicBlock[] incomingBlocks) { LLVM.AddIncoming(this.Unwrap(), incomingValues.Unwrap(), incomingBlocks.Unwrap <LLVMBasicBlockRef>()); }
/// <summary> /// Update stack with phi nodes. /// </summary> /// <param name="builder">The builder.</param> /// <param name="srcStack">The source stack.</param> /// <param name="oldBlock">The old block.</param> /// <param name="newBlock">The new block.</param> /// <param name="refers">The amount of references to the new block.</param> public void Update(BuilderRef builder, ILStack srcStack, BasicBlockRef oldBlock, BasicBlockRef newBlock, int refers) { // If there's only one reference to this branch, there's only one way to get here. // That means the stack elements only depend on one other branch, therefor we don't need to build phi nodes. if (refers == 1) { for (int i = 0; i < srcStack.Count; i++) { Push(new StackElement(srcStack[i])); } } // Multiple references. else { // We got three possible cases here: // 1. #deststack = #srcstack => build phi nodes for every element. // 2. #deststack > #srcstack => build phi nodes for the top elements of the srcstack. // 3. #deststack < #srcstack => build phi nodes for the top elements and put the rest on the stack as independent values. int dstOffset = Count - 1; int difference = 0; // Case 3. if (Count < srcStack.Count) { difference = srcStack.Count - Count; // Push independent values on the stack start. for (int i = difference - 1; i >= 0; i--) { InsertAtStart(srcStack[i]); oldBlocks.Insert(0, oldBlock); } } difference += srcStack.GetDependentCount(); for (int i = srcStack.Count - 1; i >= difference; i--) { // Not a phi node yet. Transform to a phi node. if (mPhi[dstOffset] == 0) { StackElement element = mStack[dstOffset]; ValueRef oldValue = element.Value; LLVM.PositionBuilderAtEnd(builder, newBlock); element.Value = LLVM.BuildPhi(builder, element.Type, "phi"); LLVM.PositionBuilderAtEnd(builder, oldBlock); LLVM.AddIncoming(element.Value, new ValueRef[] { oldValue }, new BasicBlockRef[] { oldBlocks[i] }); } ValueRef phi = mStack[dstOffset].Value; // We might need to cast the incoming value to the phi type. // This is because it is possible that an integer type of a smaller type is pushed on the stack. // by IL, for example in "branch on condition". TypeRef phiType = LLVM.TypeOf(phi); ValueRef incomingValue = srcStack[i].Value; // Cast if not the same type. if (srcStack[i].Type != phiType) { CastHelper.HelpIntAndPtrCast(builder, ref incomingValue, ref srcStack[i].Type, phiType, "phicast"); } // Add new incoming from source stack. LLVM.AddIncoming(phi, new ValueRef[] { incomingValue }, new BasicBlockRef[] { oldBlock }); mPhi[dstOffset]++; dstOffset--; } } }