Ast.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. Value *IfExprAST::codegen() {
  66. Value *CondV = Cond->codegen();
  67. if (!CondV)
  68. return nullptr;
  69. // Convert condition to a bool by comparing equal to 0.0.
  70. CondV = AstObjects::Builder.CreateFCmpONE(
  71. CondV, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "ifcond");
  72. Function *TheFunction = AstObjects::Builder.GetInsertBlock()->getParent();
  73. // Create blocks for the then and else cases. Insert the 'then' block at the
  74. // end of the function.
  75. BasicBlock *ThenBB =
  76. BasicBlock::Create(getGlobalContext(), "then", TheFunction);
  77. BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
  78. BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
  79. AstObjects::Builder.CreateCondBr(CondV, ThenBB, ElseBB);
  80. // Emit then value.
  81. AstObjects::Builder.SetInsertPoint(ThenBB);
  82. Value *ThenV = Then->codegen();
  83. if (!ThenV)
  84. return nullptr;
  85. AstObjects::Builder.CreateBr(MergeBB);
  86. // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
  87. ThenBB = AstObjects::Builder.GetInsertBlock();
  88. // Emit else block.
  89. TheFunction->getBasicBlockList().push_back(ElseBB);
  90. AstObjects::Builder.SetInsertPoint(ElseBB);
  91. Value *ElseV = Else->codegen();
  92. if (!ElseV)
  93. return nullptr;
  94. AstObjects::Builder.CreateBr(MergeBB);
  95. // codegen of 'Else' can change the current block, update ElseBB for the PHI.
  96. ElseBB = AstObjects::Builder.GetInsertBlock();
  97. // Emit merge block.
  98. TheFunction->getBasicBlockList().push_back(MergeBB);
  99. AstObjects::Builder.SetInsertPoint(MergeBB);
  100. PHINode *PN =
  101. AstObjects::Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()), 2, "iftmp");
  102. PN->addIncoming(ThenV, ThenBB);
  103. PN->addIncoming(ElseV, ElseBB);
  104. return PN;
  105. }
  106. Value *ForExprAST::codegen() {
  107. // Emit the start code first, without 'variable' in scope.
  108. Value *StartVal = Start->codegen();
  109. if (StartVal == 0) return 0;
  110. // Make the new basic block for the loop header, inserting after current
  111. // block.
  112. Function *TheFunction = AstObjects::Builder.GetInsertBlock()->getParent();
  113. BasicBlock *PreheaderBB = AstObjects::Builder.GetInsertBlock();
  114. BasicBlock *LoopBB =
  115. BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
  116. // Insert an explicit fall through from the current block to the LoopBB.
  117. AstObjects::Builder.CreateBr(LoopBB);
  118. // Start insertion in LoopBB.
  119. AstObjects::Builder.SetInsertPoint(LoopBB);
  120. // Start the PHI node with an entry for Start.
  121. PHINode *Variable = AstObjects::Builder.CreatePHI(Type::getDoubleTy(getGlobalContext()),
  122. 2, VarName.c_str());
  123. Variable->addIncoming(StartVal, PreheaderBB);
  124. // Within the loop, the variable is defined equal to the PHI node. If it
  125. // shadows an existing variable, we have to restore it, so save it now.
  126. Value *OldVal = AstObjects::NamedValues[VarName];
  127. AstObjects::NamedValues[VarName] = Variable;
  128. // Emit the body of the loop. This, like any other expr, can change the
  129. // current BB. Note that we ignore the value computed by the body, but don't
  130. // allow an error.
  131. if (!Body->codegen())
  132. return nullptr;
  133. // Emit the step value.
  134. Value *StepVal = nullptr;
  135. if (Step) {
  136. StepVal = Step->codegen();
  137. if (!StepVal)
  138. return nullptr;
  139. } else {
  140. // If not specified, use 1.0.
  141. StepVal = ConstantFP::get(getGlobalContext(), APFloat(1.0));
  142. }
  143. Value *NextVar = AstObjects::Builder.CreateFAdd(Variable, StepVal, "nextvar");
  144. // Compute the end condition.
  145. Value *EndCond = End->codegen();
  146. if (!EndCond)
  147. return nullptr;
  148. // Convert condition to a bool by comparing equal to 0.0.
  149. EndCond = AstObjects::Builder.CreateFCmpONE(
  150. EndCond, ConstantFP::get(getGlobalContext(), APFloat(0.0)), "loopcond");
  151. // Create the "after loop" block and insert it.
  152. BasicBlock *LoopEndBB = AstObjects::Builder.GetInsertBlock();
  153. BasicBlock *AfterBB =
  154. BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
  155. // Insert the conditional branch into the end of LoopEndBB.
  156. AstObjects::Builder.CreateCondBr(EndCond, LoopBB, AfterBB);
  157. // Any new code will be inserted in AfterBB.
  158. AstObjects::Builder.SetInsertPoint(AfterBB);
  159. // Add a new entry to the PHI node for the backedge.
  160. Variable->addIncoming(NextVar, LoopEndBB);
  161. // Restore the unshadowed variable.
  162. if (OldVal)
  163. AstObjects::NamedValues[VarName] = OldVal;
  164. else
  165. AstObjects::NamedValues.erase(VarName);
  166. // for expr always returns 0.0.
  167. return Constant::getNullValue(Type::getDoubleTy(getGlobalContext()));
  168. }
  169. Function *PrototypeAST::codegen() {
  170. // Make the function type: double(double,double) etc.
  171. std::vector<Type *> Doubles(Args.size(),
  172. Type::getDoubleTy(getGlobalContext()));
  173. FunctionType *FT = FunctionType::get(Type::getDoubleTy(
  174. getGlobalContext()), Doubles, false);
  175. Function *F = Function::Create(FT, Function::ExternalLinkage, Name,
  176. AstObjects::TheModule.get());
  177. // Set names for all arguments.
  178. unsigned Idx = 0;
  179. for (auto &Arg : F->args())
  180. Arg.setName(Args[Idx++]);
  181. return F;
  182. }
  183. Function *FunctionAST::codegen() {
  184. // Transfer ownership of the prototype to the FunctionProtos map, but keep a
  185. // reference to it for use below.
  186. auto &P = *Proto;
  187. JITObjects::FunctionProtos[Proto->getName()] = std::move(Proto);
  188. Function *TheFunction = getFunction(P.getName());
  189. if (!TheFunction)
  190. return nullptr;
  191. // Create a new basic block to start insertion into.
  192. BasicBlock *BB = BasicBlock::Create(getGlobalContext(),
  193. "entry", TheFunction);
  194. AstObjects::Builder.SetInsertPoint(BB);
  195. // Record the function arguments in the NamedValues map.
  196. AstObjects::NamedValues.clear();
  197. for (auto &Arg : TheFunction->args()) {
  198. AstObjects::NamedValues[Arg.getName()] = &Arg;
  199. }
  200. if (Value *RetVal = Body->codegen()) {
  201. // Finish off the function.
  202. AstObjects::Builder.CreateRet(RetVal);
  203. // Validate the generated code, checking for consistency.
  204. verifyFunction(*TheFunction);
  205. // Optimize the function.
  206. JITObjects::TheFPM->run(*TheFunction);
  207. return TheFunction;
  208. }
  209. // Error reading body, remove function.
  210. TheFunction->eraseFromParent();
  211. return nullptr;
  212. }
  213. }