Inheritance: IDisposable, IPointerWrapper
Exemplo n.º 1
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");
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            var context = new LLVMContext();
            var module = new Module("NoName", context);
            var builder = new IRBuilder(context);
            var t = builder.getInt32Ty();
            var funcType = FunctionType.get(t, false);
            var main = Function.Create(funcType, GlobalValue.LinkageTypes.ExternalLinkage, "main", module);
            var entry = BasicBlock.Create(context, "entrypoint", main);
            builder.SetInsertPoint(entry);

            var hello = builder.CreateGlobalStringPtr("Hello, World!");

            var putsType = FunctionType.get(builder.getInt32Ty(),
                new[] { builder.getInt8Ty().getPointerTo(0) }, false);
            var putsFunc = module.getOrInsertFunction("puts", putsType);

            builder.CreateCall(putsFunc, hello);

            var variable = builder.CreateAlloca(t);
            var val = ConstantInt.get(t, 127);
            builder.CreateStore(val, variable);

            builder.CreateRetVoid();

            var pm = new PassManager();
            var os = new raw_fd_ostream("code.ll");
            pm.add(Passes.createPrintModulePass(os));
            pm.run(module);
            os.close();

            Console.ReadKey();
        }
Exemplo n.º 3
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value value = Value.Null;

            if(!CodeGenManager.NamedValues.TryGetValue(this.Name, out value))
                CodeGenManager.ErrorOutput.WriteLine("Unknown variable name.");

            return value;
        }
Exemplo n.º 4
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());
            }

            CodeGenManager.ErrorOutput.WriteLine("Unknown binary operator.");
            return Value.Null;
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
0
 public override Value CodeGen(IRBuilder builder)
 {
     return Value.CreateConstReal(TypeRef.CreateDouble(), this.Val);
 }
Exemplo n.º 7
0
        public Function CodeGen(IRBuilder builder)
        {
            CodeGenManager.NamedValues.Clear();
            Function func = this.Proto.CodeGen(builder);
            if(func == null)
                return null;

            // Create a new basic block to start insertion into.
            BasicBlock bb = func.AppendBasicBlock("entry");
            builder.SetInsertPoint(bb);
            Value retVal = Body.CodeGen(builder);

            if(!retVal.IsNull)
            {
                builder.BuildReturn(retVal);

                // Validate the generated code, checking for consistency.
                func.Validate(LLVMVerifierFailureAction.PrintMessageAction);

                return func;
            }

            // Error reading body, remove function.
            func.Delete();
            return null;
        }
Exemplo n.º 8
0
        public Function CodeGen(IRBuilder builder)
        {
            List<TypeRef> args = new List<TypeRef>();
            this.Args.ForEach(a => args.Add(TypeRef.CreateDouble()));

            Function func = new Function(CodeGenManager.Module, this.Name,
                                                 TypeRef.CreateDouble(), args.ToArray());
            func.SetLinkage(LLVMLinkage.ExternalLinkage);

            // If F conflicted, there was already something named 'Name'.  If it has a
            // body, don't allow redefinition or reextern.
            if(func.IsDuplicate())
            {
                // Delete the one we just made and get the existing one.
                func.Delete();
                func = CodeGenManager.Module.GetFunction(this.Name);

                // If F already has a body, reject this.
                if(func.HasBody)
                {
                    CodeGenManager.ErrorOutput.WriteLine("redefinition of function.");
                    return null;
                }

                // If F took a different number of args, reject.
                if(func.ArgCount != this.Args.Count)
                {
                    CodeGenManager.ErrorOutput.WriteLine("redefinition of function with different # args.");
                    return null;
                }
            }

            // Set names for all arguments.
            for(int i = 0; i < func.ArgCount; ++i)
            {
                Value val = func.GetParameter((uint)i);
                val.Name = this.Args[i];
                CodeGenManager.NamedValues[this.Args[i]] = val;
            }

            return func;
        }
Exemplo n.º 9
0
 public abstract Value CodeGen(IRBuilder builder);
Exemplo n.º 10
0
        public override Value CodeGen(IRBuilder builder)
        {
            // Look up the name in the global module table.
            Function func = CodeGenManager.Module.GetFunction(this.Callee);
            if(func == null)
            {
                CodeGenManager.ErrorOutput.WriteLine("Unknown function referenced.");
                return Value.Null;
            }

            // If argument mismatch error.
            if(func.ArgCount != Args.Count)
            {
                CodeGenManager.ErrorOutput.WriteLine("Incorrect # arguments passed.");
                return Value.Null;
            }

            List<Value> args = new List<Value>();
            foreach(var arg in this.Args)
            {
                Value val = arg.CodeGen(builder);
                if(val.IsNull)
                    return Value.Null;

                args.Add(val);
            }

            return builder.BuildCall(func, args.ToArray());
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
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;
        }
Exemplo n.º 13
0
        public Function CodeGen(IRBuilder builder, PassManager passManager)
        {
            CodeGenManager.NamedValues.Clear();
            Function func = this.Proto.CodeGen(builder);
            if(func == null)
                return null;

            // If this is an operator, install it.
            if(this.Proto.IsBinaryOp)
                CodeGenManager.BinopPrecendence[Proto.OperatorName] = Proto.Precedence;

            // Create a new basic block to start insertion into.
            BasicBlock bb = func.AppendBasicBlock("entry");
            builder.SetInsertPoint(bb);

            Proto.CreateArgAllocas(func, builder);

            Value retVal = Body.CodeGen(builder);

            if(!retVal.IsNull)
            {
                builder.BuildReturn(retVal);

                // Validate the generated code, checking for consistency.
                func.Validate(LLVMVerifierFailureAction.PrintMessageAction);

                // Optimize the function.
                passManager.Run(func);

                return func;
            }

            // Error reading body, remove function.
            func.Delete();
            return null;
        }
Exemplo n.º 14
0
 public void CreateArgAllocas(Function function, IRBuilder builder)
 {
     for(int i = 0; i < function.ArgCount; ++i)
     {
         Value alloca = builder.BuildEntryBlockAlloca(function, TypeRef.CreateDouble(), this.Args[i]);
         builder.BuildStore(function.GetParameter((uint)i), alloca);
         CodeGenManager.NamedValues[this.Args[i]] = alloca;
     }
 }
Exemplo n.º 15
0
        public override Value CodeGen(IRBuilder builder)
        {
            // Output this as:
            //   var = alloca double
            //   ...
            //   start = startexpr
            //   store start -> var
            //   goto loop
            // loop: 
            //   ...
            //   bodyexpr
            //   ...
            // loopend:
            //   step = stepexpr
            //   endcond = endexpr
            //
            //   curvar = load var
            //   nextvar = curvar + step
            //   store nextvar -> var
            //   br endcond, loop, endloop
            // outloop:

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

            Value alloca = builder.BuildEntryBlockAlloca(func, TypeRef.CreateDouble(), this.VarName);

            Value startV = this.Start.CodeGen(builder);
            if(startV.IsNull) return startV;

            builder.BuildStore(startV, alloca);

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

            /* 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] = alloca;

            /* 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);

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

            Value curvar = builder.BuildLoad(alloca, VarName);
            Value nextVar = builder.BuildFAdd(curvar, stepV, "nextvar");
            builder.BuildStore(nextVar, alloca);

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

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

            return Value.CreateConstDouble(0);
        }
Exemplo n.º 16
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");
        }