summaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorConnor Abbott <[email protected]>2015-07-21 19:54:32 -0700
committerKenneth Graunke <[email protected]>2015-08-24 13:31:42 -0700
commitd356f84d4ceb9fb63e4b254ab8b26ce891c2f2b9 (patch)
tree1d5f8f64a205456fef0518b6eafb4506f6d49c1a /src/glsl
parent58a360c6b8aead1fec34aea298654ab544e7c8e8 (diff)
nir/cf: add split_block_cursor()
This is a helper that will be shared between the new control flow insertion and modification code. Signed-off-by: Connor Abbott <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/nir/nir_control_flow.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/glsl/nir/nir_control_flow.c b/src/glsl/nir/nir_control_flow.c
index fcdabc75a82..935ec9f2c47 100644
--- a/src/glsl/nir/nir_control_flow.c
+++ b/src/glsl/nir/nir_control_flow.c
@@ -394,6 +394,54 @@ split_block_before_instr(nir_instr *instr)
return new_block;
}
+/* Splits a basic block at the point specified by the cursor. The "before" and
+ * "after" arguments are filled out with the blocks resulting from the split
+ * if non-NULL. Note that the "beginning" of the block is actually interpreted
+ * as before the first non-phi instruction, and it's illegal to split a block
+ * before a phi instruction.
+ */
+
+static void
+split_block_cursor(nir_cursor cursor,
+ nir_block **_before, nir_block **_after)
+{
+ nir_block *before, *after;
+ switch (cursor.option) {
+ case nir_cursor_before_block:
+ after = cursor.block;
+ before = split_block_beginning(cursor.block);
+ break;
+
+ case nir_cursor_after_block:
+ before = cursor.block;
+ after = split_block_end(cursor.block);
+ break;
+
+ case nir_cursor_before_instr:
+ after = cursor.instr->block;
+ before = split_block_before_instr(cursor.instr);
+ break;
+
+ case nir_cursor_after_instr:
+ /* We lower this to split_block_before_instr() so that we can keep the
+ * after-a-jump-instr case contained to split_block_end().
+ */
+ if (nir_instr_is_last(cursor.instr)) {
+ before = cursor.instr->block;
+ after = split_block_end(cursor.instr->block);
+ } else {
+ after = cursor.instr->block;
+ before = split_block_before_instr(nir_instr_next(cursor.instr));
+ }
+ break;
+ }
+
+ if (_before)
+ *_before = before;
+ if (_after)
+ *_after = after;
+}
+
/**
* Inserts a non-basic block between two basic blocks and links them together.
*/