Skip to content
This repository was archived by the owner on Nov 22, 2023. It is now read-only.

Commit cddfb00

Browse files
author
gek
committed
make push
1 parent 615210d commit cddfb00

File tree

4 files changed

+215
-38
lines changed

4 files changed

+215
-38
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ CFLAGS_CBAS= -O3 -fwrapv -s -lpthread -lm
88

99

1010
cbas_dirty:
11-
$(CC) $(CFLAGS) ctok.c parser.c data.c constexpr.c metaprogramming.c code_validator.c astexec.c astdump.c reflection_library.c -o cbas_dirty -lm -g
11+
$(CC) $(CFLAGS) ctok.c parser.c data.c constexpr.c metaprogramming.c code_validator.c astexec.c astdump.c reflection_library.c ast_opt.c -o cbas_dirty -lm -g
1212

1313
all: cbas_tcc cbas_clean cbas_dirty cbas_dbg cbas_pure cbas_dbg2
1414

ast_opt.c

+208-35
Original file line numberDiff line numberDiff line change
@@ -11,62 +11,235 @@
1111

1212
//
1313
static size_t memneeded = 0;
14-
static char* bbuf = 0;
15-
static const size_t ALGN = 32;
14+
//our big buffer!
15+
static void* bbuf = 0;
16+
static const size_t ALGN = 32; //memory alignment...
17+
typedef struct{
18+
void* p;
19+
size_t t;
20+
} ptr_sizet_pair;
21+
static ptr_sizet_pair* ptr_cache = 0;
22+
static size_t npairs = 0;
23+
24+
//register a pointer to be allocated somewhere at/ahead of the
25+
//current position. It may also point to the same place...
26+
static void push_pointer_ahead(void* p, size_t depth){
27+
ptr_sizet_pair pr;
28+
pr.p = p;
29+
pr.t = memneeded + depth;
30+
npairs++;
31+
ptr_cache = realloc(ptr_cache, sizeof(ptr_sizet_pair) * (npairs));
32+
ptr_cache[npairs-1] = pr;
33+
}
34+
35+
//register a pointer in the system. It will
36+
//be allocated at the current position....
37+
static void push_pointer(void* p){
38+
push_pointer_ahead(p,0);
39+
}
40+
41+
42+
//plan a single chunk of memory...
43+
//you may not use this to allocate array elements!
1644
static void plan_memory(size_t amt){
17-
amt = (amt + (ALGN-1)) % ALGN;
45+
amt = (amt + (ALGN-1)) & ~(size_t)(ALGN-1);
1846
memneeded = memneeded + amt;
1947
}
20-
static void plan_string(char* s){
21-
plan_memory(strlen(s)+1);
48+
49+
static void push_plan(void* p, size_t amt){
50+
push_pointer(p);
51+
plan_memory(amt);
52+
}
53+
54+
//plan an array of things...
55+
static void plan_array(void* p, size_t elemsz, size_t n){
56+
for(unsigned long i = 0; i < n; i++)
57+
{
58+
push_pointer_ahead(p + elemsz * i, elemsz * i);
59+
}
60+
plan_memory(elemsz * n);
61+
}
62+
63+
64+
static size_t lookup_pointer(void* p){
65+
for(unsigned long i = 0; i < npairs; i++){
66+
if(p == ptr_cache[i].p)
67+
return ptr_cache[i].t;
68+
}
69+
return ~(size_t)0;
2270
}
2371

72+
//decode a pointer from the original AST into the new, compacted one...
73+
static void* pdecode(void* p){
74+
size_t q = lookup_pointer(p);
75+
if(q == ~(size_t)0) return NULL;
76+
return bbuf + q;
77+
}
78+
79+
#define REP(A) (A) = pdecode(A);
80+
#define FREP(A) free(A); (A) = pdecode(A);
81+
82+
83+
static void plan_string(char* s){
84+
push_plan(s, strlen(s)+1);
85+
}
86+
static void write_string(char* s){
87+
memcpy(pdecode(s),s,strlen(s)+1);
88+
}
2489
static void plan_lvar(symdecl* s){
25-
//TODO
26-
plan_memory(sizeof(symdecl));
27-
plan_memory(strlen(s->name)+1);//the name of the variable will be stored...
90+
plan_string(s->name);
91+
}
92+
static void plan_lvars(symdecl* s, unsigned long n){
93+
plan_array(s, sizeof(symdecl), n);
94+
for(unsigned long i = 0; i < n; i++){
95+
plan_lvar(s+i);
96+
}
2897
}
98+
static void write_lvars(symdecl* s, unsigned long n){
99+
memcpy(pdecode(s),s,n * sizeof(symdecl));
100+
REP(s)
101+
for(unsigned long i = 0; i < n; i++){
102+
write_string(s[i].name);
103+
FREP(s[i].name);
104+
}
105+
}
106+
107+
//Does not do any allocation of itself, because
108+
//expr_node appears both in an array of pointers,
109+
//and an array of objects (inside itself, actually...)
110+
static void plan_expr_node(expr_node* s);
111+
static void write_expr_node(expr_node* s);
29112

30-
static void plan_expr_node(expr_node* e){
31-
plan_memory(sizeof(expr_node));
32-
if(e->kind == EXPR_STRINGLIT || e->kind == EXPR_BUILTIN_CALL)
33-
plan_string(e->symname);
113+
static void plan_expr_node(expr_node* s){
114+
//plan ourselves..
115+
push_plan(s, sizeof(expr_node));
116+
if(s->symname)
117+
plan_string(s->symname);
118+
if(s->method_name)
119+
plan_string(s->method_name);
120+
for(unsigned long i = 0; i < MAX_FARGS; i++)
121+
if(s->subnodes[i])
122+
plan_expr_node(s->subnodes[i]);
123+
}
124+
static void write_expr_node(expr_node* s){
125+
memcpy(pdecode(s),s, sizeof(expr_node));
126+
REP(s)
127+
if(s->symname){
128+
write_string(s->symname);
129+
FREP(s->symname);
130+
}
131+
if(s->method_name){
132+
write_string(s->method_name);
133+
FREP(s->method_name);
134+
}
34135
for(unsigned long i = 0; i < MAX_FARGS; i++)
35-
if(e->subnodes[i])
36-
plan_expr_node(e->subnodes[i]);
37-
//TODO
136+
if(s->subnodes[i]){
137+
write_expr_node(s->subnodes[i]);
138+
FREP(s->subnodes[i]);
139+
}
38140
}
39141
static void plan_scope(scope* s);
40-
static void plan_stmt(stmt* s){
41-
plan_memory(sizeof(stmt));
42-
//TODO
43-
if(s->referenced_label_name)
44-
plan_string(s->referenced_label_name);
45-
for(unsigned long i = 0; i < s->nexpressions; i++)
46-
plan_expr_node(s->expressions[i]);
47-
if(s->myscope)
48-
plan_scope(s->myscope);
49-
142+
static void write_scope(scope* s);
143+
144+
static void plan_stmts(stmt* s, unsigned long n){
145+
plan_array(s, sizeof(stmt), n);
146+
for(unsigned long i = 0; i < n; i++){
147+
if(s[i].myscope){
148+
plan_scope(s[i].myscope);
149+
}
150+
for(unsigned long j = 0; j < s[i].nexpressions; j++)
151+
{
152+
if(s[i].nexpressions == 0) continue;
153+
plan_expr_node(s[i].expressions[j]);
154+
}
155+
if(s[i].referenced_label_name){
156+
plan_string(s[i].referenced_label_name);
157+
}
158+
if(s[i].switch_nlabels){
159+
push_plan(s[i].switch_label_indices, sizeof(uint64_t) * s[i].switch_nlabels);
160+
}
161+
}
162+
}
163+
static void write_stmts(stmt* s, unsigned long n){
164+
memcpy(pdecode(s),s,n * sizeof(stmt));
165+
REP(s)
166+
for(unsigned long i = 0; i < n; i++){
167+
REP(s[i].whereami)
168+
if(s[i].referenced_loop){
169+
REP(s[i].referenced_loop);
170+
}
171+
if(s[i].myscope){
172+
write_scope(s[i].myscope);
173+
FREP(s[i].myscope);
174+
}
175+
for(unsigned long j = 0; j < s[i].nexpressions; j++)
176+
{
177+
if(s[i].nexpressions == 0) continue;
178+
write_expr_node(s[i].expressions[j]);
179+
FREP(s[i].expressions[j])
180+
}
181+
if(s[i].referenced_label_name){
182+
write_string(s[i].referenced_label_name);
183+
FREP(s[i].referenced_label_name)
184+
}
185+
if(s[i].switch_nlabels){
186+
memcpy(
187+
pdecode(s[i].switch_label_indices),
188+
s[i].switch_label_indices,
189+
s[i].switch_nlabels * sizeof(uint64_t)
190+
);
191+
FREP(s[i].switch_label_indices);
192+
}
193+
}
50194
}
51195

196+
197+
52198
static void plan_scope(scope* s){
53-
plan_memory(sizeof(scope));
54-
for(unsigned long i = 0; i < s->nsyms; i++){
55-
plan_lvar(s->syms + i);
199+
push_plan(s, sizeof(scope));
200+
if(s->nsyms)
201+
plan_lvars(s->syms, s->nsyms);
202+
if(s->nstmts)
203+
plan_stmts(s->stmts, s->nstmts);
204+
}
205+
static void write_scope(scope* s){
206+
memcpy(pdecode(s),s, sizeof(scope));
207+
REP(s)
208+
if(s->nsyms){
209+
write_lvars(s->syms, s->nsyms);
210+
FREP(s->syms)
56211
}
57-
for(unsigned long i = 0; i < s->nstmts; i++){
58-
plan_stmt(s->stmts + i);
212+
if(s->nstmts){
213+
write_stmts(s->stmts, s->nstmts);
214+
FREP(s->stmts)
59215
}
60216
}
61217

218+
219+
62220
void optimize_fn(symdecl* ss){
221+
63222
memneeded = 0;
64223
bbuf = 0;
65-
//we don't eat its name...
66-
if(ss->t.is_function == 0 || ss->is_codegen == 0) return; //this is not a codegen function...
67-
for(unsigned long i = 0; i < ss->nargs; i++)
68-
plan_memory(sizeof(type));
224+
npairs = 0;
225+
if(ss->t.is_function == 0 ) return;
226+
//printf("Optimizing function %s\n", ss->name);
69227
plan_scope(ss->fbody);
70-
//TODO:
228+
for(unsigned long i = 0; i < ss->nargs; i++){
229+
push_plan(ss->fargs[i], sizeof(type));
230+
}
231+
//Malloc must be aligned to ALGN here...
232+
bbuf = malloc(memneeded);
233+
memneeded = 0;
234+
235+
236+
//WALK THE TREE, BUT THIS TIME, DECODING...
237+
write_scope(ss->fbody);
238+
FREP(ss->fbody);
239+
for(unsigned long i = 0; i < ss->nargs; i++){
240+
memcpy(pdecode(ss->fargs[i]), ss->fargs[i], sizeof(type));
241+
FREP(ss->fargs[i])
242+
}
243+
//FUNCTION IS OPTIMIZED...
71244
}
72245

ast_opt.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
#define AST_OPT_H
44

55
/*
6-
Optimization for the AST....
6+
ARENA ALLOCATION OPTIMIZATION FOR FUNCTIONS.
7+
8+
Meant primarily to speed up compiletimes for SEABASS,
9+
especially compiletime execution.
710
*/
811

912
#include "data.h"

code_validator.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "parser.h"
66
#include "data.h"
77
#include "metaprogramming.h"
8+
#include "ast_opt.h"
89

910
/*
1011
Code validator.
@@ -3349,7 +3350,7 @@ void validate_function(symdecl* funk){
33493350
//these steps must be repeated...
33503351
check_label_declarations(funk->fbody);
33513352
walk_assign_lsym_gsym();
3352-
3353+
optimize_fn(funk);
33533354
/*
33543355
TODO:
33553356
Fix big: You can shadow variables by accident...

0 commit comments

Comments
 (0)