1 #include "codegen/code_generator.h"
2 #include "ast/ast_base.h"
7 #include "ast/intrinsic.h"
8 #include "ast/package.h"
9 #include "ast/default_value.h"
12 #include <llvm/IR/Value.h>
13 #include <llvm/IR/LLVMContext.h>
14 #include <llvm/IR/IRBuilder.h>
15 #include <llvm/ADT/APFloat.h>
16 #include <llvm/IR/Function.h>
17 #include <llvm/ADT/APInt.h>
18 #include "llvm/ADT/StringRef.h"
19 #include <llvm/IR/Verifier.h>
20 #include <llvm/IR/Instruction.h>
21 #include <llvm/IR/DerivedTypes.h>
22 #include <llvm/MC/TargetRegistry.h>
23 #include <llvm/IR/Module.h>
24 #include <llvm/Support/FileSystem.h>
25 #include <llvm/IR/LegacyPassManager.h>
26 #include <llvm/IR/DataLayout.h>
27 #include <llvm/ExecutionEngine/SectionMemoryManager.h>
28 #include <llvm/IR/GlobalVariable.h>
29 #include <llvm/IR/GlobalValue.h>
30 #include <llvm/Transforms/IPO/PassManagerBuilder.h>
31 #include <llvm/Transforms/Scalar.h>
32 #include <llvm/Transforms/Scalar/GVN.h>
33 #include <llvm/IR/DIBuilder.h>
34 #include <llvm/IR/DebugInfo.h>
35 #include <llvm/Support/CodeGen.h>
36 #include <clang/Basic/TargetOptions.h>
37 #include <clang/Frontend/CompilerInvocation.h>
38 #include <llvm/LinkAllPasses.h>
39 #include <llvm/Option/OptTable.h>
40 #include <llvm/Support/ManagedStatic.h>
41 #include <llvm/Support/Signals.h>
42 #include <llvm/Support/TimeProfiler.h>
43 #include <llvm/Support/raw_ostream.h>
44 #include <llvm/Target/TargetMachine.h>
45 #include <llvm/Analysis/TargetTransformInfo.h>
46 #include <clang/Basic/DiagnosticOptions.h>
47 #include <llvm/ADT/StringSwitch.h>
48 #include <llvm/MC/MCAsmBackend.h>
49 #include <llvm/MC/MCAsmInfo.h>
50 #include <llvm/MC/MCCodeEmitter.h>
51 #include <llvm/MC/MCContext.h>
52 #include <llvm/MC/MCInstrInfo.h>
53 #include <llvm/MC/MCObjectFileInfo.h>
54 #include <llvm/MC/MCObjectWriter.h>
55 #include <llvm/MC/MCParser/MCAsmParser.h>
56 #include <llvm/MC/MCParser/MCTargetAsmParser.h>
57 #include <llvm/MC/MCRegisterInfo.h>
58 #include <llvm/MC/MCSectionMachO.h>
59 #include <llvm/MC/MCStreamer.h>
60 #include <llvm/MC/MCSubtargetInfo.h>
61 #include <llvm/Support/FormattedStream.h>
62 #include <llvm/Support/Process.h>
63 #include <llvm/Support/Regex.h>
64 #include <llvm/Support/StringSaver.h>
65 #include <llvm/ADT/Triple.h>
66 #include <llvm/Object/Archive.h>
67 #include <llvm/Object/IRObjectFile.h>
68 #include <llvm/Object/MachO.h>
69 #include <llvm/Support/ConvertUTF.h>
70 #include <llvm/Support/Errc.h>
71 #include <clang/CodeGen/CodeGenAction.h>
72 #include <lld/Common/Driver.h>
73 #include <llvm/Passes/PassBuilder.h>
75 using llvm::AllocaInst;
78 using llvm::BasicBlock;
79 using llvm::CGSCCAnalysisManager;
81 using llvm::ConstantArray;
82 using llvm::ConstantFP;
83 using llvm::ConstantInt;
84 using llvm::ConstantPointerNull;
85 using llvm::ConstantStruct;
86 using llvm::DataLayout;
88 using llvm::DIBuilder;
89 using llvm::DICompileUnit;
91 using llvm::DILocation;
94 using llvm::DISubprogram;
95 using llvm::DISubroutineType;
99 using llvm::FunctionAnalysisManager;
100 using llvm::GlobalValue;
101 using llvm::GlobalVariable;
102 using llvm::IRBuilder;
103 using llvm::LLVMContext;
104 using llvm::LoopAnalysisManager;
106 using llvm::Metadata;
108 using llvm::ModuleAnalysisManager;
109 using llvm::ModulePassManager;
110 using llvm::PassBuilder;
111 using llvm::PassManagerBuilder;
113 using llvm::SectionMemoryManager;
114 using llvm::StringRef;
115 using llvm::TargetMachine;
118 using llvm::verifyFunction;
119 using llvm::legacy::FunctionPassManager;
120 using llvm::legacy::PassManager;
122 #define AST_LINENO(p) (p->src()->get_line(p->start()))
123 #define AST_COL(p) (p->src()->get_col(p->start()))
127 void CodeGenerator::init(Package *package) {
128 _llvm_ctx =
new LLVMContext();
129 _builder =
new IRBuilder<>(*_llvm_ctx);
130 _module =
new Module(package->get_name(), *_llvm_ctx);
131 _module->setDataLayout(_target_machine->createDataLayout());
132 _module->setTargetTriple(_target_machine->getTargetTriple().str());
135 _module->addModuleFlag(Module::Warning,
"Dwarf Version", llvm::dwarf::DWARF_VERSION);
136 _module->addModuleFlag(Module::Warning,
"Debug Info Version", llvm::DEBUG_METADATA_VERSION);
139 _di_builder =
new DIBuilder(*_module);
141 auto *di_package = _di_builder->createFile(
"<package-" + package->get_name() +
">",
".");
144 auto *cu = _di_builder->createCompileUnit(llvm::dwarf::DW_LANG_C, di_package, package->get_name(),
false,
"", 0);
147 _di_scope.push_back(di_package);
150 CodeGenerator::CodeGenerator(TargetMachine *target_machine) : _target_machine(target_machine) {}
152 CodeGenerator::~CodeGenerator() {
163 void CodeGenerator::run_impl(Package *package) {
168 _di_builder->finalize();
173 llvm::Value *CodeGenerator::cached_visit(ASTBase *p) {
174 auto it = _llvm_value_cache.find(p);
175 if (it != _llvm_value_cache.end()) {
178 set_current_debug_location(p);
182 return _llvm_value_cache[p];
185 void CodeGenerator::default_visit(ASTBase *) { TAN_ASSERT(
false); }
187 void CodeGenerator::run_passes() {
188 auto opt_level = _target_machine->getOptLevel();
189 bool debug = opt_level == llvm::CodeGenOpt::Level::None;
193 LoopAnalysisManager LAM;
194 FunctionAnalysisManager FAM;
195 CGSCCAnalysisManager CGAM;
196 ModuleAnalysisManager MAM;
199 PassBuilder PB(_target_machine);
202 PB.registerModuleAnalyses(MAM);
203 PB.registerCGSCCAnalyses(CGAM);
204 PB.registerFunctionAnalyses(FAM);
205 PB.registerLoopAnalyses(LAM);
206 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
211 ModulePassManager MPM = PB.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O2);
213 MPM.run(*_module, MAM);
217 void CodeGenerator::emit_to_file(
const str &filename) {
219 llvm::raw_fd_ostream dest(filename, ec, llvm::sys::fs::OF_None);
221 Error err(
"Could not open file: " + ec.message());
224 PassManager emit_pass;
225 auto file_type = llvm::CGFT_ObjectFile;
226 if (_target_machine->addPassesToEmitFile(emit_pass, dest,
nullptr, file_type)) {
227 Error err(
"Target machine can't emit a file of this type");
230 emit_pass.run(*_module);
234 void CodeGenerator::dump_ir()
const { _module->print(llvm::outs(),
nullptr); }
238 DIFile *CodeGenerator::get_or_create_di_file(ASTBase *p) {
239 auto *src = p->src();
241 auto q = _di_files.find(src);
242 if (q != _di_files.end()) {
246 auto *ret = _di_builder->createFile(src->get_filename(),
".");
247 _di_files[src] = ret;
252 AllocaInst *CodeGenerator::create_block_alloca(BasicBlock *block, llvm::Type *type,
size_t size,
const str &name) {
253 block = &block->getParent()->getEntryBlock();
254 IRBuilder<> tmp_builder(block, block->begin());
256 return tmp_builder.CreateAlloca(type,
nullptr, name);
258 return tmp_builder.CreateAlloca(type, tmp_builder.getInt32((
unsigned)size), name);
262 llvm::Value *CodeGenerator::convert_llvm_type_to(Expr *expr, Type *dest) {
264 Value *loaded = load_if_is_lvalue(expr);
266 Type *orig = expr->get_type();
268 bool is_pointer1 = orig->is_pointer();
269 bool is_pointer2 = dest->is_pointer();
275 if (is_pointer1 && is_pointer2) {
277 return _builder->CreateBitCast(loaded, to_llvm_type(dest));
278 }
else if ((orig->is_int() || orig->is_char()) && (dest->is_char() || dest->is_int())) {
279 if (dest->is_unsigned())
280 return _builder->CreateZExtOrTrunc(loaded, to_llvm_type(dest));
282 return _builder->CreateSExtOrTrunc(loaded, to_llvm_type(dest));
283 }
else if (orig->is_int() && dest->is_float()) {
284 if (orig->is_unsigned()) {
285 return _builder->CreateUIToFP(loaded, to_llvm_type(dest));
287 return _builder->CreateSIToFP(loaded, to_llvm_type(dest));
289 }
else if (orig->is_float() && dest->is_int()) {
290 if (dest->is_unsigned()) {
291 return _builder->CreateFPToUI(loaded, to_llvm_type(dest));
293 return _builder->CreateFPToSI(loaded, to_llvm_type(dest));
295 }
else if (orig->is_float() && dest->is_float()) {
296 return _builder->CreateFPCast(loaded, to_llvm_type(dest));
297 }
else if (orig->is_bool() && dest->is_int()) {
298 return _builder->CreateZExtOrTrunc(loaded, to_llvm_type(dest));
299 }
else if (orig->is_bool() && dest->is_float()) {
300 return _builder->CreateUIToFP(loaded, to_llvm_type(dest));
301 }
else if (dest->is_bool()) {
302 if (orig->is_float()) {
303 if (orig->get_size_bits() == 32) {
304 return _builder->CreateFCmpONE(loaded, ConstantFP::get(_builder->getFloatTy(), 0.0f));
306 return _builder->CreateFCmpONE(loaded, ConstantFP::get(_builder->getDoubleTy(), 0.0f));
308 }
else if (orig->is_pointer()) {
309 size_t s1 = _target_machine->getPointerSizeInBits(0);
310 loaded = _builder->CreatePtrToInt(loaded, _builder->getIntNTy((
unsigned)s1));
311 return _builder->CreateICmpNE(loaded, ConstantInt::get(_builder->getIntNTy((
unsigned)s1), 0,
false));
312 }
else if (orig->is_int()) {
313 return _builder->CreateICmpNE(loaded,
314 ConstantInt::get(_builder->getIntNTy((
unsigned)orig->get_size_bits()), 0,
false));
316 }
else if (orig->is_string() && dest->is_pointer()) {
318 }
else if (orig->is_array() && dest->is_pointer()) {
320 }
else if (orig->is_array() && dest->is_string()) {
324 error(ErrorType::SEMANTIC_ERROR, expr,
"Cannot perform type conversion");
327 llvm::Value *CodeGenerator::load_if_is_lvalue(Expr *expr) {
328 Value *val = _llvm_value_cache[expr];
331 if (expr->is_lvalue()) {
332 return _builder->CreateLoad(to_llvm_type(expr->get_type()), val,
"lvalue_load");
337 llvm::Type *CodeGenerator::to_llvm_type(Type *p) {
339 TAN_ASSERT(!p->is_ref());
341 auto it = _llvm_type_cache.find(p);
342 if (it != _llvm_type_cache.end()) {
346 llvm::Type *ret =
nullptr;
348 if (p->is_primitive()) {
349 int size_bits = p->get_size_bits();
351 ret = _builder->getIntNTy((
unsigned)size_bits);
352 }
else if (p->is_char()) {
353 ret = _builder->getInt8Ty();
354 }
else if (p->is_bool()) {
355 ret = _builder->getInt1Ty();
356 }
else if (p->is_float()) {
357 if (32 == size_bits) {
358 ret = _builder->getFloatTy();
359 }
else if (64 == size_bits) {
360 ret = _builder->getDoubleTy();
364 }
else if (p->is_void()) {
365 ret = _builder->getVoidTy();
367 }
else if (p->is_string()) {
368 ret = _builder->getInt8PtrTy();
369 }
else if (p->is_struct()) {
371 _llvm_type_cache[p] = ret = llvm::StructType::create(*_llvm_ctx, p->get_typename());
372 auto types = pcast<StructType>(p)->get_member_types();
373 vector<llvm::Type *> elements(types.size(),
nullptr);
374 for (
size_t i = 0; i < types.size(); ++i) {
375 elements[i] = to_llvm_type(types[i]);
377 ((llvm::StructType *)ret)->setBody(elements);
378 }
else if (p->is_array()) {
379 auto *e_type = to_llvm_type(pcast<ArrayType>(p)->get_element_type());
380 ret = e_type->getPointerTo();
381 }
else if (p->is_pointer()) {
382 auto *e_type = to_llvm_type(pcast<PointerType>(p)->get_pointee());
383 ret = e_type->getPointerTo();
384 }
else if (p->is_function()) {
385 auto *func_type = pcast<tanlang::FunctionType>(p);
386 vector<llvm::Type *> arg_types{};
387 for (
auto *t : func_type->get_arg_types()) {
388 arg_types.push_back(to_llvm_type(t));
390 auto *ret_type = to_llvm_type(func_type->get_return_type());
391 ret = llvm::FunctionType::get(ret_type, arg_types,
false);
396 _llvm_type_cache[p] = ret;
400 llvm::Metadata *CodeGenerator::to_llvm_metadata(Type *p, DIFile *di_file, uint32_t lineno) {
402 TAN_ASSERT(!p->is_ref());
404 auto it = _llvm_meta_cache.find(p);
405 if (it != _llvm_meta_cache.end()) {
409 DIType *ret =
nullptr;
410 if (p->is_primitive()) {
411 unsigned dwarf_encoding = 0;
412 int size_bits = p->get_size_bits();
414 if (p->is_unsigned()) {
415 if (size_bits == 8) {
416 dwarf_encoding = llvm::dwarf::DW_ATE_unsigned_char;
418 dwarf_encoding = llvm::dwarf::DW_ATE_unsigned;
421 if (size_bits == 8) {
422 dwarf_encoding = llvm::dwarf::DW_ATE_signed_char;
424 dwarf_encoding = llvm::dwarf::DW_ATE_signed;
427 }
else if (p->is_char()) {
428 dwarf_encoding = llvm::dwarf::DW_ATE_signed_char;
429 }
else if (p->is_bool()) {
430 dwarf_encoding = llvm::dwarf::DW_ATE_boolean;
431 }
else if (p->is_float()) {
432 dwarf_encoding = llvm::dwarf::DW_ATE_float;
433 }
else if (p->is_void()) {
434 dwarf_encoding = llvm::dwarf::DW_ATE_signed;
437 ret = _di_builder->createBasicType(p->get_typename(), (uint64_t)size_bits, dwarf_encoding);
438 }
else if (p->is_string()) {
439 auto *e_di_type = _di_builder->createBasicType(
"u8", 8, llvm::dwarf::DW_ATE_unsigned_char);
440 ret = _di_builder->createPointerType(e_di_type, _target_machine->getPointerSizeInBits(0),
441 _target_machine->getPointerSizeInBits(0), std::nullopt, p->get_typename());
442 }
else if (p->is_struct()) {
443 auto member_types = pcast<StructType>(p)->get_member_types();
444 unsigned n = (unsigned)member_types.size();
447 ret = _di_builder->createStructType(
448 di_file, p->get_typename(), di_file, (unsigned)lineno, (uint32_t)p->get_size_bits(),
449 (uint32_t)p->get_align_bits(), DINode::DIFlags::FlagZero,
nullptr,
450 _di_builder->getOrCreateArray(vector<Metadata *>(n,
nullptr)), 0,
nullptr, p->get_typename());
452 vector<Metadata *> elements(member_types.size(),
nullptr);
453 for (
unsigned i = 0; i < n; ++i) {
454 elements[i] = to_llvm_metadata(member_types[i], di_file, lineno);
457 ret->replaceOperandWith(4, _di_builder->getOrCreateArray(elements).get());
458 }
else if (p->is_array()) {
459 auto *sub = to_llvm_metadata(pcast<ArrayType>(p)->get_element_type(), di_file, lineno);
460 ret = _di_builder->createPointerType((DIType *)sub, _target_machine->getPointerSizeInBits(0),
461 _target_machine->getPointerSizeInBits(0), std::nullopt, p->get_typename());
462 }
else if (p->is_pointer()) {
464 _llvm_meta_cache[p] = ret =
465 _di_builder->createPointerType(
nullptr, _target_machine->getPointerSizeInBits(0),
466 _target_machine->getPointerSizeInBits(0), std::nullopt, p->get_typename());
467 auto *sub = to_llvm_metadata(pcast<PointerType>(p)->get_pointee(), di_file, lineno);
468 ret->replaceOperandWith(3, sub);
473 return _llvm_meta_cache[p] = ret;
476 llvm::DISubroutineType *CodeGenerator::create_function_debug_info_type(llvm::Metadata *ret,
477 vector<llvm::Metadata *> args) {
478 vector<Metadata *> types{ret};
479 types.reserve(args.size());
480 types.insert(types.begin() + 1, args.begin(), args.end());
483 return _di_builder->createSubroutineType(_di_builder->getOrCreateTypeArray(types));
486 void CodeGenerator::set_current_debug_location(ASTBase *p) {
487 unsigned line = AST_LINENO(p) + 1;
488 unsigned col = AST_COL(p) + 1;
489 _builder->SetCurrentDebugLocation(DILocation::get(*_llvm_ctx, line, col, get_current_di_scope()));
492 DIScope *CodeGenerator::get_current_di_scope()
const {
return _di_scope.back(); }
493 void CodeGenerator::push_di_scope(DIScope *scope) { _di_scope.push_back(scope); }
494 void CodeGenerator::pop_di_scope() { _di_scope.pop_back(); }
496 DebugLoc CodeGenerator::debug_loc_of_node(ASTBase *p, MDNode *scope) {
497 return DILocation::get(*_llvm_ctx, AST_LINENO(p), AST_COL(p), scope);
502 Value *CodeGenerator::codegen_var_arg_decl(Decl *p) {
503 llvm::Type *type = to_llvm_type(p->get_type());
504 auto *ret = create_block_alloca(_builder->GetInsertBlock(), type, 1, p->get_name());
507 if (p->get_node_type() == ASTNodeType::VAR_DECL) {
508 Value *default_value = codegen_type_default_value(p->get_type());
509 TAN_ASSERT(default_value);
510 _builder->CreateStore(default_value, ret);
514 auto *curr_di_scope = get_current_di_scope();
515 auto *di_file = get_or_create_di_file(p);
516 auto *arg_meta = to_llvm_metadata(p->get_type(), di_file, AST_LINENO(p));
518 _di_builder->createAutoVariable(curr_di_scope, p->get_name(), di_file, AST_LINENO(p), (DIType *)arg_meta);
519 _di_builder->insertDeclare(ret, di_arg, _di_builder->createExpression(), debug_loc_of_node(p, curr_di_scope),
520 _builder->GetInsertBlock());
524 Value *CodeGenerator::codegen_struct_default_value(StructType *ty) {
525 StructDecl *struct_decl = ty->get_decl();
527 auto member_types = ty->get_member_types();
528 TAN_ASSERT(member_types.size() == struct_decl->get_member_decls().size());
530 vector<Constant *> values(member_types.size(),
nullptr);
531 for (
size_t i = 0; i < member_types.size(); ++i) {
532 Expr *v = struct_decl->get_member_default_val((
int)i);
535 TAN_ASSERT(v->is_comptime_known());
537 values[i] = (llvm::Constant *)cached_visit(v);
539 values[i] = (llvm::Constant *)codegen_type_default_value(member_types[i]);
543 return ConstantStruct::get((llvm::StructType *)to_llvm_type(ty), values);
546 Value *CodeGenerator::codegen_type_default_value(Type *p) {
547 TAN_ASSERT(!p->is_ref());
550 auto *src =
new TokenizedSourceFile(
"__plain_type_default_value__", {});
552 Value *ret =
nullptr;
553 if (p->is_primitive() || p->is_string() || p->is_array() || p->is_pointer()) {
554 ret = cached_visit(DefaultValue::CreateTypeDefaultValueLiteral(src, p));
556 }
else if (p->is_struct()) {
557 ret = codegen_struct_default_value(pcast<StructType>(p));
565 Value *CodeGenerator::codegen_literals(Literal *p) {
566 llvm::Type *type = to_llvm_type(p->get_type());
567 Value *ret =
nullptr;
568 Type *ptype = p->get_type();
569 if (ptype->is_primitive()) {
570 int size_bits = ptype->get_size_bits();
572 if (ptype->is_char()) {
573 ret = ConstantInt::get(type, pcast<CharLiteral>(p)->get_value());
574 }
else if (ptype->is_int()) {
575 auto pp = pcast<IntegerLiteral>(p);
576 ret = ConstantInt::get(_builder->getIntNTy((
unsigned)size_bits), pp->get_value(), !pp->is_unsigned());
577 }
else if (ptype->is_bool()) {
578 auto pp = pcast<BoolLiteral>(p);
579 ret = ConstantInt::get(type, (uint64_t)pp->get_value());
580 }
else if (ptype->is_float()) {
581 ret = ConstantFP::get(type, pcast<FloatLiteral>(p)->get_value());
585 }
else if (ptype->is_string()) {
586 ret = _builder->CreateGlobalStringPtr(pcast<StringLiteral>(p)->get_value());
587 }
else if (ptype->is_struct()) {
590 }
else if (ptype->is_array()) {
591 auto arr = pcast<ArrayLiteral>(p);
594 auto elements = arr->get_elements();
595 auto *e_type = to_llvm_type(pcast<ArrayType>(ptype)->get_element_type());
598 size_t n = elements.size();
599 ret = create_block_alloca(_builder->GetInsertBlock(), e_type, n,
"array_storage");
600 for (
size_t i = 0; i < n; ++i) {
601 auto *idx = _builder->getInt32((
unsigned)i);
602 auto *e_val = cached_visit(elements[i]);
603 auto *e_ptr = _builder->CreateGEP(e_type, ret, idx);
604 _builder->CreateStore(e_val, e_ptr);
606 }
else if (ptype->is_pointer()) {
607 ret = ConstantPointerNull::get((llvm::PointerType *)type);
615 Value *CodeGenerator::codegen_func_prototype(FunctionDecl *p,
bool import_) {
616 auto linkage = Function::InternalLinkage;
617 if (p->is_external()) {
618 linkage = Function::ExternalWeakLinkage;
620 if (p->is_public()) {
622 linkage = Function::ExternalWeakLinkage;
624 linkage = Function::ExternalLinkage;
627 Function *func = Function::Create((llvm::FunctionType *)to_llvm_type(p->get_type()), linkage, p->get_name(), _module);
628 func->setCallingConv(llvm::CallingConv::C);
632 Value *CodeGenerator::codegen_ptr_deref(UnaryOperator *p) {
633 auto *rhs = p->get_rhs();
634 Value *val = cached_visit(rhs);
635 TAN_ASSERT(val->getType()->isPointerTy());
638 if (rhs->is_lvalue()) {
639 val = _builder->CreateLoad(to_llvm_type(rhs->get_type()), val,
"ptr_deref");
644 Value *CodeGenerator::codegen_relop(BinaryOperator *p) {
645 auto lhs = p->get_lhs();
646 auto rhs = p->get_rhs();
647 Value *l = cached_visit(lhs);
648 Value *r = cached_visit(rhs);
650 r = load_if_is_lvalue(rhs);
651 l = load_if_is_lvalue(lhs);
653 Value *ret =
nullptr;
654 switch (p->get_op()) {
655 case BinaryOpKind::BAND:
656 ret = _builder->CreateAnd(l, r,
"binary_and");
658 case BinaryOpKind::LAND:
659 ret = _builder->CreateAnd(l, r,
"logical_and");
661 case BinaryOpKind::BOR:
662 ret = _builder->CreateOr(l, r,
"binary_or");
664 case BinaryOpKind::LOR:
665 ret = _builder->CreateOr(l, r,
"logical_or");
667 case BinaryOpKind::XOR:
668 ret = _builder->CreateXor(l, r,
"logical_or");
679 Value *CodeGenerator::codegen_bnot(UnaryOperator *p) {
680 auto *rhs = cached_visit(p->get_rhs());
682 error(ErrorType::SEMANTIC_ERROR, p,
"Invalid operand");
684 if (p->get_rhs()->is_lvalue()) {
685 rhs = _builder->CreateLoad(to_llvm_type(p->get_rhs()->get_type()), rhs);
687 return _builder->CreateNot(rhs);
690 Value *CodeGenerator::codegen_lnot(UnaryOperator *p) {
691 auto *rhs = cached_visit(p->get_rhs());
694 error(ErrorType::SEMANTIC_ERROR, p,
"Invalid operand");
697 if (p->get_rhs()->is_lvalue()) {
698 rhs = _builder->CreateLoad(to_llvm_type(p->get_rhs()->get_type()), rhs);
701 auto size_in_bits = rhs->getType()->getPrimitiveSizeInBits();
702 if (rhs->getType()->isFloatingPointTy()) {
703 return _builder->CreateFCmpOEQ(rhs, ConstantFP::get(_builder->getFloatTy(), 0.0f));
704 }
else if (rhs->getType()->isSingleValueType()) {
705 return _builder->CreateICmpEQ(rhs, ConstantInt::get(_builder->getIntNTy((
unsigned)size_in_bits), 0,
false));
708 error(ErrorType::SEMANTIC_ERROR, p,
"Invalid operand");
711 Value *CodeGenerator::codegen_address_of(UnaryOperator *p) {
712 if (!p->get_rhs()->is_lvalue()) {
713 error(ErrorType::SEMANTIC_ERROR, p,
"Cannot get address of rvalue");
716 return cached_visit(p->get_rhs());
719 Value *CodeGenerator::codegen_arithmetic(BinaryOperator *p) {
721 auto *lhs = p->get_lhs();
722 auto *rhs = p->get_rhs();
723 Value *l = cached_visit(lhs);
724 Value *r = cached_visit(rhs);
725 r = load_if_is_lvalue(rhs);
726 l = load_if_is_lvalue(lhs);
728 Value *ret =
nullptr;
729 if (l->getType()->isFloatingPointTy()) {
731 switch (p->get_op()) {
732 case BinaryOpKind::MULTIPLY:
733 ret = _builder->CreateFMul(l, r,
"mul_tmp");
735 case BinaryOpKind::DIVIDE:
736 ret = _builder->CreateFDiv(l, r,
"div_tmp");
738 case BinaryOpKind::SUM:
739 ret = _builder->CreateFAdd(l, r,
"sum_tmp");
741 case BinaryOpKind::SUBTRACT:
742 ret = _builder->CreateFSub(l, r,
"sub_tmp");
744 case BinaryOpKind::MOD:
745 ret = _builder->CreateFRem(l, r,
"mod_tmp");
753 switch (p->get_op()) {
754 case BinaryOpKind::MULTIPLY:
755 ret = _builder->CreateMul(l, r,
"mul_tmp");
757 case BinaryOpKind::DIVIDE: {
758 auto ty = lhs->get_type();
759 if (ty->is_unsigned()) {
760 ret = _builder->CreateUDiv(l, r,
"div_tmp");
762 ret = _builder->CreateSDiv(l, r,
"div_tmp");
766 case BinaryOpKind::SUM:
767 ret = _builder->CreateAdd(l, r,
"sum_tmp");
769 case BinaryOpKind::SUBTRACT:
770 ret = _builder->CreateSub(l, r,
"sub_tmp");
772 case BinaryOpKind::MOD: {
773 auto ty = lhs->get_type();
774 if (ty->is_unsigned()) {
775 ret = _builder->CreateURem(l, r,
"mod_tmp");
777 ret = _builder->CreateSRem(l, r,
"mod_tmp");
791 Value *CodeGenerator::codegen_comparison(BinaryOperator *p) {
792 auto lhs = p->get_lhs();
793 auto rhs = p->get_rhs();
794 Value *l = cached_visit(lhs);
795 Value *r = cached_visit(rhs);
797 bool is_signed = !lhs->get_type()->is_unsigned();
798 r = load_if_is_lvalue(rhs);
799 l = load_if_is_lvalue(lhs);
801 Value *ret =
nullptr;
802 if (l->getType()->isFloatingPointTy()) {
803 switch (p->get_op()) {
804 case BinaryOpKind::EQ:
805 ret = _builder->CreateFCmpOEQ(l, r,
"eq");
807 case BinaryOpKind::NE:
808 ret = _builder->CreateFCmpONE(l, r,
"ne");
810 case BinaryOpKind::GT:
811 ret = _builder->CreateFCmpOGT(l, r,
"gt");
813 case BinaryOpKind::GE:
814 ret = _builder->CreateFCmpOGE(l, r,
"ge");
816 case BinaryOpKind::LT:
817 ret = _builder->CreateFCmpOLT(l, r,
"lt");
819 case BinaryOpKind::LE:
820 ret = _builder->CreateFCmpOLE(l, r,
"le");
827 switch (p->get_op()) {
828 case BinaryOpKind::EQ:
829 ret = _builder->CreateICmpEQ(l, r,
"eq");
831 case BinaryOpKind::NE:
832 ret = _builder->CreateICmpNE(l, r,
"ne");
834 case BinaryOpKind::GT:
836 ret = _builder->CreateICmpSGT(l, r,
"gt");
838 ret = _builder->CreateICmpUGT(l, r,
"gt");
841 case BinaryOpKind::GE:
843 ret = _builder->CreateICmpSGE(l, r,
"ge");
845 ret = _builder->CreateICmpUGE(l, r,
"ge");
848 case BinaryOpKind::LT:
850 ret = _builder->CreateICmpSLT(l, r,
"lt");
852 ret = _builder->CreateICmpULT(l, r,
"lt");
855 case BinaryOpKind::LE:
857 ret = _builder->CreateICmpSLE(l, r,
"le");
859 ret = _builder->CreateICmpULE(l, r,
"le");
872 Value *CodeGenerator::codegen_member_access(BinaryOperator *_p) {
873 auto *p = pcast<MemberAccess>(_p);
874 auto lhs = p->get_lhs();
875 auto rhs = p->get_rhs();
877 auto *lhs_val = cached_visit(lhs);
879 Value *ret =
nullptr;
880 switch (p->_access_type) {
881 case MemberAccess::MemberAccessBracket: {
882 lhs_val = load_if_is_lvalue(lhs);
885 auto *rhs_val = load_if_is_lvalue(rhs);
887 llvm::Type *element_type =
nullptr;
888 if (lhs->get_type()->is_array()) {
889 auto *lhs_type = pcast<tanlang::ArrayType>(lhs->get_type());
890 element_type = to_llvm_type(lhs_type->get_element_type());
891 }
else if (lhs->get_type()->is_string()) {
892 element_type = llvm::Type::getInt8Ty(*_llvm_ctx);
893 }
else if (lhs->get_type()->is_pointer()) {
894 auto *lhs_type = pcast<tanlang::PointerType>(lhs->get_type());
895 element_type = to_llvm_type(lhs_type->get_pointee());
899 ret = _builder->CreateGEP(element_type, lhs_val, rhs_val,
"bracket_access");
902 case MemberAccess::MemberAccessMemberVariable: {
903 StructType *st =
nullptr;
904 if (lhs->get_type()->is_pointer()) {
905 lhs_val = load_if_is_lvalue(lhs);
906 st = pcast<StructType>(pcast<PointerType>(lhs->get_type())->get_pointee());
908 st = pcast<StructType>(lhs->get_type());
910 TAN_ASSERT(st->is_struct());
911 TAN_ASSERT(lhs_val->getType()->isPointerTy());
913 lhs_val->getType()->print(llvm::outs());
914 ret = _builder->CreateStructGEP(to_llvm_type(st), lhs_val, (
unsigned)p->_access_idx,
"member_variable");
917 case MemberAccess::MemberAccessMemberFunction:
919 ret = cached_visit(rhs);
930 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Package) {
931 for (
auto *c : p->get_children()) {
936 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Identifier) {
937 switch (p->get_id_type()) {
938 case IdentifierType::ID_VAR_REF:
939 _llvm_value_cache[p] = cached_visit(p->get_var_ref());
941 case IdentifierType::ID_TYPE_REF:
948 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Parenthesis) { _llvm_value_cache[p] = cached_visit(p->get_sub()); }
950 DEFINE_AST_VISITOR_IMPL(CodeGenerator, If) {
951 Function *func = _builder->GetInsertBlock()->getParent();
952 size_t n = p->get_num_branches();
955 vector<BasicBlock *> cond_blocks(n);
956 vector<BasicBlock *> then_blocks(n);
957 for (
size_t i = 0; i < n; ++i) {
958 cond_blocks[i] = BasicBlock::Create(*_llvm_ctx,
"cond", func);
959 then_blocks[i] = BasicBlock::Create(*_llvm_ctx,
"branch", func);
961 BasicBlock *merge_bb = BasicBlock::Create(*_llvm_ctx,
"endif", func);
964 _builder->CreateBr(cond_blocks[0]);
965 for (
size_t i = 0; i < n; ++i) {
967 _builder->SetInsertPoint(cond_blocks[i]);
969 Expr *cond = p->get_predicate(i);
971 TAN_ASSERT(i == n - 1);
972 _builder->CreateBr(then_blocks[i]);
975 Value *cond_v = load_if_is_lvalue(cond);
977 _builder->CreateCondBr(cond_v, then_blocks[i], cond_blocks[i + 1]);
979 _builder->CreateCondBr(cond_v, then_blocks[i], merge_bb);
984 _builder->SetInsertPoint(then_blocks[i]);
985 cached_visit(p->get_branch(i));
988 if (!_builder->GetInsertBlock()->back().isTerminator()) {
989 _builder->CreateBr(merge_bb);
994 _builder->SetInsertPoint(merge_bb);
996 _llvm_value_cache[p] =
nullptr;
999 DEFINE_AST_VISITOR_IMPL(CodeGenerator, VarDecl) { _llvm_value_cache[p] = codegen_var_arg_decl(p); }
1001 DEFINE_AST_VISITOR_IMPL(CodeGenerator, ArgDecl) { _llvm_value_cache[p] = codegen_var_arg_decl(p); }
1003 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Return) {
1004 auto rhs = p->get_rhs();
1006 Value *result = cached_visit(rhs);
1007 if (rhs->is_lvalue()) {
1008 result = _builder->CreateLoad(to_llvm_type(rhs->get_type()), result);
1010 _builder->CreateRet(result);
1012 _builder->CreateRetVoid();
1014 _llvm_value_cache[p] =
nullptr;
1017 DEFINE_AST_VISITOR_IMPL(CodeGenerator, CompoundStmt) {
1018 for (
auto *c : p->get_children()) {
1021 _llvm_value_cache[p] =
nullptr;
1024 DEFINE_AST_VISITOR_IMPL(CodeGenerator, BinaryOrUnary) { _llvm_value_cache[p] = cached_visit(p->get_expr_ptr()); }
1026 DEFINE_AST_VISITOR_IMPL(CodeGenerator, BinaryOperator) {
1027 Value *ret =
nullptr;
1029 switch (p->get_op()) {
1030 case BinaryOpKind::SUM:
1031 case BinaryOpKind::SUBTRACT:
1032 case BinaryOpKind::MULTIPLY:
1033 case BinaryOpKind::DIVIDE:
1034 case BinaryOpKind::MOD:
1035 ret = codegen_arithmetic(p);
1037 case BinaryOpKind::BAND:
1038 case BinaryOpKind::LAND:
1039 case BinaryOpKind::BOR:
1040 case BinaryOpKind::LOR:
1041 case BinaryOpKind::XOR:
1042 ret = codegen_relop(p);
1044 case BinaryOpKind::GT:
1045 case BinaryOpKind::GE:
1046 case BinaryOpKind::LT:
1047 case BinaryOpKind::LE:
1048 case BinaryOpKind::EQ:
1049 case BinaryOpKind::NE:
1050 ret = codegen_comparison(p);
1052 case BinaryOpKind::MEMBER_ACCESS:
1053 ret = codegen_member_access(p);
1060 _llvm_value_cache[p] = ret;
1063 DEFINE_AST_VISITOR_IMPL(CodeGenerator, UnaryOperator) {
1064 Value *ret =
nullptr;
1066 auto rhs = p->get_rhs();
1067 switch (p->get_op()) {
1068 case UnaryOpKind::LNOT:
1069 ret = codegen_lnot(p);
1071 case UnaryOpKind::BNOT:
1072 ret = codegen_bnot(p);
1074 case UnaryOpKind::ADDRESS_OF:
1075 ret = codegen_address_of(p);
1077 case UnaryOpKind::PTR_DEREF:
1078 ret = codegen_ptr_deref(p);
1080 case UnaryOpKind::PLUS:
1081 ret = cached_visit(rhs);
1083 case UnaryOpKind::MINUS: {
1084 auto *r = cached_visit(rhs);
1085 if (rhs->is_lvalue()) {
1086 r = _builder->CreateLoad(to_llvm_type(rhs->get_type()), r);
1088 if (r->getType()->isFloatingPointTy()) {
1089 ret = _builder->CreateFNeg(r);
1091 ret = _builder->CreateNeg(r);
1100 _llvm_value_cache[p] = ret;
1103 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Cast) {
1104 auto lhs = p->get_lhs();
1105 auto *dest_type = to_llvm_type(p->get_type());
1107 Value *val = cached_visit(lhs);
1110 Value *ret =
nullptr;
1111 val = convert_llvm_type_to(lhs, p->get_type());
1112 if (lhs->is_lvalue()) {
1113 ret = create_block_alloca(_builder->GetInsertBlock(), dest_type, 1,
"casted");
1114 _builder->CreateStore(val, ret);
1119 _llvm_value_cache[p] = ret;
1122 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Assignment) {
1124 auto *lhs = pcast<Expr>(p->get_lhs());
1125 auto *rhs = p->get_rhs();
1128 if (!lhs->is_lvalue()) {
1129 error(ErrorType::SEMANTIC_ERROR, lhs,
"Value can only be assigned to an lvalue");
1132 Value *from = cached_visit(rhs);
1133 from = load_if_is_lvalue(rhs);
1134 Value *to = cached_visit(lhs);
1135 TAN_ASSERT(from && to);
1137 _builder->CreateStore(from, to);
1139 _llvm_value_cache[p] = to;
1142 DEFINE_AST_VISITOR_IMPL(CodeGenerator, FunctionCall) {
1143 FunctionDecl *callee = p->_callee;
1144 auto *callee_type = pcast<tanlang::FunctionType>(callee->get_type());
1145 size_t n = callee->get_n_args();
1148 vector<Value *> arg_vals;
1149 for (
size_t i = 0; i < n; ++i) {
1150 auto actual_arg = p->_args[i];
1151 auto *a = cached_visit(actual_arg);
1153 error(ErrorType::SEMANTIC_ERROR, actual_arg,
"Invalid function call argument");
1157 auto expected_ty = callee_type->get_arg_types()[i];
1158 a = convert_llvm_type_to(actual_arg, expected_ty);
1159 arg_vals.push_back(a);
1162 auto *func_type = (llvm::FunctionType *)to_llvm_type(callee->get_type());
1163 auto *F = cached_visit(callee);
1165 _llvm_value_cache[p] = _builder->CreateCall(func_type, F, arg_vals);
1168 DEFINE_AST_VISITOR_IMPL(CodeGenerator, FunctionDecl) {
1169 auto *func_type = pcast<tanlang::FunctionType>(p->get_type());
1171 auto ret_ty = func_type->get_return_type();
1172 Metadata *ret_meta = to_llvm_metadata(ret_ty, get_or_create_di_file(p), AST_LINENO(p));
1175 str func_name = p->get_name();
1177 if (func_name ==
"main") {
1178 p->set_name(func_name =
"tan_main");
1179 p->set_public(
true);
1183 auto *F = (Function *)codegen_func_prototype(p);
1186 vector<Metadata *> arg_metas;
1187 for (
size_t i = 0; i < p->get_n_args(); ++i) {
1188 auto ty = func_type->get_arg_types()[i];
1189 arg_metas.push_back(to_llvm_metadata(ty, get_or_create_di_file(p), AST_LINENO(p)));
1193 if (!p->is_external()) {
1195 BasicBlock *main_block = BasicBlock::Create(*_llvm_ctx,
"func_entry", F);
1196 _builder->SetInsertPoint(main_block);
1199 DIScope *di_scope = get_current_di_scope();
1200 auto *di_func_t = create_function_debug_info_type(ret_meta, arg_metas);
1201 DISubprogram *subprogram =
1202 _di_builder->createFunction(di_scope, func_name, func_name, get_or_create_di_file(p), AST_LINENO(p), di_func_t,
1203 p->src()->get_col(p->start()), DINode::FlagPrototyped,
1204 DISubprogram::SPFlagDefinition,
nullptr,
nullptr,
nullptr);
1205 F->setSubprogram(subprogram);
1206 push_di_scope(subprogram);
1210 for (
auto &a : F->args()) {
1211 auto arg_name = p->get_arg_name(i);
1212 auto *arg_val = cached_visit(p->get_arg_decls()[i]);
1213 _builder->CreateStore(&a, arg_val);
1216 auto *arg_meta = to_llvm_metadata(func_type->get_arg_types()[i], get_or_create_di_file(p), AST_LINENO(p));
1217 llvm::DILocalVariable *di_arg = _di_builder->createParameterVariable(
1218 subprogram, arg_name, (
unsigned)i + 1, get_or_create_di_file(p), AST_LINENO(p), (DIType *)arg_meta,
true);
1219 _di_builder->insertDeclare(arg_val, di_arg, _di_builder->createExpression(),
1220 debug_loc_of_node(p->get_arg_decls()[i], subprogram), _builder->GetInsertBlock());
1225 cached_visit(p->get_body());
1228 auto *trailing_block = _builder->GetInsertBlock();
1229 if (trailing_block->sizeWithoutDebug() == 0 || !trailing_block->back().isTerminator()) {
1230 if (ret_ty->is_void()) {
1231 _builder->CreateRetVoid();
1233 auto *ret_val = codegen_type_default_value(ret_ty);
1234 TAN_ASSERT(ret_val);
1235 _builder->CreateRet(ret_val);
1241 _llvm_value_cache[p] = F;
1244 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Import) {
1245 for (FunctionDecl *f : p->_imported_funcs) {
1247 auto *func = _module->getFunction(f->get_name());
1249 _llvm_value_cache[f] = func;
1251 _llvm_value_cache[f] = codegen_func_prototype(f);
1254 _llvm_value_cache[p] =
nullptr;
1257 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Intrinsic) {
1258 Value *ret =
nullptr;
1259 switch (p->get_intrinsic_type()) {
1261 case IntrinsicType::GET_DECL:
1262 case IntrinsicType::LINENO:
1263 case IntrinsicType::ABORT:
1264 case IntrinsicType::STACK_TRACE:
1265 case IntrinsicType::FILENAME: {
1266 ret = cached_visit(p->get_sub());
1269 case IntrinsicType::NOOP:
1274 _llvm_value_cache[p] = ret;
1277 DEFINE_AST_VISITOR_IMPL(CodeGenerator, ArrayLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1278 DEFINE_AST_VISITOR_IMPL(CodeGenerator, CharLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1279 DEFINE_AST_VISITOR_IMPL(CodeGenerator, BoolLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1280 DEFINE_AST_VISITOR_IMPL(CodeGenerator, IntegerLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1281 DEFINE_AST_VISITOR_IMPL(CodeGenerator, FloatLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1282 DEFINE_AST_VISITOR_IMPL(CodeGenerator, StringLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1283 DEFINE_AST_VISITOR_IMPL(CodeGenerator, NullPointerLiteral) { _llvm_value_cache[p] = codegen_literals(p); }
1285 DEFINE_AST_VISITOR_IMPL(CodeGenerator, StructDecl) {
1289 DEFINE_AST_VISITOR_IMPL(CodeGenerator, Loop) {
1317 Function *func = _builder->GetInsertBlock()->getParent();
1320 auto *init_block = BasicBlock::Create(*_llvm_ctx,
"init", func);
1321 auto *predicate_block = BasicBlock::Create(*_llvm_ctx,
"predicate", func);
1322 BasicBlock *body_block = BasicBlock::Create(*_llvm_ctx,
"loop_body", func);
1323 auto *iter_block = BasicBlock::Create(*_llvm_ctx,
"iter", func);
1324 auto *end_block = BasicBlock::Create(*_llvm_ctx,
"loop_end", func);
1328 p->_loop_start = predicate_block;
1329 p->_loop_end = end_block;
1333 if (!_builder->GetInsertBlock()->back().isTerminator()) {
1334 _builder->CreateBr(init_block);
1338 _builder->SetInsertPoint(init_block);
1339 if (p->_loop_type == ASTLoopType::FOR) {
1340 cached_visit(p->_initialization);
1342 _builder->CreateBr(predicate_block);
1345 _builder->SetInsertPoint(predicate_block);
1346 auto *cond = cached_visit(p->_predicate);
1347 _builder->CreateCondBr(cond, body_block, end_block);
1350 _builder->SetInsertPoint(body_block);
1351 cached_visit(p->_body);
1353 if (!_builder->GetInsertBlock()->back().isTerminator()) {
1354 _builder->CreateBr(iter_block);
1358 _builder->SetInsertPoint(iter_block);
1359 if (p->_loop_type == ASTLoopType::FOR) {
1360 cached_visit(p->_iteration);
1363 _builder->CreateBr(predicate_block);
1366 _builder->SetInsertPoint(end_block);
1368 _llvm_value_cache[p] =
nullptr;
1371 DEFINE_AST_VISITOR_IMPL(CodeGenerator, BreakContinue) {
1372 auto loop = p->get_parent_loop();
1375 auto s = loop->_loop_start;
1376 auto e = loop->_loop_end;
1380 if (p->get_node_type() == ASTNodeType::BREAK) {
1381 _builder->CreateBr(e);
1382 }
else if (p->get_node_type() == ASTNodeType::CONTINUE) {
1383 _builder->CreateBr(s);
1388 _llvm_value_cache[p] =
nullptr;
1391 DEFINE_AST_VISITOR_IMPL(CodeGenerator, VarRef) { _llvm_value_cache[p] = cached_visit(p->get_referred()); }
1393 DEFINE_AST_VISITOR_IMPL(CodeGenerator, PackageDecl) {}
1395 void CodeGenerator::error(ErrorType type, ASTBase *p,
const str &message) {
1396 Error(type, p->src()->get_token(p->start()), p->src()->get_token(p->end()), message).raise();