BuildPhi() public method

public BuildPhi ( TypeRef type, string name, PhiIncoming incoming ) : Value
type TypeRef
name string
incoming PhiIncoming
return Value
Ejemplo n.º 1
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value startV = this.Start.CodeGen(builder);
            if(startV.IsNull) return startV;

            BasicBlock startBlock = builder.GetInsertPoint();
            Function func = startBlock.GetParent();

            BasicBlock loopBB = func.AppendBasicBlock("loop");
            builder.BuildBr(loopBB);
            builder.SetInsertPoint(loopBB);

            Value variable = builder.BuildPhi(TypeRef.CreateDouble(), this.VarName, new PhiIncoming(startV, startBlock));

            /* 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. */
            Value oldVal = Value.Null;
            CodeGenManager.NamedValues.TryGetValue(this.VarName, out oldVal);
            CodeGenManager.NamedValues[this.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 */
            Body.CodeGen(builder);

            // Emit the step value;
            Value stepV = Value.Null;

            if(this.Step != null)
                stepV = this.Step.CodeGen(builder);
            else
                stepV = Value.CreateConstDouble(1);

            Value nextVar = builder.BuildFAdd(variable, stepV, "nextvar");

            // Compute the end condition
            Value endCond = this.End.CodeGen(builder);
            endCond = builder.BuildFCmp(endCond, LLVMRealPredicate.RealONE, Value.CreateConstDouble(0), "loopcond");

            BasicBlock loopEndBB = builder.GetInsertPoint();
            BasicBlock afterBB = func.AppendBasicBlock("afterloop");
            builder.BuildCondBr(endCond, loopBB, afterBB);
            builder.SetInsertPoint(afterBB);

            builder.AddPhiIncoming(variable, nextVar, loopEndBB);

            if(!oldVal.IsNull)
                CodeGenManager.NamedValues[this.VarName] = oldVal;

            return Value.CreateConstDouble(0);
        }
Ejemplo n.º 2
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value condV = this.Cond.CodeGen(builder);
            if(condV.IsNull) return condV;

            condV = builder.BuildFCmp(condV, LLVMRealPredicate.RealONE, 
                                      Value.CreateConstDouble(0));
            
            BasicBlock startBlock = builder.GetInsertPoint();
            Function func = startBlock.GetParent();

            BasicBlock thenBB = func.AppendBasicBlock("then");
            builder.SetInsertPoint(thenBB);

            Value thenV = this.Then.CodeGen(builder);
            if(thenV.IsNull) return thenV;
      
            /* Codegen of 'then' can change the current block, update then_bb for the
            * phi. We create a new name because one is used for the phi node, and the
            * other is used for the conditional branch. */
            BasicBlock newThenBB = builder.GetInsertPoint();

            // Emit else block
            BasicBlock elseBB = func.AppendBasicBlock("else");
            func.AppendBasicBlock(elseBB);
            builder.SetInsertPoint(elseBB);

            Value elseV = this.Else.CodeGen(builder);
            if(elseV.IsNull) return elseV;

            // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
            BasicBlock newElseBB = builder.GetInsertPoint();

            // Emit merge block
            BasicBlock mergeBB = func.AppendBasicBlock("ifcont");
            func.AppendBasicBlock(mergeBB);
            builder.SetInsertPoint(mergeBB);

            PhiIncoming incoming = new PhiIncoming();
            incoming.Add(thenV, thenBB);
            incoming.Add(elseV, elseBB);
            Value phi = builder.BuildPhi(TypeRef.CreateDouble(), "iftmp", incoming);

            builder.SetInsertPoint(startBlock);
            builder.BuildCondBr(condV, thenBB, elseBB);

            builder.SetInsertPoint(thenBB);
            builder.BuildBr(mergeBB);

            builder.SetInsertPoint(elseBB);
            builder.BuildBr(mergeBB);

            builder.SetInsertPoint(mergeBB);

            return phi;
        }