Наследование: LLVM.RefBase
Пример #1
0
        public void Add(Value value, BasicBlock block)
        {
            Guard.ArgumentNull(value, "value");
            Guard.ArgumentNull(block, "block");

            m_incomingVals.Add(value);
            m_incomingBlocks.Add(block);
        }
Пример #2
0
Файл: CLR.cs Проект: tytouf/cilc
    public static void Initialize(LLVM.Module module)
    {
        TargetData tgt = new TargetData("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32");
          // TargetData tgt = new TargetData(module.DataLayout);

          Void = LLVM.Type.GetVoid();
          //module.AddTypeName("type System.Void", Void);
          Bool = LLVM.Type.GetInt8();
          //module.AddTypeName("type System.Bool", Bool);
          Char = LLVM.Type.GetInt8();
          //module.AddTypeName("type System.Char", Char);
          Int8 = LLVM.Type.GetInt8();
          //module.AddTypeName("type System.Int8", Int8);
          Int16 = LLVM.Type.GetInt16();
          //module.AddTypeName("type System.Int16", Int16);
          Int32 = LLVM.Type.GetInt32();
          //module.AddTypeName("type System.Int32", Int32);
          Int64 = LLVM.Type.GetInt64();
          //module.AddTypeName("type System.Int64", Int64);

          Native = tgt.GetIntPtrType();
          //module.AddTypeName("type System.Native", Native);

          Ptr = Native.GetPointerTo(0);
          //module.AddTypeName("type System.Ptr", Ptr);

          Object = LLVM.StructType.Get(module.Context, "type System.Object", new LLVM.Type[2] { Int32, Int32 }, false);
          //module.AddTypeName("type System.Object", Object);

          String = LLVM.Type.GetInt8(); // FIXME, TODO
          //module.AddTypeName("type System.String", String);

          // Initialize constants
          //
          Const_0 = GetConstant(0);
          Const_1 = GetConstant(1);
          Const_2 = GetConstant(2);
          Const_3 = GetConstant(3);
          Const_4 = GetConstant(4);
          Const_5 = GetConstant(5);
          Const_6 = GetConstant(6);
          Const_7 = GetConstant(7);
          Const_8 = GetConstant(8);
          Const_m1 = GetConstant(-1);

          LLVM.FunctionType ft = LLVM.FunctionType.Get(Object.GetPointerTo(0),
                                    new LLVM.Type[1] { Native }, false);
          Newobj = new LLVM.Function(module, "newobj", ft);

          ft = LLVM.FunctionType.Get(String.GetPointerTo(0),
                               new LLVM.Type[1] { Int8.GetPointerTo(0) }, false);
          Newstr = new LLVM.Function(module, "newstring", ft);

          ft = LLVM.FunctionType.Get(Object.GetPointerTo(0),
                                  new LLVM.Type[2] { Native, Native }, false);
          Newarr = new LLVM.Function(module, "newarr", ft);
    }
        public override Value code(IRBuilder builder)
        {
            Value L = LHS.code(builder);
            Value R = RHS.code(builder);

            // import strcmp function
            LLVM.Type[]  argTypes          = new LLVM.Type[] { Parser.i8p, Parser.i8p };
            FunctionType stringStringToInt = new FunctionType(Parser.i8, argTypes);
            Value        strcmp            = Parser.module.GetOrInsertFunction("strcmp", stringStringToInt);

            LLVM.Value[] args = new LLVM.Value[] { L, R };

            Value strCmpResult = builder.CreateCall(strcmp, args);

            Predicate comparison = (relation == EqualityRelation.EQUAL) ? Predicate.Equal : Predicate.NotEqual;

            Value output = builder.CreateFCmp(comparison, strCmpResult, Parser.zero, "tempStrEqExp");

            return(output);
        }
Пример #4
0
 public Value BuildFMul(Value lhs, Value rhs)
 {
     return BuildFMul(lhs, rhs, "multmp");
 }
Пример #5
0
 public static Value FloatTrunc(this InstructionBuilder builder, Value value, LLVM.Type type, string name = "")
 {
     return (Value)ValueConstructor.Invoke(new object[] { LLVMBuildFPTrunc(builder, value, type, name) });
 }
Пример #6
0
 public EmitFuncObj(Context context, Module module, Function function, InstructionBuilder instructionBuilder, object argument, Stack<Value> stack, Value[] locals, Value[] parameters)
 {
     Context = context;
     Module = module;
     Function = function;
     Builder = instructionBuilder;
     Argument = argument;
     Stack = stack;
     Locals = locals;
     Parameters = parameters;
 }
