Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

compiler: better register allocator

  • Loading branch information...
commit bdc87f6c821012008df36df8bde17eef7d710e03 1 parent de3210b
Sébastien Bourdeauducq authored November 24, 2011

Showing 1 changed file with 70 additions and 57 deletions. Show diff stats Hide diff stats

  1. 127  src/renderer/compiler.c
127  src/renderer/compiler.c
@@ -36,10 +36,7 @@ struct compiler_sc {
36 36
 	int linenr;
37 37
 
38 38
 	struct fpvm_fragment pfv_fragment;
39  
-	int pfv_preallocation[COMP_PFV_COUNT];	/* < where per-frame variables can be mapped in PFPU regf */
40  
-
41 39
 	struct fpvm_fragment pvv_fragment;
42  
-	int pvv_preallocation[COMP_PVV_COUNT];	/* < where per-vertex variables can be mapped in PFPU regf */
43 40
 };
44 41
 
45 42
 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] = {
173 170
 	"image2_zoom"
174 171
 };
175 172
 
176  
-static int pfv_from_name(struct compiler_sc *sc, const char *name)
  173
+static int pfv_from_name(const char *name)
177 174
 {
178 175
 	int i;
  176
+	
179 177
 	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)
185 179
 			return i;
186  
-		}
187 180
 	}
188 181
 
189 182
 	if(strcmp(name, "fDecay") == 0) return pfv_decay;
@@ -197,6 +190,14 @@ static int pfv_from_name(struct compiler_sc *sc, const char *name)
197 190
 	return -1;
198 191
 }
199 192
 
  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
+
200 201
 static void load_defaults(struct compiler_sc *sc)
201 202
 {
202 203
 	int i;
@@ -257,27 +258,32 @@ static void all_initials_to_pfv(struct compiler_sc *sc)
257 258
 		initial_to_pfv(sc, i);
258 259
 }
259 260
 
  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
+
260 273
 static bool init_pfv(struct compiler_sc *sc)
261 274
 {
262 275
 	int i;
263 276
 
264 277
 	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);
273 282
 	return true;
274 283
 }
275 284
 
276 285
 static bool finalize_pfv(struct compiler_sc *sc)
277 286
 {
278  
-	int i;
279  
-	int references[FPVM_MAXBINDINGS];
280  
-
281 287
 	/* assign dummy values for output */
282 288
 	if(!fpvm_assign(&sc->pfv_fragment, "_Xo", "_Xi")) goto fail_fpvm;
283 289
 	if(!fpvm_assign(&sc->pfv_fragment, "_Yo", "_Yi")) goto fail_fpvm;
@@ -287,17 +293,9 @@ static bool finalize_pfv(struct compiler_sc *sc)
287 293
 	fpvm_dump(&sc->pfv_fragment);
288 294
 	#endif
289 295
 
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  
-
298 296
 	return true;
299 297
 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));
301 299
 	return false;
302 300
 }
303 301
 
@@ -321,7 +319,7 @@ static bool schedule_pfv(struct compiler_sc *sc)
321 319
 static bool add_per_frame(struct compiler_sc *sc, char *dest, char *val)
322 320
 {
323 321
 	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));
325 323
 		return false;
326 324
 	}
327 325
 	return true;
@@ -392,19 +390,45 @@ static const char pvv_names[COMP_PVV_COUNT][FPVM_MAXSYMLEN] = {
392 390
 	"midi8",
393 391
 };
394 392
 
395  
-static bool init_pvv(struct compiler_sc *sc)
  393
+static int pvv_from_name(const char *name)
396 394
 {
397 395
 	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
+}
398 403
 
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
+}
400 410
 
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;
407 420
 	}
  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);
408 432
 
409 433
 	#define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val)) goto fail_assign
410 434
 	A("x", "i2f(_Xi)*_hmeshsize");
@@ -412,19 +436,16 @@ static bool init_pvv(struct compiler_sc *sc)
412 436
 	A("rad", "sqrt(sqr(x-0.5)+sqr(y-0.5))");
413 437
 	/* TODO: generate ang */
414 438
 	#undef A
415  
-
  439
+	
416 440
 	return true;
417 441
 
418 442
 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));
420 444
 	return false;
421 445
 }
422 446
 
423 447
 static int finalize_pvv(struct compiler_sc *sc)
424 448
 {
425  
-	int i;
426  
-	int references[FPVM_MAXBINDINGS];
427  
-
428 449
 	#define A(dest, val) if(!fpvm_assign(&sc->pvv_fragment, dest, val)) goto fail_assign
429 450
 
430 451
 	/* Zoom */
@@ -476,21 +497,12 @@ static int finalize_pvv(struct compiler_sc *sc)
476 497
 	fpvm_dump(&sc->pvv_fragment);
477 498
 	#endif
478 499
 
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  
-
488 500
 	return true;
489 501
 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));
491 503
 	return false;
492 504
 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));
494 506
 	return false;
495 507
 }
496 508
 
@@ -513,7 +525,7 @@ static bool schedule_pvv(struct compiler_sc *sc)
513 525
 static bool add_per_vertex(struct compiler_sc *sc, char *dest, char *val)
514 526
 {
515 527
 	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));
517 529
 		return false;
518 530
 	}
519 531
 	return true;
@@ -605,9 +617,10 @@ static bool process_top_assign(struct compiler_sc *sc, char *left, char *right)
605 617
 		return true;
606 618
 	}
607 619
 
608  
-	pfv = pfv_from_name(sc, left);
  620
+	pfv = pfv_from_name(left);
609 621
 	if(pfv >= 0) {
610 622
 		/* patch initial condition or global parameter */
  623
+		pfv_update_patch_requires(sc, pfv);
611 624
 		set_initial(sc, pfv, atof(right));
612 625
 		return true;
613 626
 	}

0 notes on commit bdc87f6

Please sign in to comment.
Something went wrong with that request. Please try again.