Skip to content

Commit 351adb6

Browse files
committed
ir: use Arg pseudo-instruction. Remove RefList from ir/
1 parent a056ccb commit 351adb6

File tree

15 files changed

+41
-266
lines changed

15 files changed

+41
-266
lines changed

generator/ir/ir_generator.c2

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import file_utils;
2525
import ir local;
2626
import ir_context local;
2727
import ir_gen_locals local;
28-
import ref_list_pool;
2928
import source_mgr;
3029
import string_buffer;
3130
import string_pool;
@@ -49,7 +48,6 @@ type Generator struct {
4948
u32 num_scopes;
5049

5150
Locals locals;
52-
ref_list_pool.Pool ref_pool;
5351

5452
string_buffer.Buf* name_buf;
5553
bool assert_generated;
@@ -79,7 +77,6 @@ fn void Generator.init(Generator* gen,
7977
gen.output_dir = output_dir;
8078
gen.string_idx = 1; // starting at 1 looks nicer
8179
gen.locals.init();
82-
gen.ref_pool.init(4);
8380
gen.print = print;
8481
gen.enable_asserts = enable_asserts;
8582
gen.ptr_type = targetInfo.intWidth == 64 ? ir.Type.U64 : ir.Type.U32;
@@ -88,7 +85,6 @@ fn void Generator.init(Generator* gen,
8885
}
8986

9087
fn void Generator.free(Generator* gen) {
91-
gen.ref_pool.free();
9288
gen.labels.free();
9389
gen.ctx.free();
9490
gen.name_buf.free();

generator/ir/ir_generator_call.c2

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module ir_generator;
1818
import ast local;
1919
import ir local;
2020
import ir_context;
21+
import ref_list local;
2122

2223
fn void Generator.emitCallExpr(Generator* gen, ir.Ref* result, const Expr* e) {
2324
CallExpr* call = cast<CallExpr*>(e);
@@ -30,7 +31,7 @@ fn void Generator.emitCallExpr(Generator* gen, ir.Ref* result, const Expr* e) {
3031
bool has_result = !qt.isVoid();
3132
bool is_tf = call.isTypeFunc();
3233

33-
RefList* arg_refs = gen.ref_pool.get();
34+
RefList arg_refs.init();
3435

3536
ir.Ref name_ref;
3637
if (is_tf) {
@@ -52,22 +53,8 @@ fn void Generator.emitCallExpr(Generator* gen, ir.Ref* result, const Expr* e) {
5253
gen.emitExpr(&ref, args[i]);
5354
arg_refs.add(ref);
5455
}
55-
// Terminate with Ref.Unspecified
56-
if (arg_refs.getCount() != 0) {
57-
ir.Ref ref;
58-
ref.init(RefKind.None, 0);
59-
arg_refs.add(ref);
60-
}
61-
62-
ir.Ref args_ref;
63-
if (arg_refs.getCount() == 0) {
64-
args_ref.init(RefKind.None, 0);
65-
} else {
66-
u32 idx = c.addCallArgs(arg_refs);
67-
args_ref.init(RefKind.RefList, idx);
68-
}
69-
gen.ref_pool.put(arg_refs);
7056

71-
*result = c.addCallInstr(name_ref, args_ref, has_result, call.isNoreturn());
57+
*result = c.addCallInstr(name_ref, arg_refs.get(), arg_refs.getCount(), has_result, call.isNoreturn());
58+
arg_refs.free();
7259
}
7360

ir/ref_list.c2 renamed to generator/ir/ref_list.c2

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,60 +13,50 @@
1313
* limitations under the License.
1414
*/
1515

16-
module ir;
16+
module ref_list;
17+
18+
import ir;
1719

1820
import string local;
1921
import stdlib;
2022

2123
public type RefList struct {
2224
u32 count;
2325
u32 capacity;
24-
Ref* refs;
26+
ir.Ref* refs;
27+
ir.Ref[4] stack;
2528
}
2629

27-
public fn void RefList.init(RefList* l, u32 initial_size) {
30+
public fn void RefList.init(RefList* l) {
2831
l.count = 0;
29-
l.refs = nil;
30-
if (initial_size) l.resize(initial_size);
32+
l.capacity = elemsof(l.stack);
33+
l.refs = l.stack;
3134
}
3235

3336
public fn void RefList.free(RefList* l) {
34-
if (l.refs) stdlib.free(l.refs);
37+
if (l.count > elemsof(l.stack)) stdlib.free(l.refs);
3538
}
3639

3740
fn void RefList.resize(RefList* l, u32 cap) {
41+
ir.Ref* refs2 = stdlib.malloc(cap * sizeof(ir.Ref));
42+
if (l.count != 0) memcpy(refs2, l.refs, l.count * sizeof(ir.Ref));
43+
if (l.capacity > elemsof(l.stack)) stdlib.free(l.refs);
3844
l.capacity = cap;
39-
// TODO only memset new part?
40-
Ref* refs2 = stdlib.calloc(l.capacity, sizeof(Ref));
41-
if (l.count != 0) memcpy(refs2, l.refs, l.count * sizeof(Ref));
42-
if (l.refs) stdlib.free(l.refs);
4345
l.refs = refs2;
4446
}
4547

46-
public fn void RefList.add(RefList* l, Ref ref) {
47-
if (l.count == l.capacity) l.resize(l.capacity ? l.capacity * 2 : 4);
48+
public fn void RefList.add(RefList* l, ir.Ref ref) {
49+
if (l.count == l.capacity) l.resize(l.capacity * 2);
4850

4951
l.refs[l.count] = ref;
5052
l.count++;
5153
}
5254

53-
public fn u32 RefList.addList(RefList* l, const RefList* l2) {
54-
u32 start = l.count;
55-
if (l.capacity < l.count + l2.count) l.resize(l.count + l2.count);
56-
memcpy(&l.refs[l.count], l2.refs, l2.count * sizeof(Ref));
57-
l.count += l2.count;
58-
return start;
59-
}
60-
61-
public fn void RefList.clear(RefList* l) {
62-
l.count = 0;
63-
}
64-
6555
public fn u32 RefList.getCount(const RefList* l) {
6656
return l.count;
6757
}
6858

69-
public fn Ref* RefList.get(const RefList* l, u32 idx) {
70-
return &l.refs[idx];
59+
public fn const ir.Ref* RefList.get(const RefList* l) {
60+
return l.refs;
7161
}
7262

generator/ir/ref_list_pool.c2

Lines changed: 0 additions & 78 deletions
This file was deleted.

ir/context.c2

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,6 @@ public fn Ref Context.addFuncArg(Context* c, Type t) {
329329
return ref;
330330
}
331331

332-
public fn u32 Context.addCallArgs(Context* c, const RefList* refs) {
333-
return c.b.tmp_info.refs.addList(refs);
334-
}
335-
336332
public fn BlockId Context.createBlock(Context* c, BlockKind kind) {
337333
BlockId id = c.b.tmp_info.blocks.add(kind);
338334
#if DebugIr
@@ -518,17 +514,22 @@ public fn Ref Context.addBinaryInstr(Context* c, InstrKind k, Ref left, Ref righ
518514
return out;
519515
}
520516

521-
public fn Ref Context.addCallInstr(Context* c, Ref name, Ref args, bool has_result, bool noreturn) {
517+
public fn Ref Context.addCallInstr(Context* c, Ref name, const Ref* args, u32 num_args, bool has_result, bool noreturn) {
522518
#if DebugIr
523519
stdio.printf(" call %s%d\n", name.getKindName(), name.value);
524520
#endif
521+
for (u32 i = 0; i < num_args; i++) {
522+
Instr* ii = c.b.tmp_info.instructions.add();
523+
ii.init1(InstrKind.Arg, args[i]);
524+
}
525+
525526
Ref out.init(RefKind.Temp, c.b.tmp_info.instructions.getCount());
526527

527528
Instr* i = c.b.tmp_info.instructions.add();
528529
if (has_result) {
529-
i.init2b(InstrKind.Call, name, args);
530+
i.init1b(InstrKind.Call, name);
530531
} else {
531-
i.init2(InstrKind.Call, name, args);
532+
i.init1(InstrKind.Call, name);
532533
}
533534
if (noreturn) {
534535
Block* b = c.b.tmp_info.blocks.get(c.b.cur_block);

ir/function_info.c2

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,26 @@ public type FunctionInfo struct {
2222
BlockList blocks;
2323
InstrList instructions;
2424
CaseList cases;
25-
RefList refs; // for call arguments
2625
PhiList phis; // for phi instructions
2726
u16 num_slots;
2827
u8 num_args;
2928
// args[0][low bits] is return type (None if no return value)
3029
u8[1 + constants.MaxCallArgs/2] args; // stores 2 ir.Types per u8, first low, then high bits
3130
}
32-
static_assert(96, sizeof(FunctionInfo));
31+
static_assert(80, sizeof(FunctionInfo));
3332

3433
public fn FunctionInfo* FunctionInfo.create(u32 num_blks, u32 num_instr, u32 num_refs) {
3534
FunctionInfo* fi = stdlib.malloc(sizeof(FunctionInfo));
3635
fi.blocks.init(num_blks);
3736
fi.instructions.init(num_instr);
3837
fi.cases.init();
39-
fi.refs.init(num_refs);
4038
fi.phis.init();
4139
fi.num_args = 0;
4240
return fi;
4341
}
4442

4543
public fn void FunctionInfo.free(FunctionInfo* fi) {
4644
fi.phis.free();
47-
fi.refs.free();
4845
fi.cases.free();
4946
fi.instructions.free();
5047
fi.blocks.free();

ir/instr.c2

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,6 @@ public fn bool Instr.isSwitch(const Instr* i) {
159159
return i.getKind() == InstrKind.Switch;
160160
}
161161

162-
public fn bool Instr.isCall(const Instr* i) {
163-
return i.getKind() == InstrKind.Call;
164-
}
165-
166162
public fn bool Instr.isPhi(const Instr* i) {
167163
return i.getKind() == InstrKind.Phi;
168164
}

ir/instr_kind.c2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public type InstrKind enum u8 {
6060
Call,
6161
// Pseudo instructions (must be converted before converting to ASM)
6262
Param,
63+
Arg,
6364
Switch,
6465
Phi,
6566
Copy,
@@ -104,6 +105,7 @@ public fn const char* InstrKind.str(InstrKind k) @(unused) {
104105
case Halt: return "halt";
105106
case Call: return "call";
106107
case Param: return "param";
108+
case Arg: return "arg";
107109
case Switch: return "switch";
108110
case Phi: return "phi";
109111
case Copy: return "copy";

ir/interference_graph.c2

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public fn InterferenceGraph* create(u32 max_elems, u16 num_variables) {
7272
g.variables = stdlib.calloc(num_variables, sizeof(Variable));
7373
g.num_variables = num_variables;
7474
g.max_elems = max_elems;
75-
g.register_map = stdlib.malloc(num_variables *sizeof(u16));
75+
g.register_map = stdlib.malloc(num_variables * sizeof(u8));
7676
string.memset(g.register_map, VAR_UNUSED, num_variables);
7777
g.queue = stdlib.malloc(num_variables * sizeof(u16));
7878

@@ -389,6 +389,8 @@ fn void InterferenceGraph.handleQueue(InterferenceGraph* g) {
389389

390390
public fn void InterferenceGraph.allocate(InterferenceGraph* g, u32 num_args) {
391391
// pre-alloc arguments as R0,R1,..
392+
393+
assert(num_args < g.num_variables);
392394
for (u8 v=0; v<num_args; v++) {
393395
g.register_map[v] = v;
394396
}

0 commit comments

Comments
 (0)