Commit 28514476ef

Andrew Kelley <andrew@ziglang.org>
2022-11-01 04:29:55
remove `-fstage1` option
After this commit, the self-hosted compiler does not offer the option to use stage1 as a backend anymore.
1 parent bf316e5
lib/std/build/TranslateCStep.zig
@@ -21,7 +21,6 @@ output_dir: ?[]const u8,
 out_basename: []const u8,
 target: CrossTarget = CrossTarget{},
 output_file: build.GeneratedFile,
-use_stage1: ?bool = null,
 
 pub fn create(builder: *Builder, source: build.FileSource) *TranslateCStep {
     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(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));
 
lib/std/build.zig
@@ -46,7 +46,6 @@ pub const Builder = struct {
     prominent_compile_errors: bool,
     color: enum { auto, on, off } = .auto,
     reference_trace: ?u32 = null,
-    use_stage1: ?bool = null,
     invalid_user_input: bool,
     zig_exe: []const u8,
     default_step: *Step,
@@ -1621,7 +1620,6 @@ pub const LibExeObjStep = struct {
     stack_size: ?u64 = null,
 
     want_lto: ?bool = null,
-    use_stage1: ?bool = null,
     use_llvm: ?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}));
         }
 
-        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 (use_llvm) {
                 try zig_args.append("-fLLVM");
lib/build_runner.zig
@@ -183,10 +183,6 @@ pub fn main() !void {
                 builder.enable_darling = true;
             } else if (mem.eql(u8, arg, "-fno-darling")) {
                 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")) {
                 builder.reference_trace = 256;
             } 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(
         \\
         \\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
         \\  -fno-reference-trace         Disable reference trace
         \\  --build-file [file]          Override path to build.zig
src/link/Coff/lld.zig
@@ -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
     // will not be part of the linker line anyway.
-    const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| 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,
-                }),
-            }
-        }
-
+    const module_obj_path: ?[]const u8 = if (self.base.options.module != null) blk: {
         try self.flushModule(comp, prog_node);
 
         if (fs.path.dirname(full_out_path)) |dirname| {
src/link/MachO/zld.zig
@@ -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
     // will not be part of the linker line anyway.
-    const module_obj_path: ?[]const u8 = if (options.module) |module| 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,
-                }),
-            }
-        }
-
+    const module_obj_path: ?[]const u8 = if (options.module != null) blk: {
         try macho_file.flushModule(comp, prog_node);
 
         if (fs.path.dirname(full_out_path)) |dirname| {
src/link/Coff.zig
@@ -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_stage1 = build_options.have_stage1 and options.use_stage1;
-    if (use_llvm and !use_stage1) {
+    if (use_llvm) {
         self.llvm_object = try LlvmObject.create(gpa, options);
     }
     return self;
src/link/Elf.zig
@@ -328,8 +328,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
         .page_size = page_size,
     };
     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 and !use_stage1) {
+    if (use_llvm) {
         self.llvm_object = try LlvmObject.create(gpa, options);
     }
     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
     // will not be part of the linker line anyway.
-    const module_obj_path: ?[]const u8 = if (self.base.options.module) |module| 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,
-                }),
-            }
-        }
-
+    const module_obj_path: ?[]const u8 = if (self.base.options.module != null) blk: {
         try self.flushModule(comp, prog_node);
 
         if (fs.path.dirname(full_out_path)) |dirname| {
src/link/MachO.zig
@@ -290,8 +290,7 @@ pub const Export = struct {
 pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
     assert(options.target.ofmt == .macho);
 
-    const use_stage1 = build_options.have_stage1 and options.use_stage1;
-    if (use_stage1 or options.emit == null or options.module == null) {
+    if (options.emit == null or options.module == null) {
         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 page_size: u16 = if (cpu_arch == .aarch64) 0x4000 else 0x1000;
     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);
     errdefer gpa.destroy(self);
@@ -390,13 +388,13 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
             .file = null,
         },
         .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
         else
             .incremental,
     };
 
-    if (use_llvm and !use_stage1) {
+    if (use_llvm) {
         self.llvm_object = try LlvmObject.create(gpa, options);
     }
 
src/link/Wasm.zig
@@ -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_stage1 = build_options.have_stage1 and options.use_stage1;
-    if (use_llvm and !use_stage1) {
+    if (use_llvm) {
         wasm.llvm_object = try LlvmObject.create(gpa, options);
     }
     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
     // will not be part of the linker line anyway.
-    const module_obj_path: ?[]const u8 = if (wasm.base.options.module) |mod| 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,
-                }),
-            }
-        }
-
+    const module_obj_path: ?[]const u8 = if (wasm.base.options.module != null) blk: {
         try wasm.flushModule(comp, prog_node);
 
         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| {
                 // when we use stage1, we use the exports that stage1 provided us.
                 // For stage2, we can directly retrieve them from the module.
-                const use_stage1 = build_options.have_stage1 and wasm.base.options.use_stage1;
-                if (use_stage1) {
-                    for (comp.export_symbol_names.items) |symbol_name| {
-                        try argv.append(try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name}));
-                    }
-                } else {
-                    const skip_export_non_fn = target.os.tag == .wasi and
-                        wasm.base.options.wasi_exec_model == .command;
-                    for (mod.decl_exports.values()) |exports| {
-                        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 skip_export_non_fn = target.os.tag == .wasi and
+                    wasm.base.options.wasi_exec_model == .command;
+                for (mod.decl_exports.values()) |exports| {
+                    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);
                     }
                 }
             }
