From 6b69dcfdd28145791da43979474fec29a13e24d0 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 6 Aug 2022 18:22:56 +0200 Subject: amdgpu: add AmdgpuKernel calling convention --- src/stage1/analyze.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/stage1/analyze.cpp') diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index f0cad841be..15b8789997 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -993,6 +993,7 @@ const char *calling_convention_name(CallingConvention cc) { case CallingConventionSysV: return "SysV"; case CallingConventionWin64: return "Win64"; case CallingConventionPtxKernel: return "PtxKernel"; + case CallingConventionAmdgpuKernel: return "AmdgpuKernel"; } zig_unreachable(); } @@ -1017,6 +1018,7 @@ bool calling_convention_allows_zig_types(CallingConvention cc) { case CallingConventionAAPCSVFP: case CallingConventionSysV: case CallingConventionWin64: + case CallingConventionAmdgpuKernel: return false; } zig_unreachable(); @@ -2019,6 +2021,9 @@ Error emit_error_unless_callconv_allowed_for_target(CodeGen *g, AstNode *source_ allowed_platforms = "nvptx and nvptx64"; } break; + case CallingConventionAmdgpuKernel: + if (g->zig_target->arch != ZigLLVM_amdgcn) + allowed_platforms = "amdgcn and amdpal"; } if (allowed_platforms != nullptr) { @@ -3857,6 +3862,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { case CallingConventionSysV: case CallingConventionWin64: case CallingConventionPtxKernel: + case CallingConventionAmdgpuKernel: add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), GlobalLinkageIdStrong, fn_cc); break; @@ -6012,7 +6018,7 @@ Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) { bool fn_returns_c_abi_small_struct(FnTypeId *fn_type_id) { ZigType *type = fn_type_id->return_type; - return !calling_convention_allows_zig_types(fn_type_id->cc) && + return !calling_convention_allows_zig_types(fn_type_id->cc) && type->id == ZigTypeIdStruct && type->abi_size <= 16; } @@ -8698,7 +8704,7 @@ static LLVMTypeRef llvm_int_for_size(size_t size) { static LLVMTypeRef llvm_sse_for_size(size_t size) { if (size > 4) return LLVMDoubleType(); - else + else return LLVMFloatType(); } @@ -8756,7 +8762,7 @@ static Error resolve_llvm_c_abi_type(CodeGen *g, ZigType *ty) { LLVMTypeRef return_elem_types[] = { LLVMVoidType(), - LLVMVoidType(), + LLVMVoidType(), }; for (uint32_t i = 0; i <= eightbyte_index; i += 1) { if (type_classes[i] == X64CABIClass_INTEGER) { -- cgit v1.2.3 From 76ad9cb10eeae5257eb51838953d0e3bcb993fa3 Mon Sep 17 00:00:00 2001 From: Robin Voetter Date: Sat, 17 Sep 2022 01:24:13 +0200 Subject: backport @addrSpaceCast to stage 1 --- src/Sema.zig | 1 - src/stage1/all_types.hpp | 14 ++++++++++++++ src/stage1/analyze.cpp | 5 +++++ src/stage1/astgen.cpp | 34 ++++++++++++++++++++++++++++++++++ src/stage1/codegen.cpp | 3 ++- src/stage1/ir.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/stage1/ir_print.cpp | 13 +++++++++++++ 7 files changed, 115 insertions(+), 2 deletions(-) (limited to 'src/stage1/analyze.cpp') diff --git a/src/Sema.zig b/src/Sema.zig index 9d05d53536..d597075df2 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -18181,7 +18181,6 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst const ptr = try sema.resolveInst(extra.rhs); const ptr_ty = sema.typeOf(ptr); - // TODO in addition to pointers, this instruction is supposed to work for // pointer-like optionals and slices. try sema.checkPtrOperand(block, ptr_src, ptr_ty); diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index f427548fdb..88dac9107f 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -95,6 +95,11 @@ enum AddressSpace { AddressSpaceGS, AddressSpaceFS, AddressSpaceSS, + AddressSpaceGlobal, + AddressSpaceConstant, + AddressSpaceParam, + AddressSpaceShared, + AddressSpaceLocal }; // This one corresponds to the builtin.zig enum. @@ -1842,6 +1847,7 @@ enum BuiltinFnId { BuiltinFnIdMaximum, BuiltinFnIdMinimum, BuiltinFnIdPrefetch, + BuiltinFnIdAddrSpaceCast, }; struct BuiltinFnEntry { @@ -2673,6 +2679,7 @@ enum Stage1ZirInstId : uint8_t { Stage1ZirInstIdWasmMemoryGrow, Stage1ZirInstIdSrc, Stage1ZirInstIdPrefetch, + Stage1ZirInstIdAddrSpaceCast, }; // ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR. @@ -4169,6 +4176,13 @@ struct Stage1AirInstAlignCast { Stage1AirInst *target; }; +struct Stage1ZirInstAddrSpaceCast { + Stage1ZirInst base; + + Stage1ZirInst *addrspace; + Stage1ZirInst *ptr; +}; + struct Stage1ZirInstSetAlignStack { Stage1ZirInst base; diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index 15b8789997..a102f2e340 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -1030,6 +1030,11 @@ const char *address_space_name(AddressSpace as) { case AddressSpaceGS: return "gs"; case AddressSpaceFS: return "fs"; case AddressSpaceSS: return "ss"; + case AddressSpaceGlobal: return "global"; + case AddressSpaceConstant: return "constant"; + case AddressSpaceParam: return "param"; + case AddressSpaceShared: return "shared"; + case AddressSpaceLocal: return "local"; } zig_unreachable(); } diff --git a/src/stage1/astgen.cpp b/src/stage1/astgen.cpp index 9eea2e650e..2d053a9e3c 100644 --- a/src/stage1/astgen.cpp +++ b/src/stage1/astgen.cpp @@ -351,6 +351,8 @@ void destroy_instruction_src(Stage1ZirInst *inst) { return heap::c_allocator.destroy(reinterpret_cast(inst)); case Stage1ZirInstIdPrefetch: return heap::c_allocator.destroy(reinterpret_cast(inst)); + case Stage1ZirInstIdAddrSpaceCast: + return heap::c_allocator.destroy(reinterpret_cast(inst)); } zig_unreachable(); } @@ -947,6 +949,10 @@ static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPrefetch *) { return Stage1ZirInstIdPrefetch; } +static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAddrSpaceCast *) { + return Stage1ZirInstIdAddrSpaceCast; +} + template static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) { T *special_instruction = heap::c_allocator.create(); @@ -2572,6 +2578,19 @@ static Stage1ZirInst *ir_build_align_cast_src(Stage1AstGen *ag, Scope *scope, As return &instruction->base; } +static Stage1ZirInst *ir_build_addrspace_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node, + Stage1ZirInst *addrspace, Stage1ZirInst *ptr) +{ + Stage1ZirInstAddrSpaceCast *instruction = ir_build_instruction(ag, scope, source_node); + instruction->addrspace = addrspace; + instruction->ptr = ptr; + + ir_ref_instruction(addrspace, ag->current_basic_block); + ir_ref_instruction(ptr, ag->current_basic_block); + + return &instruction->base; +} + static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ResultLoc *result_loc, Stage1ZirInst *ty) { @@ -5459,6 +5478,21 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast Stage1ZirInst *ir_extern = ir_build_prefetch(ag, scope, node, ptr_value, casted_options_value); return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc); } + case BuiltinFnIdAddrSpaceCast: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope); + if (arg0_value == ag->codegen->invalid_inst_src) + return arg0_value; + + AstNode* arg1_node = node->data.fn_call_expr.params.at(1); + Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope); + if (arg1_value == ag->codegen->invalid_inst_src) + return arg1_value; + + Stage1ZirInst *addrspace_cast = ir_build_addrspace_cast(ag, scope, node, arg0_value, arg1_value); + return ir_lval_wrap(ag, scope, addrspace_cast, lval, result_loc); + } } zig_unreachable(); } diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 6e1593ccca..2a05ba44d1 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -4371,7 +4371,7 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable, static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) { uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; - uint16_t num_bits = operand_type->id == ZigTypeIdVector ? + uint16_t num_bits = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.elem_type->data.floating.bit_count : operand_type->data.floating.bit_count; @@ -10085,6 +10085,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2); create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2); create_builtin_fn(g, BuiltinFnIdPrefetch, "prefetch", 2); + create_builtin_fn(g, BuiltinFnIdAddrSpaceCast, "addrSpaceCast", 2); } static const char *bool_to_str(bool b) { diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index c5f15c5cc9..9627384fbc 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -23746,6 +23746,50 @@ static Stage1AirInst *ir_analyze_instruction_align_cast(IrAnalyze *ira, Stage1Zi return result; } +static bool ir_resolve_addrspace(IrAnalyze *ira, Stage1AirInst *value, AddressSpace *out) { + if (type_is_invalid(value->value->type)) + return false; + + ZigType *addrspace_type = get_builtin_type(ira->codegen, "AddressSpace"); + + Stage1AirInst *casted_value = ir_implicit_cast(ira, value, addrspace_type); + if (type_is_invalid(casted_value->value->type)) + return false; + + ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); + if (!const_val) + return false; + + *out = (AddressSpace)bigint_as_u32(&const_val->data.x_enum_tag); + return true; +} + +static Stage1AirInst *ir_analyze_instruction_addrspace_cast(IrAnalyze *ira, Stage1ZirInstAddrSpaceCast *instruction) { + Stage1AirInst *ptr_inst = instruction->ptr->child; + ZigType *ptr_type = ptr_inst->value->type; + if (type_is_invalid(ptr_type)) + return ira->codegen->invalid_inst_gen; + + AddressSpace addrspace; + if (!ir_resolve_addrspace(ira, instruction->addrspace->child, &addrspace)) + return ira->codegen->invalid_inst_gen; + + if (addrspace != AddressSpaceGeneric) { + ir_add_error_node(ira, instruction->addrspace->source_node, buf_sprintf( + "address space '%s' not available in stage 1 compiler, must be .generic", + address_space_name(addrspace))); + return ira->codegen->invalid_inst_gen; + } + + if (is_slice(ptr_type) || get_src_ptr_type(ptr_type) != nullptr) { + ir_add_error_node(ira, instruction->ptr->source_node, + buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&ptr_type->name))); + return ira->codegen->invalid_inst_gen; + } + + return ptr_inst; +} + static Stage1AirInst *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Stage1ZirInstSetAlignStack *instruction) { uint32_t align_bytes; Stage1AirInst *align_bytes_inst = instruction->align_bytes->child; @@ -25451,6 +25495,8 @@ static Stage1AirInst *ir_analyze_instruction_base(IrAnalyze *ira, Stage1ZirInst return ir_analyze_instruction_src(ira, (Stage1ZirInstSrc *)instruction); case Stage1ZirInstIdPrefetch: return ir_analyze_instruction_prefetch(ira, (Stage1ZirInstPrefetch *)instruction); + case Stage1ZirInstIdAddrSpaceCast: + return ir_analyze_instruction_addrspace_cast(ira, (Stage1ZirInstAddrSpaceCast *)instruction); } zig_unreachable(); } @@ -25832,6 +25878,7 @@ bool ir_inst_src_has_side_effects(Stage1ZirInst *instruction) { case Stage1ZirInstIdWasmMemorySize: case Stage1ZirInstIdSrc: case Stage1ZirInstIdReduce: + case Stage1ZirInstIdAddrSpaceCast: return false; case Stage1ZirInstIdAsm: diff --git a/src/stage1/ir_print.cpp b/src/stage1/ir_print.cpp index 9296242a3e..366e48004c 100644 --- a/src/stage1/ir_print.cpp +++ b/src/stage1/ir_print.cpp @@ -373,6 +373,8 @@ const char* ir_inst_src_type_str(Stage1ZirInstId id) { return "SrcSrc"; case Stage1ZirInstIdPrefetch: return "SrcPrefetch"; + case Stage1ZirInstIdAddrSpaceCast: + return "SrcAddrSpaceCast"; } zig_unreachable(); } @@ -2382,6 +2384,14 @@ static void ir_print_align_cast(IrPrintSrc *irp, Stage1ZirInstAlignCast *instruc fprintf(irp->f, ")"); } +static void ir_print_addrspace_cast(IrPrintSrc *irp, Stage1ZirInstAddrSpaceCast *instruction) { + fprintf(irp->f, "@addrSpaceCast("); + ir_print_other_inst_src(irp, instruction->addrspace); + fprintf(irp->f, ","); + ir_print_other_inst_src(irp, instruction->ptr); + fprintf(irp->f, ")"); +} + static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) { fprintf(irp->f, "@alignCast("); ir_print_other_inst_gen(irp, instruction->target); @@ -3127,6 +3137,9 @@ static void ir_print_inst_src(IrPrintSrc *irp, Stage1ZirInst *instruction, bool case Stage1ZirInstIdPrefetch: ir_print_prefetch(irp, (Stage1ZirInstPrefetch *)instruction); break; + case Stage1ZirInstIdAddrSpaceCast: + ir_print_addrspace_cast(irp, (Stage1ZirInstAddrSpaceCast *)instruction); + break; } fprintf(irp->f, "\n"); } -- cgit v1.2.3