1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
#ifndef IR_H
#define IR_H
#include "arena.h"
#include "dynarr.h"
#include "lex.h" /* for error reporting only */
#include "str.h"
/* nodes */
typedef enum {
N_START,
N_RETURN,
N_KEEPALIVE,
N_LIT,
N_OP_ADD, N_OP_SUB, N_OP_MUL, N_OP_DIV,
N_OP_AND, N_OP_OR, N_OP_XOR,
N_OP_SHL, N_OP_SHR,
N_OP_NEG, N_OP_NOT,
N_VALUE
} NodeType;
const char *node_type_name(NodeType t);
typedef enum {
T_BOT,
T_TOP,
T_CONST,
T_INT
} Type;
typedef struct {
Type type;
union {
int64_t i;
uint64_t u;
};
} Value;
typedef struct Node {
union {
struct Node *prev_free;
struct {
int id, refs;
int walked;
NodeType type;
LexSpan src_pos;
DYNARR(struct Node *) in, out;
Value val;
};
};
} Node;
/* procedure graph */
typedef struct NameBinding {
struct NameBinding *prev;
LexSpan src_pos;
Str name;
Node *node;
} NameBinding;
typedef struct ScopeFrame {
struct ScopeFrame *prev;
NameBinding *latest;
} ScopeFrame;
typedef struct {
ScopeFrame *tail, *free_scope;
NameBinding *free_bind;
} Scope;
typedef struct {
Arena arena;
Str name;
Node *start, *stop, *keepalive;
Node *free_list;
Scope scope;
} Proc;
void node_kill(Node *n, Proc *p);
void node_die(Node *n, Proc *p);
void node_del_out(Node *n, Node *p);
void node_del_in(Node *n, Node *p);
void node_kill(Node *n, Proc *p);
void node_add(Proc *p, Node *src, Node *dest);
void node_remove(Proc *p, Node *src, Node *dest);
Node *node_new_empty(Proc *p, NodeType t);
Node *node_newv(Proc *p, NodeType t, ...);
Node *node_dedup_lit(Proc *p, Value v);
Node *node_new_lit_i64(Proc *p, int64_t i);
Value node_compute(Node *n, Lexer *l);
Node *node_peephole(Node *n, Proc *p, Lexer *l);
#define node_new(...) node_newv(__VA_ARGS__, NULL)
void proc_init(Proc *proc, Str name);
void proc_free(Proc *proc);
ScopeFrame *scope_push(Scope *scope, Proc *proc);
ScopeFrame *scope_pop(Scope *scope, Proc *proc);
NameBinding *scope_find(Scope *scope, Str name);
NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Proc *proc);
#endif
|