Skip to content

Commit bdc87f6

Browse files
author
Sebastien Bourdeauducq
committedNov 24, 2011
compiler: better register allocator
1 parent de3210b commit bdc87f6

File tree

1 file changed

+70
-57
lines changed

1 file changed

+70
-57
lines changed
 

Diff for: ‎src/renderer/compiler.c

+70-57
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ struct compiler_sc {
3636
int linenr;
3737

3838
struct fpvm_fragment pfv_fragment;
39-
int pfv_preallocation[COMP_PFV_COUNT]; /* < where per-frame variables can be mapped in PFPU regf */
40-
4139
struct fpvm_fragment pvv_fragment;
42-
int pvv_preallocation[COMP_PVV_COUNT]; /* < where per-vertex variables can be mapped in PFPU regf */
4340
};
4441

4542
static void comp_report(struct compiler_sc *sc, const char *format, ...)
@@ -173,17 +170,13 @@ static const char pfv_names[COMP_PFV_COUNT][FPVM_MAXSYMLEN] = {
173170
"image2_zoom"
174171
};
175172

176-
static int pfv_from_name(struct compiler_sc *sc, const char *name)
173+
static int pfv_from_name(const char *name)
177174
{
178175
int i;
176+
179177
for(i=0;i<COMP_PFV_COUNT;i++) {
180-
if(strcmp(pfv_names[i], name) == 0) {
181-
if(i >= pfv_dmx1 && i <= pfv_idmx8) sc->p->require |= REQUIRE_DMX;
182-
if(i >= pfv_osc1 && i <= pfv_osc4) sc->p->require |= REQUIRE_OSC;
183-
if(i >= pfv_midi1 && i <= pfv_midi8) sc->p->require |= REQUIRE_MIDI;
184-
if(i == pfv_video_a) sc->p->require |= REQUIRE_VIDEO;
178+
if(strcmp(pfv_names[i], name) == 0)
185179
return i;
186-
}
187180
}
188181

189182
if(strcmp(name, "fDecay") == 0) return pfv_decay;
@@ -197,6 +190,14 @@ static int pfv_from_name(struct compiler_sc *sc, const char *name)
197190
return -1;
198191
}
199192

193+
static void pfv_update_patch_requires(struct compiler_sc *sc, int pfv)
194+
{
195+
if(pfv >= pfv_dmx1 && pfv <= pfv_idmx8) sc->p->require |= REQUIRE_DMX;
196+
if(pfv >= pfv_osc1 && pfv <= pfv_osc4) sc->p->require |= REQUIRE_OSC;
197+
if(pfv >= pfv_midi1 && pfv <= pfv_midi8) sc->p->require |= REQUIRE_MIDI;
198+
if(pfv == pfv_video_a) sc->p->require |= REQUIRE_VIDEO;
199+
}
200+
200201
static void load_defaults(struct compiler_sc *sc)
201202
{
202203
int i;
@@ -257,27 +258,32 @@ static void all_initials_to_pfv(struct compiler_sc *sc)
257258
initial_to_pfv(sc, i);
258259
}
259260

261+
static void pfv_bind_callback(void *_sc, const char *sym, int reg)
262+
{
263+
struct compiler_sc *sc = _sc;
264+
int pfv;
265+
266+
pfv = pfv_from_name(sym);
267+
if(pfv >= 0) {
268+
pfv_update_patch_requires(sc, pfv);
269+
sc->p->pfv_allocation[pfv] = reg;
270+
}
271+
}
272+
260273
static bool init_pfv(struct compiler_sc *sc)
261274
{
262275
int i;
263276

264277
fpvm_init(&sc->pfv_fragment, 0);
265-
sc->pfv_fragment.bind_mode = 1; /* < keep user-defined variables from frame to frame */
266-
for(i=0;i<COMP_PFV_COUNT;i++) {
267-
sc->pfv_preallocation[i] = fpvm_bind(&sc->pfv_fragment, pfv_names[i]);
268-
if(sc->pfv_preallocation[i] == FPVM_INVALID_REG) {
269-
comp_report(sc, "failed to bind per-frame variable %s: %s", pfv_names[i], sc->pfv_fragment.last_error);
270-
return false;
271-
}
272-
}
278+
fpvm_set_bind_mode(&sc->pfv_fragment, 1);
279+
for(i=0;i<COMP_PFV_COUNT;i++)
280+
sc->p->pfv_allocation[i] = -1;
281+
fpvm_set_bind_callback(&sc->pfv_fragment, pfv_bind_callback, sc);
273282
return true;
274283
}
275284

