From 9f6c5a20de03a59bfcaead703fe9490a6d622f84 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 25 Feb 2018 15:10:29 -0500 Subject: [PATCH] codegen for coro_id instruction See #727 --- src/all_types.hpp | 1 + src/analyze.cpp | 4 ++++ src/analyze.hpp | 2 ++ src/codegen.cpp | 30 +++++++++++++++++++++++++++++- src/ir.cpp | 3 ++- src/zig_llvm.cpp | 3 +++ src/zig_llvm.h | 2 ++ 7 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index e9b4561eb..8e362cd64 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1610,6 +1610,7 @@ struct CodeGen { LLVMValueRef return_address_fn_val; LLVMValueRef frame_address_fn_val; LLVMValueRef coro_destroy_fn_val; + LLVMValueRef coro_id_fn_val; bool error_during_imports; const char **clang_argv; diff --git a/src/analyze.cpp b/src/analyze.cpp index 2126f5ba0..2787906c6 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -5776,3 +5776,7 @@ bool type_is_global_error_set(TypeTableEntry *err_set_type) { assert(err_set_type->data.error_set.infer_fn == nullptr); return err_set_type->data.error_set.err_count == UINT32_MAX; } + +uint32_t get_coro_frame_align_bytes(CodeGen *g) { + return g->pointer_size_bytes * 2; +} diff --git a/src/analyze.hpp b/src/analyze.hpp index 2fe41f657..926793c58 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -191,4 +191,6 @@ void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry); TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry); +uint32_t get_coro_frame_align_bytes(CodeGen *g); + #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index 783f5fd8f..21ad71597 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -942,6 +942,24 @@ static LLVMValueRef get_coro_destroy_fn_val(CodeGen *g) { return g->coro_destroy_fn_val; } +static LLVMValueRef get_coro_id_fn_val(CodeGen *g) { + if (g->coro_id_fn_val) + return g->coro_id_fn_val; + + LLVMTypeRef param_types[] = { + LLVMInt32Type(), + LLVMPointerType(LLVMInt8Type(), 0), + LLVMPointerType(LLVMInt8Type(), 0), + LLVMPointerType(LLVMInt8Type(), 0), + }; + LLVMTypeRef fn_type = LLVMFunctionType(ZigLLVMTokenTypeInContext(LLVMGetGlobalContext()), param_types, 4, false); + Buf *name = buf_sprintf("llvm.coro.id"); + g->coro_id_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type); + assert(LLVMGetIntrinsicID(g->coro_id_fn_val)); + + return g->coro_id_fn_val; +} + static LLVMValueRef get_return_address_fn_val(CodeGen *g) { if (g->return_address_fn_val) return g->return_address_fn_val; @@ -3730,7 +3748,17 @@ static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInst } static LLVMValueRef ir_render_coro_id(CodeGen *g, IrExecutable *executable, IrInstructionCoroId *instruction) { - zig_panic("TODO ir_render_coro_id"); + LLVMValueRef promise_ptr = ir_llvm_value(g, instruction->promise_ptr); + LLVMValueRef align_val = LLVMConstInt(LLVMInt32Type(), get_coro_frame_align_bytes(g), false); + LLVMValueRef null = LLVMConstIntToPtr(LLVMConstNull(g->builtin_types.entry_usize->type_ref), + LLVMPointerType(LLVMInt8Type(), 0)); + LLVMValueRef params[] = { + align_val, + promise_ptr, + null, + null, + }; + return LLVMBuildCall(g->builder, get_coro_id_fn_val(g), params, 4, ""); } static LLVMValueRef ir_render_coro_alloc(CodeGen *g, IrExecutable *executable, IrInstructionCoroAlloc *instruction) { diff --git a/src/ir.cpp b/src/ir.cpp index f484f32e0..5ab2b149d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6027,7 +6027,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, irb->exec->implicit_allocator_ptr, alloc_field_name); IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr); - IrInstruction *alignment = ir_build_const_u29(irb, scope, node, irb->codegen->pointer_size_bytes * 2); + IrInstruction *alignment = ir_build_const_u29(irb, scope, node, + get_coro_frame_align_bytes(irb->codegen)); size_t arg_count = 3; IrInstruction **args = allocate(arg_count); args[0] = irb->exec->implicit_allocator_ptr; // self diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 97c07ab82..34defc6dc 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -182,6 +182,9 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM return false; } +ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { + return wrap(Type::getTokenTy(*unwrap(context_ref))); +} LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, unsigned CC, ZigLLVM_FnInline fn_inline, const char *Name) diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 4ae25ef6f..01a78a6af 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -54,6 +54,8 @@ enum ZigLLVM_EmitOutputType { ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug); +ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); + enum ZigLLVM_FnInline { ZigLLVM_FnInlineAuto, ZigLLVM_FnInlineAlways,