예제 #1
0
        protected internal virtual ExprAST VisitForExprAST(ForExprAST node)
        {
            this.Visit(node.Start);
            this.Visit(node.End);
            this.Visit(node.Step);
            this.Visit(node.Body);

            return node;
        }
예제 #2
0
        protected internal virtual ExprAST VisitForExprAST(ForExprAST node)
        {
            this.Visit(node.Start);
            this.Visit(node.End);
            this.Visit(node.Step);
            this.Visit(node.Body);

            return(node);
        }
예제 #3
0
        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);
        }