authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-10 15:27:33-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-10 15:38:13-07:00
log40764650afd47f2ca2d191ed4d910f680702e014
tree0dd5d4a704d74b4d6515f18bfd070aeadf50b4e9
parentb9e896d7b076e59d6f6dd9b0bad9697875d1f6e4

stage1: avoid wasting padding with IR instruction tag

For stage1 ZIR instructions and stage1 AIR instructions, the instruction op code was taking up 8 bytes due to padding even though it only needed 1 byte. This commit reduces the ref_count field from uint32_t to uint16_t because the code only really cares if instructions are referenced at all, not how many times they are referenced. With the ref_count field reduced to uint16_t the uint8_t op code is now placed in the freed up space. Empirically, this saves 382 MiB of peak RAM usage when building the self-hosted compiler, which is a reduction of 5%. Consequently this resulted in a 3% reduction of cache-misses when building the self-hosted compiler. This was @SpexGuy's idea, committed by me because we tested it on my computer.

1 files changed, 5 insertions(+), 6 deletions(-)

src/stage1/all_types.hpp+5-6
...@@ -2475,7 +2475,7 @@ struct IrBasicBlockGen {...@@ -2475,7 +2475,7 @@ struct IrBasicBlockGen {
2475// Src instructions are generated by ir_gen_* functions in ir.cpp from AST.2475// Src instructions are generated by ir_gen_* functions in ir.cpp from AST.
2476// ir_analyze_* functions consume Src instructions and produce Gen instructions.2476// ir_analyze_* functions consume Src instructions and produce Gen instructions.
2477// Src instructions do not have type information; Gen instructions do.2477// Src instructions do not have type information; Gen instructions do.
2478enum IrInstSrcId {2478enum IrInstSrcId : uint8_t {
2479 IrInstSrcIdInvalid,2479 IrInstSrcIdInvalid,
2480 IrInstSrcIdDeclVar,2480 IrInstSrcIdDeclVar,
2481 IrInstSrcIdBr,2481 IrInstSrcIdBr,
...@@ -2620,7 +2620,7 @@ enum IrInstSrcId {...@@ -2620,7 +2620,7 @@ enum IrInstSrcId {
26202620
2621// ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR.2621// ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR.
2622// Src instructions do not have type information; Gen instructions do.2622// Src instructions do not have type information; Gen instructions do.
2623enum IrInstGenId {2623enum IrInstGenId : uint8_t {
2624 IrInstGenIdInvalid,2624 IrInstGenIdInvalid,
2625 IrInstGenIdDeclVar,2625 IrInstGenIdDeclVar,
2626 IrInstGenIdBr,2626 IrInstGenIdBr,
...@@ -2714,14 +2714,13 @@ enum IrInstGenId {...@@ -2714,14 +2714,13 @@ enum IrInstGenId {
2714};2714};
27152715
2716struct IrInstSrc {2716struct IrInstSrc {
2717 uint32_t ref_count;2717 IrInstSrcId id;
2718 uint16_t ref_count;
2718 uint32_t debug_id;2719 uint32_t debug_id;
27192720
2720 Scope *scope;2721 Scope *scope;
2721 AstNode *source_node;2722 AstNode *source_node;
27222723
2723 IrInstSrcId id;
2724
2725 // When analyzing IR, instructions that point to this instruction in the "old ir"2724 // When analyzing IR, instructions that point to this instruction in the "old ir"
2726 // can find the instruction that corresponds to this value in the "new ir"2725 // can find the instruction that corresponds to this value in the "new ir"
2727 // with this child field.2726 // with this child field.
...@@ -2737,7 +2736,7 @@ struct IrInstGen {...@@ -2737,7 +2736,7 @@ struct IrInstGen {
2737 IrInstGenId id;2736 IrInstGenId id;
2738 // if ref_count is zero and the instruction has no side effects,2737 // if ref_count is zero and the instruction has no side effects,
2739 // the instruction can be omitted in codegen2738 // the instruction can be omitted in codegen
2740 uint32_t ref_count;2739 uint16_t ref_count;
2741 uint32_t debug_id;2740 uint32_t debug_id;
27422741
2743 Scope *scope;2742 Scope *scope;