Пример #7
0
        /// <summary>
        /// Generates the BrainF runtime environment.
        /// </summary>
        private void GenerateHeader()
        {
            this.module = new Module(this.context, "BrainF");

            // === Function prototypes =========================================
            Function memsetFunction = Intrinsic.GetDecleration(this.module, IntrinsicType.memset,
                Type.GetInteger8PointerType(this.context), Type.GetInteger32Type(this.context));

            // declare i32 @getchar()
            this.getcharFunction = (Function)this.module.GetOrInsertFunction("getchar",
                new FunctionType(Type.GetInteger32Type(this.context)));

            // declare i32 @putchar(i32)
            this.putcharFunction = (Function)this.module.GetOrInsertFunction("putchar",
                new FunctionType(Type.GetInteger32Type(this.context), Type.GetInteger32Type(this.context)));

            // === Function header =============================================

            // define void @brainf()
            this.brainfFunction = (Function)this.module.GetOrInsertFunction("brainf",
                new FunctionType(Type.GetVoidType(this.context)));

            this.builder = new IRBuilder(new BasicBlock(
                this.context, this.brainfFunction, "brainf"));

            // %arr = malloc i8, i32 %d
            Constant valMemory = new Constant(this.context, 32, this.totalMemory);
            BasicBlock bb = this.builder.GetInsertBlock();
            Type intType = Type.GetInteger32Type(this.context);
            Type byteType = Type.GetInteger8Type(this.context);
            Constant allocsize = new Constant(byteType);
            allocsize.TruncOrBitCast(intType);
            Instruction pointerArray = CallInstruction.CreateMalloc(bb, intType, byteType, allocsize, valMemory, "arr");
            bb.PushBack(pointerArray);

            // call void @llvm.memset.
            CallInstruction memsetCall = this.builder.CreateCall(
                memsetFunction,
                pointerArray,
                new Constant(this.context, 8, 0),
                valMemory,
                new Constant(this.context, 32, 1),
                new Constant(this.context, 1, 0));
            memsetCall.TailCall = false;

            //
            this.currentHead = this.builder.CreateGEP(
                pointerArray, new Constant(this.context, 32, this.totalMemory / 2), "head");

            // Footer
            this.endBlock = new BasicBlock(this.context, this.brainfFunction, "brainf");
            this.endBlock.PushBack(CallInstruction.CreateFree(pointerArray, this.endBlock));

            ReturnInstruction.Create(this.context, this.endBlock);
        }
Пример #8
0
 public Value BuildCondBr(Value ifVal, BasicBlock thenBlock, BasicBlock elseBlock)
 {
     return new Value(Native.BuildCondBr(m_builder, ifVal.Handle, thenBlock.BBHandle, elseBlock.BBHandle));
 }
Пример #9
0
 public Value BuildLoad(Value value, string varName = tmpvarname)
 {
     return new Value(Native.BuildLoad(m_builder, value.Handle, varName));
 }
Пример #10
0
 private static void LdVarA(EmitFuncObj _, Value[] values, int index)
 {
     _.Stack.Push(values[index]);
 }
Пример #11
0
 public Value BuildFCmp(Value lhs, LLVMRealPredicate predicate, Value rhs, string varName = tmpvarname)
 {
     return new Value(Native.BuildFCmp(m_builder, predicate, lhs.Handle, rhs.Handle, varName));
 }
Пример #12
0
 private static Value ElementPointer(EmitFuncObj _, Value pointer, int index)
 {
     var zeroConstant = IntegerType.GetInt32(_.Context).Constant(0, false);
     var indexConstant = IntegerType.GetInt32(_.Context).Constant((ulong)index, false);
     return _.Builder.Element(pointer, new Value[] { zeroConstant, indexConstant }); // guarenteed to be pointer type
 }
Пример #13
0
 private static void LdVar(EmitFuncObj _, Value[] values, int index)
 {
     _.Stack.Push(_.Builder.Load(values[index]));
 }
Пример #14
0
 public EmitFuncObj(Module module, Function function, MethodBody cilMethod, InstructionBuilder instructionBuilder, object argument, Stack<Value> stack, Value[] locals, Value[] parameters)
 {
     Module = module;
     Function = function;
     CilMethod = cilMethod;
     Builder = instructionBuilder;
     Argument = argument;
     Stack = stack;
     Locals = locals;
     Parameters = parameters;
 }
