remove -fstage1 option

After this commit, the self-hosted compiler does not offer the option to
use stage1 as a backend anymore.
This commit is contained in:
Andrew Kelley 2022-10-31 20:29:55 -07:00
parent bf316e5506
commit 28514476ef
25 changed files with 97 additions and 463 deletions

View File

@ -1084,7 +1084,6 @@ set(ZIG_BUILD_ARGS
--zig-lib-dir "${CMAKE_SOURCE_DIR}/lib" --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib"
"-Dconfig_h=${ZIG_CONFIG_H_OUT}" "-Dconfig_h=${ZIG_CONFIG_H_OUT}"
"-Denable-llvm" "-Denable-llvm"
"-Denable-stage1"
${ZIG_RELEASE_ARG} ${ZIG_RELEASE_ARG}
${ZIG_STATIC_ARG} ${ZIG_STATIC_ARG}
${ZIG_NO_LIB_ARG} ${ZIG_NO_LIB_ARG}

123
build.zig
View File

@ -69,9 +69,8 @@ pub fn build(b: *Builder) !void {
const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false; const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
const have_stage1 = b.option(bool, "enable-stage1", "Include the stage1 compiler behind a feature flag") orelse false;
const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false; const static_llvm = b.option(bool, "static-llvm", "Disable integration with system-installed LLVM, Clang, LLD, and libc++") orelse false;
const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse (have_stage1 or static_llvm); const enable_llvm = b.option(bool, "enable-llvm", "Build self-hosted compiler with LLVM backend enabled") orelse static_llvm;
const llvm_has_m68k = b.option( const llvm_has_m68k = b.option(
bool, bool,
"llvm-has-m68k", "llvm-has-m68k",
@ -133,7 +132,6 @@ pub fn build(b: *Builder) !void {
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse (enable_llvm or only_c); const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse (enable_llvm or only_c);
const sanitize_thread = b.option(bool, "sanitize-thread", "Enable thread-sanitization") orelse false; const sanitize_thread = b.option(bool, "sanitize-thread", "Enable thread-sanitization") orelse false;
const strip = b.option(bool, "strip", "Omit debug information") orelse false; const strip = b.option(bool, "strip", "Omit debug information") orelse false;
const use_zig0 = b.option(bool, "zig0", "Bootstrap using zig0") orelse false;
const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false; const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false;
const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: { const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
@ -146,11 +144,7 @@ pub fn build(b: *Builder) !void {
target.ofmt = .c; target.ofmt = .c;
} }
const main_file: ?[]const u8 = mf: { const main_file: ?[]const u8 = "src/main.zig";
if (!have_stage1) break :mf "src/main.zig";
if (use_zig0) break :mf null;
break :mf "src/stage1.zig";
};
const exe = b.addExecutable("zig", main_file); const exe = b.addExecutable("zig", main_file);
@ -264,92 +258,6 @@ pub fn build(b: *Builder) !void {
} }
}; };
if (have_stage1) {
const softfloat = b.addStaticLibrary("softfloat", null);
softfloat.setBuildMode(.ReleaseFast);
softfloat.setTarget(target);
softfloat.addIncludePath("deps/SoftFloat-3e-prebuilt");
softfloat.addIncludePath("deps/SoftFloat-3e/source/8086");
softfloat.addIncludePath("deps/SoftFloat-3e/source/include");
softfloat.addCSourceFiles(&softfloat_sources, &[_][]const u8{ "-std=c99", "-O3" });
softfloat.single_threaded = single_threaded;
const zig0 = b.addExecutable("zig0", null);
zig0.addCSourceFiles(&.{"src/stage1/zig0.cpp"}, &exe_cflags);
zig0.addIncludePath("zig-cache/tmp"); // for config.h
zig0.defineCMacro("ZIG_VERSION_MAJOR", b.fmt("{d}", .{zig_version.major}));
zig0.defineCMacro("ZIG_VERSION_MINOR", b.fmt("{d}", .{zig_version.minor}));
zig0.defineCMacro("ZIG_VERSION_PATCH", b.fmt("{d}", .{zig_version.patch}));
zig0.defineCMacro("ZIG_VERSION_STRING", b.fmt("\"{s}\"", .{version}));
for ([_]*std.build.LibExeObjStep{ zig0, exe, test_cases }) |artifact| {
artifact.addIncludePath("src");
artifact.addIncludePath("deps/SoftFloat-3e/source/include");
artifact.addIncludePath("deps/SoftFloat-3e-prebuilt");
artifact.defineCMacro("ZIG_LINK_MODE", "Static");
artifact.addCSourceFiles(&stage1_sources, &exe_cflags);
artifact.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
artifact.linkLibrary(softfloat);
artifact.linkLibCpp();
}
try addStaticLlvmOptionsToExe(zig0);
const zig1_obj_ext = target.getObjectFormat().fileExt(target.getCpuArch());
const zig1_obj_path = b.pathJoin(&.{ "zig-cache", "tmp", b.fmt("zig1{s}", .{zig1_obj_ext}) });
const zig1_compiler_rt_path = b.pathJoin(&.{ b.pathFromRoot("lib"), "std", "special", "compiler_rt.zig" });
const zig1_obj = zig0.run();
zig1_obj.addArgs(&.{
"src/stage1.zig",
"-target",
try target.zigTriple(b.allocator),
"-mcpu=baseline",
"--name",
"zig1",
"--zig-lib-dir",
b.pathFromRoot("lib"),
b.fmt("-femit-bin={s}", .{b.pathFromRoot(zig1_obj_path)}),
"-fcompiler-rt",
"-lc",
});
{
zig1_obj.addArgs(&.{ "--pkg-begin", "build_options" });
zig1_obj.addFileSourceArg(exe_options.getSource());
zig1_obj.addArgs(&.{ "--pkg-end", "--pkg-begin", "compiler_rt", zig1_compiler_rt_path, "--pkg-end" });
}
switch (mode) {
.Debug => {},
.ReleaseFast => {
zig1_obj.addArg("-OReleaseFast");
zig1_obj.addArg("-fstrip");
},
.ReleaseSafe => {
zig1_obj.addArg("-OReleaseSafe");
zig1_obj.addArg("-fstrip");
},
.ReleaseSmall => {
zig1_obj.addArg("-OReleaseSmall");
zig1_obj.addArg("-fstrip");
},
}
if (single_threaded orelse false) {
zig1_obj.addArg("-fsingle-threaded");
}
if (use_zig0) {
exe.step.dependOn(&zig1_obj.step);
exe.addObjectFile(zig1_obj_path);
}
// This is intentionally a dummy path. stage1.zig tries to @import("compiler_rt") in case
// of being built by cmake. But when built by zig it's gonna get a compiler_rt so that
// is pointless.
exe.addPackagePath("compiler_rt", "src/empty.zig");
}
if (cmake_cfg) |cfg| { if (cmake_cfg) |cfg| {
// Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD. // Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
// That means we also have to rely on stage1 compiled c++ files. We parse config.h to find // That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
@ -379,7 +287,6 @@ pub fn build(b: *Builder) !void {
exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack); exe_options.addOption(bool, "enable_tracy_callstack", tracy_callstack);
exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation); exe_options.addOption(bool, "enable_tracy_allocation", tracy_allocation);
exe_options.addOption(bool, "value_tracing", value_tracing); exe_options.addOption(bool, "value_tracing", value_tracing);
exe_options.addOption(bool, "have_stage1", have_stage1);
if (tracy) |tracy_path| { if (tracy) |tracy_path| {
const client_cpp = fs.path.join( const client_cpp = fs.path.join(
b.allocator, b.allocator,
@ -414,7 +321,6 @@ pub fn build(b: *Builder) !void {
test_cases_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots); test_cases_options.addOption(bool, "enable_link_snapshots", enable_link_snapshots);
test_cases_options.addOption(bool, "skip_non_native", skip_non_native); test_cases_options.addOption(bool, "skip_non_native", skip_non_native);
test_cases_options.addOption(bool, "skip_stage1", skip_stage1); test_cases_options.addOption(bool, "skip_stage1", skip_stage1);
test_cases_options.addOption(bool, "have_stage1", have_stage1);
test_cases_options.addOption(bool, "have_llvm", enable_llvm); test_cases_options.addOption(bool, "have_llvm", enable_llvm);
test_cases_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k); test_cases_options.addOption(bool, "llvm_has_m68k", llvm_has_m68k);
test_cases_options.addOption(bool, "llvm_has_csky", llvm_has_csky); test_cases_options.addOption(bool, "llvm_has_csky", llvm_has_csky);
@ -1010,31 +916,6 @@ const softfloat_sources = [_][]const u8{
"deps/SoftFloat-3e/source/ui64_to_extF80M.c", "deps/SoftFloat-3e/source/ui64_to_extF80M.c",
}; };
const stage1_sources = [_][]const u8{
"src/stage1/analyze.cpp",
"src/stage1/astgen.cpp",
"src/stage1/bigfloat.cpp",
"src/stage1/bigint.cpp",
"src/stage1/buffer.cpp",
"src/stage1/codegen.cpp",
"src/stage1/errmsg.cpp",
"src/stage1/error.cpp",
"src/stage1/heap.cpp",
"src/stage1/ir.cpp",
"src/stage1/ir_print.cpp",
"src/stage1/mem.cpp",
"src/stage1/os.cpp",
"src/stage1/parser.cpp",
"src/stage1/range_set.cpp",
"src/stage1/stage1.cpp",
"src/stage1/target.cpp",
"src/stage1/tokenizer.cpp",
"src/stage1/util.cpp",
"src/stage1/softfloat_ext.cpp",
};
const optimized_c_sources = [_][]const u8{
"src/stage1/parse_f128.c",
};
const zig_cpp_sources = [_][]const u8{ const zig_cpp_sources = [_][]const u8{
// These are planned to stay even when we are self-hosted. // These are planned to stay even when we are self-hosted.
"src/zig_llvm.cpp", "src/zig_llvm.cpp",

View File

@ -183,10 +183,6 @@ pub fn main() !void {
builder.enable_darling = true; builder.enable_darling = true;
} else if (mem.eql(u8, arg, "-fno-darling")) { } else if (mem.eql(u8, arg, "-fno-darling")) {
builder.enable_darling = false; builder.enable_darling = false;
} else if (mem.eql(u8, arg, "-fstage1")) {
builder.use_stage1 = true;
} else if (mem.eql(u8, arg, "-fno-stage1")) {
builder.use_stage1 = false;
} else if (mem.eql(u8, arg, "-freference-trace")) { } else if (mem.eql(u8, arg, "-freference-trace")) {
builder.reference_trace = 256; builder.reference_trace = 256;
} else if (mem.startsWith(u8, arg, "-freference-trace=")) { } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
@ -318,8 +314,6 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: anytype) !void
try out_stream.writeAll( try out_stream.writeAll(
\\ \\
\\Advanced Options: \\Advanced Options:
\\ -fstage1 Force using bootstrap compiler as the codegen backend
\\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend
\\ -freference-trace[=num] How many lines of reference trace should be shown per compile error \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
\\ -fno-reference-trace Disable reference trace \\ -fno-reference-trace Disable reference trace
\\ --build-file [file] Override path to build.zig \\ --build-file [file] Override path to build.zig

View File

@ -46,7 +46,6 @@ pub const Builder = struct {
prominent_compile_errors: bool, prominent_compile_errors: bool,
color: enum { auto, on, off } = .auto, color: enum { auto, on, off } = .auto,
reference_trace: ?u32 = null, reference_trace: ?u32 = null,
use_stage1: ?bool = null,
invalid_user_input: bool, invalid_user_input: bool,
zig_exe: []const u8, zig_exe: []const u8,
default_step: *Step, default_step: *Step,
@ -1621,7 +1620,6 @@ pub const LibExeObjStep = struct {
stack_size: ?u64 = null, stack_size: ?u64 = null,
want_lto: ?bool = null, want_lto: ?bool = null,
use_stage1: ?bool = null,
use_llvm: ?bool = null, use_llvm: ?bool = null,
use_lld: ?bool = null, use_lld: ?bool = null,
@ -2467,20 +2465,6 @@ pub const LibExeObjStep = struct {
try zig_args.append(try std.fmt.allocPrint(builder.allocator, "-freference-trace={d}", .{some})); try zig_args.append(try std.fmt.allocPrint(builder.allocator, "-freference-trace={d}", .{some}));
} }
if (self.use_stage1) |stage1| {
if (stage1) {
try zig_args.append("-fstage1");
} else {
try zig_args.append("-fno-stage1");
}
} else if (builder.use_stage1) |stage1| {
if (stage1) {
try zig_args.append("-fstage1");
} else {
try zig_args.append("-fno-stage1");
}
}
if (self.use_llvm) |use_llvm| { if (self.use_llvm) |use_llvm| {
if (use_llvm) { if (use_llvm) {
try zig_args.append("-fLLVM"); try zig_args.append("-fLLVM");

View File

@ -21,7 +21,6 @@ output_dir: ?[]const u8,
out_basename: []const u8, out_basename: []const u8,
target: CrossTarget = CrossTarget{}, target: CrossTarget = CrossTarget{},
output_file: build.GeneratedFile, output_file: build.GeneratedFile,
use_stage1: ?bool = null,
pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep { pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
const self = builder.allocator.create(TranslateCStep) catch unreachable; const self = builder.allocator.create(TranslateCStep) catch unreachable;
@ -92,19 +91,6 @@ fn make(step: *Step) !void {
try argv_list.append("-D"); try argv_list.append("-D");
try argv_list.append(c_macro); try argv_list.append(c_macro);
} }
if (self.use_stage1) |stage1| {
if (stage1) {
try argv_list.append("-fstage1");
} else {
try argv_list.append("-fno-stage1");
}
} else if (self.builder.use_stage1) |stage1| {
if (stage1) {
try argv_list.append("-fstage1");
} else {
try argv_list.append("-fno-stage1");
}
}
try argv_list.append(self.source.getPath(self.builder)); try argv_list.append(self.source.getPath(self.builder));

View File

@ -935,7 +935,6 @@ pub const InitOptions = struct {
use_llvm: ?bool = null, use_llvm: ?bool = null,
use_lld: ?bool = null, use_lld: ?bool = null,
use_clang: ?bool = null, use_clang: ?bool = null,
use_stage1: ?bool = null,
single_threaded: ?bool = null, single_threaded: ?bool = null,
strip: ?bool = null, strip: ?bool = null,
formatted_panics: ?bool = null, formatted_panics: ?bool = null,
@ -1133,9 +1132,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const comp = try arena.create(Compilation); const comp = try arena.create(Compilation);
const root_name = try arena.dupeZ(u8, options.root_name); const root_name = try arena.dupeZ(u8, options.root_name);
const use_stage1 = options.use_stage1 orelse false;
if (use_stage1 and !build_options.have_stage1) return error.ZigCompilerBuiltWithoutStage1;
// Make a decision on whether to use LLVM or our own backend. // Make a decision on whether to use LLVM or our own backend.
const use_llvm = build_options.have_llvm and blk: { const use_llvm = build_options.have_llvm and blk: {
if (options.use_llvm) |explicit| if (options.use_llvm) |explicit|
@ -1149,11 +1145,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
if (options.main_pkg == null) if (options.main_pkg == null)
break :blk false; break :blk false;
// The stage1 compiler depends on the stage1 C++ LLVM backend
// to compile zig code.
if (use_stage1)
break :blk true;
// If LLVM does not support the target, then we can't use it. // If LLVM does not support the target, then we can't use it.
if (!target_util.hasLlvmSupport(options.target, options.target.ofmt)) if (!target_util.hasLlvmSupport(options.target, options.target.ofmt))
break :blk false; break :blk false;
@ -1181,8 +1172,10 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
// compiler state, the second clause here can be removed so that incremental // compiler state, the second clause here can be removed so that incremental
// cache mode is used for LLVM backend too. We need some fuzz testing before // cache mode is used for LLVM backend too. We need some fuzz testing before
// that can be enabled. // that can be enabled.
const cache_mode = if ((use_stage1 and !options.disable_lld_caching) or const cache_mode = if (use_llvm and !options.disable_lld_caching)
(use_llvm and !options.disable_lld_caching)) CacheMode.whole else options.cache_mode; CacheMode.whole
else
options.cache_mode;
const tsan = options.want_tsan orelse false; const tsan = options.want_tsan orelse false;
// TSAN is implemented in C++ so it requires linking libc++. // TSAN is implemented in C++ so it requires linking libc++.
@ -1545,7 +1538,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
// Synchronize with other matching comments: ZigOnlyHashStuff // Synchronize with other matching comments: ZigOnlyHashStuff
hash.add(valgrind); hash.add(valgrind);
hash.add(single_threaded); hash.add(single_threaded);
hash.add(use_stage1);
hash.add(use_llvm); hash.add(use_llvm);
hash.add(dll_export_fns); hash.add(dll_export_fns);
hash.add(options.is_test); hash.add(options.is_test);
@ -1587,9 +1579,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.handle = artifact_dir, .handle = artifact_dir,
.path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}), .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),
}; };
log.debug("zig_cache_artifact_directory='{?s}' use_stage1={}", .{
zig_cache_artifact_directory.path, use_stage1,
});
const builtin_pkg = try Package.createWithDir( const builtin_pkg = try Package.createWithDir(
gpa, gpa,
@ -1907,7 +1896,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.subsystem = options.subsystem, .subsystem = options.subsystem,
.is_test = options.is_test, .is_test = options.is_test,
.wasi_exec_model = wasi_exec_model, .wasi_exec_model = wasi_exec_model,
.use_stage1 = use_stage1,
.hash_style = options.hash_style, .hash_style = options.hash_style,
.enable_link_snapshots = options.enable_link_snapshots, .enable_link_snapshots = options.enable_link_snapshots,
.native_darwin_sdk = options.native_darwin_sdk, .native_darwin_sdk = options.native_darwin_sdk,
@ -2344,7 +2332,6 @@ pub fn update(comp: *Compilation) !void {
comp.c_object_work_queue.writeItemAssumeCapacity(key); comp.c_object_work_queue.writeItemAssumeCapacity(key);
} }
const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
if (comp.bin_file.options.module) |module| { if (comp.bin_file.options.module) |module| {
module.compile_log_text.shrinkAndFree(module.gpa, 0); module.compile_log_text.shrinkAndFree(module.gpa, 0);
module.generation += 1; module.generation += 1;
@ -2360,7 +2347,7 @@ pub fn update(comp: *Compilation) !void {
// import_table here. // import_table here.
// Likewise, in the case of `zig test`, the test runner is the root source file, // Likewise, in the case of `zig test`, the test runner is the root source file,
// and so there is nothing to import the main file. // and so there is nothing to import the main file.
if (use_stage1 or comp.bin_file.options.is_test) { if (comp.bin_file.options.is_test) {
_ = try module.importPkg(module.main_pkg); _ = try module.importPkg(module.main_pkg);
} }
@ -2374,21 +2361,19 @@ pub fn update(comp: *Compilation) !void {
comp.astgen_work_queue.writeItemAssumeCapacity(value); comp.astgen_work_queue.writeItemAssumeCapacity(value);
} }
if (!use_stage1) { // Put a work item in for checking if any files used with `@embedFile` changed.
// Put a work item in for checking if any files used with `@embedFile` changed. {
{ try comp.embed_file_work_queue.ensureUnusedCapacity(module.embed_table.count());
try comp.embed_file_work_queue.ensureUnusedCapacity(module.embed_table.count()); var it = module.embed_table.iterator();
var it = module.embed_table.iterator(); while (it.next()) |entry| {
while (it.next()) |entry| { const embed_file = entry.value_ptr.*;
const embed_file = entry.value_ptr.*; comp.embed_file_work_queue.writeItemAssumeCapacity(embed_file);
comp.embed_file_work_queue.writeItemAssumeCapacity(embed_file);
}
} }
}
try comp.work_queue.writeItem(.{ .analyze_pkg = std_pkg }); try comp.work_queue.writeItem(.{ .analyze_pkg = std_pkg });
if (comp.bin_file.options.is_test) { if (comp.bin_file.options.is_test) {
try comp.work_queue.writeItem(.{ .analyze_pkg = module.main_pkg }); try comp.work_queue.writeItem(.{ .analyze_pkg = module.main_pkg });
}
} }
} }
@ -2400,36 +2385,34 @@ pub fn update(comp: *Compilation) !void {
try comp.performAllTheWork(main_progress_node); try comp.performAllTheWork(main_progress_node);
if (!use_stage1) { if (comp.bin_file.options.module) |module| {
if (comp.bin_file.options.module) |module| { if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {
if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) { // The `test_functions` decl has been intentionally postponed until now,
// The `test_functions` decl has been intentionally postponed until now, // at which point we must populate it with the list of test functions that
// at which point we must populate it with the list of test functions that // have been discovered and not filtered out.
// have been discovered and not filtered out. try module.populateTestFunctions(main_progress_node);
try module.populateTestFunctions(main_progress_node);
}
// Process the deletion set. We use a while loop here because the
// deletion set may grow as we call `clearDecl` within this loop,
// and more unreferenced Decls are revealed.
while (module.deletion_set.count() != 0) {
const decl_index = module.deletion_set.keys()[0];
const decl = module.declPtr(decl_index);
assert(decl.deletion_flag);
assert(decl.dependants.count() == 0);
const is_anon = if (decl.zir_decl_index == 0) blk: {
break :blk decl.src_namespace.anon_decls.swapRemove(decl_index);
} else false;
try module.clearDecl(decl_index, null);
if (is_anon) {
module.destroyDecl(decl_index);
}
}
try module.processExports();
} }
// Process the deletion set. We use a while loop here because the
// deletion set may grow as we call `clearDecl` within this loop,
// and more unreferenced Decls are revealed.
while (module.deletion_set.count() != 0) {
const decl_index = module.deletion_set.keys()[0];
const decl = module.declPtr(decl_index);
assert(decl.deletion_flag);
assert(decl.dependants.count() == 0);
const is_anon = if (decl.zir_decl_index == 0) blk: {
break :blk decl.src_namespace.anon_decls.swapRemove(decl_index);
} else false;
try module.clearDecl(decl_index, null);
if (is_anon) {
module.destroyDecl(decl_index);
}
}
try module.processExports();
} }
if (comp.totalErrorCount() != 0) { if (comp.totalErrorCount() != 0) {
@ -2536,11 +2519,8 @@ fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
}; };
comp.link_error_flags = comp.bin_file.errorFlags(); comp.link_error_flags = comp.bin_file.errorFlags();
const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1; if (comp.bin_file.options.module) |module| {
if (!use_stage1) { try link.File.C.flushEmitH(module);
if (comp.bin_file.options.module) |module| {
try link.File.C.flushEmitH(module);
}
} }
} }
@ -2610,7 +2590,6 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
// Synchronize with other matching comments: ZigOnlyHashStuff // Synchronize with other matching comments: ZigOnlyHashStuff
man.hash.add(comp.bin_file.options.valgrind); man.hash.add(comp.bin_file.options.valgrind);
man.hash.add(comp.bin_file.options.single_threaded); man.hash.add(comp.bin_file.options.single_threaded);
man.hash.add(comp.bin_file.options.use_stage1);
man.hash.add(comp.bin_file.options.use_llvm); man.hash.add(comp.bin_file.options.use_llvm);
man.hash.add(comp.bin_file.options.dll_export_fns); man.hash.add(comp.bin_file.options.dll_export_fns);
man.hash.add(comp.bin_file.options.is_test); man.hash.add(comp.bin_file.options.is_test);
@ -3010,8 +2989,6 @@ pub fn performAllTheWork(
comp.work_queue_wait_group.reset(); comp.work_queue_wait_group.reset();
defer comp.work_queue_wait_group.wait(); defer comp.work_queue_wait_group.wait();
const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
{ {
const astgen_frame = tracy.namedFrame("astgen"); const astgen_frame = tracy.namedFrame("astgen");
defer astgen_frame.end(); defer astgen_frame.end();
@ -3056,7 +3033,7 @@ pub fn performAllTheWork(
} }
} }
if (!use_stage1) { {
const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls"); const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");
defer outdated_and_deleted_decls_frame.end(); defer outdated_and_deleted_decls_frame.end();
@ -3064,15 +3041,6 @@ pub fn performAllTheWork(
if (comp.bin_file.options.module) |mod| { if (comp.bin_file.options.module) |mod| {
try mod.processOutdatedAndDeletedDecls(); try mod.processOutdatedAndDeletedDecls();
} }
} else if (comp.bin_file.options.module) |mod| {
// If there are any AstGen compile errors, report them now to avoid
// hitting stage1 bugs.
if (mod.failed_files.count() != 0) {
return;
}
comp.updateStage1Module(main_progress_node) catch |err| {
fatal("unable to build stage1 zig object: {s}", .{@errorName(err)});
};
} }
if (comp.bin_file.options.module) |mod| { if (comp.bin_file.options.module) |mod| {
@ -3598,10 +3566,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
var man = comp.obtainCObjectCacheManifest(); var man = comp.obtainCObjectCacheManifest();
defer man.deinit(); defer man.deinit();
const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
man.hash.add(use_stage1);
man.hash.addBytes(c_src); man.hash.addBytes(c_src);
// If the previous invocation resulted in clang errors, we will see a hit // If the previous invocation resulted in clang errors, we will see a hit
@ -3665,7 +3630,6 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
new_argv.ptr + new_argv.len, new_argv.ptr + new_argv.len,
&clang_errors, &clang_errors,
c_headers_dir_path_z, c_headers_dir_path_z,
use_stage1,
) catch |err| switch (err) { ) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory, error.OutOfMemory => return error.OutOfMemory,
error.ASTUnitFailure => { error.ASTUnitFailure => {
@ -5097,8 +5061,6 @@ pub fn dump_argv(argv: []const []const u8) void {
} }
pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend { pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {
const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
if (use_stage1) return .stage1;
if (build_options.have_llvm and comp.bin_file.options.use_llvm) return .stage2_llvm; if (build_options.have_llvm and comp.bin_file.options.use_llvm) return .stage2_llvm;
const target = comp.bin_file.options.target; const target = comp.bin_file.options.target;
if (target.ofmt == .c) return .stage2_c; if (target.ofmt == .c) return .stage2_c;
@ -5394,7 +5356,6 @@ fn buildOutputFromZig(
.link_mode = .Static, .link_mode = .Static,
.function_sections = true, .function_sections = true,
.no_builtin = true, .no_builtin = true,
.use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1,
.want_sanitize_c = false, .want_sanitize_c = false,
.want_stack_check = false, .want_stack_check = false,
.want_stack_protector = 0, .want_stack_protector = 0,

View File

@ -2121,8 +2121,6 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
const msg = msg: { const msg = msg: {
const msg = try sema.errMsg(block, src, "async has not been implemented in the self-hosted compiler yet", .{}); const msg = try sema.errMsg(block, src, "async has not been implemented in the self-hosted compiler yet", .{});
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
try sema.errNote(block, src, msg, "to use async enable the stage1 compiler with either '-fstage1' or by setting '.use_stage1 = true` in your 'build.zig' script", .{});
break :msg msg; break :msg msg;
}; };
return sema.failWithOwnedErrorMsg(msg); return sema.failWithOwnedErrorMsg(msg);

View File

@ -155,7 +155,6 @@ pub const Options = struct {
build_id: bool, build_id: bool,
disable_lld_caching: bool, disable_lld_caching: bool,
is_test: bool, is_test: bool,
use_stage1: bool,
hash_style: HashStyle, hash_style: HashStyle,
major_subsystem_version: ?u32, major_subsystem_version: ?u32,
minor_subsystem_version: ?u32, minor_subsystem_version: ?u32,
@ -293,8 +292,7 @@ pub const File = struct {
return &(try MachO.openPath(allocator, options)).base; return &(try MachO.openPath(allocator, options)).base;
} }
const use_stage1 = build_options.have_stage1 and options.use_stage1; if (options.emit == null) {
if (use_stage1 or options.emit == null) {
return switch (options.target.ofmt) { return switch (options.target.ofmt) {
.coff => &(try Coff.createEmpty(allocator, options)).base, .coff => &(try Coff.createEmpty(allocator, options)).base,
.elf => &(try Elf.createEmpty(allocator, options)).base, .elf => &(try Elf.createEmpty(allocator, options)).base,
@ -983,24 +981,7 @@ pub const File = struct {
// If there is no Zig code to compile, then we should skip flushing the output file // If there is no Zig code to compile, then we should skip flushing the output file
// because it will not be part of the linker line anyway. // because it will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (base.options.module) |module| blk: { const module_obj_path: ?[]const u8 = if (base.options.module != null) blk: {
const use_stage1 = build_options.have_stage1 and base.options.use_stage1;
if (use_stage1) {
const obj_basename = try std.zig.binNameAlloc(arena, .{
.root_name = base.options.root_name,
.target = base.options.target,
.output_mode = .Obj,
});
switch (base.options.cache_mode) {
.incremental => break :blk try module.zig_cache_artifact_directory.join(
arena,
&[_][]const u8{obj_basename},
),
.whole => break :blk try fs.path.join(arena, &.{
fs.path.dirname(full_out_path_z).?, obj_basename,
}),
}
}
try base.flushModule(comp, prog_node); try base.flushModule(comp, prog_node);
const dirname = fs.path.dirname(full_out_path_z) orelse "."; const dirname = fs.path.dirname(full_out_path_z) orelse ".";

View File

@ -248,8 +248,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff {
}; };
const use_llvm = build_options.have_llvm and options.use_llvm; const use_llvm = build_options.have_llvm and options.use_llvm;
const use_stage1 = build_options.have_stage1 and options.use_stage1; if (use_llvm) {
if (use_llvm and !use_stage1) {
self.llvm_object = try LlvmObject.create(gpa, options); self.llvm_object = try LlvmObject.create(gpa, options);
} }
return self; return self;

View File

@ -30,25 +30,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
// If there is no Zig code to compile, then we should skip flushing the output file because it // If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway. // will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { const module_obj_path: ?[]const u8 = if (self.base.options.module != null) blk: {
const use_stage1 = build_options.have_stage1 and self.base.options.use_stage1;
if (use_stage1) {
const obj_basename = try std.zig.binNameAlloc(arena, .{
.root_name = self.base.options.root_name,
.target = self.base.options.target,
.output_mode = .Obj,
});
switch (self.base.options.cache_mode) {
.incremental => break :blk try module.zig_cache_artifact_directory.join(
arena,
&[_][]const u8{obj_basename},
),
.whole => break :blk try fs.path.join(arena, &.{
fs.path.dirname(full_out_path).?, obj_basename,
}),
}
}
try self.flushModule(comp, prog_node); try self.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| { if (fs.path.dirname(full_out_path)) |dirname| {

View File

@ -328,8 +328,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
.page_size = page_size, .page_size = page_size,
}; };
const use_llvm = build_options.have_llvm and options.use_llvm; const use_llvm = build_options.have_llvm and options.use_llvm;
const use_stage1 = build_options.have_stage1 and options.use_stage1; if (use_llvm) {
if (use_llvm and !use_stage1) {
self.llvm_object = try LlvmObject.create(gpa, options); self.llvm_object = try LlvmObject.create(gpa, options);
} }
return self; return self;
@ -1228,25 +1227,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
// If there is no Zig code to compile, then we should skip flushing the output file because it // If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway. // will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| blk: { const module_obj_path: ?[]const u8 = if (self.base.options.module != null) blk: {
// stage1 puts the object file in the cache directory.
if (self.base.options.use_stage1) {
const obj_basename = try std.zig.binNameAlloc(arena, .{
.root_name = self.base.options.root_name,
.target = self.base.options.target,
.output_mode = .Obj,
});
switch (self.base.options.cache_mode) {
.incremental => break :blk try module.zig_cache_artifact_directory.join(
arena,
&[_][]const u8{obj_basename},
),
.whole => break :blk try fs.path.join(arena, &.{
fs.path.dirname(full_out_path).?, obj_basename,
}),
}
}
try self.flushModule(comp, prog_node); try self.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| { if (fs.path.dirname(full_out_path)) |dirname| {

View File

@ -290,8 +290,7 @@ pub const Export = struct {
pub fn openPath(allocator: Allocator, options: link.Options) !*MachO { pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
assert(options.target.ofmt == .macho); assert(options.target.ofmt == .macho);
const use_stage1 = build_options.have_stage1 and options.use_stage1; if (options.emit == null or options.module == null) {
if (use_stage1 or options.emit == null or options.module == null) {
return createEmpty(allocator, options); return createEmpty(allocator, options);
} }
@ -377,7 +376,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
const cpu_arch = options.target.cpu.arch; const cpu_arch = options.target.cpu.arch;
const page_size: u16 = if (cpu_arch == .aarch64) 0x4000 else 0x1000; const page_size: u16 = if (cpu_arch == .aarch64) 0x4000 else 0x1000;
const use_llvm = build_options.have_llvm and options.use_llvm; const use_llvm = build_options.have_llvm and options.use_llvm;
const use_stage1 = build_options.have_stage1 and options.use_stage1;
const self = try gpa.create(MachO); const self = try gpa.create(MachO);
errdefer gpa.destroy(self); errdefer gpa.destroy(self);
@ -390,13 +388,13 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
.file = null, .file = null,
}, },
.page_size = page_size, .page_size = page_size,
.mode = if (use_stage1 or use_llvm or options.module == null or options.cache_mode == .whole) .mode = if (use_llvm or options.module == null or options.cache_mode == .whole)
.one_shot .one_shot
else else
.incremental, .incremental,
}; };
if (use_llvm and !use_stage1) { if (use_llvm) {
self.llvm_object = try LlvmObject.create(gpa, options); self.llvm_object = try LlvmObject.create(gpa, options);
} }

View File

@ -3746,24 +3746,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
// If there is no Zig code to compile, then we should skip flushing the output file because it // If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway. // will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (options.module) |module| blk: { const module_obj_path: ?[]const u8 = if (options.module != null) blk: {
if (options.use_stage1) {
const obj_basename = try std.zig.binNameAlloc(arena, .{
.root_name = options.root_name,
.target = target,
.output_mode = .Obj,
});
switch (options.cache_mode) {
.incremental => break :blk try module.zig_cache_artifact_directory.join(
arena,
&[_][]const u8{obj_basename},
),
.whole => break :blk try fs.path.join(arena, &.{
fs.path.dirname(full_out_path).?, obj_basename,
}),
}
}
try macho_file.flushModule(comp, prog_node); try macho_file.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| { if (fs.path.dirname(full_out_path)) |dirname| {

View File

@ -382,8 +382,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm {
}; };
const use_llvm = build_options.have_llvm and options.use_llvm; const use_llvm = build_options.have_llvm and options.use_llvm;
const use_stage1 = build_options.have_stage1 and options.use_stage1; if (use_llvm) {
if (use_llvm and !use_stage1) {
wasm.llvm_object = try LlvmObject.create(gpa, options); wasm.llvm_object = try LlvmObject.create(gpa, options);
} }
return wasm; return wasm;
@ -2986,25 +2985,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
// If there is no Zig code to compile, then we should skip flushing the output file because it // If there is no Zig code to compile, then we should skip flushing the output file because it
// will not be part of the linker line anyway. // will not be part of the linker line anyway.
const module_obj_path: ?[]const u8 = if (wasm.base.options.module) |mod| blk: { const module_obj_path: ?[]const u8 = if (wasm.base.options.module != null) blk: {
const use_stage1 = build_options.have_stage1 and wasm.base.options.use_stage1;
if (use_stage1) {
const obj_basename = try std.zig.binNameAlloc(arena, .{
.root_name = wasm.base.options.root_name,
.target = wasm.base.options.target,
.output_mode = .Obj,
});
switch (wasm.base.options.cache_mode) {
.incremental => break :blk try mod.zig_cache_artifact_directory.join(
arena,
&[_][]const u8{obj_basename},
),
.whole => break :blk try fs.path.join(arena, &.{
fs.path.dirname(full_out_path).?, obj_basename,
}),
}
}
try wasm.flushModule(comp, prog_node); try wasm.flushModule(comp, prog_node);
if (fs.path.dirname(full_out_path)) |dirname| { if (fs.path.dirname(full_out_path)) |dirname| {
@ -3198,26 +3179,19 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
if (wasm.base.options.module) |mod| { if (wasm.base.options.module) |mod| {
// when we use stage1, we use the exports that stage1 provided us. // when we use stage1, we use the exports that stage1 provided us.
// For stage2, we can directly retrieve them from the module. // For stage2, we can directly retrieve them from the module.
const use_stage1 = build_options.have_stage1 and wasm.base.options.use_stage1; const skip_export_non_fn = target.os.tag == .wasi and
if (use_stage1) { wasm.base.options.wasi_exec_model == .command;
for (comp.export_symbol_names.items) |symbol_name| { for (mod.decl_exports.values()) |exports| {
try argv.append(try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name})); for (exports.items) |exprt| {
} const exported_decl = mod.declPtr(exprt.exported_decl);
} else { if (skip_export_non_fn and exported_decl.ty.zigTypeTag() != .Fn) {
const skip_export_non_fn = target.os.tag == .wasi and // skip exporting symbols when we're building a WASI command
wasm.base.options.wasi_exec_model == .command; // and the symbol is not a function
for (mod.decl_exports.values()) |exports| { continue;
for (exports.items) |exprt| {
const exported_decl = mod.declPtr(exprt.exported_decl);
if (skip_export_non_fn and exported_decl.ty.zigTypeTag() != .Fn) {
// skip exporting symbols when we're building a WASI command
// and the symbol is not a function
continue;
}
const symbol_name = exported_decl.name;
const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
try argv.append(arg);
} }
const symbol_name = exported_decl.name;
const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
try argv.append(arg);
} }
} }
} }

View File

@ -394,8 +394,6 @@ const usage_build_generic =
\\ -fno-LLVM Prevent using LLVM as the codegen backend \\ -fno-LLVM Prevent using LLVM as the codegen backend
\\ -fClang Force using Clang as the C/C++ compilation backend \\ -fClang Force using Clang as the C/C++ compilation backend
\\ -fno-Clang Prevent using Clang as the C/C++ compilation backend \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend
\\ -fstage1 Force using bootstrap compiler as the codegen backend
\\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend
\\ -freference-trace[=num] How many lines of reference trace should be shown per compile error \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
\\ -fno-reference-trace Disable reference trace \\ -fno-reference-trace Disable reference trace
\\ -fsingle-threaded Code assumes there is only one thread \\ -fsingle-threaded Code assumes there is only one thread
@ -719,7 +717,6 @@ fn buildOutputType(
var use_llvm: ?bool = null; var use_llvm: ?bool = null;
var use_lld: ?bool = null; var use_lld: ?bool = null;
var use_clang: ?bool = null; var use_clang: ?bool = null;
var use_stage1: ?bool = null;
var link_eh_frame_hdr = false; var link_eh_frame_hdr = false;
var link_emit_relocs = false; var link_emit_relocs = false;
var each_lib_rpath: ?bool = null; var each_lib_rpath: ?bool = null;
@ -1158,10 +1155,6 @@ fn buildOutputType(
use_clang = true; use_clang = true;
} else if (mem.eql(u8, arg, "-fno-Clang")) { } else if (mem.eql(u8, arg, "-fno-Clang")) {
use_clang = false; use_clang = false;
} else if (mem.eql(u8, arg, "-fstage1")) {
use_stage1 = true;
} else if (mem.eql(u8, arg, "-fno-stage1")) {
use_stage1 = false;
} else if (mem.eql(u8, arg, "-freference-trace")) { } else if (mem.eql(u8, arg, "-freference-trace")) {
reference_trace = 256; reference_trace = 256;
} else if (mem.startsWith(u8, arg, "-freference-trace=")) { } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
@ -2909,7 +2902,6 @@ fn buildOutputType(
.use_llvm = use_llvm, .use_llvm = use_llvm,
.use_lld = use_lld, .use_lld = use_lld,
.use_clang = use_clang, .use_clang = use_clang,
.use_stage1 = use_stage1,
.hash_style = hash_style, .hash_style = hash_style,
.rdynamic = rdynamic, .rdynamic = rdynamic,
.linker_script = linker_script, .linker_script = linker_script,
@ -3024,8 +3016,7 @@ fn buildOutputType(
return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena)); return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
} }
if (arg_mode == .translate_c) { if (arg_mode == .translate_c) {
const stage1_mode = use_stage1 orelse false; return cmdTranslateC(comp, arena, have_enable_cache);
return cmdTranslateC(comp, arena, have_enable_cache, stage1_mode);
} }
const hook: AfterUpdateHook = blk: { const hook: AfterUpdateHook = blk: {
@ -3444,7 +3435,7 @@ fn freePkgTree(gpa: Allocator, pkg: *Package, free_parent: bool) void {
} }
} }
fn cmdTranslateC(comp: *Compilation, arena: Allocator, enable_cache: bool, stage1_mode: bool) !void { fn cmdTranslateC(comp: *Compilation, arena: Allocator, enable_cache: bool) !void {
if (!build_options.have_llvm) if (!build_options.have_llvm)
fatal("cannot translate-c: compiler built without LLVM extensions", .{}); fatal("cannot translate-c: compiler built without LLVM extensions", .{});
@ -3457,7 +3448,6 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, enable_cache: bool, stage
defer if (enable_cache) man.deinit(); defer if (enable_cache) man.deinit();
man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
man.hash.add(stage1_mode);
man.hashCSource(c_source_file) catch |err| { man.hashCSource(c_source_file) catch |err| {
fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) }); fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) });
}; };
@ -3509,7 +3499,6 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, enable_cache: bool, stage
new_argv.ptr + new_argv.len, new_argv.ptr + new_argv.len,
&clang_errors, &clang_errors,
c_headers_dir_path_z, c_headers_dir_path_z,
stage1_mode,
) catch |err| switch (err) { ) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory, error.OutOfMemory => return error.OutOfMemory,
error.ASTUnitFailure => fatal("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{}), error.ASTUnitFailure => fatal("clang API returned errors but due to a clang bug, it is not exposing the errors for zig to see. For more details: https://github.com/ziglang/zig/issues/4455", .{}),
@ -3755,8 +3744,6 @@ pub const usage_build =
\\ Build a project from build.zig. \\ Build a project from build.zig.
\\ \\
\\Options: \\Options:
\\ -fstage1 Force using bootstrap compiler as the codegen backend
\\ -fno-stage1 Prevent using bootstrap compiler as the codegen backend
\\ -freference-trace[=num] How many lines of reference trace should be shown per compile error \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
\\ -fno-reference-trace Disable reference trace \\ -fno-reference-trace Disable reference trace
\\ --build-file [file] Override path to build.zig \\ --build-file [file] Override path to build.zig
@ -3770,7 +3757,6 @@ pub const usage_build =
pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
var prominent_compile_errors: bool = false; var prominent_compile_errors: bool = false;
var use_stage1: ?bool = null;
// We want to release all the locks before executing the child process, so we make a nice // We want to release all the locks before executing the child process, so we make a nice
// big block here to ensure the cleanup gets run when we extract out our argv. // big block here to ensure the cleanup gets run when we extract out our argv.
@ -3827,12 +3813,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
continue; continue;
} else if (mem.eql(u8, arg, "--prominent-compile-errors")) { } else if (mem.eql(u8, arg, "--prominent-compile-errors")) {
prominent_compile_errors = true; prominent_compile_errors = true;
} else if (mem.eql(u8, arg, "-fstage1")) {
use_stage1 = true;
try child_argv.append(arg);
} else if (mem.eql(u8, arg, "-fno-stage1")) {
use_stage1 = false;
try child_argv.append(arg);
} else if (mem.eql(u8, arg, "-freference-trace")) { } else if (mem.eql(u8, arg, "-freference-trace")) {
try child_argv.append(arg); try child_argv.append(arg);
reference_trace = 256; reference_trace = 256;
@ -3979,7 +3959,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
.optimize_mode = .Debug, .optimize_mode = .Debug,
.self_exe_path = self_exe_path, .self_exe_path = self_exe_path,
.thread_pool = &thread_pool, .thread_pool = &thread_pool,
.use_stage1 = use_stage1,
.cache_mode = .whole, .cache_mode = .whole,
.reference_trace = reference_trace, .reference_trace = reference_trace,
.debug_compile_errors = debug_compile_errors, .debug_compile_errors = debug_compile_errors,

View File

@ -1548,7 +1548,6 @@ pub const TestContext = struct {
.dynamic_linker = target_info.dynamic_linker.get(), .dynamic_linker = target_info.dynamic_linker.get(),
.link_libc = case.link_libc, .link_libc = case.link_libc,
.use_llvm = use_llvm, .use_llvm = use_llvm,
.use_stage1 = null, // We already handled stage1 tests
.self_exe_path = zig_exe_path, .self_exe_path = zig_exe_path,
// TODO instead of turning off color, pass in a std.Progress.Node // TODO instead of turning off color, pass in a std.Progress.Node
.color = .off, .color = .off,

View File

@ -327,16 +327,6 @@ pub const Context = struct {
pattern_list: PatternList, pattern_list: PatternList,
/// This is used to emit different code depending on whether
/// the output zig source code is intended to be compiled with stage1 or stage2.
/// Ideally we will have stage1 and stage2 support the exact same Zig language,
/// but for now they diverge because I would rather focus on finishing and shipping
/// stage2 than implementing the features in stage1.
/// The list of differences are currently:
/// * function pointers in stage1 are e.g. `fn()void`
/// but in stage2 they are `*const fn()void`.
zig_is_stage1: bool,
fn getMangle(c: *Context) u32 { fn getMangle(c: *Context) u32 {
c.mangle_count += 1; c.mangle_count += 1;
return c.mangle_count; return c.mangle_count;
@ -365,7 +355,6 @@ pub fn translate(
args_end: [*]?[*]const u8, args_end: [*]?[*]const u8,
errors: *[]ClangErrMsg, errors: *[]ClangErrMsg,
resources_path: [*:0]const u8, resources_path: [*:0]const u8,
zig_is_stage1: bool,
) !std.zig.Ast { ) !std.zig.Ast {
// TODO stage2 bug // TODO stage2 bug
var tmp = errors; var tmp = errors;
@ -395,7 +384,6 @@ pub fn translate(
.global_scope = try arena.create(Scope.Root), .global_scope = try arena.create(Scope.Root),
.clang_context = ast_unit.getASTContext(), .clang_context = ast_unit.getASTContext(),
.pattern_list = try PatternList.init(gpa), .pattern_list = try PatternList.init(gpa),
.zig_is_stage1 = zig_is_stage1,
}; };
context.global_scope.* = Scope.Root.init(&context); context.global_scope.* = Scope.Root.init(&context);
defer { defer {
@ -435,7 +423,7 @@ pub fn translate(
} }
} }
return ast.render(gpa, zig_is_stage1, context.global_scope.nodes.items); return ast.render(gpa, context.global_scope.nodes.items);
} }
/// Determines whether macro is of the form: `#define FOO FOO` (Possibly with trailing tokens) /// Determines whether macro is of the form: `#define FOO FOO` (Possibly with trailing tokens)
@ -4747,9 +4735,6 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
.Pointer => { .Pointer => {
const child_qt = ty.getPointeeType(); const child_qt = ty.getPointeeType();
const is_fn_proto = qualTypeChildIsFnProto(child_qt); const is_fn_proto = qualTypeChildIsFnProto(child_qt);
if (c.zig_is_stage1 and is_fn_proto) {
return Tag.optional_type.create(c.arena, try transQualType(c, scope, child_qt, source_loc));
}
const is_const = is_fn_proto or child_qt.isConstQualified(); const is_const = is_fn_proto or child_qt.isConstQualified();
const is_volatile = child_qt.isVolatileQualified(); const is_volatile = child_qt.isVolatileQualified();
const elem_type = try transQualType(c, scope, child_qt, source_loc); const elem_type = try transQualType(c, scope, child_qt, source_loc);
@ -6681,16 +6666,10 @@ fn getFnProto(c: *Context, ref: Node) ?*ast.Payload.Func {
return null; return null;
if (getContainerTypeOf(c, init)) |ty_node| { if (getContainerTypeOf(c, init)) |ty_node| {
if (ty_node.castTag(.optional_type)) |prefix| { if (ty_node.castTag(.optional_type)) |prefix| {
if (c.zig_is_stage1) { if (prefix.data.castTag(.single_pointer)) |sp| {
if (prefix.data.castTag(.func)) |fn_proto| { if (sp.data.elem_type.castTag(.func)) |fn_proto| {
return fn_proto; return fn_proto;
} }
} else {
if (prefix.data.castTag(.single_pointer)) |sp| {
if (sp.data.elem_type.castTag(.func)) |fn_proto| {
return fn_proto;
}
}
} }
} }
} }

View File

@ -732,11 +732,10 @@ pub const Payload = struct {
/// Converts the nodes into a Zig Ast. /// Converts the nodes into a Zig Ast.
/// Caller must free the source slice. /// Caller must free the source slice.
pub fn render(gpa: Allocator, zig_is_stage1: bool, nodes: []const Node) !std.zig.Ast { pub fn render(gpa: Allocator, nodes: []const Node) !std.zig.Ast {
var ctx = Context{ var ctx = Context{
.gpa = gpa, .gpa = gpa,
.buf = std.ArrayList(u8).init(gpa), .buf = std.ArrayList(u8).init(gpa),
.zig_is_stage1 = zig_is_stage1,
}; };
defer ctx.buf.deinit(); defer ctx.buf.deinit();
defer ctx.nodes.deinit(gpa); defer ctx.nodes.deinit(gpa);
@ -805,11 +804,6 @@ const Context = struct {
extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{}, extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
tokens: std.zig.Ast.TokenList = .{}, tokens: std.zig.Ast.TokenList = .{},
/// This is used to emit different code depending on whether
/// the output zig source code is intended to be compiled with stage1 or stage2.
/// Refer to the Context in translate_c.zig.
zig_is_stage1: bool,
fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex { fn addTokenFmt(c: *Context, tag: TokenTag, comptime format: []const u8, args: anytype) Allocator.Error!TokenIndex {
const start_index = c.buf.items.len; const start_index = c.buf.items.len;
try c.buf.writer().print(format ++ " ", args); try c.buf.writer().print(format ++ " ", args);
@ -932,7 +926,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
.call => { .call => {
const payload = node.castTag(.call).?.data; const payload = node.castTag(.call).?.data;
// Cosmetic: avoids an unnecesary address_of on most function calls. // Cosmetic: avoids an unnecesary address_of on most function calls.
const lhs = if (!c.zig_is_stage1 and payload.lhs.tag() == .fn_identifier) const lhs = if (payload.lhs.tag() == .fn_identifier)
try c.addNode(.{ try c.addNode(.{
.tag = .identifier, .tag = .identifier,
.main_token = try c.addIdentifier(payload.lhs.castTag(.fn_identifier).?.data), .main_token = try c.addIdentifier(payload.lhs.castTag(.fn_identifier).?.data),
@ -1097,28 +1091,20 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
// value (implicit in stage1, explicit in stage2), except in // value (implicit in stage1, explicit in stage2), except in
// the context of an address_of, which is handled there. // the context of an address_of, which is handled there.
const payload = node.castTag(.fn_identifier).?.data; const payload = node.castTag(.fn_identifier).?.data;
if (c.zig_is_stage1) { const tok = try c.addToken(.ampersand, "&");
return try c.addNode(.{ const arg = try c.addNode(.{
.tag = .identifier, .tag = .identifier,
.main_token = try c.addIdentifier(payload), .main_token = try c.addIdentifier(payload),
.data = undefined, .data = undefined,
}); });
} else { return c.addNode(.{
const tok = try c.addToken(.ampersand, "&"); .tag = .address_of,
const arg = try c.addNode(.{ .main_token = tok,
.tag = .identifier, .data = .{
.main_token = try c.addIdentifier(payload), .lhs = arg,
.data = undefined, .rhs = undefined,
}); },
return c.addNode(.{ });
.tag = .address_of,
.main_token = tok,
.data = .{
.lhs = arg,
.rhs = undefined,
},
});
}
}, },
.float_literal => { .float_literal => {
const payload = node.castTag(.float_literal).?.data; const payload = node.castTag(.float_literal).?.data;
@ -1448,7 +1434,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
.optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"), .optional_type => return renderPrefixOp(c, node, .optional_type, .question_mark, "?"),
.address_of => { .address_of => {
const payload = node.castTag(.address_of).?.data; const payload = node.castTag(.address_of).?.data;
if (c.zig_is_stage1 and payload.tag() == .fn_identifier) if (payload.tag() == .fn_identifier)
return try c.addNode(.{ return try c.addNode(.{
.tag = .identifier, .tag = .identifier,
.main_token = try c.addIdentifier(payload.castTag(.fn_identifier).?.data), .main_token = try c.addIdentifier(payload.castTag(.fn_identifier).?.data),

View File

@ -13,7 +13,6 @@ pub fn build(b: *Builder) void {
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
lib.use_llvm = false; lib.use_llvm = false;
lib.use_stage1 = false;
lib.use_lld = false; lib.use_lld = false;
lib.strip = false; lib.strip = false;

View File

@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
lib.use_llvm = false; lib.use_llvm = false;
lib.use_stage1 = false;
lib.use_lld = false; lib.use_lld = false;
lib.strip = false; lib.strip = false;
// to make sure the bss segment is emitted, we must import memory // to make sure the bss segment is emitted, we must import memory

View File

@ -12,7 +12,6 @@ pub fn build(b: *Builder) void {
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
lib.use_llvm = false; lib.use_llvm = false;
lib.use_stage1 = false;
lib.use_lld = false; lib.use_lld = false;
lib.strip = false; lib.strip = false;
lib.install(); lib.install();

View File

@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
lib.use_llvm = false; lib.use_llvm = false;
lib.use_stage1 = false;
lib.use_lld = false; lib.use_lld = false;
lib.strip = false; lib.strip = false;
lib.install(); lib.install();

View File

@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
lib.use_llvm = false; lib.use_llvm = false;
lib.use_stage1 = false;
lib.use_lld = false; lib.use_lld = false;
lib.strip = false; lib.strip = false;
lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size

View File

@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
lib.setBuildMode(mode); lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }); lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
lib.use_llvm = false; lib.use_llvm = false;
lib.use_stage1 = false;
lib.use_lld = false; lib.use_lld = false;
lib.strip = false; lib.strip = false;
lib.install(); lib.install();

View File

@ -720,20 +720,18 @@ pub fn addPkgTests(
these_tests.addIncludePath("test"); these_tests.addIncludePath("test");
if (test_target.backend) |backend| switch (backend) { if (test_target.backend) |backend| switch (backend) {
.stage1 => { .stage1 => {
these_tests.use_stage1 = true; @panic("stage1 testing requested");
}, },
.stage2_llvm => { .stage2_llvm => {
these_tests.use_stage1 = false;
these_tests.use_llvm = true; these_tests.use_llvm = true;
}, },
.stage2_c => { .stage2_c => {
these_tests.use_stage1 = false;
these_tests.use_llvm = false; these_tests.use_llvm = false;
}, },
else => { else => {
these_tests.use_stage1 = false;
these_tests.use_llvm = false; these_tests.use_llvm = false;
// TODO: force self-hosted linkers to avoid LLD creeping in until the auto-select mechanism deems them worthy // TODO: force self-hosted linkers to avoid LLD creeping in
// until the auto-select mechanism deems them worthy
these_tests.use_lld = false; these_tests.use_lld = false;
}, },
}; };
@ -1355,8 +1353,6 @@ pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool) *build.Step {
triple_prefix, triple_prefix,
})); }));
test_step.use_stage1 = false;
step.dependOn(&test_step.step); step.dependOn(&test_step.step);
} }
return step; return step;