diff options
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 454 |
1 files changed, 161 insertions, 293 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index f17d537863..dd55f3a665 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -18,7 +18,7 @@ #include "target.hpp" #include "util.hpp" #include "zig_llvm.h" -#include "userland.h" +#include "stage2.h" #include "dump_analysis.hpp" #include "softfloat.hpp" #include "mem_profile.hpp" @@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc g->version_patch = patch; } -void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) { - g->emit_file_type = emit_file_type; -} - void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { g->each_lib_rpath = each_lib_rpath; } @@ -975,8 +971,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) { return buf_create_from_str("remainder division by zero or negative value"); case PanicMsgIdExactDivisionRemainder: return buf_create_from_str("exact division produced remainder"); - case PanicMsgIdSliceWidenRemainder: - return buf_create_from_str("slice widening size mismatch"); case PanicMsgIdUnwrapOptionalFail: return buf_create_from_str("attempt to unwrap null"); case PanicMsgIdUnreachable: @@ -3085,74 +3079,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in } } -static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executable, - IrInstGenResizeSlice *instruction) -{ - ZigType *actual_type = instruction->operand->value->type; - ZigType *wanted_type = instruction->base.value->type; - LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); - assert(expr_val); - - LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); - assert(wanted_type->id == ZigTypeIdStruct); - assert(wanted_type->data.structure.special == StructSpecialSlice); - assert(actual_type->id == ZigTypeIdStruct); - assert(actual_type->data.structure.special == StructSpecialSlice); - - ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry; - ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; - ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry; - ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type; - - - size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index; - size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index; - size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index; - size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index; - - LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, ""); - LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, ""); - LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, - get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), ""); - LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc, - (unsigned)wanted_ptr_index, ""); - gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false); - - LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, ""); - LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, ""); - uint64_t src_size = type_size(g, actual_child_type); - uint64_t dest_size = type_size(g, wanted_child_type); - - LLVMValueRef new_len; - if (dest_size == 1) { - LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, src_size, false); - new_len = LLVMBuildMul(g->builder, src_len, src_size_val, ""); - } else if (src_size == 1) { - LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, dest_size, false); - if (ir_want_runtime_safety(g, &instruction->base)) { - LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, ""); - LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type); - LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, ""); - LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk"); - LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail"); - LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); - - LLVMPositionBuilderAtEnd(g->builder, fail_block); - gen_safety_crash(g, PanicMsgIdSliceWidenRemainder); - - LLVMPositionBuilderAtEnd(g->builder, ok_block); - } - new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, ""); - } else { - zig_unreachable(); - } - - LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, ""); - gen_store_untyped(g, new_len, dest_len_ptr, 0, false); - - return result_loc; -} - static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable, IrInstGenCast *cast_instruction) { @@ -5014,6 +4940,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns if (!type_has_bits(instruction->base.value->type)) { return nullptr; } + if (instruction->operand->id == IrInstGenIdCall) { + IrInstGenCall *call = reinterpret_cast<IrInstGenCall *>(instruction->operand); + if (call->result_loc != nullptr) { + return ir_llvm_value(g, call->result_loc); + } + } LLVMValueRef value = ir_llvm_value(g, instruction->operand); if (handle_is_ptr(instruction->operand->value->type)) { return value; @@ -6177,7 +6109,9 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI LLVMValueRef result_loc = (instruction->result_loc == nullptr) ? nullptr : ir_llvm_value(g, instruction->result_loc); - if (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)) { + if (instruction->is_noasync || + (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn))) + { return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, ptr_result_type, result_loc, true); } @@ -6476,8 +6410,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction); case IrInstGenIdAssertNonNull: return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction); - case IrInstGenIdResizeSlice: - return ir_render_resize_slice(g, executable, (IrInstGenResizeSlice *)instruction); case IrInstGenIdPtrOfArrayToSlice: return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction); case IrInstGenIdSuspendBegin: @@ -6528,7 +6460,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) { set_debug_location(g, instruction); } instruction->llvm_value = ir_render_instruction(g, executable, instruction); - if (instruction->spill != nullptr) { + if (instruction->spill != nullptr && instruction->llvm_value != nullptr) { LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill); gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value); instruction->llvm_value = nullptr; @@ -7912,50 +7844,44 @@ static void zig_llvm_emit_output(CodeGen *g) { bool is_small = g->build_mode == BuildModeSmallRelease; - Buf *output_path = &g->o_file_output_path; char *err_msg = nullptr; - switch (g->emit_file_type) { - case EmitFileTypeBinary: - if (g->disable_bin_generation) - return; - if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) - { - zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg); - } - validate_inline_fns(g); - g->link_objects.append(output_path); - if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || - (g->out_type == OutTypeLib && !g->is_dynamic))) - { - zig_link_add_compiler_rt(g, g->sub_progress_node); - } - break; + const char *asm_filename = nullptr; + const char *bin_filename = nullptr; + const char *llvm_ir_filename = nullptr; + + if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path); + if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path); + if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path); + + // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire + // pipeline multiple times if this is requested. + if (asm_filename != nullptr && bin_filename != nullptr) { + if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug, + is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename)) + { + fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg); + exit(1); + } + bin_filename = nullptr; + llvm_ir_filename = nullptr; + } - case EmitFileTypeAssembly: - if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) - { - zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); - } - validate_inline_fns(g); - break; + if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug, + is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename)) + { + fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg); + exit(1); + } - case EmitFileTypeLLVMIr: - if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) - { - zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); - } - validate_inline_fns(g); - break; + validate_inline_fns(g); - default: - zig_unreachable(); + if (g->emit_bin) { + g->link_objects.append(&g->o_file_output_path); + if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) { + zig_link_add_compiler_rt(g, g->sub_progress_node); + } } + LLVMDisposeModule(g->module); g->module = nullptr; LLVMDisposeTargetData(g->target_data_ref); @@ -8221,9 +8147,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3); create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1); create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1); - create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1); - create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2); - create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2); create_builtin_fn(g, BuiltinFnIdField, "field", 2); create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1); create_builtin_fn(g, BuiltinFnIdType, "Type", 1); @@ -8261,7 +8184,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdIntToEnum, "intToEnum", 2); create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); - create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4); create_builtin_fn(g, BuiltinFnIdSplat, "splat", 2); @@ -8299,22 +8221,18 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdRound, "round", 1); create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4); create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX); - create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1); create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2); create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2); create_builtin_fn(g, BuiltinFnIdSetEvalBranchQuota, "setEvalBranchQuota", 1); create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2); create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0); create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); - create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2); create_builtin_fn(g, BuiltinFnIdExport, "export", 2); create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4); create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2); - create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); - create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); create_builtin_fn(g, BuiltinFnIdThis, "This", 0); create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2); create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3); @@ -8361,9 +8279,11 @@ static bool detect_dynamic_link(CodeGen *g) { return true; if (g->zig_target->os == OsFreestanding) return false; - if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr)) + if (target_os_requires_libc(g->zig_target->os)) return true; - // If there are no dynamic libraries then we can disable PIC + if (g->libc_link_lib != nullptr && target_is_glibc(g->zig_target)) + return true; + // If there are no dynamic libraries then we can disable dynamic linking. for (size_t i = 0; i < g->link_libs_list.length; i += 1) { LinkLib *link_lib = g->link_libs_list.at(i); if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) @@ -8498,25 +8418,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) { ZigLLVM_ArchType arch = target_arch_enum(arch_i); const char *arch_name = target_arch_name(arch); - SubArchList sub_arch_list = target_subarch_list(arch); - if (sub_arch_list == SubArchListNone) { - if (arch == g->zig_target->arch) { - g->target_arch_index = arch_i; - cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name)); - } - } else { - const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list); - if (arch == g->zig_target->arch) { - size_t sub_count = target_subarch_count(sub_arch_list); - for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) { - ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); - if (sub == g->zig_target->sub_arch) { - g->target_sub_arch_index = sub_i; - cur_arch = buf_ptr(buf_sprintf("Arch{ .%s = Arch.%s.%s }", - arch_name, sub_arch_list_name, target_subarch_name(sub))); - } - } - } + if (arch == g->zig_target->arch) { + g->target_arch_index = arch_i; + cur_arch = arch_name; } } } @@ -8610,22 +8514,19 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { break; } buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type); - const char *link_type = g->is_dynamic ? "Dynamic" : "Static"; + const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static"; buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type); buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); - buf_appendf(contents, "pub const arch = %s;\n", cur_arch); + buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch); buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); { - buf_append_str(contents, "pub const cpu_features: CpuFeatures = "); - if (g->zig_target->cpu_features != nullptr) { - const char *ptr; - size_t len; - stage2_cpu_features_get_builtin_str(g->zig_target->cpu_features, &ptr, &len); - buf_append_mem(contents, ptr, len); + buf_append_str(contents, "pub const cpu: Cpu = "); + if (g->zig_target->builtin_str != nullptr) { + buf_append_str(contents, g->zig_target->builtin_str); } else { - buf_append_str(contents, "arch.getBaselineCpuFeatures();\n"); + buf_append_str(contents, "Target.Cpu.baseline(arch);\n"); } } if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) { @@ -8717,22 +8618,18 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_int(&cache_hash, g->build_mode); cache_bool(&cache_hash, g->strip_debug_symbols); cache_int(&cache_hash, g->out_type); - cache_bool(&cache_hash, g->is_dynamic); + cache_bool(&cache_hash, detect_dynamic_link(g)); cache_bool(&cache_hash, g->is_test_build); cache_bool(&cache_hash, g->is_single_threaded); cache_bool(&cache_hash, g->test_is_evented); cache_int(&cache_hash, g->code_model); cache_int(&cache_hash, g->zig_target->is_native); cache_int(&cache_hash, g->zig_target->arch); - cache_int(&cache_hash, g->zig_target->sub_arch); cache_int(&cache_hash, g->zig_target->vendor); cache_int(&cache_hash, g->zig_target->os); cache_int(&cache_hash, g->zig_target->abi); - if (g->zig_target->cpu_features != nullptr) { - const char *ptr; - size_t len; - stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len); - cache_str(&cache_hash, ptr); + if (g->zig_target->cache_hash != nullptr) { + cache_str(&cache_hash, g->zig_target->cache_hash); } if (g->zig_target->glibc_version != nullptr) { cache_int(&cache_hash, g->zig_target->glibc_version->major); @@ -8867,9 +8764,11 @@ static void init(CodeGen *g) { } // Override CPU and features if defined by user. - if (g->zig_target->cpu_features != nullptr) { - target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features); - target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features); + if (g->zig_target->llvm_cpu_name != nullptr) { + target_specific_cpu_args = g->zig_target->llvm_cpu_name; + } + if (g->zig_target->llvm_cpu_features != nullptr) { + target_specific_features = g->zig_target->llvm_cpu_features; } if (g->verbose_llvm_cpu_features) { fprintf(stderr, "name=%s triple=%s\n", buf_ptr(g->root_out_name), buf_ptr(&g->llvm_triple_str)); @@ -8943,6 +8842,8 @@ static void init(CodeGen *g) { } static void detect_dynamic_linker(CodeGen *g) { + Error err; + if (g->dynamic_linker_path != nullptr) return; if (!g->have_dynamic_link) @@ -8950,42 +8851,16 @@ static void detect_dynamic_linker(CodeGen *g) { if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) return; - const char *standard_ld_path = target_dynamic_linker(g->zig_target); - if (standard_ld_path == nullptr) - return; - - if (g->zig_target->is_native) { - // target_dynamic_linker is usually correct. However on some systems, such as NixOS - // it will be incorrect. See if we can do better by looking at what zig's own - // dynamic linker path is. - g->dynamic_linker_path = get_self_dynamic_linker_path(); - if (g->dynamic_linker_path != nullptr) - return; - - // If Zig is statically linked, such as via distributed binary static builds, the above - // trick won't work. What are we left with? Try to run the system C compiler and get - // it to tell us the dynamic linker path -#if defined(ZIG_OS_LINUX) - { - Error err; - Buf *result = buf_alloc(); - for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) { - const char *lib_name = possible_ld_names[i]; - if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) { - if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) { - fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err)); - exit(1); - } - continue; - } - g->dynamic_linker_path = result; - return; - } - } -#endif + char *dynamic_linker_ptr; + size_t dynamic_linker_len; + if ((err = stage2_detect_dynamic_linker(g->zig_target, &dynamic_linker_ptr, &dynamic_linker_len))) { + if (err == ErrorTargetHasNoDynamicLinker) return; + fprintf(stderr, "Unable to detect dynamic linker: %s\n", err_str(err)); + exit(1); } - - g->dynamic_linker_path = buf_create_from_str(standard_ld_path); + g->dynamic_linker_path = buf_create_from_mem(dynamic_linker_ptr, dynamic_linker_len); + // Skips heap::c_allocator because the memory is allocated by stage2 library. + free(dynamic_linker_ptr); } static void detect_libc(CodeGen *g) { @@ -9014,16 +8889,16 @@ static void detect_libc(CodeGen *g) { buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os)); g->libc_include_dir_len = 4; - g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(g->libc_include_dir_len); - g->libc_include_dir_list[0] = arch_include_dir; - g->libc_include_dir_list[1] = generic_include_dir; - g->libc_include_dir_list[2] = arch_os_include_dir; - g->libc_include_dir_list[3] = generic_os_include_dir; + g->libc_include_dir_list = heap::c_allocator.allocate<const char*>(g->libc_include_dir_len); + g->libc_include_dir_list[0] = buf_ptr(arch_include_dir); + g->libc_include_dir_list[1] = buf_ptr(generic_include_dir); + g->libc_include_dir_list[2] = buf_ptr(arch_os_include_dir); + g->libc_include_dir_list[3] = buf_ptr(generic_os_include_dir); return; } if (g->zig_target->is_native) { - g->libc = heap::c_allocator.create<ZigLibCInstallation>(); + g->libc = heap::c_allocator.create<Stage2LibCInstallation>(); // search for native_libc.txt in following dirs: // - LOCAL_CACHE_DIR @@ -9068,8 +8943,8 @@ static void detect_libc(CodeGen *g) { if (libc_txt == nullptr) libc_txt = &global_libc_txt; - if ((err = zig_libc_parse(g->libc, libc_txt, g->zig_target, false))) { - if ((err = zig_libc_find_native(g->libc, true))) { + if ((err = stage2_libc_parse(g->libc, buf_ptr(libc_txt)))) { + if ((err = stage2_libc_find_native(g->libc))) { fprintf(stderr, "Unable to link against libc: Unable to find libc installation: %s\n" "See `zig libc --help` for more details.\n", err_str(err)); @@ -9089,7 +8964,7 @@ static void detect_libc(CodeGen *g) { fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno)); exit(1); } - zig_libc_render(g->libc, file); + stage2_libc_render(g->libc, file); if (fclose(file) != 0) { fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno)); exit(1); @@ -9099,27 +8974,28 @@ static void detect_libc(CodeGen *g) { exit(1); } } - bool want_sys_dir = !buf_eql_buf(&g->libc->include_dir, &g->libc->sys_include_dir); + bool want_sys_dir = !mem_eql_mem(g->libc->include_dir, g->libc->include_dir_len, + g->libc->sys_include_dir, g->libc->sys_include_dir_len); size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0; size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs; g->libc_include_dir_len = 0; - g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(dir_count); + g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count); - g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->include_dir; + g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir; g->libc_include_dir_len += 1; if (want_sys_dir) { - g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->sys_include_dir; + g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir; g->libc_include_dir_len += 1; } if (want_um_and_shared_dirs != 0) { - g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "um", - buf_ptr(&g->libc->include_dir)); + g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf( + "%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir)); g->libc_include_dir_len += 1; - g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "shared", - buf_ptr(&g->libc->include_dir)); + g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf( + "%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir)); g->libc_include_dir_len += 1; } assert(g->libc_include_dir_len == dir_count); @@ -9194,9 +9070,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa args.append(buf_ptr(g->zig_c_headers_dir)); for (size_t i = 0; i < g->libc_include_dir_len; i += 1) { - Buf *include_dir = g->libc_include_dir_list[i]; + const char *include_dir = g->libc_include_dir_list[i]; args.append("-isystem"); - args.append(buf_ptr(include_dir)); + args.append(include_dir); } if (g->zig_target->is_native) { @@ -9207,19 +9083,17 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa args.append("-target"); args.append(buf_ptr(&g->llvm_triple_str)); - const char *llvm_cpu = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features); - if (llvm_cpu != nullptr) { + if (g->zig_target->llvm_cpu_name != nullptr) { args.append("-Xclang"); args.append("-target-cpu"); args.append("-Xclang"); - args.append(llvm_cpu); + args.append(g->zig_target->llvm_cpu_name); } - const char *llvm_target_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features); - if (llvm_target_features != nullptr) { + if (g->zig_target->llvm_cpu_features != nullptr) { args.append("-Xclang"); args.append("-target-feature"); args.append("-Xclang"); - args.append(llvm_target_features); + args.append(g->zig_target->llvm_cpu_features); } } @@ -9652,10 +9526,9 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose cache_buf(cache_hash, compiler_id); cache_int(cache_hash, g->err_color); cache_buf(cache_hash, g->zig_c_headers_dir); - cache_list_of_buf(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len); + cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len); cache_int(cache_hash, g->zig_target->is_native); cache_int(cache_hash, g->zig_target->arch); - cache_int(cache_hash, g->zig_target->sub_arch); cache_int(cache_hash, g->zig_target->vendor); cache_int(cache_hash, g->zig_target->os); cache_int(cache_hash, g->zig_target->abi); @@ -10419,15 +10292,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_int(ch, g->out_type); cache_bool(ch, g->zig_target->is_native); cache_int(ch, g->zig_target->arch); - cache_int(ch, g->zig_target->sub_arch); cache_int(ch, g->zig_target->vendor); cache_int(ch, g->zig_target->os); cache_int(ch, g->zig_target->abi); - if (g->zig_target->cpu_features != nullptr) { - const char *ptr; - size_t len; - stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len); - cache_str(ch, ptr); + if (g->zig_target->cache_hash != nullptr) { + cache_str(ch, g->zig_target->cache_hash); } if (g->zig_target->glibc_version != nullptr) { cache_int(ch, g->zig_target->glibc_version->major); @@ -10457,7 +10326,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->function_sections); cache_bool(ch, g->enable_dump_analysis); cache_bool(ch, g->enable_doc_generation); - cache_bool(ch, g->disable_bin_generation); + cache_bool(ch, g->emit_bin); + cache_bool(ch, g->emit_llvm_ir); + cache_bool(ch, g->emit_asm); cache_buf_opt(ch, g->mmacosx_version_min); cache_buf_opt(ch, g->mios_version_min); cache_usize(ch, g->version_major); @@ -10468,11 +10339,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length); cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length); if (g->libc) { - cache_buf(ch, &g->libc->include_dir); - cache_buf(ch, &g->libc->sys_include_dir); - cache_buf(ch, &g->libc->crt_dir); - cache_buf(ch, &g->libc->msvc_lib_dir); - cache_buf(ch, &g->libc->kernel32_lib_dir); + cache_str(ch, g->libc->include_dir); + cache_str(ch, g->libc->sys_include_dir); + cache_str(ch, g->libc->crt_dir); + cache_str(ch, g->libc->msvc_lib_dir); + cache_str(ch, g->libc->kernel32_lib_dir); } cache_buf_opt(ch, g->dynamic_linker_path); cache_buf_opt(ch, g->version_script_path); @@ -10502,58 +10373,54 @@ static void resolve_out_paths(CodeGen *g) { assert(g->output_dir != nullptr); assert(g->root_out_name != nullptr); - Buf *out_basename = buf_create_from_buf(g->root_out_name); - Buf *o_basename = buf_create_from_buf(g->root_out_name); - switch (g->emit_file_type) { - case EmitFileTypeBinary: { - switch (g->out_type) { - case OutTypeUnknown: - zig_unreachable(); - case OutTypeObj: - if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) { - buf_init_from_buf(&g->output_file_path, g->link_objects.at(0)); - return; - } - if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && - buf_eql_buf(o_basename, out_basename)) - { - // make it not collide with main output object - buf_append_str(o_basename, ".root"); - } - buf_append_str(o_basename, target_o_file_ext(g->zig_target)); - buf_append_str(out_basename, target_o_file_ext(g->zig_target)); - break; - case OutTypeExe: - buf_append_str(o_basename, target_o_file_ext(g->zig_target)); - buf_append_str(out_basename, target_exe_file_ext(g->zig_target)); - break; - case OutTypeLib: - buf_append_str(o_basename, target_o_file_ext(g->zig_target)); - buf_resize(out_basename, 0); - buf_append_str(out_basename, target_lib_file_prefix(g->zig_target)); - buf_append_buf(out_basename, g->root_out_name); - buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, - g->version_major, g->version_minor, g->version_patch)); - break; - } - break; - } - case EmitFileTypeAssembly: { - const char *asm_ext = target_asm_file_ext(g->zig_target); - buf_append_str(o_basename, asm_ext); - buf_append_str(out_basename, asm_ext); - break; - } - case EmitFileTypeLLVMIr: { - const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); - buf_append_str(o_basename, llvm_ir_ext); - buf_append_str(out_basename, llvm_ir_ext); - break; + if (g->emit_bin) { + Buf *out_basename = buf_create_from_buf(g->root_out_name); + Buf *o_basename = buf_create_from_buf(g->root_out_name); + switch (g->out_type) { + case OutTypeUnknown: + zig_unreachable(); + case OutTypeObj: + if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) { + buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0)); + return; + } + if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && + buf_eql_buf(o_basename, out_basename)) + { + // make it not collide with main output object + buf_append_str(o_basename, ".root"); + } + buf_append_str(o_basename, target_o_file_ext(g->zig_target)); + buf_append_str(out_basename, target_o_file_ext(g->zig_target)); + break; + case OutTypeExe: + buf_append_str(o_basename, target_o_file_ext(g->zig_target)); + buf_append_str(out_basename, target_exe_file_ext(g->zig_target)); + break; + case OutTypeLib: + buf_append_str(o_basename, target_o_file_ext(g->zig_target)); + buf_resize(out_basename, 0); + buf_append_str(out_basename, target_lib_file_prefix(g->zig_target)); + buf_append_buf(out_basename, g->root_out_name); + buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, + g->version_major, g->version_minor, g->version_patch)); + break; } + os_path_join(g->output_dir, o_basename, &g->o_file_output_path); + os_path_join(g->output_dir, out_basename, &g->bin_file_output_path); + } + if (g->emit_asm) { + Buf *asm_basename = buf_create_from_buf(g->root_out_name); + const char *asm_ext = target_asm_file_ext(g->zig_target); + buf_append_str(asm_basename, asm_ext); + os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path); + } + if (g->emit_llvm_ir) { + Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name); + const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); + buf_append_str(llvm_ir_basename, llvm_ir_ext); + os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path); } - - os_path_join(g->output_dir, o_basename, &g->o_file_output_path); - os_path_join(g->output_dir, out_basename, &g->output_file_path); } void codegen_build_and_link(CodeGen *g) { @@ -10715,7 +10582,7 @@ void codegen_build_and_link(CodeGen *g) { // If there is more than one object, we have to link them (with -r). // Finally, if we didn't make an object from zig source, and we don't have caching enabled, // then we have an object from C source that we must copy to the output dir which we do with a -r link. - if (!g->disable_bin_generation && g->emit_file_type == EmitFileTypeBinary && + if (g->emit_bin && (g->out_type != OutTypeObj || g->link_objects.length > 1 || (!need_llvm_module(g) && !g->enable_cache))) { @@ -10751,7 +10618,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c } CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type, - ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node) + Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node) { Stage2ProgressNode *child_progress_node = stage2_progress_start( parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node, @@ -10790,9 +10657,10 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode, Buf *override_lib_dir, - ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) + Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) { CodeGen *g = heap::c_allocator.create<CodeGen>(); + g->emit_bin = true; g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); g->main_progress_node = progress_node; |
