コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
            }
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
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);
        }
コード例 #7
0
 public void Merge(LLVMBuilderRef builder, BasicBlock origin, EmulatedStateValue other)
 {
     LLVMValueRef[]      incoming    = { other.Value };
     LLVMBasicBlockRef[] basicBlocks = { origin.LLVMBlock };
     LLVM.AddIncoming(Value, incoming, basicBlocks, 1);
 }
コード例 #8
0
ファイル: UnitTest3.cs プロジェクト: kaby76/swigged.llvm
        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);
        }
コード例 #9
0
 public void AddIncoming(Value[] incomingValues, BasicBlock[] incomingBlocks)
 {
     LLVM.AddIncoming(this.Unwrap(), incomingValues.Unwrap(), incomingBlocks.Unwrap <LLVMBasicBlockRef>());
 }
コード例 #10
0
ファイル: ILStack.cs プロジェクト: SharpNative/CSharpLLVM
        /// <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--;
                }
            }
        }