Пример #15
0
 private static void StVar(EmitFuncObj _, Value[] values, int index)
 {
     var pop = _.Stack.Pop();
     if (values[index] == null)
         values[index] = _.Builder.StackAlloc(pop.Type);
     _.Builder.Store(pop, values[index]);
 }
Пример #16
0
 private static void LdVar(EmitFuncObj _, Value[] values, int index, bool isParameter)
 {
     if (values[index] == null)
     {
         if (!isParameter)
             throw new Exception("Uninitialized variable at index " + index);
         var arg = _.Function[index];
         values[index] = _.Builder.StackAlloc(_.Function[index].Type);
         _.Builder.Store(arg, values[index]);
         _.Stack.Push(arg);
     }
     else
     {
         var load = _.Builder.Load(values[index]);
         _.Stack.Push(load);
     }
 }
Пример #17
0
 public Value BuildFMul(Value lhs, Value rhs, string varName)
 {
     return new Value(Native.BuildFMul(m_builder, lhs.Handle, rhs.Handle, varName));
 }
Пример #18
0
 private static void StVar(EmitFuncObj _, Value[] values, int index)
 {
     _.Builder.Store(_.Stack.Pop(), values[index]);
 }
Пример #19
0
 public Value BuildNot(Value val, string varName = tmpvarname)
 {
     return new Value(Native.BuildNot(m_builder, val.Handle, varName));
 }
Пример #20
0
 public void SetInitializer(Value init)
 {
     Native.SetInitializer(this.Handle, init.Handle);
 }
Пример #21
0
 public Value BuildFCmpAndPromote(Value lhs, LLVMRealPredicate predicate, Value rhs, TypeRef promoteType)
 {
     lhs = BuildFCmp(lhs, predicate, rhs);
     return new Value(Native.BuildUIToFP(m_builder, lhs.Handle, promoteType.Handle, "promotetmp")); 
 }
Пример #22
0
 public Value BuildReturn(Value returnValue)
 {
     return new Value(Native.BuildRet(m_builder, returnValue.Handle));
 }
Пример #23
0
 public Value BuildIntToPtr(Value arg, TypeRef ptrType, string name = tmpvarname)
 {
     return new Value(Native.BuildIntToPtr(m_builder, arg.Handle, ptrType.Handle, name));
 }
Пример #24
0
 public Value BuildSDiv(Value lhs, Value rhs, string varName = tmpvarname)
 {
     return new Value(Native.BuildSDiv(m_builder, lhs.Handle, rhs.Handle, varName));
 }
Пример #25
0
 public Value BuildStore(Value src, Value dest)
 {
     return new Value(Native.BuildStore(m_builder, src.Handle, dest.Handle));
 }
Пример #26
0
 public Value BuildFCmp(Value lhs, LLVMRealPredicate predicate, Value rhs)
 {
     return BuildFCmp(lhs, predicate, rhs, "cmptmp");
 }
Пример #27
0
        public void AddPhiIncoming(Value phiNode, Value value, BasicBlock block)
        {
            IntPtr[] valPointers = new IntPtr[] { (IntPtr)value.Handle };
            IntPtr[] blockPointers = new IntPtr[] { (IntPtr)block.BBHandle };

            Native.AddIncoming(phiNode.Handle, valPointers, blockPointers, 1);
        }
Пример #28
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value operandV = this.Operand.CodeGen(builder);
            if(operandV.IsNull) return operandV;

            Function f = CodeGenManager.Module.GetFunction("unary" + this.Op);
            Debug.Assert(f != null);

            Value[] ops = new Value[] { operandV };
            return builder.BuildCall(f, ops, "unop");
        }
