summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50/nv50_pc_optimize.c
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-09-07 15:40:34 +0200
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-09-09 19:21:34 +0200
commitd91b8865ec2bb41f9b58ad5ce2df7f6f48f98281 (patch)
treebc6ff85f2f891b9b05124cc1f8ec874159a3ace0 /src/gallium/drivers/nv50/nv50_pc_optimize.c
parent217542a061ef31150b1b04f1b45b6099bcc153fe (diff)
nv50: prepare for having multiple functions
At some point we'll want to support real subroutines instead of just inlining them into the main shader. Since recursive calls are forbidden, we can just save all used registers to a fixed local memory region and restore them on a return, no need for a stack pointer.
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_pc_optimize.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_optimize.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c
index 1ed5032175..4f5bdc1f9f 100644
--- a/src/gallium/drivers/nv50/nv50_pc_optimize.c
+++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c
@@ -213,23 +213,36 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b)
pc->bin_size += b->bin_size *= 4;
}
-int
-nv_pc_exec_pass2(struct nv_pc *pc)
+static int
+nv_pc_pass2(struct nv_pc *pc, struct nv_basic_block *root)
{
struct nv_pass pass;
pass.pc = pc;
pc->pass_seq++;
- nv_pass_flatten(&pass, pc->root);
+
+ nv_pass_flatten(&pass, root);
+
+ nv_pc_pass_in_order(root, nv_pc_pass_pre_emission, pc);
+
+ return 0;
+}
+
+int
+nv_pc_exec_pass2(struct nv_pc *pc)
+{
+ int i, ret;
NV50_DBGMSG("preparing %u blocks for emission\n", pc->num_blocks);
- pc->bb_list = CALLOC(pc->num_blocks, sizeof(struct nv_basic_block *));
- pc->num_blocks = 0;
+ pc->bb_list = CALLOC(pc->num_blocks, sizeof(pc->bb_list[0]));
- nv_pc_pass_in_order(pc->root, nv_pc_pass_pre_emission, pc);
+ pc->num_blocks = 0;
+ for (i = 0; i < pc->num_subroutines + 1; ++i)
+ if (pc->root[i] && (ret = nv_pc_pass2(pc, pc->root[i])))
+ return ret;
return 0;
}
@@ -1032,8 +1045,8 @@ nv_pass_cse(struct nv_pass *ctx, struct nv_basic_block *b)
return 0;
}
-int
-nv_pc_exec_pass0(struct nv_pc *pc)
+static int
+nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root)
{
struct nv_pass_reld_elim *reldelim;
struct nv_pass pass;
@@ -1047,35 +1060,35 @@ nv_pc_exec_pass0(struct nv_pc *pc)
* to whether sources are supported memory loads.
*/
pc->pass_seq++;
- ret = nv_pass_lower_arith(&pass, pc->root);
+ ret = nv_pass_lower_arith(&pass, root);
if (ret)
return ret;
pc->pass_seq++;
- ret = nv_pass_fold_loads(&pass, pc->root);
+ ret = nv_pass_fold_loads(&pass, root);
if (ret)
return ret;
pc->pass_seq++;
- ret = nv_pass_fold_stores(&pass, pc->root);
+ ret = nv_pass_fold_stores(&pass, root);
if (ret)
return ret;
reldelim = CALLOC_STRUCT(nv_pass_reld_elim);
reldelim->pc = pc;
pc->pass_seq++;
- ret = nv_pass_reload_elim(reldelim, pc->root);
+ ret = nv_pass_reload_elim(reldelim, root);
FREE(reldelim);
if (ret)
return ret;
pc->pass_seq++;
- ret = nv_pass_cse(&pass, pc->root);
+ ret = nv_pass_cse(&pass, root);
if (ret)
return ret;
pc->pass_seq++;
- ret = nv_pass_lower_mods(&pass, pc->root);
+ ret = nv_pass_lower_mods(&pass, root);
if (ret)
return ret;
@@ -1083,14 +1096,25 @@ nv_pc_exec_pass0(struct nv_pc *pc)
do {
dce.removed = 0;
pc->pass_seq++;
- ret = nv_pass_dce(&dce, pc->root);
+ ret = nv_pass_dce(&dce, root);
if (ret)
return ret;
} while (dce.removed);
- ret = nv_pass_tex_mask(&pass, pc->root);
+ ret = nv_pass_tex_mask(&pass, root);
if (ret)
return ret;
return ret;
}
+
+int
+nv_pc_exec_pass0(struct nv_pc *pc)
+{
+ int i, ret;
+
+ for (i = 0; i < pc->num_subroutines + 1; ++i)
+ if (pc->root[i] && (ret = nv_pc_pass0(pc, pc->root[i])))
+ return ret;
+ return 0;
+}