2 #include <llvm/Passes/PassBuilder.h>
3 #include <llvm/IR/LLVMContext.h>
4 #include <llvm/IR/IRBuilder.h>
5 #include <llvm/IR/Verifier.h>
6 #include <llvm/IR/PassManager.h>
7 #include "llvm/Transforms/Scalar.h"
8 #include "llvm/Transforms/Scalar/Reassociate.h"
9 #include "llvm/Transforms/Scalar/GVN.h"
10 #include <llvm/Transforms/Scalar/DCE.h>
11 #include <llvm/Transforms/Scalar/SimplifyCFG.h>
12 #include <llvm/Transforms/InstCombine/InstCombine.h>
13 #include <llvm/Transforms/IPO/PassManagerBuilder.h>
14 #include <llvm/Analysis/OptimizationDiagnosticInfo.h>
15 #include <llvm/Analysis/MemorySSA.h>
16 #include <llvm/Analysis/PostDominators.h>
18 #include "codegen.hpp"
23 static LLVMContext TheContext;
24 static IRBuilder<> Builder(TheContext);
25 static AnalysisManager<int, int> TheAM;
26 static std::map<std::string, Value *> NamedValues;
27 static std::unique_ptr<FunctionPassManager> TheFPM;
28 static std::unique_ptr<FunctionAnalysisManager> TheFAM;
30 void InitializeModuleAndPassManager(void) {
31 TheModule = llvm::make_unique<Module>("Kaleidoscope jit", TheContext);
33 TheFPM = make_unique<FunctionPassManager>();
34 TheFAM = make_unique<FunctionAnalysisManager>();
37 PB.registerFunctionAnalyses(*TheFAM);
39 TheFPM->addPass(InstCombinePass());
40 TheFPM->addPass(ReassociatePass());
41 TheFPM->addPass(SimplifyCFGPass());
42 TheFPM->addPass(GVNHoistPass());
43 TheFPM->addPass(GVNSinkPass());
47 TheModule->print(errs(), nullptr);
50 std::map<std::string, std::unique_ptr<PrototypeAST>> functionProtos;
52 Function *getFunction(std::string name) {
53 if (auto *func = TheModule->getFunction(name))
56 auto iterator = functionProtos.find(name);
57 if (iterator != functionProtos.end())
58 return iterator->second->codegen();
63 Value *LogErrorV(const char *Str) {
68 Value *NumberExprAST::codegen() {
69 return ConstantFP::get(TheContext, APFloat(Val));
72 Value *VariableExprAST::codegen() {
73 Value *V = NamedValues[Name];
75 LogErrorV("Unknown variable name");
79 Value *BinaryExprAST::codegen() {
80 Value *L = LHS->codegen();
81 Value *R = RHS->codegen();
83 if (!L || !R) return nullptr;
87 return Builder.CreateFAdd(L, R, "addtmp");
89 return Builder.CreateFSub(L, R, "subtmp");
91 return Builder.CreateFMul(L, R, "multmp");
93 L = Builder.CreateFCmpULT(L, R, "cmptmp");
94 // convert bool 0/1 to double 0.0/1.0
95 return Builder.CreateUIToFP(L, Type::getDoubleTy(TheContext), "booltmp");
97 return LogErrorV("Invalid binary operator");
101 Value *CallExprAST::codegen() {
102 Function *CalleeF = getFunction(Callee);
104 return LogErrorV("Unknown function referenced");
106 if (CalleeF->arg_size() != Args.size())
107 return LogErrorV("Incorrect number of arguments passed");
109 std::vector<Value *> ArgsV;
110 for (unsigned long i = 0, e = Args.size(); i != e; ++i) {
111 ArgsV.push_back(Args[i]->codegen());
112 if (!ArgsV.back()) return nullptr;
115 return Builder.CreateCall(CalleeF, ArgsV, "calltmp");
118 Function *PrototypeAST::codegen() {
119 std::vector<Type*> Doubles(Args.size(), Type::getDoubleTy(TheContext));
121 FunctionType *FT = FunctionType::get(Type::getDoubleTy(TheContext), Doubles, false);
122 Function *func = Function::Create(FT, Function::ExternalLinkage, Name, TheModule.get());
125 for (auto &arg : func->args())
126 arg.setName(Args[i++]);
131 Function *FunctionAST::codegen() {
132 //Transfer ownership but keep a reference
133 auto &P = *Prototype;
134 functionProtos[Prototype->getName()] = std::move(Prototype);
136 Function *func = getFunction(P.getName());
138 if (!func) return nullptr;
140 BasicBlock *bb = BasicBlock::Create(TheContext, "entry", func);
141 Builder.SetInsertPoint(bb);
144 for (auto &arg: func->args())
145 NamedValues[arg.getName()] = &arg;
147 if (Value *retVal = Body->codegen()) {
148 Builder.CreateRet(retVal);
149 verifyFunction(*func);
150 TheFPM->run(*func, *TheFAM);
154 func->eraseFromParent();