authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-12 15:30:30-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:16-07:00
log913393fd3b986dd262a8419341dced9ad5d9620d
tree24206439ed1abe1e7ca09a0f164d79981ea4eb2b
parentee6432537ee29485c5de6c8b0911ef1482d752a7

stage2: first pass over Module.zig for AIR memory layout


9 files changed, 429 insertions(+), 455 deletions(-)

BRANCH_TODO+122
...@@ -568,3 +568,125 @@ const DumpAir = struct {...@@ -568,3 +568,125 @@ const DumpAir = struct {
568 }568 }
569 }569 }
570};570};
571
572pub fn constInst(mod: *Module, arena: *Allocator, src: LazySrcLoc, typed_value: TypedValue) !*ir.Inst {
573 _ = mod;
574 const const_inst = try arena.create(ir.Inst.Constant);
575 const_inst.* = .{
576 .base = .{
577 .tag = ir.Inst.Constant.base_tag,
578 .ty = typed_value.ty,
579 .src = src,
580 },
581 .val = typed_value.val,
582 };
583 return &const_inst.base;
584}
585
586pub fn constType(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
587 return mod.constInst(arena, src, .{
588 .ty = Type.initTag(.type),
589 .val = try ty.toValue(arena),
590 });
591}
592
593pub fn constVoid(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
594 return mod.constInst(arena, src, .{
595 .ty = Type.initTag(.void),
596 .val = Value.initTag(.void_value),
597 });
598}
599
600pub fn constNoReturn(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
601 return mod.constInst(arena, src, .{
602 .ty = Type.initTag(.noreturn),
603 .val = Value.initTag(.unreachable_value),
604 });
605}
606
607pub fn constUndef(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
608 return mod.constInst(arena, src, .{
609 .ty = ty,
610 .val = Value.initTag(.undef),
611 });
612}
613
614pub fn constBool(mod: *Module, arena: *Allocator, src: LazySrcLoc, v: bool) !*ir.Inst {
615 return mod.constInst(arena, src, .{
616 .ty = Type.initTag(.bool),
617 .val = ([2]Value{ Value.initTag(.bool_false), Value.initTag(.bool_true) })[@boolToInt(v)],
618 });
619}
620
621pub fn constIntUnsigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: u64) !*ir.Inst {
622 return mod.constInst(arena, src, .{
623 .ty = ty,
624 .val = try Value.Tag.int_u64.create(arena, int),
625 });
626}
627
628pub fn constIntSigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: i64) !*ir.Inst {
629 return mod.constInst(arena, src, .{
630 .ty = ty,
631 .val = try Value.Tag.int_i64.create(arena, int),
632 });
633}
634
635pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, big_int: BigIntConst) !*ir.Inst {
636 if (big_int.positive) {
637 if (big_int.to(u64)) |x| {
638 return mod.constIntUnsigned(arena, src, ty, x);
639 } else |err| switch (err) {
640 error.NegativeIntoUnsigned => unreachable,
641 error.TargetTooSmall => {}, // handled below
642 }
643 return mod.constInst(arena, src, .{
644 .ty = ty,
645 .val = try Value.Tag.int_big_positive.create(arena, big_int.limbs),
646 });
647 } else {
648 if (big_int.to(i64)) |x| {
649 return mod.constIntSigned(arena, src, ty, x);
650 } else |err| switch (err) {
651 error.NegativeIntoUnsigned => unreachable,
652 error.TargetTooSmall => {}, // handled below
653 }
654 return mod.constInst(arena, src, .{
655 .ty = ty,
656 .val = try Value.Tag.int_big_negative.create(arena, big_int.limbs),
657 });
658 }
659}
660
661pub fn dumpInst(mod: *Module, scope: *Scope, inst: *ir.Inst) void {
662 const zir_module = scope.namespace();
663 const source = zir_module.getSource(mod) catch @panic("dumpInst failed to get source");
664 const loc = std.zig.findLineColumn(source, inst.src);
665 if (inst.tag == .constant) {
666 std.debug.print("constant ty={} val={} src={s}:{d}:{d}\n", .{
667 inst.ty,
668 inst.castTag(.constant).?.val,
669 zir_module.subFilePath(),
670 loc.line + 1,
671 loc.column + 1,
672 });
673 } else if (inst.deaths == 0) {
674 std.debug.print("{s} ty={} src={s}:{d}:{d}\n", .{
675 @tagName(inst.tag),
676 inst.ty,
677 zir_module.subFilePath(),
678 loc.line + 1,
679 loc.column + 1,
680 });
681 } else {
682 std.debug.print("{s} ty={} deaths={b} src={s}:{d}:{d}\n", .{
683 @tagName(inst.tag),
684 inst.ty,
685 inst.deaths,
686 zir_module.subFilePath(),
687 loc.line + 1,
688 loc.column + 1,
689 });
690 }
691}
692
src/Air.zig+12-2
...@@ -29,8 +29,11 @@ pub const Inst = struct {...@@ -29,8 +29,11 @@ pub const Inst = struct {
29 data: Data,29 data: Data,
3030
31 pub const Tag = enum(u8) {31 pub const Tag = enum(u8) {
32 /// The first N instructions in Air must be one arg instruction per function parameter.32 /// The first N instructions in the main block must be one arg instruction per
33 /// Uses the `ty` field.33 /// function parameter. This makes function parameters participate in
34 /// liveness analysis without any special handling.
35 /// Uses the `ty_str` field.
36 /// The string is the parameter name.
34 arg,37 arg,
35 /// Float or integer addition. For integers, wrapping is undefined behavior.38 /// Float or integer addition. For integers, wrapping is undefined behavior.
36 /// Both operands are guaranteed to be the same type, and the result type39 /// Both operands are guaranteed to be the same type, and the result type
...@@ -131,6 +134,8 @@ pub const Inst = struct {...@@ -131,6 +134,8 @@ pub const Inst = struct {
131 /// A comptime-known value. Uses the `ty_pl` field, payload is index of134 /// A comptime-known value. Uses the `ty_pl` field, payload is index of
132 /// `values` array.135 /// `values` array.
133 constant,136 constant,
137 /// A comptime-known type. Uses the `ty` field.
138 const_ty,
134 /// Notes the beginning of a source code statement and marks the line and column.139 /// Notes the beginning of a source code statement and marks the line and column.
135 /// Result type is always void.140 /// Result type is always void.
136 /// Uses the `dbg_stmt` field.141 /// Uses the `dbg_stmt` field.
...@@ -289,6 +294,11 @@ pub const Inst = struct {...@@ -289,6 +294,11 @@ pub const Inst = struct {
289 // Index into a different array.294 // Index into a different array.
290 payload: u32,295 payload: u32,
291 },296 },
297 ty_str: struct {
298 ty: Ref,
299 // ZIR string table index.
300 str: u32,
301 },
292 br: struct {302 br: struct {
293 block_inst: Index,303 block_inst: Index,
294 operand: Ref,304 operand: Ref,
src/AstGen.zig+1-1
...@@ -9821,7 +9821,7 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {...@@ -9821,7 +9821,7 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {
9821 astgen.source_column = column;9821 astgen.source_column = column;
9822}9822}
98239823
9824const ref_start_index = Zir.Inst.Ref.typed_value_map.len;9824const ref_start_index: u32 = Zir.Inst.Ref.typed_value_map.len;
98259825
9826fn indexToRef(inst: Zir.Inst.Index) Zir.Inst.Ref {9826fn indexToRef(inst: Zir.Inst.Index) Zir.Inst.Ref {
9827 return @intToEnum(Zir.Inst.Ref, ref_start_index + inst);9827 return @intToEnum(Zir.Inst.Ref, ref_start_index + inst);
src/Module.zig+30-329
...@@ -1155,7 +1155,7 @@ pub const Scope = struct {...@@ -1155,7 +1155,7 @@ pub const Scope = struct {
1155 /// This can vary during inline or comptime function calls. See `Sema.owner_decl`1155 /// This can vary during inline or comptime function calls. See `Sema.owner_decl`
1156 /// for the one that will be the same for all Block instances.1156 /// for the one that will be the same for all Block instances.
1157 src_decl: *Decl,1157 src_decl: *Decl,
1158 instructions: ArrayListUnmanaged(*ir.Inst),1158 instructions: ArrayListUnmanaged(Air.Inst.Index),
1159 label: ?*Label = null,1159 label: ?*Label = null,
1160 inlining: ?*Inlining,1160 inlining: ?*Inlining,
1161 /// If runtime_index is not 0 then one of these is guaranteed to be non null.1161 /// If runtime_index is not 0 then one of these is guaranteed to be non null.
...@@ -1187,14 +1187,14 @@ pub const Scope = struct {...@@ -1187,14 +1187,14 @@ pub const Scope = struct {
1187 };1187 };
11881188
1189 pub const Merges = struct {1189 pub const Merges = struct {
1190 block_inst: *ir.Inst.Block,1190 block_inst: Air.Inst.Index,
1191 /// Separate array list from break_inst_list so that it can be passed directly1191 /// Separate array list from break_inst_list so that it can be passed directly
1192 /// to resolvePeerTypes.1192 /// to resolvePeerTypes.
1193 results: ArrayListUnmanaged(*ir.Inst),1193 results: ArrayListUnmanaged(Air.Inst.Index),
1194 /// Keeps track of the break instructions so that the operand can be replaced1194 /// Keeps track of the break instructions so that the operand can be replaced
1195 /// if we need to add type coercion at the end of block analysis.1195 /// if we need to add type coercion at the end of block analysis.
1196 /// Same indexes, capacity, length as `results`.1196 /// Same indexes, capacity, length as `results`.
1197 br_list: ArrayListUnmanaged(*ir.Inst.Br),1197 br_list: ArrayListUnmanaged(Air.Inst.Index),
1198 };1198 };
11991199
1200 /// For debugging purposes.1200 /// For debugging purposes.
...@@ -1230,187 +1230,6 @@ pub const Scope = struct {...@@ -1230,187 +1230,6 @@ pub const Scope = struct {
1230 pub fn getFileScope(block: *Block) *Scope.File {1230 pub fn getFileScope(block: *Block) *Scope.File {
1231 return block.src_decl.namespace.file_scope;1231 return block.src_decl.namespace.file_scope;
1232 }1232 }
1233
1234 pub fn addNoOp(
1235 block: *Scope.Block,
1236 src: LazySrcLoc,
1237 ty: Type,
1238 comptime tag: ir.Inst.Tag,
1239 ) !*ir.Inst {
1240 const inst = try block.sema.arena.create(tag.Type());
1241 inst.* = .{
1242 .base = .{
1243 .tag = tag,
1244 .ty = ty,
1245 .src = src,
1246 },
1247 };
1248 try block.instructions.append(block.sema.gpa, &inst.base);
1249 return &inst.base;
1250 }
1251
1252 pub fn addUnOp(
1253 block: *Scope.Block,
1254 src: LazySrcLoc,
1255 ty: Type,
1256 tag: ir.Inst.Tag,
1257 operand: *ir.Inst,
1258 ) !*ir.Inst {
1259 const inst = try block.sema.arena.create(ir.Inst.UnOp);
1260 inst.* = .{
1261 .base = .{
1262 .tag = tag,
1263 .ty = ty,
1264 .src = src,
1265 },
1266 .operand = operand,
1267 };
1268 try block.instructions.append(block.sema.gpa, &inst.base);
1269 return &inst.base;
1270 }
1271
1272 pub fn addBinOp(
1273 block: *Scope.Block,
1274 src: LazySrcLoc,
1275 ty: Type,
1276 tag: ir.Inst.Tag,
1277 lhs: *ir.Inst,
1278 rhs: *ir.Inst,
1279 ) !*ir.Inst {
1280 const inst = try block.sema.arena.create(ir.Inst.BinOp);
1281 inst.* = .{
1282 .base = .{
1283 .tag = tag,
1284 .ty = ty,
1285 .src = src,
1286 },
1287 .lhs = lhs,
1288 .rhs = rhs,
1289 };
1290 try block.instructions.append(block.sema.gpa, &inst.base);
1291 return &inst.base;
1292 }
1293
1294 pub fn addBr(
1295 scope_block: *Scope.Block,
1296 src: LazySrcLoc,
1297 target_block: *ir.Inst.Block,
1298 operand: *ir.Inst,
1299 ) !*ir.Inst.Br {
1300 const inst = try scope_block.sema.arena.create(ir.Inst.Br);
1301 inst.* = .{
1302 .base = .{
1303 .tag = .br,
1304 .ty = Type.initTag(.noreturn),
1305 .src = src,
1306 },
1307 .operand = operand,
1308 .block = target_block,
1309 };
1310 try scope_block.instructions.append(scope_block.sema.gpa, &inst.base);
1311 return inst;
1312 }
1313
1314 pub fn addCondBr(
1315 block: *Scope.Block,
1316 src: LazySrcLoc,
1317 condition: *ir.Inst,
1318 then_body: ir.Body,
1319 else_body: ir.Body,
1320 ) !*ir.Inst {
1321 const inst = try block.sema.arena.create(ir.Inst.CondBr);
1322 inst.* = .{
1323 .base = .{
1324 .tag = .condbr,
1325 .ty = Type.initTag(.noreturn),
1326 .src = src,
1327 },
1328 .condition = condition,
1329 .then_body = then_body,
1330 .else_body = else_body,
1331 };
1332 try block.instructions.append(block.sema.gpa, &inst.base);
1333 return &inst.base;
1334 }
1335
1336 pub fn addCall(
1337 block: *Scope.Block,
1338 src: LazySrcLoc,
1339 ty: Type,
1340 func: *ir.Inst,
1341 args: []const *ir.Inst,
1342 ) !*ir.Inst {
1343 const inst = try block.sema.arena.create(ir.Inst.Call);
1344 inst.* = .{
1345 .base = .{
1346 .tag = .call,
1347 .ty = ty,
1348 .src = src,
1349 },
1350 .func = func,
1351 .args = args,
1352 };
1353 try block.instructions.append(block.sema.gpa, &inst.base);
1354 return &inst.base;
1355 }
1356
1357 pub fn addSwitchBr(
1358 block: *Scope.Block,
1359 src: LazySrcLoc,
1360 operand: *ir.Inst,
1361 cases: []ir.Inst.SwitchBr.Case,
1362 else_body: ir.Body,
1363 ) !*ir.Inst {
1364 const inst = try block.sema.arena.create(ir.Inst.SwitchBr);
1365 inst.* = .{
1366 .base = .{
1367 .tag = .switchbr,
1368 .ty = Type.initTag(.noreturn),
1369 .src = src,
1370 },
1371 .target = operand,
1372 .cases = cases,
1373 .else_body = else_body,
1374 };
1375 try block.instructions.append(block.sema.gpa, &inst.base);
1376 return &inst.base;
1377 }
1378
1379 pub fn addDbgStmt(block: *Scope.Block, src: LazySrcLoc, line: u32, column: u32) !*ir.Inst {
1380 const inst = try block.sema.arena.create(ir.Inst.DbgStmt);
1381 inst.* = .{
1382 .base = .{
1383 .tag = .dbg_stmt,
1384 .ty = Type.initTag(.void),
1385 .src = src,
1386 },
1387 .line = line,
1388 .column = column,
1389 };
1390 try block.instructions.append(block.sema.gpa, &inst.base);
1391 return &inst.base;
1392 }
1393
1394 pub fn addStructFieldPtr(
1395 block: *Scope.Block,
1396 src: LazySrcLoc,
1397 ty: Type,
1398 struct_ptr: *ir.Inst,
1399 field_index: u32,
1400 ) !*ir.Inst {
1401 const inst = try block.sema.arena.create(ir.Inst.StructFieldPtr);
1402 inst.* = .{
1403 .base = .{
1404 .tag = .struct_field_ptr,
1405 .ty = ty,
1406 .src = src,
1407 },
1408 .struct_ptr = struct_ptr,
1409 .field_index = field_index,
1410 };
1411 try block.instructions.append(block.sema.gpa, &inst.base);
1412 return &inst.base;
1413 }
1414 };1233 };
1415};1234};
14161235
...@@ -3594,30 +3413,14 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !Air {...@@ -3594,30 +3413,14 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !Air {
3594 defer decl.value_arena.?.* = arena.state;3413 defer decl.value_arena.?.* = arena.state;
35953414
3596 const fn_ty = decl.ty;3415 const fn_ty = decl.ty;
3597 const param_inst_list = try gpa.alloc(*ir.Inst, fn_ty.fnParamLen());3416 const param_inst_list = try gpa.alloc(Air.Inst.Index, fn_ty.fnParamLen());
3598 defer gpa.free(param_inst_list);3417 defer gpa.free(param_inst_list);
35993418
3600 for (param_inst_list) |*param_inst, param_index| {
3601 const param_type = fn_ty.fnParamType(param_index);
3602 const arg_inst = try arena.allocator.create(ir.Inst.Arg);
3603 arg_inst.* = .{
3604 .base = .{
3605 .tag = .arg,
3606 .ty = param_type,
3607 .src = .unneeded,
3608 },
3609 .name = undefined, // Set in the semantic analysis of the arg instruction.
3610 };
3611 param_inst.* = &arg_inst.base;
3612 }
3613
3614 const zir = decl.namespace.file_scope.zir;
3615
3616 var sema: Sema = .{3419 var sema: Sema = .{
3617 .mod = mod,3420 .mod = mod,
3618 .gpa = gpa,3421 .gpa = gpa,
3619 .arena = &arena.allocator,3422 .arena = &arena.allocator,
3620 .code = zir,3423 .code = decl.namespace.file_scope.zir,
3621 .owner_decl = decl,3424 .owner_decl = decl,
3622 .namespace = decl.namespace,3425 .namespace = decl.namespace,
3623 .func = func,3426 .func = func,
...@@ -3641,7 +3444,21 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !Air {...@@ -3641,7 +3444,21 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !Air {
3641 };3444 };
3642 defer inner_block.instructions.deinit(gpa);3445 defer inner_block.instructions.deinit(gpa);
36433446
3644 // AIR currently requires the arg parameters to be the first N instructions3447 // AIR requires the arg parameters to be the first N instructions.
3448 for (param_inst_list) |*param_inst, param_index| {
3449 const param_type = fn_ty.fnParamType(param_index);
3450 const ty_ref = try sema.addType(param_type);
3451 param_inst.* = @intCast(u32, sema.air_instructions.len);
3452 try sema.air_instructions.append(gpa, .{
3453 .tag = .arg,
3454 .data = .{
3455 .ty_str = .{
3456 .ty = ty_ref,
3457 .str = undefined, // Set in the semantic analysis of the arg instruction.
3458 },
3459 },
3460 });
3461 }
3645 try inner_block.instructions.appendSlice(gpa, param_inst_list);3462 try inner_block.instructions.appendSlice(gpa, param_inst_list);
36463463
3647 func.state = .in_progress;3464 func.state = .in_progress;
...@@ -3650,17 +3467,21 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !Air {...@@ -3650,17 +3467,21 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !Air {
3650 try sema.analyzeFnBody(&inner_block, func.zir_body_inst);3467 try sema.analyzeFnBody(&inner_block, func.zir_body_inst);
36513468
3652 // Copy the block into place and mark that as the main block.3469 // Copy the block into place and mark that as the main block.
3653 sema.air_extra.items[@enumToInt(Air.ExtraIndex.main_block)] = sema.air_extra.items.len;3470 try sema.air_extra.ensureUnusedCapacity(gpa, inner_block.instructions.items.len + 1);
3654 try sema.air_extra.appendSlice(inner_block.instructions.items);3471 const main_block_index = sema.addExtraAssumeCapacity(Air.Block{
3472 .body_len = @intCast(u32, inner_block.instructions.items.len),
3473 });
3474 sema.air_extra.appendSliceAssumeCapacity(inner_block.instructions.items);
3475 sema.air_extra.items[@enumToInt(Air.ExtraIndex.main_block)] = main_block_index;
36553476
3656 func.state = .success;3477 func.state = .success;
3657 log.debug("set {s} to success", .{decl.name});3478 log.debug("set {s} to success", .{decl.name});
36583479
3659 return Air{3480 return Air{
3660 .instructions = sema.air_instructions.toOwnedSlice(),3481 .instructions = sema.air_instructions.toOwnedSlice(),
3661 .extra = sema.air_extra.toOwnedSlice(),3482 .extra = sema.air_extra.toOwnedSlice(gpa),
3662 .values = sema.air_values.toOwnedSlice(),3483 .values = sema.air_values.toOwnedSlice(gpa),
3663 .variables = sema.air_variables.toOwnedSlice(),3484 .variables = sema.air_variables.toOwnedSlice(gpa),
3664 };3485 };
3665}3486}
36663487
...@@ -3815,94 +3636,6 @@ pub fn analyzeExport(...@@ -3815,94 +3636,6 @@ pub fn analyzeExport(
3815 de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export;3636 de_gop.value_ptr.*[de_gop.value_ptr.len - 1] = new_export;
3816 errdefer de_gop.value_ptr.* = mod.gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);3637 errdefer de_gop.value_ptr.* = mod.gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);
3817}3638}
3818pub fn constInst(mod: *Module, arena: *Allocator, src: LazySrcLoc, typed_value: TypedValue) !*ir.Inst {
3819 _ = mod;
3820 const const_inst = try arena.create(ir.Inst.Constant);
3821 const_inst.* = .{
3822 .base = .{
3823 .tag = ir.Inst.Constant.base_tag,
3824 .ty = typed_value.ty,
3825 .src = src,
3826 },
3827 .val = typed_value.val,
3828 };
3829 return &const_inst.base;
3830}
3831
3832pub fn constType(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
3833 return mod.constInst(arena, src, .{
3834 .ty = Type.initTag(.type),
3835 .val = try ty.toValue(arena),
3836 });
3837}
3838
3839pub fn constVoid(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
3840 return mod.constInst(arena, src, .{
3841 .ty = Type.initTag(.void),
3842 .val = Value.initTag(.void_value),
3843 });
3844}
3845
3846pub fn constNoReturn(mod: *Module, arena: *Allocator, src: LazySrcLoc) !*ir.Inst {
3847 return mod.constInst(arena, src, .{
3848 .ty = Type.initTag(.noreturn),
3849 .val = Value.initTag(.unreachable_value),
3850 });
3851}
3852
3853pub fn constUndef(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type) !*ir.Inst {
3854 return mod.constInst(arena, src, .{
3855 .ty = ty,
3856 .val = Value.initTag(.undef),
3857 });
3858}
3859
3860pub fn constBool(mod: *Module, arena: *Allocator, src: LazySrcLoc, v: bool) !*ir.Inst {
3861 return mod.constInst(arena, src, .{
3862 .ty = Type.initTag(.bool),
3863 .val = ([2]Value{ Value.initTag(.bool_false), Value.initTag(.bool_true) })[@boolToInt(v)],
3864 });
3865}
3866
3867pub fn constIntUnsigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: u64) !*ir.Inst {
3868 return mod.constInst(arena, src, .{
3869 .ty = ty,
3870 .val = try Value.Tag.int_u64.create(arena, int),
3871 });
3872}
3873
3874pub fn constIntSigned(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, int: i64) !*ir.Inst {
3875 return mod.constInst(arena, src, .{
3876 .ty = ty,
3877 .val = try Value.Tag.int_i64.create(arena, int),
3878 });
3879}
3880
3881pub fn constIntBig(mod: *Module, arena: *Allocator, src: LazySrcLoc, ty: Type, big_int: BigIntConst) !*ir.Inst {
3882 if (big_int.positive) {
3883 if (big_int.to(u64)) |x| {
3884 return mod.constIntUnsigned(arena, src, ty, x);
3885 } else |err| switch (err) {
3886 error.NegativeIntoUnsigned => unreachable,
3887 error.TargetTooSmall => {}, // handled below
3888 }
3889 return mod.constInst(arena, src, .{
3890 .ty = ty,
3891 .val = try Value.Tag.int_big_positive.create(arena, big_int.limbs),
3892 });
3893 } else {
3894 if (big_int.to(i64)) |x| {
3895 return mod.constIntSigned(arena, src, ty, x);
3896 } else |err| switch (err) {
3897 error.NegativeIntoUnsigned => unreachable,
3898 error.TargetTooSmall => {}, // handled below
3899 }
3900 return mod.constInst(arena, src, .{
3901 .ty = ty,
3902 .val = try Value.Tag.int_big_negative.create(arena, big_int.limbs),
3903 });
3904 }
3905}
39063639
3907pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void {3640pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void {
3908 const scope_decl = scope.ownerDecl().?;3641 const scope_decl = scope.ownerDecl().?;
...@@ -4438,38 +4171,6 @@ pub fn errorUnionType(...@@ -4438,38 +4171,6 @@ pub fn errorUnionType(
4438 });4171 });
4439}4172}
44404173
4441pub fn dumpInst(mod: *Module, scope: *Scope, inst: *ir.Inst) void {
4442 const zir_module = scope.namespace();
4443 const source = zir_module.getSource(mod) catch @panic("dumpInst failed to get source");
4444 const loc = std.zig.findLineColumn(source, inst.src);
4445 if (inst.tag == .constant) {
4446 std.debug.print("constant ty={} val={} src={s}:{d}:{d}\n", .{
4447 inst.ty,
4448 inst.castTag(.constant).?.val,
4449 zir_module.subFilePath(),
4450 loc.line + 1,
4451 loc.column + 1,
4452 });
4453 } else if (inst.deaths == 0) {
4454 std.debug.print("{s} ty={} src={s}:{d}:{d}\n", .{
4455 @tagName(inst.tag),
4456 inst.ty,
4457 zir_module.subFilePath(),
4458 loc.line + 1,
4459 loc.column + 1,
4460 });
4461 } else {
4462 std.debug.print("{s} ty={} deaths={b} src={s}:{d}:{d}\n", .{
4463 @tagName(inst.tag),
4464 inst.ty,
4465 inst.deaths,
4466 zir_module.subFilePath(),
4467 loc.line + 1,
4468 loc.column + 1,
4469 });
4470 }
4471}
4472
4473pub fn getTarget(mod: Module) Target {4174pub fn getTarget(mod: Module) Target {
4474 return mod.comp.bin_file.options.target;4175 return mod.comp.bin_file.options.target;
4475}4176}
src/Sema.zig+107-7
...@@ -12,9 +12,9 @@ gpa: *Allocator,...@@ -12,9 +12,9 @@ gpa: *Allocator,
12arena: *Allocator,12arena: *Allocator,
13code: Zir,13code: Zir,
14air_instructions: std.MultiArrayList(Air.Inst) = .{},14air_instructions: std.MultiArrayList(Air.Inst) = .{},
15air_extra: ArrayListUnmanaged(u32) = .{},15air_extra: std.ArrayListUnmanaged(u32) = .{},
16air_values: ArrayListUnmanaged(Value) = .{},16air_values: std.ArrayListUnmanaged(Value) = .{},
17air_variables: ArrayListUnmanaged(Module.Var) = .{},17air_variables: std.ArrayListUnmanaged(*Module.Var) = .{},
18/// Maps ZIR to AIR.18/// Maps ZIR to AIR.
19inst_map: InstMap = .{},19inst_map: InstMap = .{},
20/// When analyzing an inline function call, owner_decl is the Decl of the caller20/// When analyzing an inline function call, owner_decl is the Decl of the caller
...@@ -1263,15 +1263,16 @@ fn zirArg(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air...@@ -1263,15 +1263,16 @@ fn zirArg(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!Air
1263 sema.next_arg_index += 1;1263 sema.next_arg_index += 1;
12641264
1265 // TODO check if arg_name shadows a Decl1265 // TODO check if arg_name shadows a Decl
1266 _ = arg_name;
12661267
1267 if (block.inlining) |_| {1268 if (block.inlining) |_| {
1268 return sema.param_inst_list[arg_index];1269 return sema.param_inst_list[arg_index];
1269 }1270 }
12701271
1271 // Need to set the name of the Air.Arg instruction.1272 // Set the name of the Air.Arg instruction for use by codegen debug info.
1272 const air_arg = sema.param_inst_list[arg_index].castTag(.arg).?;1273 const air_arg = sema.param_inst_list[arg_index];
1273 air_arg.name = arg_name;1274 sema.air.instructions.items(.data)[air_arg].ty_str.str = inst_data.start;
1274 return &air_arg.base;1275 return air_arg;
1275}1276}
12761277
1277fn zirAllocExtended(1278fn zirAllocExtended(
...@@ -7940,3 +7941,102 @@ fn enumFieldSrcLoc(...@@ -7940,3 +7941,102 @@ fn enumFieldSrcLoc(
7940 }7941 }
7941 } else unreachable;7942 } else unreachable;
7942}7943}
7944
7945pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref {
7946 switch (ty.tag()) {
7947 .u8 => return .u8_type,
7948 .i8 => return .i8_type,
7949 .u16 => return .u16_type,
7950 .i16 => return .i16_type,
7951 .u32 => return .u32_type,
7952 .i32 => return .i32_type,
7953 .u64 => return .u64_type,
7954 .i64 => return .i64_type,
7955 .u128 => return .u128_type,
7956 .i128 => return .i128_type,
7957 .usize => return .usize_type,
7958 .isize => return .isize_type,
7959 .c_short => return .c_short_type,
7960 .c_ushort => return .c_ushort_type,
7961 .c_int => return .c_int_type,
7962 .c_uint => return .c_uint_type,
7963 .c_long => return .c_long_type,
7964 .c_ulong => return .c_ulong_type,
7965 .c_longlong => return .c_longlong_type,
7966 .c_ulonglong => return .c_ulonglong_type,
7967 .c_longdouble => return .c_longdouble_type,
7968 .f16 => return .f16_type,
7969 .f32 => return .f32_type,
7970 .f64 => return .f64_type,
7971 .f128 => return .f128_type,
7972 .c_void => return .c_void_type,
7973 .bool => return .bool_type,
7974 .void => return .void_type,
7975 .type => return .type_type,
7976 .anyerror => return .anyerror_type,
7977 .comptime_int => return .comptime_int_type,
7978 .comptime_float => return .comptime_float_type,
7979 .noreturn => return .noreturn_type,
7980 .@"anyframe" => return .anyframe_type,
7981 .@"null" => return .null_type,
7982 .@"undefined" => return .undefined_type,
7983 .enum_literal => return .enum_literal_type,
7984 .atomic_ordering => return .atomic_ordering_type,
7985 .atomic_rmw_op => return .atomic_rmw_op_type,
7986 .calling_convention => return .calling_convention_type,
7987 .float_mode => return .float_mode_type,
7988 .reduce_op => return .reduce_op_type,
7989 .call_options => return .call_options_type,
7990 .export_options => return .export_options_type,
7991 .extern_options => return .extern_options_type,
7992 .manyptr_u8 => return .manyptr_u8_type,
7993 .manyptr_const_u8 => return .manyptr_const_u8_type,
7994 .fn_noreturn_no_args => return .fn_noreturn_no_args_type,
7995 .fn_void_no_args => return .fn_void_no_args_type,
7996 .fn_naked_noreturn_no_args => return .fn_naked_noreturn_no_args_type,
7997 .fn_ccc_void_no_args => return .fn_ccc_void_no_args_type,
7998 .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type,
7999 .const_slice_u8 => return .const_slice_u8_type,
8000 else => {},
8001 }
8002 try sema.air_instructions.append(sema.gpa, .{
8003 .tag = .const_ty,
8004 .data = .{ .ty = ty },
8005 });
8006 return indexToRef(@intCast(u32, sema.air_instructions.len - 1));
8007}
8008
8009const ref_start_index: u32 = Air.Inst.Ref.typed_value_map.len;
8010
8011fn indexToRef(inst: Air.Inst.Index) Air.Inst.Ref {
8012 return @intToEnum(Air.Inst.Ref, ref_start_index + inst);
8013}
8014
8015fn refToIndex(inst: Air.Inst.Ref) ?Air.Inst.Index {
8016 const ref_int = @enumToInt(inst);
8017 if (ref_int >= ref_start_index) {
8018 return ref_int - ref_start_index;
8019 } else {
8020 return null;
8021 }
8022}
8023
8024pub fn addExtra(sema: *Sema, extra: anytype) Allocator.Error!u32 {
8025 const fields = std.meta.fields(@TypeOf(extra));
8026 try sema.air_extra.ensureUnusedCapacity(sema.gpa, fields.len);
8027 return addExtraAssumeCapacity(sema, extra);
8028}
8029
8030pub fn addExtraAssumeCapacity(sema: *Sema, extra: anytype) u32 {
8031 const fields = std.meta.fields(@TypeOf(extra));
8032 const result = @intCast(u32, sema.air_extra.items.len);
8033 inline for (fields) |field| {
8034 sema.air_extra.appendAssumeCapacity(switch (field.field_type) {
8035 u32 => @field(extra, field.name),
8036 Air.Inst.Ref => @enumToInt(@field(extra, field.name)),
8037 i32 => @bitCast(u32, @field(extra, field.name)),
8038 else => @compileError("bad field type"),
8039 });
8040 }
8041 return result;
8042}
src/codegen.zig+110-86
...@@ -3,6 +3,7 @@ const mem = std.mem;...@@ -3,6 +3,7 @@ const mem = std.mem;
3const math = std.math;3const math = std.math;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const Air = @import("Air.zig");5const Air = @import("Air.zig");
6const Liveness = @import("Liveness.zig");
6const Type = @import("type.zig").Type;7const Type = @import("type.zig").Type;
7const Value = @import("value.zig").Value;8const Value = @import("value.zig").Value;
8const TypedValue = @import("TypedValue.zig");9const TypedValue = @import("TypedValue.zig");
...@@ -45,6 +46,71 @@ pub const DebugInfoOutput = union(enum) {...@@ -45,6 +46,71 @@ pub const DebugInfoOutput = union(enum) {
45 none,46 none,
46};47};
4748
49pub fn generateFunction(
50 bin_file: *link.File,
51 src_loc: Module.SrcLoc,
52 func: *Module.Fn,
53 air: Air,
54 liveness: Liveness,
55 code: *std.ArrayList(u8),
56 debug_output: DebugInfoOutput,
57) GenerateSymbolError!Result {
58 switch (bin_file.options.target.cpu.arch) {
59 .wasm32 => unreachable, // has its own code path
60 .wasm64 => unreachable, // has its own code path
61 .arm => return Function(.arm).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
62 .armeb => return Function(.armeb).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
63 .aarch64 => return Function(.aarch64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
64 .aarch64_be => return Function(.aarch64_be).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
65 .aarch64_32 => return Function(.aarch64_32).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
66 //.arc => return Function(.arc).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
67 //.avr => return Function(.avr).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
68 //.bpfel => return Function(.bpfel).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
69 //.bpfeb => return Function(.bpfeb).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
70 //.hexagon => return Function(.hexagon).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
71 //.mips => return Function(.mips).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
72 //.mipsel => return Function(.mipsel).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
73 //.mips64 => return Function(.mips64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
74 //.mips64el => return Function(.mips64el).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
75 //.msp430 => return Function(.msp430).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
76 //.powerpc => return Function(.powerpc).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
77 //.powerpc64 => return Function(.powerpc64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
78 //.powerpc64le => return Function(.powerpc64le).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
79 //.r600 => return Function(.r600).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
80 //.amdgcn => return Function(.amdgcn).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
81 //.riscv32 => return Function(.riscv32).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
82 .riscv64 => return Function(.riscv64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
83 //.sparc => return Function(.sparc).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
84 //.sparcv9 => return Function(.sparcv9).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
85 //.sparcel => return Function(.sparcel).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
86 //.s390x => return Function(.s390x).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
87 //.tce => return Function(.tce).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
88 //.tcele => return Function(.tcele).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
89 //.thumb => return Function(.thumb).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
90 //.thumbeb => return Function(.thumbeb).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
91 //.i386 => return Function(.i386).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
92 .x86_64 => return Function(.x86_64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
93 //.xcore => return Function(.xcore).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
94 //.nvptx => return Function(.nvptx).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
95 //.nvptx64 => return Function(.nvptx64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
96 //.le32 => return Function(.le32).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
97 //.le64 => return Function(.le64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
98 //.amdil => return Function(.amdil).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
99 //.amdil64 => return Function(.amdil64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
100 //.hsail => return Function(.hsail).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
101 //.hsail64 => return Function(.hsail64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
102 //.spir => return Function(.spir).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
103 //.spir64 => return Function(.spir64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
104 //.kalimba => return Function(.kalimba).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
105 //.shave => return Function(.shave).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
106 //.lanai => return Function(.lanai).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
107 //.renderscript32 => return Function(.renderscript32).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
108 //.renderscript64 => return Function(.renderscript64).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
109 //.ve => return Function(.ve).generate(bin_file, src_loc, func, air, liveness, code, debug_output),
110 else => @panic("Backend architectures that don't have good support yet are commented out, to improve compilation performance. If you are interested in one of these other backends feel free to uncomment them. Eventually these will be completed, but stage1 is slow and a memory hog."),
111 }
112}
113
48pub fn generateSymbol(114pub fn generateSymbol(
49 bin_file: *link.File,115 bin_file: *link.File,
50 src_loc: Module.SrcLoc,116 src_loc: Module.SrcLoc,
...@@ -57,60 +123,14 @@ pub fn generateSymbol(...@@ -57,60 +123,14 @@ pub fn generateSymbol(
57123
58 switch (typed_value.ty.zigTypeTag()) {124 switch (typed_value.ty.zigTypeTag()) {
59 .Fn => {125 .Fn => {
60 switch (bin_file.options.target.cpu.arch) {126 return Result{
61 .wasm32 => unreachable, // has its own code path127 .fail = try ErrorMsg.create(
62 .wasm64 => unreachable, // has its own code path128 bin_file.allocator,
63 .arm => return Function(.arm).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),129 src_loc,
64 .armeb => return Function(.armeb).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),130 "TODO implement generateSymbol function pointers",
65 .aarch64 => return Function(.aarch64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),131 .{},
66 .aarch64_be => return Function(.aarch64_be).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),132 ),
67 .aarch64_32 => return Function(.aarch64_32).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),133 };
68 //.arc => return Function(.arc).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
69 //.avr => return Function(.avr).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
70 //.bpfel => return Function(.bpfel).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
71 //.bpfeb => return Function(.bpfeb).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
72 //.hexagon => return Function(.hexagon).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
73 //.mips => return Function(.mips).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
74 //.mipsel => return Function(.mipsel).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
75 //.mips64 => return Function(.mips64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
76 //.mips64el => return Function(.mips64el).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
77 //.msp430 => return Function(.msp430).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
78 //.powerpc => return Function(.powerpc).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
79 //.powerpc64 => return Function(.powerpc64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
80 //.powerpc64le => return Function(.powerpc64le).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
81 //.r600 => return Function(.r600).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
82 //.amdgcn => return Function(.amdgcn).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
83 //.riscv32 => return Function(.riscv32).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
84 .riscv64 => return Function(.riscv64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
85 //.sparc => return Function(.sparc).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
86 //.sparcv9 => return Function(.sparcv9).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
87 //.sparcel => return Function(.sparcel).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
88 //.s390x => return Function(.s390x).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
89 //.tce => return Function(.tce).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
90 //.tcele => return Function(.tcele).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
91 //.thumb => return Function(.thumb).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
92 //.thumbeb => return Function(.thumbeb).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
93 //.i386 => return Function(.i386).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
94 .x86_64 => return Function(.x86_64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
95 //.xcore => return Function(.xcore).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
96 //.nvptx => return Function(.nvptx).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
97 //.nvptx64 => return Function(.nvptx64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
98 //.le32 => return Function(.le32).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
99 //.le64 => return Function(.le64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
100 //.amdil => return Function(.amdil).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
101 //.amdil64 => return Function(.amdil64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
102 //.hsail => return Function(.hsail).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
103 //.hsail64 => return Function(.hsail64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
104 //.spir => return Function(.spir).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
105 //.spir64 => return Function(.spir64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
106 //.kalimba => return Function(.kalimba).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
107 //.shave => return Function(.shave).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
108 //.lanai => return Function(.lanai).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
109 //.renderscript32 => return Function(.renderscript32).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
110 //.renderscript64 => return Function(.renderscript64).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
111 //.ve => return Function(.ve).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
112 else => @panic("Backend architectures that don't have good support yet are commented out, to improve compilation performance. If you are interested in one of these other backends feel free to uncomment them. Eventually these will be completed, but stage1 is slow and a memory hog."),
113 }
114 },134 },
115 .Array => {135 .Array => {
116 // TODO populate .debug_info for the array136 // TODO populate .debug_info for the array
...@@ -262,6 +282,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -262,6 +282,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
262282
263 return struct {283 return struct {
264 gpa: *Allocator,284 gpa: *Allocator,
285 air: *const Air,
265 bin_file: *link.File,286 bin_file: *link.File,
266 target: *const std.Target,287 target: *const std.Target,
267 mod_fn: *const Module.Fn,288 mod_fn: *const Module.Fn,
...@@ -421,10 +442,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -421,10 +442,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
421442
422 const Self = @This();443 const Self = @This();
423444
424 fn generateSymbol(445 fn generate(
425 bin_file: *link.File,446 bin_file: *link.File,
426 src_loc: Module.SrcLoc,447 src_loc: Module.SrcLoc,
427 typed_value: TypedValue,448 module_fn: *Module.Fn,
449 air: Air,
450 liveness: Liveness,
428 code: *std.ArrayList(u8),451 code: *std.ArrayList(u8),
429 debug_output: DebugInfoOutput,452 debug_output: DebugInfoOutput,
430 ) GenerateSymbolError!Result {453 ) GenerateSymbolError!Result {
...@@ -432,8 +455,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -432,8 +455,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
432 @panic("Attempted to compile for architecture that was disabled by build configuration");455 @panic("Attempted to compile for architecture that was disabled by build configuration");
433 }456 }
434457
435 const module_fn = typed_value.val.castTag(.function).?.data;
436
437 assert(module_fn.owner_decl.has_tv);458 assert(module_fn.owner_decl.has_tv);
438 const fn_type = module_fn.owner_decl.ty;459 const fn_type = module_fn.owner_decl.ty;
439460
...@@ -447,6 +468,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -447,6 +468,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
447468
448 var function = Self{469 var function = Self{
449 .gpa = bin_file.allocator,470 .gpa = bin_file.allocator,
471 .air = &air,
472 .liveness = &liveness,
450 .target = &bin_file.options.target,473 .target = &bin_file.options.target,
451 .bin_file = bin_file,474 .bin_file = bin_file,
452 .mod_fn = module_fn,475 .mod_fn = module_fn,
...@@ -2131,8 +2154,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2131,8 +2154,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2131 }2154 }
21322155
2133 fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue) !void {2156 fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue) !void {
2134 const name_with_null = inst.name[0 .. mem.lenZ(inst.name) + 1];2157 const ty_str = self.air.instruction.items(.data)[inst].ty_str;
2135 const ty = self.air.getType(inst);2158 const zir = &self.mod_fn.owner_decl.namespace.file_scope.zir;
2159 const name = zir.nullTerminatedString(ty_str.str);
2160 const name_with_null = name.ptr[0 .. name.len + 1];
2161 const ty = self.air.getRefType(ty_str.ty);
21362162
2137 switch (mcv) {2163 switch (mcv) {
2138 .register => |reg| {2164 .register => |reg| {
...@@ -2249,8 +2275,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2249,8 +2275,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2249 }2275 }
22502276
2251 fn genCall(self: *Self, inst: Air.Inst.Index) !MCValue {2277 fn genCall(self: *Self, inst: Air.Inst.Index) !MCValue {
2252 const inst_datas = self.air.instructions.items(.data);2278 const pl_op = self.air.instruction.items(.data)[inst].pl_op;
2253 const pl_op = inst_datas[inst].pl_op;
2254 const fn_ty = self.air.getType(pl_op.operand);2279 const fn_ty = self.air.getType(pl_op.operand);
2255 const callee = pl_op.operand;2280 const callee = pl_op.operand;
2256 const extra = self.air.extraData(Air.Call, inst_data.payload);2281 const extra = self.air.extraData(Air.Call, inst_data.payload);
...@@ -2848,8 +2873,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2848,8 +2873,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2848 }2873 }
28492874
2850 fn genCondBr(self: *Self, inst: Air.Inst.Index) !MCValue {2875 fn genCondBr(self: *Self, inst: Air.Inst.Index) !MCValue {
2851 const inst_datas = self.air.instructions.items(.data);2876 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
2852 const pl_op = inst_datas[inst].pl_op;
2853 const cond = try self.resolveInst(pl_op.operand);2877 const cond = try self.resolveInst(pl_op.operand);
2854 const extra = self.air.extraData(Air.CondBr, inst_data.payload);2878 const extra = self.air.extraData(Air.CondBr, inst_data.payload);
2855 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];2879 const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len];
...@@ -3101,16 +3125,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3101,16 +3125,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3101 fn genIsNull(self: *Self, inst: Air.Inst.Index) !MCValue {3125 fn genIsNull(self: *Self, inst: Air.Inst.Index) !MCValue {
3102 if (self.liveness.isUnused(inst))3126 if (self.liveness.isUnused(inst))
3103 return MCValue.dead;3127 return MCValue.dead;
3104 const inst_datas = self.air.instructions.items(.data);3128 const un_op = self.air.instructions.items(.data)[inst].un_op;
3105 const operand = try self.resolveInst(inst_datas[inst].un_op);3129 const operand = try self.resolveInst(un_op);
3106 return self.isNull(operand);3130 return self.isNull(operand);
3107 }3131 }
31083132
3109 fn genIsNullPtr(self: *Self, inst: Air.Inst.Index) !MCValue {3133 fn genIsNullPtr(self: *Self, inst: Air.Inst.Index) !MCValue {
3110 if (self.liveness.isUnused(inst))3134 if (self.liveness.isUnused(inst))
3111 return MCValue.dead;3135 return MCValue.dead;
3112 const inst_datas = self.air.instructions.items(.data);3136 const un_op = self.air.instructions.items(.data)[inst].un_op;
3113 const operand_ptr = try self.resolveInst(inst_datas[inst].un_op);3137 const operand_ptr = try self.resolveInst(un_op);
3114 const operand: MCValue = blk: {3138 const operand: MCValue = blk: {
3115 if (self.reuseOperand(inst, 0, operand_ptr)) {3139 if (self.reuseOperand(inst, 0, operand_ptr)) {
3116 // The MCValue that holds the pointer can be re-used as the value.3140 // The MCValue that holds the pointer can be re-used as the value.
...@@ -3126,16 +3150,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3126,16 +3150,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3126 fn genIsNonNull(self: *Self, inst: Air.Inst.Index) !MCValue {3150 fn genIsNonNull(self: *Self, inst: Air.Inst.Index) !MCValue {
3127 if (self.liveness.isUnused(inst))3151 if (self.liveness.isUnused(inst))
3128 return MCValue.dead;3152 return MCValue.dead;
3129 const inst_datas = self.air.instructions.items(.data);3153 const un_op = self.air.instructions.items(.data)[inst].un_op;
3130 const operand = try self.resolveInst(inst_datas[inst].un_op);3154 const operand = try self.resolveInst(un_op);
3131 return self.isNonNull(operand);3155 return self.isNonNull(operand);
3132 }3156 }
31333157
3134 fn genIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !MCValue {3158 fn genIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !MCValue {
3135 if (self.liveness.isUnused(inst))3159 if (self.liveness.isUnused(inst))
3136 return MCValue.dead;3160 return MCValue.dead;
3137 const inst_datas = self.air.instructions.items(.data);3161 const un_op = self.air.instructions.items(.data)[inst].un_op;
3138 const operand_ptr = try self.resolveInst(inst_datas[inst].un_op);3162 const operand_ptr = try self.resolveInst(un_op);
3139 const operand: MCValue = blk: {3163 const operand: MCValue = blk: {
3140 if (self.reuseOperand(inst, 0, operand_ptr)) {3164 if (self.reuseOperand(inst, 0, operand_ptr)) {
3141 // The MCValue that holds the pointer can be re-used as the value.3165 // The MCValue that holds the pointer can be re-used as the value.
...@@ -3151,16 +3175,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3151,16 +3175,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3151 fn genIsErr(self: *Self, inst: Air.Inst.Index) !MCValue {3175 fn genIsErr(self: *Self, inst: Air.Inst.Index) !MCValue {
3152 if (self.liveness.isUnused(inst))3176 if (self.liveness.isUnused(inst))
3153 return MCValue.dead;3177 return MCValue.dead;
3154 const inst_datas = self.air.instructions.items(.data);3178 const un_op = self.air.instructions.items(.data)[inst].un_op;
3155 const operand = try self.resolveInst(inst_datas[inst].un_op);3179 const operand = try self.resolveInst(un_op);
3156 return self.isErr(operand);3180 return self.isErr(operand);
3157 }3181 }
31583182
3159 fn genIsErrPtr(self: *Self, inst: Air.Inst.Index) !MCValue {3183 fn genIsErrPtr(self: *Self, inst: Air.Inst.Index) !MCValue {
3160 if (self.liveness.isUnused(inst))3184 if (self.liveness.isUnused(inst))
3161 return MCValue.dead;3185 return MCValue.dead;
3162 const inst_datas = self.air.instructions.items(.data);3186 const un_op = self.air.instructions.items(.data)[inst].un_op;
3163 const operand_ptr = try self.resolveInst(inst_datas[inst].un_op);3187 const operand_ptr = try self.resolveInst(un_op);
3164 const operand: MCValue = blk: {3188 const operand: MCValue = blk: {
3165 if (self.reuseOperand(inst, 0, operand_ptr)) {3189 if (self.reuseOperand(inst, 0, operand_ptr)) {
3166 // The MCValue that holds the pointer can be re-used as the value.3190 // The MCValue that holds the pointer can be re-used as the value.
...@@ -3176,16 +3200,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3176,16 +3200,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3176 fn genIsNonErr(self: *Self, inst: Air.Inst.Index) !MCValue {3200 fn genIsNonErr(self: *Self, inst: Air.Inst.Index) !MCValue {
3177 if (self.liveness.isUnused(inst))3201 if (self.liveness.isUnused(inst))
3178 return MCValue.dead;3202 return MCValue.dead;
3179 const inst_datas = self.air.instructions.items(.data);3203 const un_op = self.air.instructions.items(.data)[inst].un_op;
3180 const operand = try self.resolveInst(inst_datas[inst].un_op);3204 const operand = try self.resolveInst(un_op);
3181 return self.isNonErr(operand);3205 return self.isNonErr(operand);
3182 }3206 }
31833207
3184 fn genIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !MCValue {3208 fn genIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !MCValue {
3185 if (self.liveness.isUnused(inst))3209 if (self.liveness.isUnused(inst))
3186 return MCValue.dead;3210 return MCValue.dead;
3187 const inst_datas = self.air.instructions.items(.data);3211 const un_op = self.air.instructions.items(.data)[inst].un_op;
3188 const operand_ptr = try self.resolveInst(inst_datas[inst].un_op);3212 const operand_ptr = try self.resolveInst(un_op);
3189 const operand: MCValue = blk: {3213 const operand: MCValue = blk: {
3190 if (self.reuseOperand(inst, 0, operand_ptr)) {3214 if (self.reuseOperand(inst, 0, operand_ptr)) {
3191 // The MCValue that holds the pointer can be re-used as the value.3215 // The MCValue that holds the pointer can be re-used as the value.
...@@ -3200,8 +3224,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3200,8 +3224,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
32003224
3201 fn genLoop(self: *Self, inst: Air.Inst.Index) !MCValue {3225 fn genLoop(self: *Self, inst: Air.Inst.Index) !MCValue {
3202 // A loop is a setup to be able to jump back to the beginning.3226 // A loop is a setup to be able to jump back to the beginning.
3203 const inst_datas = self.air.instructions.items(.data);3227 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
3204 const loop = self.air.extraData(Air.Block, inst_datas[inst].ty_pl.payload);3228 const loop = self.air.extraData(Air.Block, ty_pl.payload);
3205 const body = self.air.extra[loop.end..][0..loop.data.body_len];3229 const body = self.air.extra[loop.end..][0..loop.data.body_len];
3206 const start_index = self.code.items.len;3230 const start_index = self.code.items.len;
3207 try self.genBody(body);3231 try self.genBody(body);
...@@ -4377,13 +4401,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4377,13 +4401,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4377 }4401 }
43784402
4379 fn genPtrToInt(self: *Self, inst: Air.Inst.Index) !MCValue {4403 fn genPtrToInt(self: *Self, inst: Air.Inst.Index) !MCValue {
4380 const inst_datas = self.air.instructions.items(.data);4404 const un_op = self.air.instructions.items(.data)[inst].un_op;
4381 return self.resolveInst(inst_datas[inst].un_op);4405 return self.resolveInst(un_op);
4382 }4406 }
43834407
4384 fn genBitCast(self: *Self, inst: Air.Inst.Index) !MCValue {4408 fn genBitCast(self: *Self, inst: Air.Inst.Index) !MCValue {
4385 const inst_datas = self.air.instructions.items(.data);4409 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
4386 return self.resolveInst(inst_datas[inst].ty_op.operand);4410 return self.resolveInst(ty_op.operand);
4387 }4411 }
43884412
4389 fn resolveInst(self: *Self, inst: Air.Inst.Index) !MCValue {4413 fn resolveInst(self: *Self, inst: Air.Inst.Index) !MCValue {
src/codegen/spirv.zig+35-22
...@@ -159,7 +159,10 @@ pub const DeclGen = struct {...@@ -159,7 +159,10 @@ pub const DeclGen = struct {
159 /// The SPIR-V module code should be put in.159 /// The SPIR-V module code should be put in.
160 spv: *SPIRVModule,160 spv: *SPIRVModule,
161161
162 /// An array of function argument result-ids. Each index corresponds with the function argument of the same index.162 air: *const Air,
163
164 /// An array of function argument result-ids. Each index corresponds with the
165 /// function argument of the same index.
163 args: std.ArrayList(ResultId),166 args: std.ArrayList(ResultId),
164167
165 /// A counter to keep track of how many `arg` instructions we've seen yet.168 /// A counter to keep track of how many `arg` instructions we've seen yet.
...@@ -168,33 +171,35 @@ pub const DeclGen = struct {...@@ -168,33 +171,35 @@ pub const DeclGen = struct {
168 /// A map keeping track of which instruction generated which result-id.171 /// A map keeping track of which instruction generated which result-id.
169 inst_results: InstMap,172 inst_results: InstMap,
170173
171 /// We need to keep track of result ids for block labels, as well as the 'incoming' blocks for a block.174 /// We need to keep track of result ids for block labels, as well as the 'incoming'
175 /// blocks for a block.
172 blocks: BlockMap,176 blocks: BlockMap,
173177
174 /// The label of the SPIR-V block we are currently generating.178 /// The label of the SPIR-V block we are currently generating.
175 current_block_label_id: ResultId,179 current_block_label_id: ResultId,
176180
177 /// The actual instructions for this function. We need to declare all locals in the first block, and because we don't181 /// The actual instructions for this function. We need to declare all locals in
178 /// know which locals there are going to be, we're just going to generate everything after the locals-section in this array.182 /// the first block, and because we don't know which locals there are going to be,
179 /// Note: It will not contain OpFunction, OpFunctionParameter, OpVariable and the initial OpLabel. These will be generated183 /// we're just going to generate everything after the locals-section in this array.
180 /// into spv.binary.fn_decls directly.184 /// Note: It will not contain OpFunction, OpFunctionParameter, OpVariable and the
185 /// initial OpLabel. These will be generated into spv.binary.fn_decls directly.
181 code: std.ArrayList(Word),186 code: std.ArrayList(Word),
182187
183 /// The decl we are currently generating code for.188 /// The decl we are currently generating code for.
184 decl: *Decl,189 decl: *Decl,
185190
186 /// If `gen` returned `Error.AnalysisFail`, this contains an explanatory message. Memory is owned by191 /// If `gen` returned `Error.AnalysisFail`, this contains an explanatory message.
187 /// `module.gpa`.192 /// Memory is owned by `module.gpa`.
188 error_msg: ?*Module.ErrorMsg,193 error_msg: ?*Module.ErrorMsg,
189194
190 /// Possible errors the `gen` function may return.195 /// Possible errors the `gen` function may return.
191 const Error = error{ AnalysisFail, OutOfMemory };196 const Error = error{ AnalysisFail, OutOfMemory };
192197
193 /// This structure is used to return information about a type typically used for arithmetic operations.198 /// This structure is used to return information about a type typically used for
194 /// These types may either be integers, floats, or a vector of these. Most scalar operations also work on vectors,199 /// arithmetic operations. These types may either be integers, floats, or a vector
195 /// so we can easily represent those as arithmetic types.200 /// of these. Most scalar operations also work on vectors, so we can easily represent
196 /// If the type is a scalar, 'inner type' refers to the scalar type. Otherwise, if its a vector, it refers201 /// those as arithmetic types. If the type is a scalar, 'inner type' refers to the
197 /// to the vector's element type.202 /// scalar type. Otherwise, if its a vector, it refers to the vector's element type.
198 const ArithmeticTypeInfo = struct {203 const ArithmeticTypeInfo = struct {
199 /// A classification of the inner type.204 /// A classification of the inner type.
200 const Class = enum {205 const Class = enum {
...@@ -206,13 +211,14 @@ pub const DeclGen = struct {...@@ -206,13 +211,14 @@ pub const DeclGen = struct {
206 /// the relevant capability is enabled).211 /// the relevant capability is enabled).
207 integer,212 integer,
208213
209 /// A regular float. These are all required to be natively supported. Floating points for214 /// A regular float. These are all required to be natively supported. Floating points
210 /// which the relevant capability is not enabled are not emulated.215 /// for which the relevant capability is not enabled are not emulated.
211 float,216 float,
212217
213 /// An integer of a 'strange' size (which' bit size is not the same as its backing type. **Note**: this218 /// An integer of a 'strange' size (which' bit size is not the same as its backing
214 /// may **also** include power-of-2 integers for which the relevant capability is not enabled), but still219 /// type. **Note**: this may **also** include power-of-2 integers for which the
215 /// within the limits of the largest natively supported integer type.220 /// relevant capability is not enabled), but still within the limits of the largest
221 /// natively supported integer type.
216 strange_integer,222 strange_integer,
217223
218 /// An integer with more bits than the largest natively supported integer type.224 /// An integer with more bits than the largest natively supported integer type.
...@@ -220,7 +226,7 @@ pub const DeclGen = struct {...@@ -220,7 +226,7 @@ pub const DeclGen = struct {
220 };226 };
221227
222 /// The number of bits in the inner type.228 /// The number of bits in the inner type.
223 /// Note: this is the actual number of bits of the type, not the size of the backing integer.229 /// This is the actual number of bits of the type, not the size of the backing integer.
224 bits: u16,230 bits: u16,
225231
226 /// Whether the type is a vector.232 /// Whether the type is a vector.
...@@ -234,10 +240,12 @@ pub const DeclGen = struct {...@@ -234,10 +240,12 @@ pub const DeclGen = struct {
234 class: Class,240 class: Class,
235 };241 };
236242
237 /// Initialize the common resources of a DeclGen. Some fields are left uninitialized, only set when `gen` is called.243 /// Initialize the common resources of a DeclGen. Some fields are left uninitialized,
244 /// only set when `gen` is called.
238 pub fn init(spv: *SPIRVModule) DeclGen {245 pub fn init(spv: *SPIRVModule) DeclGen {
239 return .{246 return .{
240 .spv = spv,247 .spv = spv,
248 .air = undefined,
241 .args = std.ArrayList(ResultId).init(spv.gpa),249 .args = std.ArrayList(ResultId).init(spv.gpa),
242 .next_arg_index = undefined,250 .next_arg_index = undefined,
243 .inst_results = InstMap.init(spv.gpa),251 .inst_results = InstMap.init(spv.gpa),
...@@ -252,8 +260,9 @@ pub const DeclGen = struct {...@@ -252,8 +260,9 @@ pub const DeclGen = struct {
252 /// Generate the code for `decl`. If a reportable error occured during code generation,260 /// Generate the code for `decl`. If a reportable error occured during code generation,
253 /// a message is returned by this function. Callee owns the memory. If this function returns such261 /// a message is returned by this function. Callee owns the memory. If this function returns such
254 /// a reportable error, it is valid to be called again for a different decl.262 /// a reportable error, it is valid to be called again for a different decl.
255 pub fn gen(self: *DeclGen, decl: *Decl) !?*Module.ErrorMsg {263 pub fn gen(self: *DeclGen, decl: *Decl, air: Air) !?*Module.ErrorMsg {
256 // Reset internal resources, we don't want to re-allocate these.264 // Reset internal resources, we don't want to re-allocate these.
265 self.air = &air;
257 self.args.items.len = 0;266 self.args.items.len = 0;
258 self.next_arg_index = 0;267 self.next_arg_index = 0;
259 self.inst_results.clearRetainingCapacity();268 self.inst_results.clearRetainingCapacity();
...@@ -680,7 +689,7 @@ pub const DeclGen = struct {...@@ -680,7 +689,7 @@ pub const DeclGen = struct {
680689
681 .br => return self.genBr(inst),690 .br => return self.genBr(inst),
682 .breakpoint => return,691 .breakpoint => return,
683 .condbr => return self.genCondBr(inst),692 .cond_br => return self.genCondBr(inst),
684 .constant => unreachable,693 .constant => unreachable,
685 .dbg_stmt => return self.genDbgStmt(inst),694 .dbg_stmt => return self.genDbgStmt(inst),
686 .loop => return self.genLoop(inst),695 .loop => return self.genLoop(inst),
...@@ -688,6 +697,10 @@ pub const DeclGen = struct {...@@ -688,6 +697,10 @@ pub const DeclGen = struct {
688 .store => return self.genStore(inst),697 .store => return self.genStore(inst),
689 .unreach => return self.genUnreach(),698 .unreach => return self.genUnreach(),
690 // zig fmt: on699 // zig fmt: on
700
701 else => |tag| return self.fail("TODO: SPIR-V backend: implement AIR tag {s}", .{
702 @tagName(tag),
703 }),
691 };704 };
692705
693 try self.inst_results.putNoClobber(inst, result_id);706 try self.inst_results.putNoClobber(inst, result_id);
src/link/SpirV.zig+4
...@@ -135,6 +135,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {...@@ -135,6 +135,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation) !void {
135 const tracy = trace(@src());135 const tracy = trace(@src());
136 defer tracy.end();136 defer tracy.end();
137137
138 if (build_options.skip_non_native) {
139 @panic("Attempted to compile for architecture that was disabled by build configuration");
140 }
141
138 const module = self.base.options.module.?;142 const module = self.base.options.module.?;
139 const target = comp.getTarget();143 const target = comp.getTarget();
140144
src/register_manager.zig+8-8
...@@ -20,7 +20,7 @@ pub fn RegisterManager(...@@ -20,7 +20,7 @@ pub fn RegisterManager(
20) type {20) type {
21 return struct {21 return struct {
22 /// The key must be canonical register.22 /// The key must be canonical register.
23 registers: [callee_preserved_regs.len]?*ir.Inst = [_]?*ir.Inst{null} ** callee_preserved_regs.len,23 registers: [callee_preserved_regs.len]?Air.Inst.Index = [_]?Air.Inst.Index{null} ** callee_preserved_regs.len,
24 free_registers: FreeRegInt = math.maxInt(FreeRegInt),24 free_registers: FreeRegInt = math.maxInt(FreeRegInt),
25 /// Tracks all registers allocated in the course of this function25 /// Tracks all registers allocated in the course of this function
26 allocated_registers: FreeRegInt = 0,26 allocated_registers: FreeRegInt = 0,
...@@ -75,7 +75,7 @@ pub fn RegisterManager(...@@ -75,7 +75,7 @@ pub fn RegisterManager(
75 pub fn tryAllocRegs(75 pub fn tryAllocRegs(
76 self: *Self,76 self: *Self,
77 comptime count: comptime_int,77 comptime count: comptime_int,
78 insts: [count]?*ir.Inst,78 insts: [count]?Air.Inst.Index,
79 exceptions: []const Register,79 exceptions: []const Register,
80 ) ?[count]Register {80 ) ?[count]Register {
81 comptime if (callee_preserved_regs.len == 0) return null;81 comptime if (callee_preserved_regs.len == 0) return null;
...@@ -113,7 +113,7 @@ pub fn RegisterManager(...@@ -113,7 +113,7 @@ pub fn RegisterManager(
113 /// Allocates a register and optionally tracks it with a113 /// Allocates a register and optionally tracks it with a
114 /// corresponding instruction. Returns `null` if all registers114 /// corresponding instruction. Returns `null` if all registers
115 /// are allocated.115 /// are allocated.
116 pub fn tryAllocReg(self: *Self, inst: ?*ir.Inst, exceptions: []const Register) ?Register {116 pub fn tryAllocReg(self: *Self, inst: ?Air.Inst.Index, exceptions: []const Register) ?Register {
117 return if (tryAllocRegs(self, 1, .{inst}, exceptions)) |regs| regs[0] else null;117 return if (tryAllocRegs(self, 1, .{inst}, exceptions)) |regs| regs[0] else null;
118 }118 }
119119
...@@ -123,7 +123,7 @@ pub fn RegisterManager(...@@ -123,7 +123,7 @@ pub fn RegisterManager(
123 pub fn allocRegs(123 pub fn allocRegs(
124 self: *Self,124 self: *Self,
125 comptime count: comptime_int,125 comptime count: comptime_int,
126 insts: [count]?*ir.Inst,126 insts: [count]?Air.Inst.Index,
127 exceptions: []const Register,127 exceptions: []const Register,
128 ) ![count]Register {128 ) ![count]Register {
129 comptime assert(count > 0 and count <= callee_preserved_regs.len);129 comptime assert(count > 0 and count <= callee_preserved_regs.len);
...@@ -168,14 +168,14 @@ pub fn RegisterManager(...@@ -168,14 +168,14 @@ pub fn RegisterManager(
168168
169 /// Allocates a register and optionally tracks it with a169 /// Allocates a register and optionally tracks it with a
170 /// corresponding instruction.170 /// corresponding instruction.
171 pub fn allocReg(self: *Self, inst: ?*ir.Inst, exceptions: []const Register) !Register {171 pub fn allocReg(self: *Self, inst: ?Air.Inst.Index, exceptions: []const Register) !Register {
172 return (try self.allocRegs(1, .{inst}, exceptions))[0];172 return (try self.allocRegs(1, .{inst}, exceptions))[0];
173 }173 }
174174
175 /// Spills the register if it is currently allocated. If a175 /// Spills the register if it is currently allocated. If a
176 /// corresponding instruction is passed, will also track this176 /// corresponding instruction is passed, will also track this
177 /// register.177 /// register.
178 pub fn getReg(self: *Self, reg: Register, inst: ?*ir.Inst) !void {178 pub fn getReg(self: *Self, reg: Register, inst: ?Air.Inst.Index) !void {
179 const index = reg.allocIndex() orelse return;179 const index = reg.allocIndex() orelse return;
180180
181 if (inst) |tracked_inst|181 if (inst) |tracked_inst|
...@@ -202,7 +202,7 @@ pub fn RegisterManager(...@@ -202,7 +202,7 @@ pub fn RegisterManager(
202 /// Allocates the specified register with the specified202 /// Allocates the specified register with the specified
203 /// instruction. Asserts that the register is free and no203 /// instruction. Asserts that the register is free and no
204 /// spilling is necessary.204 /// spilling is necessary.
205 pub fn getRegAssumeFree(self: *Self, reg: Register, inst: *ir.Inst) void {205 pub fn getRegAssumeFree(self: *Self, reg: Register, inst: Air.Inst.Index) void {
206 const index = reg.allocIndex() orelse return;206 const index = reg.allocIndex() orelse return;
207207
208 assert(self.registers[index] == null);208 assert(self.registers[index] == null);
...@@ -264,7 +264,7 @@ fn MockFunction(comptime Register: type) type {...@@ -264,7 +264,7 @@ fn MockFunction(comptime Register: type) type {
264 self.spilled.deinit(self.allocator);264 self.spilled.deinit(self.allocator);
265 }265 }
266266
267 pub fn spillInstruction(self: *Self, reg: Register, inst: *ir.Inst) !void {267 pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void {
268 _ = inst;268 _ = inst;
269 try self.spilled.append(self.allocator, reg);269 try self.spilled.append(self.allocator, reg);
270 }270 }