authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-21 12:13:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-07-21 12:13:15-07:00
log8ee629aa4c7fb0127c71aec0b2c81353c4291ebb
tree221c6b97638b189d66e328c300d013292e0227f6
parent7a1a92478878f591abbadcd5735f03c817c6eb53

stage2: ability for ZIR to map multiple tags to the same type


4 files changed, 298 insertions(+), 325 deletions(-)

src-self-hosted/Module.zig+142-70
...@@ -1215,7 +1215,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1215,7 +1215,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1215 .return_type = return_type_inst,1215 .return_type = return_type_inst,
1216 .param_types = param_types,1216 .param_types = param_types,
1217 }, .{});1217 }, .{});
1218 _ = try self.addZIRInst(&fn_type_scope.base, fn_src, zir.Inst.Return, .{ .operand = fn_type_inst }, .{});1218 _ = try self.addZIRUnOp(&fn_type_scope.base, fn_src, .@"return", fn_type_inst);
12191219
1220 // We need the memory for the Type to go into the arena for the Decl1220 // We need the memory for the Type to go into the arena for the Decl
1221 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);1221 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);
...@@ -1256,7 +1256,15 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1256,7 +1256,15 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1256 const name_token = param.name_token.?;1256 const name_token = param.name_token.?;
1257 const src = tree.token_locs[name_token].start;1257 const src = tree.token_locs[name_token].start;
1258 const param_name = tree.tokenSlice(name_token);1258 const param_name = tree.tokenSlice(name_token);
1259 const arg = try newZIRInst(&gen_scope_arena.allocator, src, zir.Inst.Arg, .{}, .{});1259 const arg = try gen_scope_arena.allocator.create(zir.Inst.NoOp);
1260 arg.* = .{
1261 .base = .{
1262 .tag = .arg,
1263 .src = src,
1264 },
1265 .positionals = .{},
1266 .kw_args = .{},
1267 };
1260 gen_scope.instructions.items[i] = &arg.base;1268 gen_scope.instructions.items[i] = &arg.base;
1261 const sub_scope = try gen_scope_arena.allocator.create(Scope.LocalVar);1269 const sub_scope = try gen_scope_arena.allocator.create(Scope.LocalVar);
1262 sub_scope.* = .{1270 sub_scope.* = .{
...@@ -1276,7 +1284,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1276,7 +1284,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1276 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn()))1284 !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn()))
1277 {1285 {
1278 const src = tree.token_locs[body_block.rbrace].start;1286 const src = tree.token_locs[body_block.rbrace].start;
1279 _ = try self.addZIRInst(&gen_scope.base, src, zir.Inst.ReturnVoid, .{}, .{});1287 _ = try self.addZIRNoOp(&gen_scope.base, src, .returnvoid);
1280 }1288 }
12811289
1282 const fn_zir = try gen_scope_arena.allocator.create(Fn.ZIR);1290 const fn_zir = try gen_scope_arena.allocator.create(Fn.ZIR);
...@@ -2067,14 +2075,17 @@ fn addCall(...@@ -2067,14 +2075,17 @@ fn addCall(
2067 return &inst.base;2075 return &inst.base;
2068}2076}
20692077
2070fn newZIRInst(2078pub fn addZIRInstSpecial(
2071 gpa: *Allocator,2079 self: *Module,
2080 scope: *Scope,
2072 src: usize,2081 src: usize,
2073 comptime T: type,2082 comptime T: type,
2074 positionals: std.meta.fieldInfo(T, "positionals").field_type,2083 positionals: std.meta.fieldInfo(T, "positionals").field_type,
2075 kw_args: std.meta.fieldInfo(T, "kw_args").field_type,2084 kw_args: std.meta.fieldInfo(T, "kw_args").field_type,
2076) !*T {2085) !*T {
2077 const inst = try gpa.create(T);2086 const gen_zir = scope.getGenZIR();
2087 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2088 const inst = try gen_zir.arena.create(T);
2078 inst.* = .{2089 inst.* = .{
2079 .base = .{2090 .base = .{
2080 .tag = T.base_tag,2091 .tag = T.base_tag,
...@@ -2083,22 +2094,79 @@ fn newZIRInst(...@@ -2083,22 +2094,79 @@ fn newZIRInst(
2083 .positionals = positionals,2094 .positionals = positionals,
2084 .kw_args = kw_args,2095 .kw_args = kw_args,
2085 };2096 };
2097 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2086 return inst;2098 return inst;
2087}2099}
20882100
2089pub fn addZIRInstSpecial(2101pub fn addZIRNoOp(
2090 self: *Module,2102 self: *Module,
2091 scope: *Scope,2103 scope: *Scope,
2092 src: usize,2104 src: usize,
2093 comptime T: type,2105 tag: zir.Inst.Tag,
2094 positionals: std.meta.fieldInfo(T, "positionals").field_type,2106) !*zir.Inst {
2095 kw_args: std.meta.fieldInfo(T, "kw_args").field_type,
2096) !*T {
2097 const gen_zir = scope.getGenZIR();2107 const gen_zir = scope.getGenZIR();
2098 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);2108 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2099 const inst = try newZIRInst(gen_zir.arena, src, T, positionals, kw_args);2109 const inst = try gen_zir.arena.create(zir.Inst.NoOp);
2110 inst.* = .{
2111 .base = .{
2112 .tag = tag,
2113 .src = src,
2114 },
2115 .positionals = .{},
2116 .kw_args = .{},
2117 };
2100 gen_zir.instructions.appendAssumeCapacity(&inst.base);2118 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2101 return inst;2119 return &inst.base;
2120}
2121
2122pub fn addZIRUnOp(
2123 self: *Module,
2124 scope: *Scope,
2125 src: usize,
2126 tag: zir.Inst.Tag,
2127 operand: *zir.Inst,
2128) !*zir.Inst {
2129 const gen_zir = scope.getGenZIR();
2130 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2131 const inst = try gen_zir.arena.create(zir.Inst.UnOp);
2132 inst.* = .{
2133 .base = .{
2134 .tag = tag,
2135 .src = src,
2136 },
2137 .positionals = .{
2138 .operand = operand,
2139 },
2140 .kw_args = .{},
2141 };
2142 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2143 return &inst.base;
2144}
2145
2146pub fn addZIRBinOp(
2147 self: *Module,
2148 scope: *Scope,
2149 src: usize,
2150 tag: zir.Inst.Tag,
2151 lhs: *zir.Inst,
2152 rhs: *zir.Inst,
2153) !*zir.Inst {
2154 const gen_zir = scope.getGenZIR();
2155 try gen_zir.instructions.ensureCapacity(self.gpa, gen_zir.instructions.items.len + 1);
2156 const inst = try gen_zir.arena.create(zir.Inst.BinOp);
2157 inst.* = .{
2158 .base = .{
2159 .tag = tag,
2160 .src = src,
2161 },
2162 .positionals = .{
2163 .lhs = lhs,
2164 .rhs = rhs,
2165 },
2166 .kw_args = .{},
2167 };
2168 gen_zir.instructions.appendAssumeCapacity(&inst.base);
2169 return &inst.base;
2102}2170}
21032171
2104pub fn addZIRInst(2172pub fn addZIRInst(
...@@ -2252,46 +2320,51 @@ fn analyzeInstConst(self: *Module, scope: *Scope, const_inst: *zir.Inst.Const) I...@@ -2252,46 +2320,51 @@ fn analyzeInstConst(self: *Module, scope: *Scope, const_inst: *zir.Inst.Const) I
22522320
2253fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {2321fn analyzeInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {
2254 switch (old_inst.tag) {2322 switch (old_inst.tag) {
2255 .arg => return self.analyzeInstArg(scope, old_inst.cast(zir.Inst.Arg).?),2323 .arg => return self.analyzeInstArg(scope, old_inst.castTag(.arg).?),
2256 .block => return self.analyzeInstBlock(scope, old_inst.cast(zir.Inst.Block).?),2324 .block => return self.analyzeInstBlock(scope, old_inst.castTag(.block).?),
2257 .@"break" => return self.analyzeInstBreak(scope, old_inst.cast(zir.Inst.Break).?),2325 .@"break" => return self.analyzeInstBreak(scope, old_inst.castTag(.@"break").?),
2258 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.cast(zir.Inst.Breakpoint).?),2326 .breakpoint => return self.analyzeInstBreakpoint(scope, old_inst.castTag(.breakpoint).?),
2259 .breakvoid => return self.analyzeInstBreakVoid(scope, old_inst.cast(zir.Inst.BreakVoid).?),2327 .breakvoid => return self.analyzeInstBreakVoid(scope, old_inst.castTag(.breakvoid).?),
2260 .call => return self.analyzeInstCall(scope, old_inst.cast(zir.Inst.Call).?),2328 .call => return self.analyzeInstCall(scope, old_inst.castTag(.call).?),
2261 .compileerror => return self.analyzeInstCompileError(scope, old_inst.cast(zir.Inst.CompileError).?),2329 .compileerror => return self.analyzeInstCompileError(scope, old_inst.castTag(.compileerror).?),
2262 .@"const" => return self.analyzeInstConst(scope, old_inst.cast(zir.Inst.Const).?),2330 .@"const" => return self.analyzeInstConst(scope, old_inst.castTag(.@"const").?),
2263 .declref => return self.analyzeInstDeclRef(scope, old_inst.cast(zir.Inst.DeclRef).?),2331 .declref => return self.analyzeInstDeclRef(scope, old_inst.castTag(.declref).?),
2264 .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.cast(zir.Inst.DeclRefStr).?),2332 .declref_str => return self.analyzeInstDeclRefStr(scope, old_inst.castTag(.declref_str).?),
2265 .declval => return self.analyzeInstDeclVal(scope, old_inst.cast(zir.Inst.DeclVal).?),2333 .declval => return self.analyzeInstDeclVal(scope, old_inst.castTag(.declval).?),
2266 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.cast(zir.Inst.DeclValInModule).?),2334 .declval_in_module => return self.analyzeInstDeclValInModule(scope, old_inst.castTag(.declval_in_module).?),
2267 .str => return self.analyzeInstStr(scope, old_inst.cast(zir.Inst.Str).?),2335 .str => return self.analyzeInstStr(scope, old_inst.castTag(.str).?),
2268 .int => {2336 .int => {
2269 const big_int = old_inst.cast(zir.Inst.Int).?.positionals.int;2337 const big_int = old_inst.castTag(.int).?.positionals.int;
2270 return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);2338 return self.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);
2271 },2339 },
2272 .inttype => return self.analyzeInstIntType(scope, old_inst.cast(zir.Inst.IntType).?),2340 .inttype => return self.analyzeInstIntType(scope, old_inst.castTag(.inttype).?),
2273 .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.cast(zir.Inst.PtrToInt).?),2341 .ptrtoint => return self.analyzeInstPtrToInt(scope, old_inst.castTag(.ptrtoint).?),
2274 .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.cast(zir.Inst.FieldPtr).?),2342 .fieldptr => return self.analyzeInstFieldPtr(scope, old_inst.castTag(.fieldptr).?),
2275 .deref => return self.analyzeInstDeref(scope, old_inst.cast(zir.Inst.Deref).?),2343 .deref => return self.analyzeInstDeref(scope, old_inst.castTag(.deref).?),
2276 .as => return self.analyzeInstAs(scope, old_inst.cast(zir.Inst.As).?),2344 .as => return self.analyzeInstAs(scope, old_inst.castTag(.as).?),
2277 .@"asm" => return self.analyzeInstAsm(scope, old_inst.cast(zir.Inst.Asm).?),2345 .@"asm" => return self.analyzeInstAsm(scope, old_inst.castTag(.@"asm").?),
2278 .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.cast(zir.Inst.Unreachable).?),2346 .@"unreachable" => return self.analyzeInstUnreachable(scope, old_inst.castTag(.@"unreachable").?),
2279 .@"return" => return self.analyzeInstRet(scope, old_inst.cast(zir.Inst.Return).?),2347 .@"return" => return self.analyzeInstRet(scope, old_inst.castTag(.@"return").?),
2280 .returnvoid => return self.analyzeInstRetVoid(scope, old_inst.cast(zir.Inst.ReturnVoid).?),2348 .returnvoid => return self.analyzeInstRetVoid(scope, old_inst.castTag(.returnvoid).?),
2281 .@"fn" => return self.analyzeInstFn(scope, old_inst.cast(zir.Inst.Fn).?),2349 .@"fn" => return self.analyzeInstFn(scope, old_inst.castTag(.@"fn").?),
2282 .@"export" => return self.analyzeInstExport(scope, old_inst.cast(zir.Inst.Export).?),2350 .@"export" => return self.analyzeInstExport(scope, old_inst.castTag(.@"export").?),
2283 .primitive => return self.analyzeInstPrimitive(scope, old_inst.cast(zir.Inst.Primitive).?),2351 .primitive => return self.analyzeInstPrimitive(scope, old_inst.castTag(.primitive).?),
2284 .fntype => return self.analyzeInstFnType(scope, old_inst.cast(zir.Inst.FnType).?),2352 .fntype => return self.analyzeInstFnType(scope, old_inst.castTag(.fntype).?),
2285 .intcast => return self.analyzeInstIntCast(scope, old_inst.cast(zir.Inst.IntCast).?),2353 .intcast => return self.analyzeInstIntCast(scope, old_inst.castTag(.intcast).?),
2286 .bitcast => return self.analyzeInstBitCast(scope, old_inst.cast(zir.Inst.BitCast).?),2354 .bitcast => return self.analyzeInstBitCast(scope, old_inst.castTag(.bitcast).?),
2287 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.cast(zir.Inst.ElemPtr).?),2355 .elemptr => return self.analyzeInstElemPtr(scope, old_inst.castTag(.elemptr).?),
2288 .add => return self.analyzeInstAdd(scope, old_inst.cast(zir.Inst.Add).?),2356 .add => return self.analyzeInstAdd(scope, old_inst.castTag(.add).?),
2289 .sub => return self.analyzeInstSub(scope, old_inst.cast(zir.Inst.Sub).?),2357 .sub => return self.analyzeInstSub(scope, old_inst.castTag(.sub).?),
2290 .cmp => return self.analyzeInstCmp(scope, old_inst.cast(zir.Inst.Cmp).?),2358 .cmp_lt => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_lt).?, .lt),
2291 .condbr => return self.analyzeInstCondBr(scope, old_inst.cast(zir.Inst.CondBr).?),2359 .cmp_lte => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_lte).?, .lte),
2292 .isnull => return self.analyzeInstIsNull(scope, old_inst.cast(zir.Inst.IsNull).?),2360 .cmp_eq => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_eq).?, .eq),
2293 .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.cast(zir.Inst.IsNonNull).?),2361 .cmp_gte => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_gte).?, .gte),
2294 .boolnot => return self.analyzeInstBoolNot(scope, old_inst.cast(zir.Inst.BoolNot).?),2362 .cmp_gt => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_gt).?, .gt),
2363 .cmp_neq => return self.analyzeInstCmp(scope, old_inst.castTag(.cmp_neq).?, .neq),
2364 .condbr => return self.analyzeInstCondBr(scope, old_inst.castTag(.condbr).?),
2365 .isnull => return self.analyzeInstIsNonNull(scope, old_inst.castTag(.isnull).?, true),
2366 .isnonnull => return self.analyzeInstIsNonNull(scope, old_inst.castTag(.isnonnull).?, false),
2367 .boolnot => return self.analyzeInstBoolNot(scope, old_inst.castTag(.boolnot).?),
2295 }2368 }
2296}2369}
22972370
...@@ -2372,7 +2445,7 @@ fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.Compile...@@ -2372,7 +2445,7 @@ fn analyzeInstCompileError(self: *Module, scope: *Scope, inst: *zir.Inst.Compile
2372 return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg});2445 return self.fail(scope, inst.base.src, "{}", .{inst.positionals.msg});
2373}2446}
23742447
2375fn analyzeInstArg(self: *Module, scope: *Scope, inst: *zir.Inst.Arg) InnerError!*Inst {2448fn analyzeInstArg(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
2376 const b = try self.requireRuntimeBlock(scope, inst.base.src);2449 const b = try self.requireRuntimeBlock(scope, inst.base.src);
2377 const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty;2450 const fn_ty = b.func.?.owner_decl.typed_value.most_recent.typed_value.ty;
2378 const param_index = b.instructions.items.len;2451 const param_index = b.instructions.items.len;
...@@ -2435,7 +2508,7 @@ fn analyzeInstBlock(self: *Module, scope: *Scope, inst: *zir.Inst.Block) InnerEr...@@ -2435,7 +2508,7 @@ fn analyzeInstBlock(self: *Module, scope: *Scope, inst: *zir.Inst.Block) InnerEr
2435 return &block_inst.base;2508 return &block_inst.base;
2436}2509}
24372510
2438fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.Breakpoint) InnerError!*Inst {2511fn analyzeInstBreakpoint(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
2439 const b = try self.requireRuntimeBlock(scope, inst.base.src);2512 const b = try self.requireRuntimeBlock(scope, inst.base.src);
2440 return self.addNoOp(b, inst.base.src, Type.initTag(.void), .breakpoint);2513 return self.addNoOp(b, inst.base.src, Type.initTag(.void), .breakpoint);
2441}2514}
...@@ -2791,11 +2864,11 @@ fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inn...@@ -2791,11 +2864,11 @@ fn analyzeInstElemPtr(self: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inn
2791 return self.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{});2864 return self.fail(scope, inst.base.src, "TODO implement more analyze elemptr", .{});
2792}2865}
27932866
2794fn analyzeInstSub(self: *Module, scope: *Scope, inst: *zir.Inst.Sub) InnerError!*Inst {2867fn analyzeInstSub(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
2795 return self.fail(scope, inst.base.src, "TODO implement analysis of sub", .{});2868 return self.fail(scope, inst.base.src, "TODO implement analysis of sub", .{});
2796}2869}
27972870
2798fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError!*Inst {2871fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError!*Inst {
2799 const tracy = trace(@src());2872 const tracy = trace(@src());
2800 defer tracy.end();2873 defer tracy.end();
28012874
...@@ -2848,9 +2921,9 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError!...@@ -2848,9 +2921,9 @@ fn analyzeInstAdd(self: *Module, scope: *Scope, inst: *zir.Inst.Add) InnerError!
2848 return self.fail(scope, inst.base.src, "TODO analyze add for {} + {}", .{ lhs.ty.zigTypeTag(), rhs.ty.zigTypeTag() });2921 return self.fail(scope, inst.base.src, "TODO analyze add for {} + {}", .{ lhs.ty.zigTypeTag(), rhs.ty.zigTypeTag() });
2849}2922}
28502923
2851fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.Deref) InnerError!*Inst {2924fn analyzeInstDeref(self: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst {
2852 const ptr = try self.resolveInst(scope, deref.positionals.ptr);2925 const ptr = try self.resolveInst(scope, deref.positionals.operand);
2853 return self.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.ptr.src);2926 return self.analyzeDeref(scope, deref.base.src, ptr, deref.positionals.operand.src);
2854}2927}
28552928
2856fn analyzeDeref(self: *Module, scope: *Scope, src: usize, ptr: *Inst, ptr_src: usize) InnerError!*Inst {2929fn analyzeDeref(self: *Module, scope: *Scope, src: usize, ptr: *Inst, ptr_src: usize) InnerError!*Inst {
...@@ -2907,10 +2980,14 @@ fn analyzeInstAsm(self: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerEr...@@ -2907,10 +2980,14 @@ fn analyzeInstAsm(self: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerEr
2907 return &inst.base;2980 return &inst.base;
2908}2981}
29092982
2910fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!*Inst {2983fn analyzeInstCmp(
2984 self: *Module,
2985 scope: *Scope,
2986 inst: *zir.Inst.BinOp,
2987 op: std.math.CompareOperator,
2988) InnerError!*Inst {
2911 const lhs = try self.resolveInst(scope, inst.positionals.lhs);2989 const lhs = try self.resolveInst(scope, inst.positionals.lhs);
2912 const rhs = try self.resolveInst(scope, inst.positionals.rhs);2990 const rhs = try self.resolveInst(scope, inst.positionals.rhs);
2913 const op = inst.positionals.op;
29142991
2915 const is_equality_cmp = switch (op) {2992 const is_equality_cmp = switch (op) {
2916 .eq, .neq => true,2993 .eq, .neq => true,
...@@ -2964,7 +3041,7 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!...@@ -2964,7 +3041,7 @@ fn analyzeInstCmp(self: *Module, scope: *Scope, inst: *zir.Inst.Cmp) InnerError!
2964 return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{});3041 return self.fail(scope, inst.base.src, "TODO implement more cmp analysis", .{});
2965}3042}
29663043
2967fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) InnerError!*Inst {3044fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
2968 const uncasted_operand = try self.resolveInst(scope, inst.positionals.operand);3045 const uncasted_operand = try self.resolveInst(scope, inst.positionals.operand);
2969 const bool_type = Type.initTag(.bool);3046 const bool_type = Type.initTag(.bool);
2970 const operand = try self.coerce(scope, bool_type, uncasted_operand);3047 const operand = try self.coerce(scope, bool_type, uncasted_operand);
...@@ -2975,14 +3052,9 @@ fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) Inn...@@ -2975,14 +3052,9 @@ fn analyzeInstBoolNot(self: *Module, scope: *Scope, inst: *zir.Inst.BoolNot) Inn
2975 return self.addUnOp(b, inst.base.src, bool_type, .not, operand);3052 return self.addUnOp(b, inst.base.src, bool_type, .not, operand);
2976}3053}
29773054
2978fn analyzeInstIsNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNull) InnerError!*Inst {3055fn analyzeInstIsNonNull(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp, invert_logic: bool) InnerError!*Inst {
2979 const operand = try self.resolveInst(scope, inst.positionals.operand);
2980 return self.analyzeIsNull(scope, inst.base.src, operand, true);
2981}
2982
2983fn analyzeInstIsNonNull(self: *Module, scope: *Scope, inst: *zir.Inst.IsNonNull) InnerError!*Inst {
2984 const operand = try self.resolveInst(scope, inst.positionals.operand);3056 const operand = try self.resolveInst(scope, inst.positionals.operand);
2985 return self.analyzeIsNull(scope, inst.base.src, operand, false);3057 return self.analyzeIsNull(scope, inst.base.src, operand, invert_logic);
2986}3058}
29873059
2988fn analyzeInstCondBr(self: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {3060fn analyzeInstCondBr(self: *Module, scope: *Scope, inst: *zir.Inst.CondBr) InnerError!*Inst {
...@@ -3031,7 +3103,7 @@ fn wantSafety(self: *Module, scope: *Scope) bool {...@@ -3031,7 +3103,7 @@ fn wantSafety(self: *Module, scope: *Scope) bool {
3031 };3103 };
3032}3104}
30333105
3034fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unreachable) InnerError!*Inst {3106fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.NoOp) InnerError!*Inst {
3035 const b = try self.requireRuntimeBlock(scope, unreach.base.src);3107 const b = try self.requireRuntimeBlock(scope, unreach.base.src);
3036 if (self.wantSafety(scope)) {3108 if (self.wantSafety(scope)) {
3037 // TODO Once we have a panic function to call, call it here instead of this.3109 // TODO Once we have a panic function to call, call it here instead of this.
...@@ -3040,13 +3112,13 @@ fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unrea...@@ -3040,13 +3112,13 @@ fn analyzeInstUnreachable(self: *Module, scope: *Scope, unreach: *zir.Inst.Unrea
3040 return self.addNoOp(b, unreach.base.src, Type.initTag(.noreturn), .unreach);3112 return self.addNoOp(b, unreach.base.src, Type.initTag(.noreturn), .unreach);
3041}3113}
30423114
3043fn analyzeInstRet(self: *Module, scope: *Scope, inst: *zir.Inst.Return) InnerError!*Inst {3115fn analyzeInstRet(self: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst {
3044 const operand = try self.resolveInst(scope, inst.positionals.operand);3116 const operand = try self.resolveInst(scope, inst.positionals.operand);
3045 const b = try self.requireRuntimeBlock(scope, inst.base.src);3117 const b = try self.requireRuntimeBlock(scope, inst.base.src);
3046 return self.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand);3118 return self.addUnOp(b, inst.base.src, Type.initTag(.noreturn), .ret, operand);
3047}3119}
30483120
3049fn analyzeInstRetVoid(self: *Module, scope: *Scope, inst: *zir.Inst.ReturnVoid) InnerError!*Inst {3121fn analyzeInstRetVoid(self: *Module, scope: *Scope, inst: *zir.Inst.NoOp) InnerError!*Inst {
3050 const b = try self.requireRuntimeBlock(scope, inst.base.src);3122 const b = try self.requireRuntimeBlock(scope, inst.base.src);
3051 return self.addNoOp(b, inst.base.src, Type.initTag(.noreturn), .retvoid);3123 return self.addNoOp(b, inst.base.src, Type.initTag(.noreturn), .retvoid);
3052}3124}
src-self-hosted/astgen.zig+18-40
...@@ -16,6 +16,15 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {...@@ -16,6 +16,15 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
16 switch (node.tag) {16 switch (node.tag) {
17 .VarDecl => unreachable, // Handled in `blockExpr`.17 .VarDecl => unreachable, // Handled in `blockExpr`.
1818
19 .Add => return simpleInfixOp(mod, scope, node.castTag(.Add).?, .add),
20 .Sub => return simpleInfixOp(mod, scope, node.castTag(.Sub).?, .sub),
21 .BangEqual => return simpleInfixOp(mod, scope, node.castTag(.BangEqual).?, .cmp_neq),
22 .EqualEqual => return simpleInfixOp(mod, scope, node.castTag(.EqualEqual).?, .cmp_eq),
23 .GreaterThan => return simpleInfixOp(mod, scope, node.castTag(.GreaterThan).?, .cmp_gt),
24 .GreaterOrEqual => return simpleInfixOp(mod, scope, node.castTag(.GreaterOrEqual).?, .cmp_gte),
25 .LessThan => return simpleInfixOp(mod, scope, node.castTag(.LessThan).?, .cmp_lt),
26 .LessOrEqual => return simpleInfixOp(mod, scope, node.castTag(.LessOrEqual).?, .cmp_lte),
27
19 .Identifier => return identifier(mod, scope, node.castTag(.Identifier).?),28 .Identifier => return identifier(mod, scope, node.castTag(.Identifier).?),
20 .Asm => return assembly(mod, scope, node.castTag(.Asm).?),29 .Asm => return assembly(mod, scope, node.castTag(.Asm).?),
21 .StringLiteral => return stringLiteral(mod, scope, node.castTag(.StringLiteral).?),30 .StringLiteral => return stringLiteral(mod, scope, node.castTag(.StringLiteral).?),
...@@ -26,13 +35,6 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {...@@ -26,13 +35,6 @@ pub fn expr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst {
26 .ControlFlowExpression => return controlFlowExpr(mod, scope, node.castTag(.ControlFlowExpression).?),35 .ControlFlowExpression => return controlFlowExpr(mod, scope, node.castTag(.ControlFlowExpression).?),
27 .If => return ifExpr(mod, scope, node.castTag(.If).?),36 .If => return ifExpr(mod, scope, node.castTag(.If).?),
28 .Assign => return assign(mod, scope, node.castTag(.Assign).?),37 .Assign => return assign(mod, scope, node.castTag(.Assign).?),
29 .Add => return add(mod, scope, node.castTag(.Add).?),
30 .BangEqual => return cmp(mod, scope, node.castTag(.BangEqual).?, .neq),
31 .EqualEqual => return cmp(mod, scope, node.castTag(.EqualEqual).?, .eq),
32 .GreaterThan => return cmp(mod, scope, node.castTag(.GreaterThan).?, .gt),
33 .GreaterOrEqual => return cmp(mod, scope, node.castTag(.GreaterOrEqual).?, .gte),
34 .LessThan => return cmp(mod, scope, node.castTag(.LessThan).?, .lt),
35 .LessOrEqual => return cmp(mod, scope, node.castTag(.LessOrEqual).?, .lte),
36 .Period => return field(mod, scope, node.castTag(.Period).?),38 .Period => return field(mod, scope, node.castTag(.Period).?),
37 .Deref => return deref(mod, scope, node.castTag(.Deref).?),39 .Deref => return deref(mod, scope, node.castTag(.Deref).?),
38 .BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?),40 .BoolNot => return boolNot(mod, scope, node.castTag(.BoolNot).?),
...@@ -97,14 +99,6 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop...@@ -97,14 +99,6 @@ fn varDecl(mod: *Module, scope: *Scope, node: *ast.Node.VarDecl) InnerError!Scop
97 },99 },
98 .Keyword_var => {100 .Keyword_var => {
99 return mod.failNode(scope, &node.base, "TODO implement local vars", .{});101 return mod.failNode(scope, &node.base, "TODO implement local vars", .{});
100 //const src = tree.token_locs[node.name_token].start;
101 //const alloc = mod.addZIRInst(scope, src, zir.Inst.Alloc, .{}, .{});
102 //if (node.getTrailer("type_node")) |type_node| {
103 // const type_inst = try expr(mod, scope, type_node);
104 // return mod.failNode(scope, type_node, "TODO implement typed var locals", .{});
105 //} else {
106 // return mod.failTok(scope, node.mut_token, "TODO implement mutable type-inferred locals", .{});
107 //}
108 },102 },
109 else => unreachable,103 else => unreachable,
110 }104 }
...@@ -114,7 +108,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr...@@ -114,7 +108,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr
114 const operand = try expr(mod, scope, node.rhs);108 const operand = try expr(mod, scope, node.rhs);
115 const tree = scope.tree();109 const tree = scope.tree();
116 const src = tree.token_locs[node.op_token].start;110 const src = tree.token_locs[node.op_token].start;
117 return mod.addZIRInst(scope, src, zir.Inst.BoolNot, .{ .operand = operand }, .{});111 return mod.addZIRUnOp(scope, src, .boolnot, operand);
118}112}
119113
120fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {114fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
...@@ -169,33 +163,21 @@ fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError!...@@ -169,33 +163,21 @@ fn field(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp) InnerError!
169 const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?);163 const field_name = try identifierStringInst(mod, scope, node.rhs.castTag(.Identifier).?);
170164
171 const pointer = try mod.addZIRInst(scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{});165 const pointer = try mod.addZIRInst(scope, src, zir.Inst.FieldPtr, .{ .object_ptr = lhs, .field_name = field_name }, .{});
172 return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = pointer }, .{});166 return mod.addZIRUnOp(scope, src, .deref, pointer);
173}167}
174168
175fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {169fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
176 const tree = scope.tree();170 const tree = scope.tree();
177 const src = tree.token_locs[node.rtoken].start;171 const src = tree.token_locs[node.rtoken].start;
178
179 const lhs = try expr(mod, scope, node.lhs);172 const lhs = try expr(mod, scope, node.lhs);
180173 return mod.addZIRUnOp(scope, src, .deref, lhs);
181 return mod.addZIRInst(scope, src, zir.Inst.Deref, .{ .ptr = lhs }, .{});
182}
183
184fn add(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst {
185 const lhs = try expr(mod, scope, infix_node.lhs);
186 const rhs = try expr(mod, scope, infix_node.rhs);
187
188 const tree = scope.tree();
189 const src = tree.token_locs[infix_node.op_token].start;
190
191 return mod.addZIRInst(scope, src, zir.Inst.Add, .{ .lhs = lhs, .rhs = rhs }, .{});
192}174}
193175
194fn cmp(176fn simpleInfixOp(
195 mod: *Module,177 mod: *Module,
196 scope: *Scope,178 scope: *Scope,
197 infix_node: *ast.Node.SimpleInfixOp,179 infix_node: *ast.Node.SimpleInfixOp,
198 op: std.math.CompareOperator,180 op_inst_tag: zir.Inst.Tag,
199) InnerError!*zir.Inst {181) InnerError!*zir.Inst {
200 const lhs = try expr(mod, scope, infix_node.lhs);182 const lhs = try expr(mod, scope, infix_node.lhs);
201 const rhs = try expr(mod, scope, infix_node.rhs);183 const rhs = try expr(mod, scope, infix_node.rhs);
...@@ -203,11 +185,7 @@ fn cmp(...@@ -203,11 +185,7 @@ fn cmp(
203 const tree = scope.tree();185 const tree = scope.tree();
204 const src = tree.token_locs[infix_node.op_token].start;186 const src = tree.token_locs[infix_node.op_token].start;
205187
206 return mod.addZIRInst(scope, src, zir.Inst.Cmp, .{188 return mod.addZIRBinOp(scope, src, op_inst_tag, lhs, rhs);
207 .lhs = lhs,
208 .op = op,
209 .rhs = rhs,
210 }, .{});
211}189}
212190
213fn ifExpr(mod: *Module, scope: *Scope, if_node: *ast.Node.If) InnerError!*zir.Inst {191fn ifExpr(mod: *Module, scope: *Scope, if_node: *ast.Node.If) InnerError!*zir.Inst {
...@@ -306,9 +284,9 @@ fn controlFlowExpr(...@@ -306,9 +284,9 @@ fn controlFlowExpr(
306 const src = tree.token_locs[cfe.ltoken].start;284 const src = tree.token_locs[cfe.ltoken].start;
307 if (cfe.rhs) |rhs_node| {285 if (cfe.rhs) |rhs_node| {
308 const operand = try expr(mod, scope, rhs_node);286 const operand = try expr(mod, scope, rhs_node);
309 return mod.addZIRInst(scope, src, zir.Inst.Return, .{ .operand = operand }, .{});287 return mod.addZIRUnOp(scope, src, .@"return", operand);
310 } else {288 } else {
311 return mod.addZIRInst(scope, src, zir.Inst.ReturnVoid, .{}, .{});289 return mod.addZIRNoOp(scope, src, .returnvoid);
312 }290 }
313}291}
314292
...@@ -519,7 +497,7 @@ fn callExpr(mod: *Module, scope: *Scope, node: *ast.Node.Call) InnerError!*zir.I...@@ -519,7 +497,7 @@ fn callExpr(mod: *Module, scope: *Scope, node: *ast.Node.Call) InnerError!*zir.I
519fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.Unreachable) InnerError!*zir.Inst {497fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.Unreachable) InnerError!*zir.Inst {
520 const tree = scope.tree();498 const tree = scope.tree();
521 const src = tree.token_locs[unreach_node.token].start;499 const src = tree.token_locs[unreach_node.token].start;
522 return mod.addZIRInst(scope, src, zir.Inst.Unreachable, .{}, .{});500 return mod.addZIRNoOp(scope, src, .@"unreachable");
523}501}
524502
525fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {503fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
src-self-hosted/zir.zig+137-214
...@@ -79,11 +79,69 @@ pub const Inst = struct {...@@ -79,11 +79,69 @@ pub const Inst = struct {
79 elemptr,79 elemptr,
80 add,80 add,
81 sub,81 sub,
82 cmp,82 cmp_lt,
83 cmp_lte,
84 cmp_eq,
85 cmp_gte,
86 cmp_gt,
87 cmp_neq,
83 condbr,88 condbr,
84 isnull,89 isnull,
85 isnonnull,90 isnonnull,
8691
92 pub fn Type(tag: Tag) type {
93 return switch (tag) {
94 .arg,
95 .breakpoint,
96 .@"unreachable",
97 .returnvoid,
98 => NoOp,
99
100 .boolnot,
101 .deref,
102 .@"return",
103 .isnull,
104 .isnonnull,
105 => UnOp,
106
107 .add,
108 .sub,
109 .cmp_lt,
110 .cmp_lte,
111 .cmp_eq,
112 .cmp_gte,
113 .cmp_gt,
114 .cmp_neq,
115 => BinOp,
116
117 .block => Block,
118 .@"break" => Break,
119 .breakvoid => BreakVoid,
120 .call => Call,
121 .declref => DeclRef,
122 .declref_str => DeclRefStr,
123 .declval => DeclVal,
124 .declval_in_module => DeclValInModule,
125 .compileerror => CompileError,
126 .@"const" => Const,
127 .str => Str,
128 .int => Int,
129 .inttype => IntType,
130 .ptrtoint => PtrToInt,
131 .fieldptr => FieldPtr,
132 .as => As,
133 .@"asm" => Asm,
134 .@"fn" => Fn,
135 .@"export" => Export,
136 .primitive => Primitive,
137 .fntype => FnType,
138 .intcast => IntCast,
139 .bitcast => BitCast,
140 .elemptr => ElemPtr,
141 .condbr => CondBr,
142 };
143 }
144
87 /// Returns whether the instruction is one of the control flow "noreturn" types.145 /// Returns whether the instruction is one of the control flow "noreturn" types.
88 /// Function calls do not count.146 /// Function calls do not count.
89 pub fn isNoReturn(tag: Tag) bool {147 pub fn isNoReturn(tag: Tag) bool {
...@@ -114,7 +172,12 @@ pub const Inst = struct {...@@ -114,7 +172,12 @@ pub const Inst = struct {
114 .elemptr,172 .elemptr,
115 .add,173 .add,
116 .sub,174 .sub,
117 .cmp,175 .cmp_lt,
176 .cmp_lte,
177 .cmp_eq,
178 .cmp_gte,
179 .cmp_gt,
180 .cmp_neq,
118 .isnull,181 .isnull,
119 .isnonnull,182 .isnonnull,
120 .boolnot,183 .boolnot,
...@@ -132,63 +195,56 @@ pub const Inst = struct {...@@ -132,63 +195,56 @@ pub const Inst = struct {
132 }195 }
133 };196 };
134197
135 pub fn TagToType(tag: Tag) type {198 /// Prefer `castTag` to this.
136 return switch (tag) {
137 .arg => Arg,
138 .block => Block,
139 .@"break" => Break,
140 .breakpoint => Breakpoint,
141 .breakvoid => BreakVoid,
142 .call => Call,
143 .declref => DeclRef,
144 .declref_str => DeclRefStr,
145 .declval => DeclVal,
146 .declval_in_module => DeclValInModule,
147 .compileerror => CompileError,
148 .@"const" => Const,
149 .boolnot => BoolNot,
150 .str => Str,
151 .int => Int,
152 .inttype => IntType,
153 .ptrtoint => PtrToInt,
154 .fieldptr => FieldPtr,
155 .deref => Deref,
156 .as => As,
157 .@"asm" => Asm,
158 .@"unreachable" => Unreachable,
159 .@"return" => Return,
160 .returnvoid => ReturnVoid,
161 .@"fn" => Fn,
162 .@"export" => Export,
163 .primitive => Primitive,
164 .fntype => FnType,
165 .intcast => IntCast,
166 .bitcast => BitCast,
167 .elemptr => ElemPtr,
168 .add => Add,
169 .sub => Sub,
170 .cmp => Cmp,
171 .condbr => CondBr,
172 .isnull => IsNull,
173 .isnonnull => IsNonNull,
174 };
175 }
176
177 pub fn cast(base: *Inst, comptime T: type) ?*T {199 pub fn cast(base: *Inst, comptime T: type) ?*T {
178 if (base.tag != T.base_tag)200 if (@hasField(T, "base_tag")) {
179 return null;201 return base.castTag(T.base_tag);
202 }
203 inline for (@typeInfo(Tag).Enum.fields) |field| {
204 const tag = @intToEnum(Tag, field.value);
205 if (base.tag == tag) {
206 if (T == tag.Type()) {
207 return @fieldParentPtr(T, "base", base);
208 }
209 return null;
210 }
211 }
212 unreachable;
213 }
180214
181 return @fieldParentPtr(T, "base", base);215 pub fn castTag(base: *Inst, comptime tag: Tag) ?*tag.Type() {
216 if (base.tag == tag) {
217 return @fieldParentPtr(tag.Type(), "base", base);
218 }
219 return null;
182 }220 }
183221
184 pub const Arg = struct {222 pub const NoOp = struct {
185 pub const base_tag = Tag.arg;
186 base: Inst,223 base: Inst,
187224
188 positionals: struct {},225 positionals: struct {},
189 kw_args: struct {},226 kw_args: struct {},
190 };227 };
191228
229 pub const UnOp = struct {
230 base: Inst,
231
232 positionals: struct {
233 operand: *Inst,
234 },
235 kw_args: struct {},
236 };
237
238 pub const BinOp = struct {
239 base: Inst,
240
241 positionals: struct {
242 lhs: *Inst,
243 rhs: *Inst,
244 },
245 kw_args: struct {},
246 };
247
192 pub const Block = struct {248 pub const Block = struct {
193 pub const base_tag = Tag.block;249 pub const base_tag = Tag.block;
194 base: Inst,250 base: Inst,
...@@ -210,14 +266,6 @@ pub const Inst = struct {...@@ -210,14 +266,6 @@ pub const Inst = struct {
210 kw_args: struct {},266 kw_args: struct {},
211 };267 };
212268
213 pub const Breakpoint = struct {
214 pub const base_tag = Tag.breakpoint;
215 base: Inst,
216
217 positionals: struct {},
218 kw_args: struct {},
219 };
220
221 pub const BreakVoid = struct {269 pub const BreakVoid = struct {
222 pub const base_tag = Tag.breakvoid;270 pub const base_tag = Tag.breakvoid;
223 base: Inst,271 base: Inst,
...@@ -301,16 +349,6 @@ pub const Inst = struct {...@@ -301,16 +349,6 @@ pub const Inst = struct {
301 kw_args: struct {},349 kw_args: struct {},
302 };350 };
303351
304 pub const BoolNot = struct {
305 pub const base_tag = Tag.boolnot;
306 base: Inst,
307
308 positionals: struct {
309 operand: *Inst,
310 },
311 kw_args: struct {},
312 };
313
314 pub const Str = struct {352 pub const Str = struct {
315 pub const base_tag = Tag.str;353 pub const base_tag = Tag.str;
316 base: Inst,354 base: Inst,
...@@ -353,16 +391,6 @@ pub const Inst = struct {...@@ -353,16 +391,6 @@ pub const Inst = struct {
353 kw_args: struct {},391 kw_args: struct {},
354 };392 };
355393
356 pub const Deref = struct {
357 pub const base_tag = Tag.deref;
358 base: Inst,
359
360 positionals: struct {
361 ptr: *Inst,
362 },
363 kw_args: struct {},
364 };
365
366 pub const As = struct {394 pub const As = struct {
367 pub const base_tag = Tag.as;395 pub const base_tag = Tag.as;
368 pub const builtin_name = "@as";396 pub const builtin_name = "@as";
...@@ -392,32 +420,6 @@ pub const Inst = struct {...@@ -392,32 +420,6 @@ pub const Inst = struct {
392 },420 },
393 };421 };
394422
395 pub const Unreachable = struct {
396 pub const base_tag = Tag.@"unreachable";
397 base: Inst,
398
399 positionals: struct {},
400 kw_args: struct {},
401 };
402
403 pub const Return = struct {
404 pub const base_tag = Tag.@"return";
405 base: Inst,
406
407 positionals: struct {
408 operand: *Inst,
409 },
410 kw_args: struct {},
411 };
412
413 pub const ReturnVoid = struct {
414 pub const base_tag = Tag.returnvoid;
415 base: Inst,
416
417 positionals: struct {},
418 kw_args: struct {},
419 };
420
421 pub const Fn = struct {423 pub const Fn = struct {
422 pub const base_tag = Tag.@"fn";424 pub const base_tag = Tag.@"fn";
423 base: Inst,425 base: Inst,
...@@ -587,42 +589,6 @@ pub const Inst = struct {...@@ -587,42 +589,6 @@ pub const Inst = struct {
587 kw_args: struct {},589 kw_args: struct {},
588 };590 };
589591
590 pub const Add = struct {
591 pub const base_tag = Tag.add;
592 base: Inst,
593
594 positionals: struct {
595 lhs: *Inst,
596 rhs: *Inst,
597 },
598 kw_args: struct {},
599 };
600
601 pub const Sub = struct {
602 pub const base_tag = Tag.sub;
603 base: Inst,
604
605 positionals: struct {
606 lhs: *Inst,
607 rhs: *Inst,
608 },
609 kw_args: struct {},
610 };
611
612 /// TODO get rid of the op positional arg and make that data part of
613 /// the base Inst tag.
614 pub const Cmp = struct {
615 pub const base_tag = Tag.cmp;
616 base: Inst,
617
618 positionals: struct {
619 lhs: *Inst,
620 op: std.math.CompareOperator,
621 rhs: *Inst,
622 },
623 kw_args: struct {},
624 };
625
626 pub const CondBr = struct {592 pub const CondBr = struct {
627 pub const base_tag = Tag.condbr;593 pub const base_tag = Tag.condbr;
628 base: Inst,594 base: Inst,
...@@ -634,26 +600,6 @@ pub const Inst = struct {...@@ -634,26 +600,6 @@ pub const Inst = struct {
634 },600 },
635 kw_args: struct {},601 kw_args: struct {},
636 };602 };
637
638 pub const IsNull = struct {
639 pub const base_tag = Tag.isnull;
640 base: Inst,
641
642 positionals: struct {
643 operand: *Inst,
644 },
645 kw_args: struct {},
646 };
647
648 pub const IsNonNull = struct {
649 pub const base_tag = Tag.isnonnull;
650 base: Inst,
651
652 positionals: struct {
653 operand: *Inst,
654 },
655 kw_args: struct {},
656 };
657};603};
658604
659pub const ErrorMsg = struct {605pub const ErrorMsg = struct {
...@@ -775,7 +721,7 @@ const Writer = struct {...@@ -775,7 +721,7 @@ const Writer = struct {
775 comptime inst_tag: Inst.Tag,721 comptime inst_tag: Inst.Tag,
776 base: *Inst,722 base: *Inst,
777 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {723 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
778 const SpecificInst = Inst.TagToType(inst_tag);724 const SpecificInst = inst_tag.Type();
779 const inst = @fieldParentPtr(SpecificInst, "base", base);725 const inst = @fieldParentPtr(SpecificInst, "base", base);
780 const Positionals = @TypeOf(inst.positionals);726 const Positionals = @TypeOf(inst.positionals);
781 try stream.writeAll("= " ++ @tagName(inst_tag) ++ "(");727 try stream.writeAll("= " ++ @tagName(inst_tag) ++ "(");
...@@ -1102,7 +1048,7 @@ const Parser = struct {...@@ -1102,7 +1048,7 @@ const Parser = struct {
1102 inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {1048 inline for (@typeInfo(Inst.Tag).Enum.fields) |field| {
1103 if (mem.eql(u8, field.name, fn_name)) {1049 if (mem.eql(u8, field.name, fn_name)) {
1104 const tag = @field(Inst.Tag, field.name);1050 const tag = @field(Inst.Tag, field.name);
1105 return parseInstructionGeneric(self, field.name, Inst.TagToType(tag), body_ctx, name, contents_start);1051 return parseInstructionGeneric(self, field.name, tag.Type(), tag, body_ctx, name, contents_start);
1106 }1052 }
1107 }1053 }
1108 return self.fail("unknown instruction '{}'", .{fn_name});1054 return self.fail("unknown instruction '{}'", .{fn_name});
...@@ -1112,6 +1058,7 @@ const Parser = struct {...@@ -1112,6 +1058,7 @@ const Parser = struct {
1112 self: *Parser,1058 self: *Parser,
1113 comptime fn_name: []const u8,1059 comptime fn_name: []const u8,
1114 comptime InstType: type,1060 comptime InstType: type,
1061 tag: Inst.Tag,
1115 body_ctx: ?*Body,1062 body_ctx: ?*Body,
1116 inst_name: []const u8,1063 inst_name: []const u8,
1117 contents_start: usize,1064 contents_start: usize,
...@@ -1119,7 +1066,7 @@ const Parser = struct {...@@ -1119,7 +1066,7 @@ const Parser = struct {
1119 const inst_specific = try self.arena.allocator.create(InstType);1066 const inst_specific = try self.arena.allocator.create(InstType);
1120 inst_specific.base = .{1067 inst_specific.base = .{
1121 .src = self.i,1068 .src = self.i,
1122 .tag = InstType.base_tag,1069 .tag = tag,
1123 };1070 };
11241071
1125 if (InstType == Inst.Block) {1072 if (InstType == Inst.Block) {
...@@ -1615,12 +1562,12 @@ const EmitZIR = struct {...@@ -1615,12 +1562,12 @@ const EmitZIR = struct {
1615 }1562 }
1616 }1563 }
16171564
1618 fn emitNoOp(self: *EmitZIR, src: usize, comptime T: type) Allocator.Error!*Inst {1565 fn emitNoOp(self: *EmitZIR, src: usize, tag: Inst.Tag) Allocator.Error!*Inst {
1619 const new_inst = try self.arena.allocator.create(T);1566 const new_inst = try self.arena.allocator.create(Inst.NoOp);
1620 new_inst.* = .{1567 new_inst.* = .{
1621 .base = .{1568 .base = .{
1622 .src = src,1569 .src = src,
1623 .tag = T.base_tag,1570 .tag = tag,
1624 },1571 },
1625 .positionals = .{},1572 .positionals = .{},
1626 .kw_args = .{},1573 .kw_args = .{},
...@@ -1628,41 +1575,18 @@ const EmitZIR = struct {...@@ -1628,41 +1575,18 @@ const EmitZIR = struct {
1628 return &new_inst.base;1575 return &new_inst.base;
1629 }1576 }
16301577
1631 fn emitCmp(
1632 self: *EmitZIR,
1633 src: usize,
1634 new_body: ZirBody,
1635 old_inst: *ir.Inst.BinOp,
1636 op: std.math.CompareOperator,
1637 ) Allocator.Error!*Inst {
1638 const new_inst = try self.arena.allocator.create(Inst.Cmp);
1639 new_inst.* = .{
1640 .base = .{
1641 .src = src,
1642 .tag = Inst.Cmp.base_tag,
1643 },
1644 .positionals = .{
1645 .lhs = try self.resolveInst(new_body, old_inst.lhs),
1646 .rhs = try self.resolveInst(new_body, old_inst.rhs),
1647 .op = op,
1648 },
1649 .kw_args = .{},
1650 };
1651 return &new_inst.base;
1652 }
1653
1654 fn emitUnOp(1578 fn emitUnOp(
1655 self: *EmitZIR,1579 self: *EmitZIR,
1656 src: usize,1580 src: usize,
1657 new_body: ZirBody,1581 new_body: ZirBody,
1658 old_inst: *ir.Inst.UnOp,1582 old_inst: *ir.Inst.UnOp,
1659 comptime I: type,1583 tag: Inst.Tag,
1660 ) Allocator.Error!*Inst {1584 ) Allocator.Error!*Inst {
1661 const new_inst = try self.arena.allocator.create(I);1585 const new_inst = try self.arena.allocator.create(Inst.UnOp);
1662 new_inst.* = .{1586 new_inst.* = .{
1663 .base = .{1587 .base = .{
1664 .src = src,1588 .src = src,
1665 .tag = I.base_tag,1589 .tag = tag,
1666 },1590 },
1667 .positionals = .{1591 .positionals = .{
1668 .operand = try self.resolveInst(new_body, old_inst.operand),1592 .operand = try self.resolveInst(new_body, old_inst.operand),
...@@ -1677,13 +1601,13 @@ const EmitZIR = struct {...@@ -1677,13 +1601,13 @@ const EmitZIR = struct {
1677 src: usize,1601 src: usize,
1678 new_body: ZirBody,1602 new_body: ZirBody,
1679 old_inst: *ir.Inst.BinOp,1603 old_inst: *ir.Inst.BinOp,
1680 comptime I: type,1604 tag: Inst.Tag,
1681 ) Allocator.Error!*Inst {1605 ) Allocator.Error!*Inst {
1682 const new_inst = try self.arena.allocator.create(I);1606 const new_inst = try self.arena.allocator.create(Inst.BinOp);
1683 new_inst.* = .{1607 new_inst.* = .{
1684 .base = .{1608 .base = .{
1685 .src = src,1609 .src = src,
1686 .tag = I.base_tag,1610 .tag = tag,
1687 },1611 },
1688 .positionals = .{1612 .positionals = .{
1689 .lhs = try self.resolveInst(new_body, old_inst.lhs),1613 .lhs = try self.resolveInst(new_body, old_inst.lhs),
...@@ -1708,26 +1632,25 @@ const EmitZIR = struct {...@@ -1708,26 +1632,25 @@ const EmitZIR = struct {
1708 const new_inst = switch (inst.tag) {1632 const new_inst = switch (inst.tag) {
1709 .constant => unreachable, // excluded from function bodies1633 .constant => unreachable, // excluded from function bodies
17101634
1711 .arg => try self.emitNoOp(inst.src, Inst.Arg),1635 .arg => try self.emitNoOp(inst.src, .arg),
1712 .breakpoint => try self.emitNoOp(inst.src, Inst.Breakpoint),1636 .breakpoint => try self.emitNoOp(inst.src, .breakpoint),
1713 .unreach => try self.emitNoOp(inst.src, Inst.Unreachable),1637 .unreach => try self.emitNoOp(inst.src, .@"unreachable"),
1714 .retvoid => try self.emitNoOp(inst.src, Inst.ReturnVoid),1638 .retvoid => try self.emitNoOp(inst.src, .returnvoid),
17151639
1716 .not => try self.emitUnOp(inst.src, new_body, inst.castTag(.not).?, Inst.BoolNot),1640 .not => try self.emitUnOp(inst.src, new_body, inst.castTag(.not).?, .boolnot),
1717 .ret => try self.emitUnOp(inst.src, new_body, inst.castTag(.ret).?, Inst.Return),1641 .ret => try self.emitUnOp(inst.src, new_body, inst.castTag(.ret).?, .@"return"),
1718 .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, Inst.PtrToInt),1642 .ptrtoint => try self.emitUnOp(inst.src, new_body, inst.castTag(.ptrtoint).?, .ptrtoint),
1719 .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, Inst.IsNull),1643 .isnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnull).?, .isnull),
1720 .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, Inst.IsNonNull),1644 .isnonnull => try self.emitUnOp(inst.src, new_body, inst.castTag(.isnonnull).?, .isnonnull),
17211645
1722 .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, Inst.Add),1646 .add => try self.emitBinOp(inst.src, new_body, inst.castTag(.add).?, .add),
1723 .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, Inst.Sub),1647 .sub => try self.emitBinOp(inst.src, new_body, inst.castTag(.sub).?, .sub),
17241648 .cmp_lt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_lt).?, .cmp_lt),
1725 .cmp_lt => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_lt).?, .lt),1649 .cmp_lte => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_lte).?, .cmp_lte),
1726 .cmp_lte => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_lte).?, .lte),1650 .cmp_eq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_eq).?, .cmp_eq),
1727 .cmp_eq => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_eq).?, .eq),1651 .cmp_gte => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gte).?, .cmp_gte),
1728 .cmp_gte => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_gte).?, .gte),1652 .cmp_gt => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_gt).?, .cmp_gt),
1729 .cmp_gt => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_gt).?, .gt),1653 .cmp_neq => try self.emitBinOp(inst.src, new_body, inst.castTag(.cmp_neq).?, .cmp_neq),
1730 .cmp_neq => try self.emitCmp(inst.src, new_body, inst.castTag(.cmp_neq).?, .neq),
17311654
1732 .bitcast => blk: {1655 .bitcast => blk: {
1733 const old_inst = inst.castTag(.bitcast).?;1656 const old_inst = inst.castTag(.bitcast).?;
test/stage2/zir.zig+1-1
...@@ -56,7 +56,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -56,7 +56,7 @@ pub fn addCases(ctx: *TestContext) !void {
56 \\ %result = add(%x0, %x1)56 \\ %result = add(%x0, %x1)
57 \\57 \\
58 \\ %expected = int(69)58 \\ %expected = int(69)
59 \\ %ok = cmp(%result, eq, %expected)59 \\ %ok = cmp_eq(%result, %expected)
60 \\ %10 = condbr(%ok, {60 \\ %10 = condbr(%ok, {
61 \\ %11 = returnvoid()61 \\ %11 = returnvoid()
62 \\ }, {62 \\ }, {