public void Add(Value value, BasicBlock block) { Guard.ArgumentNull(value, "value"); Guard.ArgumentNull(block, "block"); m_incomingVals.Add(value); m_incomingBlocks.Add(block); }
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); }
public Value BuildFMul(Value lhs, Value rhs) { return BuildFMul(lhs, rhs, "multmp"); }
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) }); }
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; }
/// <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); }
public Value BuildCondBr(Value ifVal, BasicBlock thenBlock, BasicBlock elseBlock) { return new Value(Native.BuildCondBr(m_builder, ifVal.Handle, thenBlock.BBHandle, elseBlock.BBHandle)); }
public Value BuildLoad(Value value, string varName = tmpvarname) { return new Value(Native.BuildLoad(m_builder, value.Handle, varName)); }
private static void LdVarA(EmitFuncObj _, Value[] values, int index) { _.Stack.Push(values[index]); }
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)); }
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 }
private static void LdVar(EmitFuncObj _, Value[] values, int index) { _.Stack.Push(_.Builder.Load(values[index])); }
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; }
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]); }
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); } }
public Value BuildFMul(Value lhs, Value rhs, string varName) { return new Value(Native.BuildFMul(m_builder, lhs.Handle, rhs.Handle, varName)); }
private static void StVar(EmitFuncObj _, Value[] values, int index) { _.Builder.Store(_.Stack.Pop(), values[index]); }
public Value BuildNot(Value val, string varName = tmpvarname) { return new Value(Native.BuildNot(m_builder, val.Handle, varName)); }
public void SetInitializer(Value init) { Native.SetInitializer(this.Handle, init.Handle); }
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")); }
public Value BuildReturn(Value returnValue) { return new Value(Native.BuildRet(m_builder, returnValue.Handle)); }
public Value BuildIntToPtr(Value arg, TypeRef ptrType, string name = tmpvarname) { return new Value(Native.BuildIntToPtr(m_builder, arg.Handle, ptrType.Handle, name)); }
public Value BuildSDiv(Value lhs, Value rhs, string varName = tmpvarname) { return new Value(Native.BuildSDiv(m_builder, lhs.Handle, rhs.Handle, varName)); }
public Value BuildStore(Value src, Value dest) { return new Value(Native.BuildStore(m_builder, src.Handle, dest.Handle)); }
public Value BuildFCmp(Value lhs, LLVMRealPredicate predicate, Value rhs) { return BuildFCmp(lhs, predicate, rhs, "cmptmp"); }
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); }
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"); }
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 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"); }
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 ]"); }
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) }); }