CodegenVisitor.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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.context.getLlvmType(lve.type, 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 == sem::NO_TYPE)//(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. /*return builder.CreateCast(
  99. llvm::Instruction::CastOps::SExt,
  100. cast.expression->accept(*this, builder),
  101. context.getType(cast.targetType).value().getLlvmType(builder.getContext())
  102. );*/
  103. return nullptr;
  104. }
  105. llvm::Value* ExpressionCodegenVisitor::visit(sem::NewExpression& nexpr, llvm::IRBuilder<>& builder)
  106. {
  107. using llvm::Value;
  108. sem::Context& semCtxt = nexpr.context;
  109. sem::TypeId type = nexpr.type;
  110. const llvm::DataLayout& layout = builder.GetInsertBlock()->getModule()->getDataLayout();
  111. llvm::Type* llvmTy = semCtxt.getLlvmType(type, builder.getContext())->getPointerElementType();
  112. auto allocSize = layout.getTypeAllocSize(llvmTy);
  113. auto size = llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, allocSize, false));
  114. auto mallocCall = llvm::CallInst::CreateMalloc(builder.GetInsertBlock(), size->getType(), llvmTy, size, nullptr, nullptr, "");
  115. //auto casted = builder.CreateBitCast(mallocCall, llvmTy);
  116. builder.GetInsertBlock()->getInstList().push_back(llvm::cast<llvm::Instruction>(mallocCall));
  117. return mallocCall;
  118. }
  119. llvm::Value* ExpressionCodegenVisitor::visit(sem::NewArrayExpression& naexpr, llvm::IRBuilder<>& builder)
  120. {
  121. using llvm::Value;
  122. // TODO implement
  123. return nullptr;
  124. }
  125. llvm::Value* ExpressionCodegenVisitor::visit(sem::MethodCallExpression& call, llvm::IRBuilder<>& builder)
  126. {
  127. using llvm::Value;
  128. sem::Context& semCtxt = call.context;
  129. if (call.arguments.size() != call.callee->arguments.size()) {
  130. throw "wrong number of arguments";
  131. }
  132. std::vector<Value*> arguments;
  133. if (call.target != nullptr) {
  134. auto* target = call.target->accept(*this, builder);
  135. #ifdef DEBUGGING
  136. Printer::getInstance() << "creating 'this' argument";
  137. #endif
  138. /*if (llvm::LoadInst* li = llvm::dyn_cast<llvm::LoadInst>(target); li) {
  139. llvm::Value* ptr = builder.CreateLoad(semCtxt.getLlvmType(call.target->type, builder.getContext()), li, "ptrload");
  140. arguments.push_back(ptr);
  141. } else*/
  142. arguments.push_back(target);
  143. }
  144. for (size_t i = 0; i < call.arguments.size(); i++) {
  145. // : call.arguments) {
  146. auto& arg = call.arguments[i];
  147. auto value = arg->accept(*this, builder);
  148. if (arg->type != call.callee->arguments[i]->type) {
  149. throw "argument type mismatch";
  150. }
  151. arguments.push_back(value);
  152. }
  153. //auto returnType = call.callee->returnType;
  154. llvm::CallInst* callInst = builder.CreateCall(call.callee->llvmNode, arguments);
  155. return callInst;
  156. }
  157. llvm::Value* ExpressionCodegenVisitor::visit(sem::FieldAccessExpression& access, llvm::IRBuilder<>& builder)
  158. {
  159. using llvm::Value;
  160. using llvm::Type;
  161. sem::Context& semCtxt = access.context;
  162. Type* type = semCtxt.getLlvmType(access.target->type, builder.getContext());
  163. if (type == nullptr)
  164. throw "no access type";
  165. if (type->isPointerTy()) {
  166. type = type->getPointerElementType();
  167. }
  168. llvm::Value* target = access.target->accept(fg.lvalueVisitor, fg);
  169. llvm::raw_os_ostream os(Printer::getInstance());
  170. type->print(os);
  171. os << "\n";
  172. os.flush();
  173. int structIndex = access.accessed->llvmStructIndex;
  174. llvm::ArrayRef<Value*> indexList = {
  175. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, structIndex, false)),
  176. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false))
  177. };
  178. Value* ptr = builder.CreateGEP(type, target, indexList);
  179. return builder.CreateLoad(ptr);
  180. //builder.CreateStructGEP(type,
  181. // llvm::ConstantInt::get(builder.getContext(),
  182. // llvm::APInt(32, 0, false)), 0);
  183. return llvm::ConstantInt::get(builder.getContext(),
  184. llvm::APInt(32, 0, false));
  185. }
  186. llvm::Value* ExpressionCodegenVisitor::visit(sem::AddressExpression& node, llvm::IRBuilder<>& builder)
  187. {
  188. using llvm::Value;
  189. Value* lvalue = node.target->accept(fg.lvalueVisitor, fg);
  190. // this check is unnecessary
  191. if (auto* allocaInst = llvm::dyn_cast<llvm::AllocaInst>(lvalue)) {
  192. return lvalue;
  193. }
  194. else {
  195. return lvalue;
  196. }
  197. }
  198. llvm::Value* ExpressionCodegenVisitor::visit(sem::IntConst& node, llvm::IRBuilder<>& builder)
  199. {
  200. return llvm::ConstantInt::get(builder.getContext(),
  201. llvm::APInt(64, std::to_string(node.value), 10));
  202. }
  203. llvm::Value* ExpressionCodegenVisitor::visit(sem::ThisExpression& thisExpr, llvm::IRBuilder<>& builder)
  204. {
  205. return thisExpr.allocaInst;
  206. }
  207. llvm::Value* LValueVisitor::visit(sem::Expression& e, qlow::gen::FunctionGenerator& fg)
  208. {
  209. throw "cannot construct lvalue from expression";
  210. }
  211. llvm::Value* LValueVisitor::visit(sem::LocalVariableExpression& lve, qlow::gen::FunctionGenerator& fg)
  212. {
  213. assert(lve.var->allocaInst != nullptr);
  214. if (llvm::dyn_cast<llvm::AllocaInst>(lve.var->allocaInst)) {
  215. return lve.var->allocaInst;
  216. /*llvm::Value* val = builder.CreateLoad(
  217. lve.type->getLlvmType(builder.getContext())->getPointerTo(),
  218. lve.var->allocaInst
  219. );
  220. return val;*/
  221. }
  222. else if (llvm::dyn_cast<llvm::PointerType> (lve.var->allocaInst->getType())) {
  223. return lve.var->allocaInst;
  224. }
  225. else {
  226. return lve.var->allocaInst;
  227. //throw "unable to find alloca instance of local variable";
  228. }
  229. }
  230. llvm::Value* LValueVisitor::visit(sem::FieldAccessExpression& access, qlow::gen::FunctionGenerator& fg)
  231. {
  232. /*
  233. using llvm::Value;
  234. using llvm::Type;
  235. auto& fieldType = fae.accessed->type;
  236. Type* ptr = fieldType->getLlvmType(builder.getContext())->getPointerTo();
  237. llvm::Value* allocaInst = fae.target->accept(*this, builder);
  238. if (ptr == nullptr)
  239. throw "no access type";
  240. llvm::ArrayRef<Value*> indices = {
  241. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false)),
  242. llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0, false))
  243. };
  244. */
  245. using llvm::Value;
  246. using llvm::Type;
  247. sem::Context& semCtxt = access.context;
  248. Type* type = semCtxt.getLlvmType(access.target->type, fg.builder.getContext());
  249. if (type == nullptr)
  250. throw "no access type";
  251. if (type->isPointerTy()) {
  252. type = type->getPointerElementType();
  253. }
  254. llvm::Value* target = access.target->accept(fg.expressionVisitor, fg.builder);
  255. int structIndex = access.accessed->llvmStructIndex;
  256. llvm::ArrayRef<Value*> indexList = {
  257. llvm::ConstantInt::get(fg.builder.getContext(), llvm::APInt(32, structIndex, false)),
  258. llvm::ConstantInt::get(fg.builder.getContext(), llvm::APInt(32, 0, false))
  259. };
  260. Value* ptr = fg.builder.CreateGEP(type, target, indexList);
  261. return ptr;
  262. }
  263. llvm::Value* StatementVisitor::visit(sem::DoEndBlock& assignment,
  264. qlow::gen::FunctionGenerator& fg)
  265. {
  266. for (auto& statement : assignment.statements) {
  267. statement->accept(*this, fg);
  268. }
  269. return nullptr;
  270. }
  271. llvm::Value* StatementVisitor::visit(sem::IfElseBlock& ifElseBlock,
  272. qlow::gen::FunctionGenerator& fg)
  273. {
  274. using llvm::Value;
  275. using llvm::BasicBlock;
  276. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  277. auto condition = ifElseBlock.condition->accept(fg.expressionVisitor, fg.builder);
  278. llvm::Function* function = fg.getCurrentBlock()->getParent();
  279. BasicBlock* thenB = BasicBlock::Create(fg.getContext(), "then", function);
  280. BasicBlock* elseB = BasicBlock::Create(fg.getContext(), "else", function);
  281. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  282. Value* boolCond = fg.builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  283. fg.builder.CreateCondBr(boolCond, thenB, elseB);
  284. fg.pushBlock(thenB);
  285. ifElseBlock.ifBlock->accept(*this, fg);
  286. fg.builder.SetInsertPoint(thenB);
  287. if (!thenB->getTerminator())
  288. fg.builder.CreateBr(merge);
  289. fg.popBlock();
  290. fg.pushBlock(elseB);
  291. ifElseBlock.elseBlock->accept(*this, fg);
  292. fg.builder.SetInsertPoint(elseB);
  293. if (!elseB->getTerminator())
  294. fg.builder.CreateBr(merge);
  295. fg.popBlock();
  296. fg.popBlock();
  297. fg.pushBlock(merge);
  298. return nullptr;
  299. }
  300. llvm::Value* StatementVisitor::visit(sem::WhileBlock& whileBlock,
  301. qlow::gen::FunctionGenerator& fg)
  302. {
  303. using llvm::Value;
  304. using llvm::BasicBlock;
  305. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  306. llvm::Function* function = fg.getCurrentBlock()->getParent();
  307. BasicBlock* startloop = BasicBlock::Create(fg.getContext(), "startloop", function);
  308. BasicBlock* body = BasicBlock::Create(fg.getContext(), "loopbody", function);
  309. BasicBlock* merge = BasicBlock::Create(fg.getContext(), "merge", function);
  310. //builder.CreateCondBr(boolCond, body, merge);
  311. fg.builder.CreateBr(startloop);
  312. fg.pushBlock(startloop);
  313. fg.builder.SetInsertPoint(startloop);
  314. auto condition = whileBlock.condition->accept(fg.expressionVisitor, fg.builder);
  315. Value* boolCond = fg.builder.CreateIntCast(condition, llvm::Type::getInt1Ty(fg.getContext()), false);
  316. fg.builder.CreateCondBr(condition, body, merge);
  317. fg.popBlock();
  318. fg.pushBlock(body);
  319. whileBlock.body->accept(*this, fg);
  320. fg.builder.SetInsertPoint(body);
  321. fg.builder.CreateBr(startloop);
  322. fg.popBlock();
  323. fg.pushBlock(merge);
  324. return nullptr;
  325. }
  326. llvm::Value* StatementVisitor::visit(sem::AssignmentStatement& assignment,
  327. qlow::gen::FunctionGenerator& fg)
  328. {
  329. Printer& printer = Printer::getInstance();
  330. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  331. auto val = assignment.value->accept(fg.expressionVisitor, fg.builder);
  332. auto target = assignment.target->accept(fg.lvalueVisitor, fg);
  333. return fg.builder.CreateStore(val, target);
  334. /*
  335. if (auto* targetVar =
  336. dynamic_cast<sem::LocalVariableExpression*>(assignment.target.get()); targetVar) {
  337. #ifdef DEBUGGING
  338. printer << "assigning to LocalVariableExpression" << std::endl;
  339. #endif
  340. builder.CreateStore(val, targetVar->var->allocaInst);
  341. }
  342. else if (auto* targetVar =
  343. dynamic_cast<sem::FieldAccessExpression*>(assignment.target.get()); targetVar) {
  344. #ifdef DEBUGGING
  345. printer << "assigning to FieldAccessExpression" << std::endl;
  346. #endif
  347. if (targetVar->target) {
  348. llvm::Value* target = targetVar->target->accept(fg.expressionVisitor, builder);
  349. //auto elementPtr = builder.CreateGEP(targetVar->target->type->getLlvmType(fg.getContext()), target, llvm::ConstantInt::get(builder.getContext(), llvm::APInt(32, 0)));
  350. auto elementPtr = llvm::ConstantPointerNull::get(val->getType()->getPointerTo());
  351. builder.CreateStore(val, elementPtr);
  352. }
  353. else {
  354. throw "field access without target";
  355. }
  356. }
  357. else {
  358. #ifdef DEBUGGING
  359. printer << "assigning to instance of " << assignment.target->toString() << std::endl;
  360. #endif
  361. throw "only local variables are assignable at the moment";
  362. }
  363. return nullptr;
  364. //return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5123.0));*/
  365. }
  366. llvm::Value* StatementVisitor::visit(sem::ReturnStatement& returnStatement,
  367. qlow::gen::FunctionGenerator& fg)
  368. {
  369. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  370. auto val = returnStatement.value->accept(fg.expressionVisitor, fg.builder);
  371. fg.builder.CreateRet(val);
  372. return val;
  373. }
  374. llvm::Value* StatementVisitor::visit(sem::FeatureCallStatement& fc, gen::FunctionGenerator& fg)
  375. {
  376. llvm::Module* module = fg.getModule();
  377. fg.builder.SetInsertPoint(fg.getCurrentBlock());
  378. //llvm::Constant* c = module->getOrInsertFunction(fc.expr->callee->name, {});
  379. return fc.expr->accept(fg.expressionVisitor, fg.builder);
  380. /*
  381. llvm::Function* f = fc.expr->callee->llvmNode;
  382. std::vector<llvm::Value*> arguments;
  383. for (auto& arg : fc.expr->arguments) {
  384. arguments
  385. }
  386. builder.CreateCall(f, {});
  387. */
  388. // return llvm::ConstantFP::get(fg.getContext(), llvm::APFloat(5.0));
  389. }
  390. llvm::Value* CastGenerator::generateCast(llvm::Value* toCast,
  391. llvm::IRBuilder<>& b)
  392. {
  393. /*return b.CreateCast(
  394. llvm::Instruction::CastOps::BitCast, toCast,
  395. cast.to->getLlvmType(b.getContext()));*/
  396. return nullptr;
  397. }