CodegenVisitor.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. #include "CodegenVisitor.h"
  2. #include "CodeGeneration.h"
  3. #include "Type.h"
  4. #include "Builtin.h"
  5. #include "ErrorReporting.h"
  6. #include <llvm/IR/Constants.h>
  7. #include <llvm/IR/IRBuilder.h>
  8. #include <llvm/IR/DataLayout.h>
  9. #include <llvm/Support/raw_os_ostream.h>
  10. using namespace qlow;
  11. llvm::Value* ExpressionCodegenVisitor::visit(sem::LocalVariableExpression& lve, llvm::IRBuilder<>& builder)
  12. {
  13. assert(lve.var->allocaInst != nullptr);
  14. if (llvm::dyn_cast<llvm::AllocaInst>(lve.var->allocaInst)) {
  15. llvm::Type* returnType = lve.type->getLlvmType(builder.getContext());
  16. llvm::Value* val = builder.CreateLoad(returnType, lve.var->allocaInst);
  17. return val;
  18. }
  19. else {
  20. return lve.var->allocaInst;
  21. }
  22. }
  23. llvm::Value* ExpressionCodegenVisitor::visit(sem::UnaryOperation& unop, llvm::IRBuilder<>& builder)
  24. {
  25. using llvm::Value;
  26. auto value = unop.arg->accept(*this, builder);
  27. auto& type = unop.arg->type;
  28. if (type == nullptr)//(type->equals(sem::NativeType(sem::NativeType::Type::VOID)))
  29. throw "invalid type to negate";
  30. /*
  31. switch (unop.op) {
  32. case ast::Operation::Operator::MINUS:
  33. return builder.CreateNeg(value, "negate");
  34. case ast::Operation::Operator::NOT:
  35. return builder.CreateNot(value, "not");
  36. default:
  37. throw "operator not supported";
  38. }*/
  39. return nullptr;
  40. }
  41. llvm::Value* ExpressionCodegenVisitor::visit(sem::BinaryOperation& binop, llvm::IRBuilder<>& builder)
  42. {
  43. using llvm::Value;
  44. using sem::Type;
  45. auto left = binop.left->accept(*this, builder);
  46. auto right = binop.right->accept(*this, builder);
  47. auto& leftType = binop.left->type;
  48. auto& rightType = binop.right->type;
  49. sem::Method* operation = binop.operationMethod;
  50. if (operation != nullptr) {
  51. // TODO rewrite
  52. if (sem::NativeMethod* nm = dynamic_cast<sem::NativeMethod*>(operation); nm) {
  53. return nm->generateCode(builder, {left, right});
  54. }
  55. else
  56. throw "only native operations supported at the moment";
  57. }
  58. else {
  59. throw "internal error: operation method null";
  60. }
  61. // unreachable
  62. if (left == nullptr) {
  63. printf("WOW: %s\n", binop.left->toString().c_str());
  64. }
  65. Value* implicitelyCastedRight = right;
  66. // TODO rewritten types
  67. //if (leftType != rightType))
  68. // implicitelyCastedRight = dynamic_cast<sem::NativeType*>(leftType.get())->generateImplicitCast(right);
  69. /*
  70. if (dynamic_cast<sem::NativeType*>(leftType.get())->isIntegerType()) {
  71. // TODO allow integer operations
  72. }*/
  73. /*
  74. // TODO insert type checks
  75. switch (binop.op) {
  76. case ast::Operation::Operator::PLUS:
  77. return builder.CreateAdd(left, right, "add");
  78. case ast::Operation::Operator::MINUS:
  79. return builder.CreateSub(left, right, "sub");
  80. case ast::Operation::Operator::ASTERISK:
  81. return builder.CreateMul(left, right, "mul");
  82. case ast::Operation::Operator::SLASH:
  83. return builder.CreateSDiv(left, right, "sdiv");
  84. case ast::Operation::Operator::AND:
  85. return builder.CreateAnd(left, right, "and");
  86. case ast::Operation::Operator::OR:
  87. return builder.CreateOr(left, right, "or");
  88. case ast::Operation::Operator::XOR:
  89. return builder.CreateXor(left, right, "xor");
  90. case ast::Operation::Operator::EQUALS:
  91. return builder.CreateICmpEQ(left, right, "equals");
  92. case ast::Operation::Operator::NOT_EQUALS:
  93. return builder.CreateICmpNE(left, right, "not_equals");
  94. }*/
  95. }
  96. llvm::Value* ExpressionCodegenVisitor::visit(sem::CastExpression& cast, llvm::IRBuilder<>& builder)
  97. {
  98. if (cast.isNativeCast) {
  99. return builder.CreateCast(
  100. llvm::Instruction::CastOps::SExt,
  101. cast.expression->accept(*this, builder),
  102. cast.targetType->getLlvmType(builder.getContext())
  103. );
  104. }
  105. return nullptr;
  106. }
  107. llvm::Value* ExpressionCodegenVisitor::visit(sem::NewExpression& nexpr, llvm::IRBuilder<>& builder)
  108. {
  109. using llvm::Value;
  110. sem::Context& semCtxt = nexpr.context;
  111. sem::Type* type = nexpr.type;
  112. const llvm::DataLayout& layout = builder.GetInsertBlock()->getModule()->getDataLayout();
  113. llvm::Type* llvmTy = type->getLlvmType(builder.getContext())->getPointerElementType();
  114. auto allocSize = layout.getTypeAllocSize(llvmTy);
  115. auto size = llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, allocSize, false));
  116. auto mallocCall = llvm::CallInst::CreateMalloc(builder.GetInsertBlock(), size->getType(), llvmTy, size, nullptr, nullptr, "");
  117. //auto casted = builder.CreateBitCast(mallocCall, llvmTy);
  118. builder.GetInsertBlock()->getInstList().push_back(llvm::cast<llvm::Instruction>(mallocCall));
  119. return mallocCall;
  120. }
  121. llvm::Value* ExpressionCodegenVisitor::visit(sem::NewArrayExpression& naexpr, llvm::IRBuilder<>& builder)
  122. {
  123. using llvm::Value;
  124. // TODO implement
  125. return nullptr;
  126. }
  127. llvm::Value* ExpressionCodegenVisitor::visit(sem::MethodCallExpression& call, llvm::IRBuilder<>& builder)
  128. {
  129. using llvm::Value;
  130. sem::Context& semCtxt = call.context;
  131. if (call.arguments.size() != call.callee->arguments.size()) {
  132. throw "wrong number of arguments";
  133. }
  134. std::vector<Value*> arguments;
  135. if (call.target != nullptr) {
  136. auto* target = call.target->accept(*this, builder);
  137. #ifdef DEBUGGING
  138. Printer::getInstance() << "creating 'this' argument";
  139. #endif
  140. /*if (llvm::LoadInst* li = llvm::dyn_cast<llvm::LoadInst>(target); li) {
  141. llvm::Value* ptr = builder.CreateLoad(semCtxt.getLlvmType(call.target->type, builder.getContext()), li, "ptrload");
  142. arguments.push_back(ptr);
  143. } else*/
  144. arguments.push_back(target);
  145. }
  146. for (size_t i = 0; i < call.arguments.size(); i++) {
  147. // : call.arguments) {
  148. auto& arg = call.arguments[i];
  149. auto value = arg->accept(*this, builder);
  150. if (arg->type != call.callee->arguments[i]->type) {
  151. throw "argument type mismatch";
  152. }
  153. arguments.push_back(value);
  154. }
  155. //auto returnType = call.callee->returnType;
  156. llvm::CallInst* callInst = builder.CreateCall(call.callee->llvmNode, arguments);
  157. return callInst;
  158. }
  159. llvm::Value* ExpressionCodegenVisitor::visit(sem::FieldAccessExpression& access, llvm::IRBuilder<>& builder)
  160. {
  161. using llvm::Value;
  162. using llvm::Type;
  163. sem::Context& semCtxt = access.context;
  164. Type* type = access.target->type->getLlvmType(builder.getContext());
  165. if (type == nullptr)
  166. throw "no access type";
  167. if (type->isPointerTy()) {
  168. type = type->getPointerElementType();
  169. }
  170. llvm::Value* target = access.target->accept(fg.lvalueVisitor, fg);
  171. int structIndex = access.accessed->llvmStructIndex;
  172. llvm::ArrayRef<Value*> indexList = {
  173. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, structIndex, false)),
  174. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false))
  175. };
  176. Value* ptr = builder.CreateGEP(type, target, indexList);
  177. return builder.CreateLoad(ptr);
  178. //builder.CreateStructGEP(type,
  179. // llvm::ConstantInt::get(builder.getContext(),
  180. // llvm::APInt(32, 0, false)), 0);
  181. return llvm::ConstantInt::get(builder.getContext(),
  182. llvm::APInt(32, 0, false));
  183. }
  184. llvm::Value* ExpressionCodegenVisitor::visit(sem::AddressExpression& node, llvm::IRBuilder<>& builder)
  185. {
  186. using llvm::Value;
  187. Value* lvalue = node.target->accept(fg.lvalueVisitor, fg);
  188. // this check is unnecessary
  189. if (auto* allocaInst = llvm::dyn_cast<llvm::AllocaInst>(lvalue)) {
  190. return lvalue;
  191. }
  192. else {
  193. return lvalue;
  194. }
  195. }
  196. llvm::Value* ExpressionCodegenVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder)
  197. {
  198. return llvm::ConstantInt::get(builder.getContext(),
  199. llvm::APInt(64, std::to_string(node.value), 10));
  200. }
  201. llvm::Value* ExpressionCodegenVisitor::visit(sem::ThisExpression& thisExpr, llvm::IRBuilder<>& builder)
  202. {
  203. return thisExpr.allocaInst;
  204. }
  205. llvm::Value* LValueVisitor::visit(sem::Expression& e, qlow::gen::FunctionGenerator& fg)
  206. {
  207. throw "cannot construct lvalue from expression";
  208. }
  209. llvm::Value* LValueVisitor::visit(sem::LocalVariableExpression& lve, qlow::gen::FunctionGenerator& fg)
  210. {
  211. assert(lve.var->allocaInst != nullptr);
  212. if (llvm::dyn_cast<llvm::AllocaInst>(lve.var->allocaInst)) {
  213. return lve.var->allocaInst;
  214. /*llvm::Value* val = builder.CreateLoad(
  215. lve.type->getLlvmType(builder.getContext())->getPointerTo(),
  216. lve.var->allocaInst
  217. );
  218. return val;*/
  219. }
  220. else if (llvm::dyn_cast<llvm::PointerType> (lve.var->allocaInst->getType())) {
  221. return lve.var->allocaInst;
  222. }
  223. else {
  224. return lve.var->allocaInst;
  225. //throw "unable to find alloca instance of local variable";
  226. }
  227. }
  228. llvm::Value* LValueVisitor::visit(sem::FieldAccessExpression& access, qlow::gen::FunctionGenerator& fg)
  229. {
  230. /*
  231. using llvm::Value;
  232. using llvm::Type;
  233. auto& fieldType = fae.accessed->type;
  234. Type* ptr = fieldType->getLlvmType(builder.getContext())->getPointerTo();
  235. llvm::Value* allocaInst = fae.target->accept(*this, builder);
  236. if (ptr == nullptr)
  237. throw "no access type";
  238. llvm::ArrayRef<Value*> indices = {
  239. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false)),
  240. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false))
  241. };
  242. */
  243. using llvm::Value;
  244. using llvm::Type;
  245. sem::Context& semCtxt = access.context;
  246. Type* type = access.target->type->getLlvmType(fg.builder.getContext());
  247. if (type == nullptr)
  248. throw "no access type";
  249. if (type->isPointerTy()) {
  250. type = type->getPointerElementType();
  251. }
  252. llvm::Value* target = access.target->accept(fg.expressionVisitor, fg.builder);
  253. int structIndex = access.accessed->llvmStructIndex;
  254. llvm::ArrayRef<Value*> indexList = {
  255. llvm::ConstantInt::get(fg.builder.getContext(), llvm::APInt(32, structIndex, false)),
  256. llvm::ConstantInt::get(fg.builder.getContext(), llvm::APInt(32, 0, false))
  257. };
  258. Value* ptr = fg.builder.CreateGEP(type, target, indexList);
  259. return ptr;
  260. }
  261. llvm::Value* StatementVisitor::visit(sem::DoEndBlock& assignment,
  262. qlow::gen::FunctionGenerator& fg)
  263. {
  264. for (auto& statement : assignment.statements) {
  265. statement->accept(*this, fg);
  266. }
  267. return nullptr;
  268. }
  269. llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
  270. qlow::gen::FunctionGenerator& fg)
  271. {
  272. using llvm::Value;
  273. using llvm::BasicBlock;
  274. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  275. auto condition = ifElseBlock.condition->accept(fg.expressionVisitor, fg.builder);
  276. llvm::Function* function = fg.getCurrentBlock()->getParent();
  277. BasicBlock* thenB = BasicBlock::Create(fg.getContext(), "then", function);
  278. BasicBlock* elseB = BasicBlock::Create(fg.getContext(), "else", function);
  279. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  280. Value* boolCond = fg.builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  281. fg.builder.CreateCondBr(boolCond, thenB, elseB);
  282. fg.pushBlock(thenB);
  283. ifElseBlock.ifBlock->accept(*this, fg);
  284. fg.builder.SetInsertPoint(thenB);
  285. if (!thenB->getTerminator())
  286. fg.builder.CreateBr(merge);
  287. fg.popBlock();
  288. fg.pushBlock(elseB);
  289. ifElseBlock.elseBlock->accept(*this, fg);
  290. fg.builder.SetInsertPoint(elseB);
  291. if (!elseB->getTerminator())
  292. fg.builder.CreateBr(merge);
  293. fg.popBlock();
  294. fg.popBlock();
  295. fg.pushBlock(merge);
  296. return nullptr;
  297. }
  298. llvm::Value* StatementVisitor::visit(sem::WhileBlock& whileBlock,
  299. qlow::gen::FunctionGenerator& fg)
  300. {
  301. using llvm::Value;
  302. using llvm::BasicBlock;
  303. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  304. llvm::Function* function = fg.getCurrentBlock()->getParent();
  305. BasicBlock* startloop = BasicBlock::Create(fg.getContext(), "startloop", function);
  306. BasicBlock* body = BasicBlock::Create(fg.getContext(), "loopbody", function);
  307. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  308. //builder.CreateCondBr(boolCond, body, merge);
  309. fg.builder.CreateBr(startloop);
  310. fg.pushBlock(startloop);
  311. fg.builder.SetInsertPoint(startloop);
  312. auto condition = whileBlock.condition->accept(fg.expressionVisitor, fg.builder);
  313. Value* boolCond = fg.builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  314. fg.builder.CreateCondBr(condition, body, merge);
  315. fg.popBlock();
  316. fg.pushBlock(body);
  317. whileBlock.body->accept(*this, fg);
  318. fg.builder.SetInsertPoint(body);
  319. fg.builder.CreateBr(startloop);
  320. fg.popBlock();
  321. fg.pushBlock(merge);
  322. return nullptr;
  323. }
  324. llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment,
  325. qlow::gen::FunctionGenerator& fg)
  326. {
  327. Printer& printer = Printer::getInstance();
  328. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  329. auto val = assignment.value->accept(fg.expressionVisitor, fg.builder);
  330. auto target = assignment.target->accept(fg.lvalueVisitor, fg);
  331. return fg.builder.CreateStore(val, target);
  332. /*
  333. if (auto* targetVar =
  334. dynamic_cast<sem::LocalVariableExpression*>(assignment.target.get()); targetVar) {
  335. #ifdef DEBUGGING
  336. printer << "assigning to LocalVariableExpression" << std::endl;
  337. #endif
  338. builder.CreateStore(val, targetVar->var->allocaInst);
  339. }
  340. else if (auto* targetVar =
  341. dynamic_cast<sem::FieldAccessExpression*>(assignment.target.get()); targetVar) {
  342. #ifdef DEBUGGING
  343. printer << "assigning to FieldAccessExpression" << std::endl;
  344. #endif
  345. if (targetVar->target) {
  346. llvm::Value* target = targetVar->target->accept(fg.expressionVisitor, builder);
  347. //auto elementPtr = builder.CreateGEP(targetVar->target->type->getLlvmType(fg.getContext()), target, llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0)));
  348. auto elementPtr = llvm::ConstantPointerNull::get(val->getType()->getPointerTo());
  349. builder.CreateStore(val, elementPtr);
  350. }
  351. else {
  352. throw "field access without target";
  353. }
  354. }
  355. else {
  356. #ifdef DEBUGGING
  357. printer << "assigning to instance of " << assignment.target->toString() << std::endl;
  358. #endif
  359. throw "only local variables are assignable at the moment";
  360. }
  361. return nullptr;
  362. //return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5123.0));*/
  363. }
  364. llvm::Value* StatementVisitor::visit(sem::ReturnStatement& returnStatement,
  365. qlow::gen::FunctionGenerator& fg)
  366. {
  367. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  368. auto val = returnStatement.value->accept(fg.expressionVisitor, fg.builder);
  369. fg.builder.CreateRet(val);
  370. return val;
  371. }
  372. llvm::Value* StatementVisitor::visit(sem::FeatureCallStatement& fc, gen::FunctionGenerator& fg)
  373. {
  374. llvm::Module* module = fg.getModule();
  375. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  376. //llvm::Constant* c = module->getOrInsertFunction(fc.expr->callee->name, {});
  377. return fc.expr->accept(fg.expressionVisitor, fg.builder);
  378. /*
  379. llvm::Function* f = fc.expr->callee->llvmNode;
  380. std::vector<llvm::Value*> arguments;
  381. for (auto& arg : fc.expr->arguments) {
  382. arguments
  383. }
  384. builder.CreateCall(f, {});
  385. */
  386. // return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5.0));
  387. }
  388. llvm::Value* CastGenerator::generateCast(llvm::Value* toCast,
  389. llvm::IRBuilder<>& b)
  390. {
  391. /*return b.CreateCast(
  392. llvm::Instruction::CastOps::BitCast, toCast,
  393. cast.to->getLlvmType(b.getContext()));*/
  394. return nullptr;
  395. }