#include <llvm/Transforms/Scalar/SimplifyCFG.h>
#include <llvm/Transforms/InstCombine/InstCombine.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
-#include <llvm/Analysis/OptimizationDiagnosticInfo.h>
#include <llvm/Analysis/MemorySSA.h>
#include <llvm/Analysis/PostDominators.h>
#include "ast.hpp"
TheFPM->addPass(GVNSinkPass());
}
-void PrintModule() {
- TheModule->print(errs(), nullptr);
-}
-
std::map<std::string, std::unique_ptr<PrototypeAST>> functionProtos;
Function *getFunction(std::string name) {
return nullptr;
}
-Value *LogErrorV(const char *Str) {
- LogError(Str);
+Value *LogErrorV(std::string str) {
+ LogError(str);
return nullptr;
}
L = Builder.CreateFCmpULT(L, R, "cmptmp");
// convert bool 0/1 to double 0.0/1.0
return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ case '>':
+ L = Builder.CreateFCmpUGT(L, R, "cmptmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
+ case '|':
+ L = Builder.CreateFCmpUGE(L, ConstantFP::get(TheContext, APFloat(1.0)), "leftbooltmp");
+ R = Builder.CreateFCmpUGE(R, ConstantFP::get(TheContext, APFloat(1.0)), "leftbooltmp");
+ L = Builder.CreateOr(L, R, "orbooltmp");
+ return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "ortmp");
default:
- return LogErrorV("Invalid binary operator");
+ break;
}
+
+ Function *F = getFunction(std::string("binary") + Op);
+ assert(F && "binary oprator not found!");
+
+ Value *Ops[2] = {L, R};
+ return Builder.CreateCall(F, Ops, "binop");
}
Value *CallExprAST::codegen() {
if (!func) return nullptr;
+ if (P.isBinaryOp())
+ BinopPrecedence[P.getOperatorName()] = P.getBinaryPrecedence();
+
BasicBlock *bb = BasicBlock::Create(TheContext, "entry", func);
Builder.SetInsertPoint(bb);
if (Value *retVal = Body->codegen()) {
Builder.CreateRet(retVal);
- verifyFunction(*func);
+
+ if (verifyFunction(*func, &errs())) {
+ func->print(errs());
+ func->eraseFromParent();
+ return nullptr;
+ }
+
TheFPM->run(*func, *TheFAM);
return func;
}
func->eraseFromParent();
return nullptr;
}
+
+Value *IfExprAST::codegen() {
+ Value *condV = Cond->codegen();
+ if (!condV) return nullptr;
+
+ //convert to bool
+ condV = Builder.CreateFCmpONE(condV, ConstantFP::get(TheContext, APFloat(0.0)), "ifcond");
+
+ Function *func = Builder.GetInsertBlock()->getParent();
+
+ BasicBlock *thenBB = BasicBlock::Create(TheContext, "then", func);
+ BasicBlock *elseBB = BasicBlock::Create(TheContext, "else", func);
+ BasicBlock *mergeBB = BasicBlock::Create(TheContext, "merge", func);
+
+ Builder.CreateCondBr(condV, thenBB, elseBB);
+
+ Builder.SetInsertPoint(thenBB);
+
+ Value *thenV = Then->codegen();
+ if (!thenV) return nullptr;
+
+ Builder.CreateBr(mergeBB);
+
+ //codegen of then can change the current block, so get then again
+ thenBB = Builder.GetInsertBlock();
+
+ Builder.SetInsertPoint(elseBB);
+
+ Value *elseV = Else->codegen();
+ if (!elseV) return nullptr;
+
+ Builder.CreateBr(mergeBB);
+
+ //codegen of else can change the current block, so get else again
+ elseBB = Builder.GetInsertBlock();
+
+ Builder.SetInsertPoint(mergeBB);
+ PHINode *phiNode = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, "iftmp");
+ phiNode->addIncoming(thenV, thenBB);
+ phiNode->addIncoming(elseV, elseBB);
+
+ return phiNode;
+}
+
+Value *ForExprAST::codegen() {
+ auto *startValue = Start->codegen();
+ if (!startValue) return nullptr;
+
+ auto *func = Builder.GetInsertBlock()->getParent();
+ auto *preheaderBB = Builder.GetInsertBlock();
+ auto *loopBB = BasicBlock::Create(TheContext, "loop", func);
+
+ Builder.CreateBr(loopBB);
+
+ Builder.SetInsertPoint(loopBB);
+
+ auto *index = Builder.CreatePHI(Type::getDoubleTy(TheContext), 2, VarName.c_str());
+ index->addIncoming(startValue, preheaderBB);
+
+ // if the index variable shadows an existing value, save it to restore later
+ auto *oldVal = NamedValues[VarName];
+ NamedValues[VarName] = index;
+
+ // emit the loop body
+ if (!Body->codegen()) return nullptr;
+
+ Value *stepVal = nullptr;
+ if (Step) {
+ stepVal = Step->codegen();
+ if (!stepVal) return nullptr;
+ } else {
+ stepVal = ConstantFP::get(TheContext, APFloat(1.0));
+ }
+
+ // increment the index
+ auto *nextVar = Builder.CreateFAdd(index, stepVal, "nextvar");
+
+ auto *endCond = End->codegen();
+ if (!endCond) return nullptr;
+
+ endCond = Builder.CreateFCmpONE(endCond, ConstantFP::get(TheContext, APFloat(0.0)), "loopcond");
+
+ auto *loopEndBB = Builder.GetInsertBlock();
+ auto *afterBB = BasicBlock::Create(TheContext, "afterloop", func);
+
+ Builder.CreateCondBr(endCond, loopBB, afterBB);
+
+ Builder.SetInsertPoint(afterBB);
+
+ index->addIncoming(nextVar, loopEndBB);
+
+ // restore shadowed index variable
+ if (oldVal)
+ NamedValues[VarName] = oldVal;
+ else
+ NamedValues.erase(VarName);
+
+ return Constant::getNullValue(Type::getDoubleTy(TheContext));
+}