diff options
author | Christoph Bumiller <[email protected]> | 2010-09-01 17:54:56 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-09-01 18:02:50 +0200 |
commit | 0a8292e096bc37eeb225bf7d3854b6b6edc4bceb (patch) | |
tree | 80bbb0365721665a8ff932e7b6ccb7a7c44a3e5c /src/gallium/drivers/nv50/nv50_pc.c | |
parent | d90502b2b468732e2a42985580bbbe9d9fdfd14e (diff) |
nv50: attempt at making more complicated loops work
Nested loops, and loops with multiple exits (BREAK, CONT).
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_pc.c')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_pc.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc.c b/src/gallium/drivers/nv50/nv50_pc.c index 1c12fe1b9e7..b03f5b27f60 100644 --- a/src/gallium/drivers/nv50/nv50_pc.c +++ b/src/gallium/drivers/nv50/nv50_pc.c @@ -220,6 +220,7 @@ edge_name(ubyte type) case CFG_EDGE_BACK: return "back"; case CFG_EDGE_LOOP_ENTER: return "loop"; case CFG_EDGE_LOOP_LEAVE: return "break"; + case CFG_EDGE_FAKE: return "fake"; default: return "?"; } @@ -247,6 +248,7 @@ nv_pc_pass_in_order(struct nv_basic_block *root, nv_pc_pass_func f, void *priv) case CFG_EDGE_BACK: continue; case CFG_EDGE_FORWARD: + case CFG_EDGE_FAKE: if (++b->out[j]->priv == b->out[j]->num_in) bb[p++] = b->out[j]; break; @@ -264,9 +266,11 @@ nv_pc_pass_in_order(struct nv_basic_block *root, nv_pc_pass_func f, void *priv) f(priv, b); - if (!p) - while (pp > 0) - bb[p++] = bbb[--pp]; + if (!p) { + p = pp; + for (; pp > 0; --pp) + bb[pp - 1] = bbb[pp - 1]; + } } } @@ -366,11 +370,17 @@ nv50_generate_code(struct nv50_translation_info *ti) ret = nv_pc_exec_pass0(pc); if (ret) goto out; +#ifdef NV50PC_DEBUG + nv_print_program(pc->root); +#endif /* register allocation */ ret = nv_pc_exec_pass1(pc); if (ret) goto out; +#ifdef NV50PC_DEBUG + nv_print_program(pc->root); +#endif /* prepare for emission */ ret = nv_pc_exec_pass2(pc); @@ -580,10 +590,10 @@ nvbb_reachable_by(struct nv_basic_block *bf, struct nv_basic_block *bp, if (bp == bt) return FALSE; - if (bp->out[0] && bp->out_kind[0] != CFG_EDGE_BACK && + if (bp->out[0] && !IS_WALL_EDGE(bp->out_kind[0]) && nvbb_reachable_by(bf, bp->out[0], bt)) return TRUE; - if (bp->out[1] && bp->out_kind[1] != CFG_EDGE_BACK && + if (bp->out[1] && !IS_WALL_EDGE(bp->out_kind[1]) && nvbb_reachable_by(bf, bp->out[1], bt)) return TRUE; return FALSE; |