src/translate_c/ast.zig
@@ -732,11 +732,10 @@ pub const Payload = struct {
 
 /// Converts the nodes into a Zig Ast.
 /// 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{
         .gpa = gpa,
         .buf = std.ArrayList(u8).init(gpa),
-        .zig_is_stage1 = zig_is_stage1,
     };
     defer ctx.buf.deinit();
     defer ctx.nodes.deinit(gpa);
@@ -805,11 +804,6 @@ const Context = struct {
     extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{},
     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 {
         const start_index = c.buf.items.len;
         try c.buf.writer().print(format ++ " ", args);
@@ -932,7 +926,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
         .call => {
             const payload = node.castTag(.call).?.data;
             // 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(.{
                     .tag = .identifier,
                     .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
             // the context of an address_of, which is handled there.
             const payload = node.castTag(.fn_identifier).?.data;
-            if (c.zig_is_stage1) {
-                return try c.addNode(.{
-                    .tag = .identifier,
-                    .main_token = try c.addIdentifier(payload),
-                    .data = undefined,
-                });
-            } else {
-                const tok = try c.addToken(.ampersand, "&");
-                const arg = try c.addNode(.{
-                    .tag = .identifier,
-                    .main_token = try c.addIdentifier(payload),
-                    .data = undefined,
-                });
-                return c.addNode(.{
-                    .tag = .address_of,
-                    .main_token = tok,
-                    .data = .{
-                        .lhs = arg,
-                        .rhs = undefined,
-                    },
-                });
-            }
+            const tok = try c.addToken(.ampersand, "&");
+            const arg = try c.addNode(.{
+                .tag = .identifier,
+                .main_token = try c.addIdentifier(payload),
+                .data = undefined,
+            });
+            return c.addNode(.{
+                .tag = .address_of,
+                .main_token = tok,
+                .data = .{
+                    .lhs = arg,
+                    .rhs = undefined,
+                },
+            });
         },
         .float_literal => {
             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, "?"),
         .address_of => {
             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(.{
                     .tag = .identifier,
                     .main_token = try c.addIdentifier(payload.castTag(.fn_identifier).?.data),
src/Compilation.zig
@@ -935,7 +935,6 @@ pub const InitOptions = struct {
     use_llvm: ?bool = null,
     use_lld: ?bool = null,
     use_clang: ?bool = null,
-    use_stage1: ?bool = null,
     single_threaded: ?bool = null,
     strip: ?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 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.
         const use_llvm = build_options.have_llvm and blk: {
             if (options.use_llvm) |explicit|
@@ -1149,11 +1145,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
             if (options.main_pkg == null)
                 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 (!target_util.hasLlvmSupport(options.target, options.target.ofmt))
                 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
         // cache mode is used for LLVM backend too. We need some fuzz testing before
         // that can be enabled.
-        const cache_mode = if ((use_stage1 and !options.disable_lld_caching) or
-            (use_llvm and !options.disable_lld_caching)) CacheMode.whole else options.cache_mode;
+        const cache_mode = if (use_llvm and !options.disable_lld_caching)
+            CacheMode.whole
+        else
+            options.cache_mode;
 
         const tsan = options.want_tsan orelse false;
         // 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
             hash.add(valgrind);
             hash.add(single_threaded);
-            hash.add(use_stage1);
             hash.add(use_llvm);
             hash.add(dll_export_fns);
             hash.add(options.is_test);
@@ -1587,9 +1579,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
                 .handle = artifact_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(
                 gpa,
@@ -1907,7 +1896,6 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
             .subsystem = options.subsystem,
             .is_test = options.is_test,
             .wasi_exec_model = wasi_exec_model,
-            .use_stage1 = use_stage1,
             .hash_style = options.hash_style,
             .enable_link_snapshots = options.enable_link_snapshots,
             .native_darwin_sdk = options.native_darwin_sdk,
@@ -2344,7 +2332,6 @@ pub fn update(comp: *Compilation) !void {
         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| {
         module.compile_log_text.shrinkAndFree(module.gpa, 0);
         module.generation += 1;
@@ -2360,7 +2347,7 @@ pub fn update(comp: *Compilation) !void {
         // import_table here.
         // 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.
-        if (use_stage1 or comp.bin_file.options.is_test) {
+        if (comp.bin_file.options.is_test) {
             _ = try module.importPkg(module.main_pkg);
         }
 
@@ -2374,21 +2361,19 @@ pub fn update(comp: *Compilation) !void {
             comp.astgen_work_queue.writeItemAssumeCapacity(value);
         }
 
-        if (!use_stage1) {
-            // 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());
-                var it = module.embed_table.iterator();
-                while (it.next()) |entry| {
-                    const embed_file = entry.value_ptr.*;
-                    comp.embed_file_work_queue.writeItemAssumeCapacity(embed_file);
-                }
+        // 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());
+            var it = module.embed_table.iterator();
+            while (it.next()) |entry| {
+                const embed_file = entry.value_ptr.*;
+                comp.embed_file_work_queue.writeItemAssumeCapacity(embed_file);
             }
+        }
 
-            try comp.work_queue.writeItem(.{ .analyze_pkg = std_pkg });
-            if (comp.bin_file.options.is_test) {
-                try comp.work_queue.writeItem(.{ .analyze_pkg = module.main_pkg });
-            }
+        try comp.work_queue.writeItem(.{ .analyze_pkg = std_pkg });
+        if (comp.bin_file.options.is_test) {
+            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);
 
-    if (!use_stage1) {
-        if (comp.bin_file.options.module) |module| {
-            if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {
-                // The `test_functions` decl has been intentionally postponed until now,
-                // at which point we must populate it with the list of test functions that
-                // have been discovered and not filtered out.
-                try module.populateTestFunctions(main_progress_node);
-            }
+    if (comp.bin_file.options.module) |module| {
+        if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {
+            // The `test_functions` decl has been intentionally postponed until now,
+            // at which point we must populate it with the list of test functions that
+            // have been discovered and not filtered out.
+            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);
-                }
-            }
+        // 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);
 
-            try module.processExports();
+            if (is_anon) {
+                module.destroyDecl(decl_index);
+            }
         }
+
+        try module.processExports();
     }
 
     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();
 
-    const use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1;
-    if (!use_stage1) {
-        if (comp.bin_file.options.module) |module| {
-            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
         man.hash.add(comp.bin_file.options.valgrind);
         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.dll_export_fns);
         man.hash.add(comp.bin_file.options.is_test);
@@ -3010,8 +2989,6 @@ pub fn performAllTheWork(
     comp.work_queue_wait_group.reset();
     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");
         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");
         defer outdated_and_deleted_decls_frame.end();
 
@@ -3064,15 +3041,6 @@ pub fn performAllTheWork(
         if (comp.bin_file.options.module) |mod| {
             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| {
@@ -3598,10 +3566,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
     var man = comp.obtainCObjectCacheManifest();
     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(use_stage1);
     man.hash.addBytes(c_src);
 
     // 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,
             &clang_errors,
             c_headers_dir_path_z,
-            use_stage1,
         ) catch |err| switch (err) {
             error.OutOfMemory => return error.OutOfMemory,
             error.ASTUnitFailure => {
@@ -5097,8 +5061,6 @@ pub fn dump_argv(argv: []const []const u8) void {
 }
 
 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;
     const target = comp.bin_file.options.target;
     if (target.ofmt == .c) return .stage2_c;
@@ -5394,7 +5356,6 @@ fn buildOutputFromZig(
         .link_mode = .Static,
         .function_sections = true,
         .no_builtin = true,
-        .use_stage1 = build_options.have_stage1 and comp.bin_file.options.use_stage1,
         .want_sanitize_c = false,
         .want_stack_check = false,
         .want_stack_protector = 0,
src/link.zig
@@ -155,7 +155,6 @@ pub const Options = struct {
     build_id: bool,
     disable_lld_caching: bool,
     is_test: bool,
-    use_stage1: bool,
     hash_style: HashStyle,
     major_subsystem_version: ?u32,
     minor_subsystem_version: ?u32,
@@ -293,8 +292,7 @@ pub const File = struct {
             return &(try MachO.openPath(allocator, options)).base;
         }
 
-        const use_stage1 = build_options.have_stage1 and options.use_stage1;
-        if (use_stage1 or options.emit == null) {
+        if (options.emit == null) {
             return switch (options.target.ofmt) {
                 .coff => &(try Coff.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
         // because it will not be part of the linker line anyway.
-        const module_obj_path: ?[]const u8 = if (base.options.module) |module| 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,
-                    }),
-                }
-            }
+        const module_obj_path: ?[]const u8 = if (base.options.module != null) blk: {
             try base.flushModule(comp, prog_node);
 
             const dirname = fs.path.dirname(full_out_path_z) orelse ".";
src/main.zig
@@ -394,8 +394,6 @@ const usage_build_generic =
     \\  -fno-LLVM                 Prevent using LLVM as the codegen backend
     \\  -fClang                   Force 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
     \\  -fno-reference-trace      Disable reference trace
     \\  -fsingle-threaded         Code assumes there is only one thread
@@ -719,7 +717,6 @@ fn buildOutputType(
     var use_llvm: ?bool = null;
     var use_lld: ?bool = null;
     var use_clang: ?bool = null;
-    var use_stage1: ?bool = null;
     var link_eh_frame_hdr = false;
     var link_emit_relocs = false;
     var each_lib_rpath: ?bool = null;
@@ -1158,10 +1155,6 @@ fn buildOutputType(
                         use_clang = true;
                     } else if (mem.eql(u8, arg, "-fno-Clang")) {
                         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")) {
                         reference_trace = 256;
                     } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
@@ -2909,7 +2902,6 @@ fn buildOutputType(
         .use_llvm = use_llvm,
         .use_lld = use_lld,
         .use_clang = use_clang,
-        .use_stage1 = use_stage1,
         .hash_style = hash_style,
         .rdynamic = rdynamic,
         .linker_script = linker_script,
@@ -3024,8 +3016,7 @@ fn buildOutputType(
         return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
     }
     if (arg_mode == .translate_c) {
-        const stage1_mode = use_stage1 orelse false;
-        return cmdTranslateC(comp, arena, have_enable_cache, stage1_mode);
+        return cmdTranslateC(comp, arena, have_enable_cache);
     }
 
     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)
         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();
 
     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| {
         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,
             &clang_errors,
             c_headers_dir_path_z,
-            stage1_mode,
         ) catch |err| switch (err) {
             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", .{}),
@@ -3755,8 +3744,6 @@ pub const usage_build =
     \\   Build a project from build.zig.
     \\
     \\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
     \\   -fno-reference-trace          Disable reference trace
     \\   --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 {
     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
     // 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;
                     } else if (mem.eql(u8, arg, "--prominent-compile-errors")) {
                         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")) {
                         try child_argv.append(arg);
                         reference_trace = 256;
@@ -3979,7 +3959,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
             .optimize_mode = .Debug,
             .self_exe_path = self_exe_path,
             .thread_pool = &thread_pool,
-            .use_stage1 = use_stage1,
             .cache_mode = .whole,
             .reference_trace = reference_trace,
             .debug_compile_errors = debug_compile_errors,
src/Sema.zig
@@ -2121,8 +2121,6 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError
     const msg = msg: {
         const msg = try sema.errMsg(block, src, "async has not been implemented in the self-hosted compiler yet", .{});
         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;
     };
     return sema.failWithOwnedErrorMsg(msg);
src/test.zig
@@ -1548,7 +1548,6 @@ pub const TestContext = struct {
             .dynamic_linker = target_info.dynamic_linker.get(),
             .link_libc = case.link_libc,
             .use_llvm = use_llvm,
-            .use_stage1 = null, // We already handled stage1 tests
             .self_exe_path = zig_exe_path,
             // TODO instead of turning off color, pass in a std.Progress.Node
             .color = .off,
src/translate_c.zig
@@ -327,16 +327,6 @@ pub const Context = struct {
 
     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 {
         c.mangle_count += 1;
         return c.mangle_count;
@@ -365,7 +355,6 @@ pub fn translate(
     args_end: [*]?[*]const u8,
     errors: *[]ClangErrMsg,
     resources_path: [*:0]const u8,
-    zig_is_stage1: bool,
 ) !std.zig.Ast {
     // TODO stage2 bug
     var tmp = errors;
@@ -395,7 +384,6 @@ pub fn translate(
         .global_scope = try arena.create(Scope.Root),
         .clang_context = ast_unit.getASTContext(),
         .pattern_list = try PatternList.init(gpa),
-        .zig_is_stage1 = zig_is_stage1,
     };
     context.global_scope.* = Scope.Root.init(&context);
     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)
@@ -4747,9 +4735,6 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan
         .Pointer => {
             const child_qt = ty.getPointeeType();
             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_volatile = child_qt.isVolatileQualified();
             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;
     if (getContainerTypeOf(c, init)) |ty_node| {
         if (ty_node.castTag(.optional_type)) |prefix| {
-            if (c.zig_is_stage1) {
-                if (prefix.data.castTag(.func)) |fn_proto| {
+            if (prefix.data.castTag(.single_pointer)) |sp| {
+                if (sp.data.elem_type.castTag(.func)) |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;
-                    }
-                }
             }
         }
     }
test/link/wasm/archive/build.zig
@@ -13,7 +13,6 @@ pub fn build(b: *Builder) void {
     lib.setBuildMode(mode);
     lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
     lib.use_llvm = false;
-    lib.use_stage1 = false;
     lib.use_lld = false;
     lib.strip = false;
 
test/link/wasm/bss/build.zig
@@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
     lib.setBuildMode(mode);
     lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
     lib.use_llvm = false;
-    lib.use_stage1 = false;
     lib.use_lld = false;
     lib.strip = false;
     // to make sure the bss segment is emitted, we must import memory
test/link/wasm/producers/build.zig
@@ -12,7 +12,6 @@ pub fn build(b: *Builder) void {
     lib.setBuildMode(mode);
     lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
     lib.use_llvm = false;
-    lib.use_stage1 = false;
     lib.use_lld = false;
     lib.strip = false;
     lib.install();
test/link/wasm/segments/build.zig
@@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
     lib.setBuildMode(mode);
     lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
     lib.use_llvm = false;
-    lib.use_stage1 = false;
     lib.use_lld = false;
     lib.strip = false;
     lib.install();
test/link/wasm/stack_pointer/build.zig
@@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
     lib.setBuildMode(mode);
     lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
     lib.use_llvm = false;
-    lib.use_stage1 = false;
     lib.use_lld = false;
     lib.strip = false;
     lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size
test/link/wasm/type/build.zig
@@ -11,7 +11,6 @@ pub fn build(b: *Builder) void {
     lib.setBuildMode(mode);
     lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });
     lib.use_llvm = false;
-    lib.use_stage1 = false;
     lib.use_lld = false;
     lib.strip = false;
     lib.install();
test/tests.zig
@@ -720,20 +720,18 @@ pub fn addPkgTests(
         these_tests.addIncludePath("test");
         if (test_target.backend) |backend| switch (backend) {
             .stage1 => {
-                these_tests.use_stage1 = true;
+                @panic("stage1 testing requested");
             },
             .stage2_llvm => {
-                these_tests.use_stage1 = false;
                 these_tests.use_llvm = true;
             },
             .stage2_c => {
-                these_tests.use_stage1 = false;
                 these_tests.use_llvm = false;
             },
             else => {
-                these_tests.use_stage1 = 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;
             },
         };
@@ -1355,8 +1353,6 @@ pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool) *build.Step {
             triple_prefix,
         }));
 
-        test_step.use_stage1 = false;
-
         step.dependOn(&test_step.step);
     }
     return step;
build.zig
@@ -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 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 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(
         bool,
         "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 sanitize_thread = b.option(bool, "sanitize-thread", "Enable thread-sanitization") 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 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;
     }
 
-    const main_file: ?[]const u8 = mf: {
-        if (!have_stage1) break :mf "src/main.zig";
-        if (use_zig0) break :mf null;
-        break :mf "src/stage1.zig";
-    };
+    const main_file: ?[]const u8 = "src/main.zig";
 
     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| {
             // 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
@@ -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_allocation", tracy_allocation);
     exe_options.addOption(bool, "value_tracing", value_tracing);
-    exe_options.addOption(bool, "have_stage1", have_stage1);
     if (tracy) |tracy_path| {
         const client_cpp = fs.path.join(
             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, "skip_non_native", skip_non_native);
     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, "llvm_has_m68k", llvm_has_m68k);
     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",
 };
 
-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{
     // These are planned to stay even when we are self-hosted.
     "src/zig_llvm.cpp",
CMakeLists.txt
@@ -1084,7 +1084,6 @@ set(ZIG_BUILD_ARGS
     --zig-lib-dir "${CMAKE_SOURCE_DIR}/lib"
     "-Dconfig_h=${ZIG_CONFIG_H_OUT}"
     "-Denable-llvm"
-    "-Denable-stage1"
     ${ZIG_RELEASE_ARG}
     ${ZIG_STATIC_ARG}
     ${ZIG_NO_LIB_ARG}