Skip to content

Commit 15dc084

Browse files
committed
ir: added usage counter (not used yet)
1 parent f112e7b commit 15dc084

File tree

8 files changed

+143
-148
lines changed

8 files changed

+143
-148
lines changed

ir/context.c2

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import index_list;
2020
import instr_inserter;
2121
import lookup_table;
2222
import string_pool;
23+
import usage_counter;
2324

2425
import stdlib;
2526
import string;
@@ -54,6 +55,7 @@ public type Context struct @(opaque) {
5455
instr_inserter.InstrInserter inserter;
5556
bit_array.BitArray active_blocks;
5657
CopyList copies;
58+
usage_counter.Counter usage;
5759
}
5860

5961
public fn Context* create() {
@@ -71,10 +73,12 @@ public fn Context* create() {
7173
c.revlist.create(256);
7274
c.inserter.create();
7375
c.copies.init(1024);
76+
c.usage.init(1024);
7477
return c;
7578
}
7679

7780
public fn void Context.free(Context* c) {
81+
c.usage.free();
7882
c.copies.free();
7983
c.inserter.free();
8084
c.revlist.free();
@@ -700,6 +704,13 @@ fn void Context.finalizeFunction(Context* c, SymbolId id) {
700704
//c.dump_function(fi2, name);
701705
if (print) c.print_function(id, fi2, "after eliminate copies");
702706

707+
708+
//c.propagateConstants(fi2);
709+
//if (print) c.print_function(id, fi2, "after propagate constants");
710+
c.fillUsage(fi2);
711+
//if (print) c.print_function(id, fi2, "after fill usage");
712+
713+
703714
c.removeNone(fi2);
704715
if (print) c.print_function(id, fi2, "after remove none");
705716
}

ir/instr.c2

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ fn bool Instr.isCopy(const Instr* i) {
118118
return k == InstrKind.Copy;
119119
}
120120

121+
fn bool Instr.isArithmetic(const Instr* i) @(unused) {
122+
InstrKind k = i.getKind();
123+
return k >= InstrKind.Add && k <= InstrKind.Shl;
124+
}
125+
121126
fn bool Instr.isLoad(const Instr* i) {
122127
InstrKind k = i.getKind();
123128
return k >= InstrKind.Load1 && k <= InstrKind.Load8;

ir/instr_kind.c2

Lines changed: 0 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,19 @@
1515

1616
module ir;
1717

18-
// NOTE keep in same order as Token!
1918
public type InstrKind enum u8 {
2019
None, // used when removing instructions
2120

2221
// Arithmetic and Bits
23-
//Neg, // KEEP THIS THE FIRST OPERATION!
2422
Add,
2523
Sub,
2624
Div,
2725
Rem,
28-
#if 0
29-
Udiv,
30-
Fdiv,
31-
Urem,
32-
#endif
3326
Mul,
3427
IDiv,
3528
And,
3629
Or,
3730
Xor,
38-
#if 0
39-
Sar,
40-
#endif
4131
Shr,
4232
Shl,
4333

@@ -48,45 +38,6 @@ public type InstrKind enum u8 {
4838
CmpGt,
4939
CmpLe,
5040
CmpGe,
51-
#if 0
52-
Ceqd,
53-
Ceql,
54-
Ceqs,
55-
Ceqw,
56-
Cged,
57-
Cges,
58-
Cgtd,
59-
Cgts,
60-
Cled,
61-
Cles,
62-
Cltd,
63-
Clts,
64-
Cned,
65-
Cnel,
66-
Cnes,
67-
Cnew,
68-
Cod,
69-
Cos,
70-
Csgel,
71-
Csgew,
72-
Csgtl,
73-
Csgtw,
74-
Cslel,
75-
Cslew,
76-
Csltl,
77-
Csltw,
78-
Cugel,
79-
Cugew,
80-
Cugtl,
81-
Cugtw,
82-
Culel,
83-
Culew,
84-
Cultl,
85-
Cultw,
86-
Cuod,
87-
Cuos,
88-
89-
#endif
9041
// Memory
9142
Load1,
9243
Load2,
@@ -96,97 +47,11 @@ public type InstrKind enum u8 {
9647
Store2,
9748
Store4,
9849
Store8,
99-
#if 0
100-
// Extensions and Truncations
101-
Cast,
102-
Dtosi,
103-
Dtoui,
104-
Exts,
105-
Extsb,
106-
Extsh,
107-
Extsw,
108-
Extub,
109-
Extuh,
110-
Extuw,
111-
Sltof,
112-
Stosi, // single to signed integer
113-
Stoui, // single to unsigned integer
114-
Swtof,
115-
Truncd, // truncate double
116-
Ultof,
117-
Uwtof,
118-
11950
// Stack Allocation
120-
#endif
12151
Alloc1,
12252
Alloc2,
12353
Alloc4,
12454
Alloc8,
125-
#if 0
126-
Alloc16,
127-
128-
// Variadic Function Helpers
129-
Copy,
130-
Vaarg,
131-
Vastart,
132-
133-
// Miscellaneous and Architecture-Specific Operations
134-
Acmn,
135-
Acmp,
136-
Addr,
137-
Afcmp,
138-
Blit,
139-
Blit0,
140-
Blit1,
141-
Nop,
142-
Reqz,
143-
Rnez,
144-
Salloc,
145-
Sign,
146-
Swap,
147-
Xcmp,
148-
Xdiv,
149-
Xidiv,
150-
Xtest,
151-
152-
// Arguments, Parameters, and Calls
153-
Arg,
154-
Argc,
155-
Arge,
156-
Argsb,
157-
Argsh,
158-
Argub,
159-
Arguh,
160-
Argv,
161-
162-
Par,
163-
Parc,
164-
Pare,
165-
Parsb,
166-
Parsh,
167-
Parub,
168-
Paruh,
169-
170-
// Flags Setting
171-
Flagfeq,
172-
Flagfge,
173-
Flagfgt,
174-
Flagfle,
175-
Flagflt,
176-
Flagfne,
177-
Flagfo,
178-
Flagfuo,
179-
Flagieq,
180-
Flagine,
181-
Flagisge,
182-
Flagisgt,
183-
Flagisle,
184-
Flagislt,
185-
Flagiuge,
186-
Flagiugt,
187-
Flagiule,
188-
Flagiult,
189-
#endif
19055
// Jump instructions
19156
Jmp,
19257
JmpIf,

ir/print.c2

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -542,9 +542,9 @@ fn void dump_function_info(string_buffer.Buf* out, const FunctionInfo* info) @(u
542542
const Instr* instr = info.instructions.get(0);
543543
for (u32 i=0; i<info.instructions.getCount(); i++) {
544544
const Instr* r = &instr[i];
545-
out.print(" [%3d] %7s", i, r.getKindName());
545+
out.print(" [%3d] %c %7s", i, r.hasResult() ? 'r' : ' ', r.getKindName());
546546
if (r.isPhi()) {
547-
out.print(" clauses: start %d count %d", r.phi_clauses.start, r.phi_clauses.count);
547+
out.print(" clauses %d-%d", r.phi_clauses.start, r.phi_clauses.start + r.phi_clauses.count - 1);
548548
} else {
549549
out.print(" %8s %3d ", r.args[0].getKindName(), r.args[0].value);
550550
out.print(" %8s %3d", r.args[01].getKindName(), r.args[1].value);
@@ -605,20 +605,24 @@ public fn void Context.dump(const Context* c) @(unused) {
605605
}
606606
out.newline();
607607

608-
out.print("constants: (%d)\n", c.constants.getCount());
609-
for (u32 i=0; i<c.constants.getCount(); i++) {
610-
const Constant* con = c.constants.get(i);
611-
// TODO need to know type, for now print as ivalue
612-
out.print(" [%2d] %d\n", i, con.ivalue);
608+
if (c.constants.getCount()) {
609+
out.print("constants: (%d)\n", c.constants.getCount());
610+
for (u32 i=0; i<c.constants.getCount(); i++) {
611+
const Constant* con = c.constants.get(i);
612+
// TODO need to know type, for now print as ivalue
613+
out.print(" [%2d] %d\n", i, con.ivalue);
614+
}
615+
out.newline();
613616
}
614-
out.newline();
615617

616-
out.print("init values: (%d)\n", c.init_values.getCount());
617-
for (u32 i=0; i<c.init_values.getCount(); i++) {
618-
const InitValue* v = c.init_values.get(i);
619-
out.print(" [%2d] %6s %d\n", i, v.getKindName(), v.value);
618+
if (c.init_values.getCount()) {
619+
out.print("init values: (%d)\n", c.init_values.getCount());
620+
for (u32 i=0; i<c.init_values.getCount(); i++) {
621+
const InitValue* v = c.init_values.get(i);
622+
out.print(" [%2d] %6s %d\n", i, v.getKindName(), v.value);
623+
}
624+
out.newline();
620625
}
621-
out.newline();
622626

623627
stdio.puts(out.data());
624628
out.free();

ir/ref.c2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ fn bool Ref.isSlot(const Ref* r) {
6363
return r.kind == RefKind.Slot;
6464
}
6565

66+
fn bool Ref.isConstant(const Ref* r) @(unused) {
67+
return r.kind >= RefKind.Value && r.kind <= RefKind.Double;
68+
}
69+
6670
fn bool Ref.isRefList(const Ref* r) {
6771
return r.kind == RefKind.RefList;
6872
}

ir/ssa.c2

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,54 @@ fn void Context.eliminateCopies(Context* c, FunctionInfo* fi) {
380380
}
381381
}
382382

383+
fn void Context.fillUsage(Context* c, FunctionInfo* fi) {
384+
c.usage.clear(fi.instructions.getCount());
385+
386+
// Usage: counter both usage and if it has a result.
387+
// count 0 means: has no result, (of course) not used
388+
// count 1 means: has result, not used (could still have side effects)
389+
// count 2+ means: used
390+
Instr* all = fi.instructions.get(0);
391+
for (u32 i=0; i<fi.instructions.getCount(); i++) {
392+
Instr* is = &all[i];
393+
if (is.hasResult()) c.usage.incr(i);
394+
if (is.isPhi()) {
395+
PhiClause* clauses = fi.phis.get(is.phi_clauses.start);
396+
for (u32 p=0; p<is.phi_clauses.count; p++) {
397+
Ref* r = &clauses[p].ref;
398+
if (r.isTemp()) c.usage.incr(r.value);
399+
}
400+
} else {
401+
Ref* r = &is.args[0];
402+
if (r.isTemp()) c.usage.incr(r.value);
403+
r = &is.args[1];
404+
if (r.isTemp()) c.usage.incr(r.value);
405+
}
406+
}
407+
}
408+
409+
#if 0
410+
// return true if changed
411+
fn bool Context.propagateConstants(Context* c, FunctionInfo* fi) {
412+
// look for add x, y where x, y are both constants, replace with copy
413+
bool changed = false;
414+
415+
c.dump_function(fi, "temp");
416+
Instr* all = fi.instructions.get(0);
417+
for (u32 i=0; i<fi.instructions.getCount(); i++) {
418+
Instr* instr = &all[i];
419+
if (!instr.isArithmetic()) continue;
420+
if (!instr.args[0].isConstant()) continue;
421+
if (!instr.args[1].isConstant()) continue;
422+
423+
// only 17 matches in c2c!
424+
changed = true;
425+
}
426+
427+
return changed;
428+
}
429+
#endif
430+
383431
fn void Context.removeNone(Context* c, FunctionInfo* fi) {
384432
c.inserter.clear();
385433
c.fixup_function(fi);

0 commit comments

Comments
 (0)