public MethodBuilder(LLVM.Builder builder, MethodData method) { _builder = builder; _method = method; _stack = new Stack<LLVM.Value>(); _params = new List<LLVM.Value>(); _variables = new List<LLVM.Value>(); _labels = new Dictionary<int, LLVM.BasicBlock>(); }
private LLVM.Value ConvertInteger(LLVM.Value v, LLVM.Type toType) { Trace.Assert(v.Type.isInteger() && toType.isInteger()); return _builder.CreateIntCast(v, toType); // signed cast }
public MethodData(MethodReference method, LLVM.Module module) { _method = method; _module = module; }
public static bool VerifyModule(this Module self, LLVMVerifierFailureAction Action, out string OutMessage) { return(LLVM.VerifyModule(self.GetModuleRef(), Action, out OutMessage)); }
public static string GetIdentifier(this Module self) { var id = LLVM.GetModuleIdentifier(self.GetModuleRef(), out var len); return(id); }
public static void AddFunctionParamAttribute(this LLVMValueRef self, LLVMContextRef context, int param, LLVMAttributeKind kind, uint value = 0) { var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value); LLVM.AddAttributeAtIndex(self, (LLVMAttributeIndex)(param + 1), att); }
public static LLVMTypeRef GetPointerTo(this LLVMTypeRef self) { return(LLVM.PointerType(self, 0)); }
public static uint AlignmentOfType(this LLVMTargetDataRef self, LLVMTypeRef type) { return(LLVM.ABIAlignmentOfType(self, type)); }
protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend) { return(LLVM.ConstReal(type, Value)); }
public LLVMValueRef ValueAsInt64(LLVMBuilderRef builder, bool signExtend) { return(ValueAsTypeInternal(LLVM.Int32Type(), builder, signExtend)); }
public bool Compile(CompilerOptions pOptions, out LLVMModuleRef?pModule) { double totalTime = 0; var sw = new System.Diagnostics.Stopwatch(); sw.Start(); //Read source files pModule = null; string source = string.IsNullOrEmpty(pOptions.SourceFile) ? pOptions.Source : ReadSourceFile(pOptions.SourceFile); if (source == null) { return(false); } var lexer = new SmallerLexer(); var stream = lexer.StartTokenStream(source, pOptions.SourceFile); var parser = new SmallerParser(stream); //Create AST var tree = parser.Parse(); if (CompilerErrors.ErrorOccurred) { return(false); } totalTime += RecordPerfData(sw, "Parsed in: "); //Type inference, type checking, AST transformations var compilationModule = ModuleBuilder.Build(tree); if (compilationModule == null) { return(false); } totalTime += RecordPerfData(sw, "Type checked in: "); LLVMModuleRef module = LLVM.ModuleCreateWithName(tree.Name); LLVMPassManagerRef passManager = LLVM.CreateFunctionPassManagerForModule(module); if (pOptions.Optimizations) { LLVM.AddConstantPropagationPass(passManager); //Promote allocas to registers LLVM.AddPromoteMemoryToRegisterPass(passManager); //Do simple peephole optimizations LLVM.AddInstructionCombiningPass(passManager); //Re-associate expressions LLVM.AddReassociatePass(passManager); //Eliminate common subexpressions LLVM.AddGVNPass(passManager); //Simplify control flow graph LLVM.AddCFGSimplificationPass(passManager); } LLVM.InitializeFunctionPassManager(passManager); //Emitting LLVM bytecode using (var c = new EmittingContext(module, passManager, pOptions.Debug)) { compilationModule.Emit(c); if (LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message).Value != 0) { LLVM.DumpModule(module); LLVM.DisposePassManager(passManager); pModule = null; return(false); } } pModule = module; LLVM.DisposePassManager(passManager); totalTime += RecordPerfData(sw, "Emitted bytecode in: "); Console.WriteLine("Total time: " + totalTime + "s"); return(true); }
protected override Expression VisitBinary(BinaryExpression b) { sb.Append("("); this.Visit(b.Left); switch (b.NodeType) { case ExpressionType.Add: LLVMTypeRef[] sumParamTypes = new LLVMTypeRef[] { LLVM.Int32Type(), LLVM.Int32Type() }; LLVMTypeRef sumRetType = LLVM.FunctionType(LLVM.Int32Type(), sumParamTypes, false); LLVMValueRef sumFunc = LLVM.AddFunction(module, "sum" + functionNumber, sumRetType); LLVMBasicBlockRef entry = LLVM.AppendBasicBlock(sumFunc, "entry"); LLVMBuilderRef sumBuilder = LLVM.CreateBuilder(); LLVM.PositionBuilderAtEnd(sumBuilder, entry); LLVMValueRef tmp = LLVM.BuildAdd(sumBuilder, LLVM.GetParam(sumFunc, 0), LLVM.GetParam(sumFunc, 1), "Sum" + functionNumber + "Entry"); LLVM.BuildRet(sumBuilder, tmp); lastLLVMFunctionCalledFromMain = LLVM.BuildCall(mainBuilder, sumFunc, new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), 3, new LLVMBool(0)), LLVM.ConstInt(LLVM.Int32Type(), 2, new LLVMBool(0)) }, "functioncall"); functionNumber++; break; default: throw new NotSupportedException(string.Format("The binary operator '{0}' is not supported", b.NodeType)); } this.Visit(b.Right); sb.Append(")"); return(b); }
protected override ExprAST VisitBinaryExprAST(BinaryExprAST node) { this.Visit(node.Lhs); this.Visit(node.Rhs); LLVMValueRef r = this.valueStack.Pop(); LLVMValueRef l = this.valueStack.Pop(); LLVMValueRef n; switch (node.NodeType) { case ExprType.AddExpr: n = LLVM.BuildFAdd(this.builder, l, r, "addtmp"); break; case ExprType.SubtractExpr: n = LLVM.BuildFSub(this.builder, l, r, "subtmp"); break; case ExprType.MultiplyExpr: n = LLVM.BuildFMul(this.builder, l, r, "multmp"); break; case ExprType.LessThanExpr: // Convert bool 0/1 to double 0.0 or 1.0 n = LLVM.BuildUIToFP(this.builder, LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealULT, l, r, "cmptmp"), LLVM.DoubleType(), "booltmp"); break; default: throw new Exception("invalid binary operator"); } this.valueStack.Push(n); return(node); }
protected override ExprAST VisitNumberExprAST(NumberExprAST node) { this.valueStack.Push(LLVM.ConstReal(LLVM.DoubleType(), node.Value)); return(node); }
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(this.builder, LLVM.DoubleType(), node.VarName); LLVM.AddIncoming(variable, out startVal, out 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. this.Visit(node.Body); // Emit the step value. LLVMValueRef stepVal; if (node.Step != null) { this.Visit(node.Step); stepVal = this.valueStack.Pop(); } else { // If not specified, use 1.0. stepVal = LLVM.ConstReal(LLVM.DoubleType(), 1.0); } LLVMValueRef nextVar = LLVM.BuildFAdd(this.builder, variable, stepVal, "nextvar"); // Compute the end condition. this.Visit(node.End); LLVMValueRef endCond = LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealONE, this.valueStack.Pop(), LLVM.ConstReal(LLVM.DoubleType(), 0.0), "loopcond"); // Create the "after loop" block and insert it. var loopEndBB = LLVM.GetInsertBlock(this.builder); var afterBB = LLVM.AppendBasicBlock(function, "afterloop"); // Insert the conditional branch into the end of LoopEndBB. LLVM.BuildCondBr(this.builder, endCond, loopBB, afterBB); // Any new code will be inserted in AfterBB. LLVM.PositionBuilderAtEnd(this.builder, afterBB); // Add a new entry to the PHI node for the backedge. LLVM.AddIncoming(variable, out nextVar, out loopEndBB, 1); // Restore the unshadowed variable. if (oldVal.Pointer != IntPtr.Zero) { this.namedValues[node.VarName] = oldVal; } else { this.namedValues.Remove(node.VarName); } this.valueStack.Push(LLVM.ConstReal(LLVM.DoubleType(), 0.0)); return(node); }
private LLVM.Value ConvertToType(LLVM.Value v, LLVM.Type toType) { LLVM.Type vType = v.Type; if (vType.isPointer() && toType.isPointer()) { return ConvertPointer(v, toType); } Console.WriteLine("v was not converted to toType"); return v; // TODO, FIXME }
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, out thenV, out thenBB, 1); LLVM.AddIncoming(phi, out elseV, out elseBB, 1); this.valueStack.Push(phi); return(node); }
public void Dispose() { LLVM.DisposeExecutionEngine(this.reference); }
public static void Dispose(this LLVMTargetMachineRef self) { LLVM.DisposeTargetMachine(self); }
public Number() { this.State = NumberState.Ok; this.Kind = Semantics.DefaultKind; this.Value = LLVM.ConstInt(GetLLVMType(), 0, new LLVMBool(0)); }
public static void AddFunctionReturnAttribute(this LLVMValueRef self, LLVMContextRef context, LLVMAttributeKind kind, uint value = 0) { var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value); LLVM.AddAttributeAtIndex(self, LLVMAttributeIndex.LLVMAttributeReturnIndex, att); }
public Number Convert(NumberKind kind) { if (kind == this.Kind) { return(this); } if (this.HasErrors) { return(new Number(this.State, this.Kind)); } if (this.Kind.IsInteger()) { if (this.Kind.IsSigned()) { var n = new Number(this.Int64Value, kind); n.State |= this.State; return(n); } else { var n = new Number(this.UInt64Value, kind); n.State |= this.State; return(n); } } else { if (kind.IsFloat()) { int status; var apFloat = LLVMExt.APFloatFromAPFloat(this.APFloat, GetAPFloatSemantics(kind), out status); return(new Number(dummy: string.Empty) { APFloat = apFloat, State = this.State | (NumberState)status, Kind = kind }); } else { if (this.Kind == NumberKind.Double) { var n = new Number(this.DoubleValue, kind); n.State |= this.State; return(n); } else if (this.Kind == NumberKind.Float) { var n = new Number(this.FloatValue, kind); n.State |= this.State; return(n); } else { if (kind.IsSigned()) { var overflows = CheckForLongOverflow(); if (overflows == 1) { return(new Number(NumberState.Overflow, kind)); } else if (overflows == -1) { return(new Number(NumberState.Underflow, kind)); } else { var longValue = LLVM.ConstFPToSI(LLVMExt.APFloatToValue(APFloat), LLVM.Int64Type()); var longValue2 = LLVM.ConstIntGetSExtValue(longValue); return(new Number(longValue2, kind)); } } else { var overflows = CheckForULongOverflow(); if (overflows == 1) { return(new Number(NumberState.Overflow, kind)); } else if (overflows == -1) { return(new Number(NumberState.Underflow, kind)); } else { var ulongValue = LLVM.ConstFPToUI(LLVMExt.APFloatToValue(APFloat), LLVM.Int64Type()); var ulongValue2 = LLVM.ConstIntGetZExtValue(ulongValue); return(new Number(ulongValue2, kind)); } } } } } }
public static void AddCallAttribute(this LLVMValueRef self, LLVMContextRef context, int arg, LLVMAttributeKind kind, uint value = 0) { var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value); LLVM.AddCallSiteAttribute(self, (LLVMAttributeIndex)(arg + 1), att); }
void LoadZeroExternalValue() { this.ExternalValue = LLVM.ConstInt(GetLLVMType(internalType: false), 0, new LLVMBool(0)); }
public static LLVMTargetDataRef GetTargetData(this Module self) { var data = LLVM.GetModuleDataLayout(self.GetModuleRef()); return(data); }
LLVMTypeRef GetLLVMType(bool internalType = true) { switch (this.Kind) { case NumberKind.Int8: return(internalType ? LLVM.Int128Type() : LLVM.Int8Type()); case NumberKind.Int16: return(internalType ? LLVM.Int128Type() : LLVM.Int16Type()); case NumberKind.Int32: return(internalType ? LLVM.Int128Type() : LLVM.Int32Type()); case NumberKind.Int64: return(internalType ? LLVM.Int128Type() : LLVM.Int64Type()); case NumberKind.UInt8: return(internalType ? LLVM.Int128Type() : LLVM.Int8Type()); case NumberKind.UInt16: return(internalType ? LLVM.Int128Type() : LLVM.Int16Type()); case NumberKind.UInt32: return(internalType ? LLVM.Int128Type() : LLVM.Int32Type()); case NumberKind.UInt64: return(internalType ? LLVM.Int128Type() : LLVM.Int64Type()); case NumberKind.Float: return(LLVM.FloatType()); case NumberKind.Double: return(LLVM.DoubleType()); case NumberKind.Real: case NumberKind.Quad: switch (this.Kind == NumberKind.Real ? Semantics.LongDoubleSemantics : Semantics.QuadSemantics) { case FloatSemantics.IEEEHalf: return(LLVM.HalfType()); case FloatSemantics.IEEESingle: return(LLVM.FloatType()); case FloatSemantics.IEEEDouble: return(LLVM.DoubleType()); case FloatSemantics.IEEEQuad: return(LLVM.FP128Type()); case FloatSemantics.PPCDoubleDouble: return(LLVM.PPCFP128Type()); case FloatSemantics.X87DoubleExtended: return(LLVM.X86FP80Type()); default: throw new NotSupportedException(); } default: throw new NotSupportedException(); } }
public static IEnumerable <(string, LLVMValueRef)> BuildFunctions(LLVMModuleRef module) { yield return(BuildFunctionEntry(module, FunctionNames.Malloc64F, new[] { LLVM.Int32Type() }, LLVM.Int64Type())); yield return(BuildFunctionEntry(module, FunctionNames.Free, new[] { LLVM.Int64Type() }, LLVM.VoidType())); yield return(BuildFunctionEntry(module, FunctionNames.Set64F, new[] { LLVM.DoubleType(), LLVM.Int64Type(), LLVM.Int32Type() })); yield return(BuildFunctionEntry(module, FunctionNames.Zero64F, new[] { LLVM.Int64Type(), LLVM.Int32Type() })); yield return(BuildFunctionEntry(module, FunctionNames.Exp64FI, new[] { LLVM.Int64Type(), LLVM.Int32Type() })); yield return(BuildFunctionEntry(module, FunctionNames.Copy64F, new[] { LLVM.Int64Type(), LLVM.Int64Type(), LLVM.Int32Type() })); yield return(BuildFunctionEntry(module, FunctionNames.Add64FI, new[] { LLVM.Int64Type(), LLVM.Int64Type(), LLVM.Int32Type() })); yield return(BuildFunctionEntry(module, FunctionNames.Mul64FI, new[] { LLVM.Int64Type(), LLVM.Int64Type(), LLVM.Int32Type() })); yield break; }
public BasicBlock GetSuccessor(uint idx) => LLVM.GetSuccessor(this.Unwrap(), idx).Wrap();
public static void Init(LLVM.Module module, LLVM.Builder builder) { if (_module == null) { _module = module; _builder = builder; _types = new Dictionary<TypeReference, CodeGenType>(); _methods = new Dictionary<MethodReference, MethodData>(); } }
public void SetSuccessor(uint idx, BasicBlock b) => LLVM.SetSuccessor(this.Unwrap(), idx, b.Unwrap <LLVMBasicBlockRef>());
private LLVM.Value ConvertPointer(LLVM.Value v, LLVM.Type toType) { Trace.Assert(v.Type.isPointer() && toType.isPointer()); return _builder.CreateBitCast(v, toType); }
public static LLVMValueRef BuildAtomicCmpXchg(this LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef @new, LLVMAtomicOrdering successOrdering, LLVMAtomicOrdering failureOrdering, bool singleThread) => LLVM.BuildAtomicCmpXchg(builder, ptr, cmp, @new, successOrdering, failureOrdering, singleThread ? 1 : 0);
public static ulong SizeOfTypeInBits(this LLVMTargetDataRef self, LLVMTypeRef type) { return(LLVM.SizeOfTypeInBits(self, type)); }
protected override ExprAST VisitPrototypeAST(PrototypeAST node) { // Make the function type: double(double,double) etc. var argumentCount = (uint)node.Arguments.Count; var arguments = new LLVMTypeRef[Math.Max(argumentCount, 1)]; var function = LLVM.GetNamedFunction(this.module, node.Name); // If F conflicted, there was already something named 'Name'. If it has a // body, don't allow redefinition or reextern. if (function.Pointer != IntPtr.Zero) { // If F already has a body, reject this. if (LLVM.CountBasicBlocks(function) != 0) { throw new Exception("redefinition of function."); } // If F took a different number of args, reject. if (LLVM.CountParams(function) != argumentCount) { throw new Exception("redefinition of function with different # args"); } } else { for (int i = 0; i < argumentCount; ++i) { arguments[i] = LLVM.DoubleType(); } function = LLVM.AddFunction(this.module, node.Name, LLVM.FunctionType(LLVM.DoubleType(), out arguments[0], argumentCount, LLVMBoolFalse)); LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage); } for (int i = 0; i < argumentCount; ++i) { string argumentName = node.Arguments[i]; LLVMValueRef param = LLVM.GetParam(function, (uint)i); LLVM.SetValueName(param, argumentName); this.namedValues[argumentName] = param; } this.valueStack.Push(function); return(node); }