276285
static bool finalize_pfv(struct compiler_sc *sc)
277286
{
278-
int i;
279-
int references[FPVM_MAXBINDINGS];
280-
281287
/* assign dummy values for output */
282288
if(!fpvm_assign(&sc->pfv_fragment, "_Xo", "_Xi")) goto fail_fpvm;
283289
if(!fpvm_assign(&sc->pfv_fragment, "_Yo", "_Yi")) goto fail_fpvm;
@@ -287,17 +293,9 @@ static bool finalize_pfv(struct compiler_sc *sc)
287293
fpvm_dump(&sc->pfv_fragment);
288294
#endif
289295

290-
/* Build variable allocation table */
291-
fpvm_get_references(&sc->pfv_fragment, references);
292-
for(i=0;i<COMP_PFV_COUNT;i++)
293-
if(references[sc->pfv_preallocation[i]])
294-
sc->p->pfv_allocation[i] = sc->pfv_preallocation[i];
295-
else
296-
sc->p->pfv_allocation[i] = -1;
297-
298296
return true;
299297
fail_fpvm:
300-
comp_report(sc, "failed to finalize per-frame variables: %s", sc->pfv_fragment.last_error);
298+
comp_report(sc, "failed to finalize per-frame variables: %s", fpvm_get_last_error(&sc->pfv_fragment));
301299
return false;
302300
}
303301

@@ -321,7 +319,7 @@ static bool schedule_pfv(struct compiler_sc *sc)
321319
static bool add_per_frame(struct compiler_sc *sc, char *dest, char *val)
322320
{
323321
if(!fpvm_assign(&sc->pfv_fragment, dest, val)) {
324-
comp_report(sc, "failed to add per-frame equation l. %d: %s", sc->linenr, sc->pfv_fragment.last_error);
322+
comp_report(sc, "failed to add per-frame equation l. %d: %s", sc->linenr, fpvm_get_last_error(&sc->pfv_fragment));
325323
return false;
326324
}
327325
return true;
@@ -392,39 +390,62 @@ static const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
392390
"midi8",
393391
};
394392

395-
static bool init_pvv(struct compiler_sc *sc)
393+
static int pvv_from_name(const char *name)
396394
{
397395
int i;
396+
397+
for(i=0;i<COMP_PVV_COUNT;i++) {
398+
if(strcmp(pvv_names[i], name) == 0)
399+
return i;
400+
}
401+
return -1;
402+
}
398403

399-
fpvm_init(&sc->pvv_fragment, 1);
404+
static void pvv_update_patch_requires(struct compiler_sc *sc, int pvv)
405+
{
406+
if(pvv >= pvv_idmx1 && pvv <= pvv_idmx8) sc->p->require |= REQUIRE_DMX;
407+
if(pvv >= pvv_osc1 && pvv <= pvv_osc4) sc->p->require |= REQUIRE_OSC;
408+
if(pvv >= pvv_midi1 && pvv <= pvv_midi8) sc->p->require |= REQUIRE_MIDI;
409+
}
400410

