CodegenVisitor.cpp 15 KB

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