Ast.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // LLVM includes
  2. #include "llvm/IR/Verifier.h"
  3. // Local includes
  4. #include "Ast.h"
  5. #include "Parser.h"
  6. #include "JIT.h"
  7. using namespace jit;
  8. namespace ast{
  9. // attributes added from chapter 3 of the tutorial
  10. std::unique_ptr<Module> AstObjects::TheModule =
  11. std::make_unique<Module>("my cool jit", getGlobalContext());
  12. IRBuilder<> AstObjects::Builder(getGlobalContext());
  13. std::map<std::string, Value *> AstObjects::NamedValues;
  14. Value *ErrorV(const char *Str) {
  15. parser::Error(Str);
  16. return nullptr;
  17. }
  18. Value *NumberExprAST::codegen() {
  19. return ConstantFP::get(getGlobalContext(), APFloat(Val));
  20. }
  21. Value *VariableExprAST::codegen() {
  22. // Look this variable up in the function.
  23. Value *V = AstObjects::NamedValues[Name];
  24. if (!V)
  25. ErrorV("Unknown variable name");
  26. return V;
  27. }
  28. Value *BinaryExprAST::codegen() {
  29. Value *L = LHS->codegen();
  30. Value *R = RHS->codegen();
  31. if (!L || !R)
  32. return nullptr;
  33. switch (Op) {
  34. case '+':
  35. return AstObjects::Builder.CreateFAdd(L, R, "addtmp");
  36. case '-':
  37. return AstObjects::Builder.CreateFSub(L, R, "subtmp");
  38. case '*':
  39. return AstObjects::Builder.CreateFMul(L, R, "multmp");
  40. case '<':
  41. L = AstObjects::Builder.CreateFCmpULT(L, R, "cmptmp");
  42. // Convert bool 0/1 to double 0.0 or 1.0
  43. return AstObjects::Builder.CreateUIToFP(L,
  44. Type::getDoubleTy(getGlobalContext()), "booltmp");
  45. default:
  46. return ErrorV("invalid binary operator");
  47. }
  48. }
  49. Value *CallExprAST::codegen() {
  50. // Look up the name in the global module table.
  51. Function *CalleeF = getFunction(Callee);
  52. if (!CalleeF)
  53. return ErrorV("Unknown function referenced");
  54. // If argument mismatch error.
  55. if (CalleeF->arg_size() != Args.size())
  56. return ErrorV("Incorrect # arguments passed");
  57. std::vector<Value *> ArgsV;
  58. for (unsigned i = 0, e = Args.size(); i != e; ++i) {
  59. ArgsV.push_back(Args[i]->codegen());
  60. if (!ArgsV.back())
  61. return nullptr;
  62. }
  63. return AstObjects::Builder.CreateCall(CalleeF, ArgsV, "calltmp");
  64. }
  65. Function *PrototypeAST::codegen() {
  66. // Make the function type: double(double,double) etc.
  67. std::vector<Type *> Doubles(Args.size(),
  68. Type::getDoubleTy(getGlobalContext()));
  69. FunctionType *FT = FunctionType::get(Type::getDoubleTy(
  70. getGlobalContext()), Doubles, false);
  71. Function *F = Function::Create(FT, Function::ExternalLinkage, Name,
  72. AstObjects::TheModule.get());
  73. // Set names for all arguments.
  74. unsigned Idx = 0;
  75. for (auto &Arg : F->args())
  76. Arg.setName(Args[Idx++]);
  77. return F;
  78. }
  79. Function *FunctionAST::codegen() {
  80. // Transfer ownership of the prototype to the FunctionProtos map, but keep a
  81. // reference to it for use below.
  82. auto &P = *Proto;
  83. JITObjects::FunctionProtos[Proto->getName()] = std::move(Proto);
  84. Function *TheFunction = getFunction(P.getName());
  85. if (!TheFunction)
  86. return nullptr;
  87. // Create a new basic block to start insertion into.
  88. BasicBlock *BB = BasicBlock::Create(getGlobalContext(),
  89. "entry", TheFunction);
  90. AstObjects::Builder.SetInsertPoint(BB);
  91. // Record the function arguments in the NamedValues map.
  92. AstObjects::NamedValues.clear();
  93. for (auto &Arg : TheFunction->args()) {
  94. AstObjects::NamedValues[Arg.getName()] = &Arg;
  95. }
  96. if (Value *RetVal = Body->codegen()) {
  97. // Finish off the function.
  98. AstObjects::Builder.CreateRet(RetVal);
  99. // Validate the generated code, checking for consistency.
  100. verifyFunction(*TheFunction);
  101. // Optimize the function.
  102. JITObjects::TheFPM->run(*TheFunction);
  103. return TheFunction;
  104. }
  105. // Error reading body, remove function.
  106. TheFunction->eraseFromParent();
  107. return nullptr;
  108. }
  109. }