Пример #29
0
    public static void Initialize(LLVM.Module module)
    {
        TargetData tgt = new TargetData("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32");

        // TargetData tgt = new TargetData(module.DataLayout);

        Void = LLVM.Type.GetVoid();
        //module.AddTypeName("type System.Void", Void);
        Bool = LLVM.Type.GetInt8();
        //module.AddTypeName("type System.Bool", Bool);
        Char = LLVM.Type.GetInt8();
        //module.AddTypeName("type System.Char", Char);
        Int8 = LLVM.Type.GetInt8();
        //module.AddTypeName("type System.Int8", Int8);
        Int16 = LLVM.Type.GetInt16();
        //module.AddTypeName("type System.Int16", Int16);
        Int32 = LLVM.Type.GetInt32();
        //module.AddTypeName("type System.Int32", Int32);
        Int64 = LLVM.Type.GetInt64();
        //module.AddTypeName("type System.Int64", Int64);

        Native = tgt.GetIntPtrType();
        //module.AddTypeName("type System.Native", Native);

        Ptr = Native.GetPointerTo(0);
        //module.AddTypeName("type System.Ptr", Ptr);

        Object = LLVM.StructType.Get(module.Context, "type System.Object", new LLVM.Type[2] {
            Int32, Int32
        }, false);
        //module.AddTypeName("type System.Object", Object);

        String = LLVM.Type.GetInt8();   // FIXME, TODO
        //module.AddTypeName("type System.String", String);

        // Initialize constants
        //
        Const_0  = GetConstant(0);
        Const_1  = GetConstant(1);
        Const_2  = GetConstant(2);
        Const_3  = GetConstant(3);
        Const_4  = GetConstant(4);
        Const_5  = GetConstant(5);
        Const_6  = GetConstant(6);
        Const_7  = GetConstant(7);
        Const_8  = GetConstant(8);
        Const_m1 = GetConstant(-1);

        LLVM.FunctionType ft = LLVM.FunctionType.Get(Object.GetPointerTo(0),
                                                     new LLVM.Type[1] {
            Native
        }, false);
        Newobj = new LLVM.Function(module, "newobj", ft);

        ft = LLVM.FunctionType.Get(String.GetPointerTo(0),
                                   new LLVM.Type[1] {
            Int8.GetPointerTo(0)
        }, false);
        Newstr = new LLVM.Function(module, "newstring", ft);

        ft = LLVM.FunctionType.Get(Object.GetPointerTo(0),
                                   new LLVM.Type[2] {
            Native, Native
        }, false);
        Newarr = new LLVM.Function(module, "newarr", ft);
    }
Пример #30
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value l = this.LHS.CodeGen(builder);
            Value r = this.RHS.CodeGen(builder);
            if(l.IsNull || r.IsNull) return Value.Null;

            switch(this.Op)
            {
                case '+':
                    return builder.BuildFAdd(l, r);
                case '-':
                    return builder.BuildFSub(l, r);
                case '*':
                    return builder.BuildFMul(l, r);
                case '<':
                    // Convert bool 0/1 to double 0.0 or 1.0
                    return builder.BuildFCmpAndPromote(l, LLVMRealPredicate.RealULT, 
                                                       r, TypeRef.CreateDouble());
            }

            // If it wasn't a builtin binary operator, it must be a user defined one. Emit
            // a call to it.
            Function f = CodeGenManager.Module.GetFunction("binary" + this.Op);
            Debug.Assert(f != null);

            Value[] ops = new Value[] { l, r };
            return builder.BuildCall(f, ops, "binop");
        }