401-
for(i=0;i<COMP_PVV_COUNT;i++) {
402-
sc->pvv_preallocation[i] = fpvm_bind(&sc->pvv_fragment, pvv_names[i]);
403-
if(sc->pvv_preallocation[i] == FPVM_INVALID_REG) {
404-
comp_report(sc, "failed to bind per-vertex variable %s: %s", pvv_names[i], sc->pvv_fragment.last_error);
405-
return false;
406-
}
411+
static void pvv_bind_callback(void *_sc, const char *sym, int reg)
412+
{
413+
struct compiler_sc *sc = _sc;
414+
int pvv;
415+
416+
pvv = pvv_from_name(sym);
417+
if(pvv >= 0) {
418+
pvv_update_patch_requires(sc, pvv);
419+
sc->p->pvv_allocation[pvv] = reg;
407420
}
421+
}
422+
423+
static bool init_pvv(struct compiler_sc *sc)
424+
{
425+
int i;
426+
427+
fpvm_init(&sc->pvv_fragment, 1);
428+
fpvm_set_bind_mode(&sc->pvv_fragment, 1);
429+
for(i=0;i<COMP_PVV_COUNT;i++)
430+
sc->p->pvv_allocation[i] = -1;
431+
fpvm_set_bind_callback(&sc->pvv_fragment, pvv_bind_callback, sc);
408432

409433
#define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val)) goto fail_assign
410434
A("x", "i2f(_Xi)*_hmeshsize");
411435
A("y", "i2f(_Yi)*_vmeshsize");
412436
A("rad", "sqrt(sqr(x-0.5)+sqr(y-0.5))");
413437
/* TODO: generate ang */
414438
#undef A
415-
439+
416440
return true;
417441

418442
fail_assign:
419-
comp_report(sc, "failed to add equation to per-vertex header: %s", sc->pvv_fragment.last_error);
443+
comp_report(sc, "failed to add equation to per-vertex header: %s", fpvm_get_last_error(&sc->pvv_fragment));
420444
return false;
421445
}
422446

423447
static int finalize_pvv(struct compiler_sc *sc)
424448
{
425-
int i;
426-
int references[FPVM_MAXBINDINGS];
427-
428449
#define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val)) goto fail_assign
429450

430451
/* Zoom */
@@ -476,21 +497,12 @@ static int finalize_pvv(struct compiler_sc *sc)
476497
fpvm_dump(&sc->pvv_fragment);
477498
#endif
478499

479-
/* Build variable allocation table */
480-
fpvm_get_references(&sc->pvv_fragment, references);
481-
for(i=0;i<COMP_PVV_COUNT;i++)
482-
if(references[sc->pvv_preallocation[i]])
483-
sc->p->pvv_allocation[i] = sc->pvv_preallocation[i];
484-
else
485-
sc->p->pvv_allocation[i] = -1;
486-
487-
488500
return true;
489501
fail_assign:
490-
comp_report(sc, "failed to add equation to per-vertex footer: %s", sc->pvv_fragment.last_error);
502+
comp_report(sc, "failed to add equation to per-vertex footer: %s", fpvm_get_last_error(&sc->pvv_fragment));
491503
return false;
492504
fail_finalize:
493-
comp_report(sc, "failed to finalize per-vertex variables: %s", sc->pvv_fragment.last_error);
505+
comp_report(sc, "failed to finalize per-vertex variables: %s", fpvm_get_last_error(&sc->pvv_fragment));
494506
return false;
495507
}
496508

@@ -513,7 +525,7 @@ static bool schedule_pvv(struct compiler_sc *sc)
513525
static bool add_per_vertex(struct compiler_sc *sc, char *dest, char *val)
514526
{
515527
if(!fpvm_assign(&sc->pvv_fragment, dest, val)) {
516-
comp_report(sc, "failed to add per-vertex equation l. %d: %s\n", sc->linenr, sc->pvv_fragment.last_error);
528+
comp_report(sc, "failed to add per-vertex equation l. %d: %s\n", sc->linenr, fpvm_get_last_error(&sc->pvv_fragment));
517529
return false;
518530
}
519531
return true;
@@ -605,9 +617,10 @@ static bool process_top_assign(struct compiler_sc *sc, char *left, char *right)
605617
return true;
606618
}
607619

608-
pfv = pfv_from_name(sc, left);
620+
pfv = pfv_from_name(left);
609621
if(pfv >= 0) {
610622
/* patch initial condition or global parameter */
623+
pfv_update_patch_requires(sc, pfv);
611624
set_initial(sc, pfv, atof(right));
612625
return true;
613626
}

0 commit comments

Comments
 (0)
Please sign in to comment.