Пример #31
0
        private void ReadLoop(PHINode phi, BasicBlock oldBlock, BasicBlock testBlock)
        {
            // parse the input file and generate code for it
            Symbol currentSymbol = Symbol.None;
            Symbol nextSymbol = Symbol.None;
            Int32 currentValue = 0, nextValue = 0;
            Char c;
            Int32 direction;

            while (currentSymbol != Symbol.EOF && currentSymbol != Symbol.EndLoop)
            {
                switch (currentSymbol)
                {
                    case Symbol.None:
                        break;
                    case Symbol.Read:
                        {
                            CallInstruction getCharCall = this.builder.CreateCall(this.getcharFunction, "tape");
                            getCharCall.TailCall = false;

                            Value tape0 = (Value)getCharCall;
                            Value tape1 = this.builder.CreateTrunc(tape0, Type.GetInteger8Type(this.context), "tape");
                            builder.CreateStore(tape1, this.currentHead);
                        }
                        break;
                    case Symbol.Write:
                        {
                            LoadInstruction tape0 = this.builder.CreateLoad(this.currentHead, "tape");
                            Value tape1 = this.builder.CreateSignExtend(tape0, Type.GetInteger32Type(this.context), "tape");
                            CallInstruction putcharCall = this.builder.CreateCall(this.putcharFunction, tape1);
                            putcharCall.TailCall = false;
                        }
                        break;
                    case Symbol.Move:
                        this.currentHead = this.builder.CreateGEP(
                            this.currentHead,
                            new Constant(this.context, 32, (UInt64)currentValue),
                            "head");
                        break;
                    case Symbol.Change:
                        {
                            LoadInstruction tape0 = this.builder.CreateLoad(this.currentHead, "tape");
                            Value tape1 = this.builder.CreateAdd(tape0, new Constant(this.context, 8, (UInt64)currentValue), "tape");
                            this.builder.CreateStore(tape1, this.currentHead);
                        }
                        break;
                    case Symbol.Loop:
                        BasicBlock testbb = new BasicBlock(this.context, this.brainfFunction, "brainf");
                        this.builder.CreateBranch(testbb);

                        BasicBlock bb0 = this.builder.GetInsertBlock();
                        BasicBlock bb1 = new BasicBlock(this.context, this.brainfFunction, "brainf");
                        this.builder.SetInsertPoint(bb1);

                        PHINode phi0 = new PHINode(PointerType.GetUnqualified(Type.GetInteger8Type(this.context)), 2, "head", testbb);
                        phi0.AddIncomding(this.currentHead, bb0);
                        this.currentHead = phi0;

                        this.ReadLoop(phi0, bb1, testbb);

                        break;
                    default:
                        throw new Exception("Unknown symbol.");
                }

                currentSymbol = nextSymbol;
                currentValue = nextValue;
                nextSymbol = Symbol.None;

                bool loop = currentSymbol == Symbol.None ||
                    currentSymbol == Symbol.Move ||
                    currentSymbol == Symbol.Change;

                while (loop)
                {
                    if (this.reader.EndOfStream)
                    {
                        if (currentSymbol == Symbol.None) currentSymbol = Symbol.EOF;
                        else nextSymbol = Symbol.EOF;

                        loop = false;
                    }
                    else
                    {
                        c = (Char)this.reader.Read();
                        direction = 1;

                        switch (c)
                        {
                            case '-':
                                direction = -1;
                                goto case '+';
                            case '+':
                                if (currentSymbol == Symbol.Change)
                                {
                                    currentValue += direction;
                                }
                                else
                                {
                                    if (currentSymbol == Symbol.None)
                                    {
                                        currentSymbol = Symbol.Change;
                                        currentValue = direction;
                                    }
                                    else
                                    {
                                        nextSymbol = Symbol.Change;
                                        nextValue = direction;
                                        loop = false;
                                    }
                                }
                                break;
                            case '<':
                                direction = -1;
                                goto case '>';
                            case '>':
                                if (currentSymbol == Symbol.Move)
                                {
                                    currentValue += direction;
                                }
                                else
                                {
                                    if (currentSymbol == Symbol.None)
                                    {
                                        currentSymbol = Symbol.Move;
                                        currentValue = direction;
                                    }
                                    else
                                    {
                                        nextSymbol = Symbol.Move;
                                        nextValue = direction;
                                        loop = false;
                                    }
                                }
                                break;
                            case ',':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.Read;
                                else
                                    nextSymbol = Symbol.Read;
                                loop = false;
                                break;
                            case '.':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.Write;
                                else
                                    nextSymbol = Symbol.Write;
                                loop = false;
                                break;
                            case '[':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.Loop;
                                else
                                    nextSymbol = Symbol.Loop;
                                loop = false;
                                break;
                            case ']':
                                if (currentSymbol == Symbol.None)
                                    currentSymbol = Symbol.EndLoop;
                                else
                                    nextSymbol = Symbol.EndLoop;
                                loop = false;
                                break;
                            default:
                                break;
                        }
                    }
                }
            }

            if (currentSymbol == Symbol.EndLoop)
            {
                if(phi == null)
                    throw new Exception("Unexpected ]");

                this.builder.CreateBranch(testBlock);

                phi.AddIncomding(this.currentHead, this.builder.GetInsertBlock());
                Value head0 = phi;

                LoadInstruction tape0 = new LoadInstruction(head0, "tape", testBlock);

                IntegerCompareInstruction test0 = new IntegerCompareInstruction(
                    testBlock, Predicate.Equal, tape0, new Constant(this.context, 8, 0), "test");

                BasicBlock bb0 = new BasicBlock(this.context, this.brainfFunction, "brainf");
                BranchInstruction.Create(bb0, oldBlock, test0, testBlock);

                this.builder.SetInsertPoint(bb0);

                PHINode phi1 = this.builder.CreatePHI(Type.GetInteger8PointerType(this.context), 1, "head");
                phi1.AddIncomding(head0, testBlock);

                this.currentHead = phi1;

                return;
            }

            this.builder.CreateBranch(this.endBlock);

            if (phi != null)
                throw new Exception("Missing ]");
        }
Пример #32
0
 public static Value UnsignedIntToFloat(this InstructionBuilder builder, Value value, LLVM.Type type, string name = "")
 {
     return (Value)ValueConstructor.Invoke(new object[] { LLVMBuildUIToFP(builder, value, type, name) });
 }