summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-10-16 22:15:27 +0200
committerBenjamin Otte <otte@redhat.com>2017-10-30 02:58:03 +0100
commit8d5fce4c6971afbb48453b6c7298700c00352d77 (patch)
treefba96a33c45c006247b49f114301011e78627372
parentfd83132d76429d6ad1d1f3931395300561d49da7 (diff)
downloadgtk+-8d5fce4c6971afbb48453b6c7298700c00352d77.tar.gz
gskspv: Change the way we deal with labels
Instead of having a code block abstraction, just make code deal with label ids instead. that way, code can just use gsk_spv_writer_make_id() and pass that ID to the label func. This simplifies code a lot as it allows special treatment of those labels at eg the beginning of functions which can be kept local to where it happens.
-rw-r--r--gsk/gskslexpression.c42
-rw-r--r--gsk/gskslfunction.c8
-rw-r--r--gsk/gskslstatement.c52
-rw-r--r--gsk/gskspvwriter.c81
-rw-r--r--gsk/gskspvwritergeneratedprivate.h10
-rw-r--r--gsk/gskspvwriterprivate.h16
-rw-r--r--gsk/spirv.js16
7 files changed, 84 insertions, 141 deletions
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 148acd2a22..a4593f0d23 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -362,32 +362,25 @@ gsk_sl_expression_logical_and_write_spv (const GskSlExpression *expression,
GskSpvWriter *writer)
{
const GskSlExpressionLogicalAnd *logical_and = (const GskSlExpressionLogicalAnd *) expression;
- GskSpvCodeBlock *current_block, *after_block, *and_block;
guint32 current_id, after_id, and_id, left_id, right_id, result_id;
left_id = gsk_sl_expression_write_spv (logical_and->left, writer);
- current_block = gsk_spv_writer_pop_code_block (writer);
- current_id = gsk_spv_code_block_get_label (current_block);
- gsk_spv_writer_push_code_block (writer, current_block);
-
- and_id = gsk_spv_writer_push_new_code_block (writer);
- and_block = gsk_spv_writer_pop_code_block (writer);
-
- after_id = gsk_spv_writer_push_new_code_block (writer);
- after_block = gsk_spv_writer_pop_code_block (writer);
+ current_id = gsk_spv_writer_get_label_id (writer);
+ and_id = gsk_spv_writer_make_id (writer);
+ after_id = gsk_spv_writer_make_id (writer);
/* mirror glslang */
gsk_spv_writer_selection_merge (writer, after_id, 0);
gsk_spv_writer_branch_conditional (writer, left_id, and_id, after_id, NULL, 0);
- gsk_spv_writer_push_code_block (writer, and_block);
+ gsk_spv_writer_start_code_block (writer, and_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, and_id);
right_id = gsk_sl_expression_write_spv (logical_and->right, writer);
gsk_spv_writer_branch (writer, after_id);
- gsk_spv_writer_commit_code_block (writer);
- gsk_spv_writer_push_code_block (writer, after_block);
- gsk_spv_writer_commit_code_block (writer);
+ gsk_spv_writer_start_code_block (writer, after_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, after_id);
result_id = gsk_spv_writer_phi (writer,
gsk_sl_type_get_scalar (GSK_SL_BOOL),
@@ -482,33 +475,26 @@ gsk_sl_expression_logical_or_write_spv (const GskSlExpression *expression,
GskSpvWriter *writer)
{
const GskSlExpressionLogicalOr *logical_or = (const GskSlExpressionLogicalOr *) expression;
- GskSpvCodeBlock *current_block, *after_block, *or_block;
guint32 current_id, condition_id, after_id, or_id, left_id, right_id, result_id;
left_id = gsk_sl_expression_write_spv (logical_or->left, writer);
- current_block = gsk_spv_writer_pop_code_block (writer);
- current_id = gsk_spv_code_block_get_label (current_block);
- gsk_spv_writer_push_code_block (writer, current_block);
-
- or_id = gsk_spv_writer_push_new_code_block (writer);
- or_block = gsk_spv_writer_pop_code_block (writer);
-
- after_id = gsk_spv_writer_push_new_code_block (writer);
- after_block = gsk_spv_writer_pop_code_block (writer);
+ current_id = gsk_spv_writer_get_label_id (writer);
+ or_id = gsk_spv_writer_make_id (writer);
+ after_id = gsk_spv_writer_make_id (writer);
/* mirror glslang */
condition_id = gsk_spv_writer_logical_not (writer, gsk_sl_type_get_scalar (GSK_SL_BOOL), left_id);
gsk_spv_writer_selection_merge (writer, after_id, 0);
gsk_spv_writer_branch_conditional (writer, condition_id, or_id, after_id, NULL, 0);
- gsk_spv_writer_push_code_block (writer, or_block);
+ gsk_spv_writer_start_code_block (writer, or_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, or_id);
right_id = gsk_sl_expression_write_spv (logical_or->right, writer);
gsk_spv_writer_branch (writer, after_id);
- gsk_spv_writer_commit_code_block (writer);
- gsk_spv_writer_push_code_block (writer, after_block);
- gsk_spv_writer_commit_code_block (writer);
+ gsk_spv_writer_start_code_block (writer, after_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, after_id);
result_id = gsk_spv_writer_phi (writer,
gsk_sl_type_get_scalar (GSK_SL_BOOL),
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 7696b09dd5..c64b7af0bb 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -424,7 +424,7 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
gpointer initializer_data)
{
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
- guint32 function_type_id, function_id;
+ guint32 function_type_id, function_id, label_id;
GskSlType *return_type;
gsize i;
@@ -447,7 +447,9 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
gsk_spv_writer_name (writer, function_id, declared->name);
/* add function body */
- gsk_spv_writer_push_new_code_block (writer);
+ label_id = gsk_spv_writer_make_id (writer);
+ gsk_spv_writer_start_code_block (writer, label_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_DECLARE, label_id);
if (initializer)
initializer (writer, initializer_data);
@@ -457,8 +459,6 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
gsk_spv_writer_function_end (writer);
- gsk_spv_writer_commit_code_block (writer);
-
return function_id;
}
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index f230dfeb85..cc54593b1e 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -403,53 +403,35 @@ gsk_sl_statement_if_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
{
GskSlStatementIf *if_stmt = (GskSlStatementIf *) statement;
- guint32 if_id, else_id, condition_id;
- GskSpvCodeBlock *if_block, *else_block, *after_block;
+ guint32 if_id, else_id, after_id, condition_id;
condition_id = gsk_sl_expression_write_spv (if_stmt->condition, writer);
- gsk_spv_writer_push_new_code_block (writer);
- if_block = gsk_spv_writer_pop_code_block (writer);
- if_id = gsk_spv_code_block_get_label (if_block);
- gsk_spv_writer_push_new_code_block (writer);
- after_block = gsk_spv_writer_pop_code_block (writer);
-
- gsk_spv_writer_push_code_block (writer, if_block);
- if (!gsk_sl_statement_write_spv (if_stmt->if_part, writer))
- gsk_spv_writer_branch (writer,
- gsk_spv_code_block_get_label (after_block));
- gsk_spv_writer_pop_code_block (writer);
-
+ if_id = gsk_spv_writer_make_id (writer);
+ after_id = gsk_spv_writer_make_id (writer);
if (if_stmt->else_part)
- {
- else_id = gsk_spv_writer_push_new_code_block (writer);
- if (!gsk_sl_statement_write_spv (if_stmt->else_part, writer))
- gsk_spv_writer_branch (writer,
- gsk_spv_code_block_get_label (after_block));
- else_block = gsk_spv_writer_pop_code_block (writer);
- }
+ else_id = gsk_spv_writer_make_id (writer);
else
- {
- else_id = gsk_spv_code_block_get_label (after_block);
- else_block = NULL;
- }
+ else_id = after_id;
- gsk_spv_writer_selection_merge (writer,
- gsk_spv_code_block_get_label (after_block),
- 0);
+ gsk_spv_writer_selection_merge (writer, after_id, 0);
gsk_spv_writer_branch_conditional (writer, condition_id, if_id, else_id, NULL, 0);
- gsk_spv_writer_push_code_block (writer, if_block);
- gsk_spv_writer_commit_code_block (writer);
+ gsk_spv_writer_start_code_block (writer, if_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, if_id);
+ if (!gsk_sl_statement_write_spv (if_stmt->if_part, writer))
+ gsk_spv_writer_branch (writer, after_id);
- if (else_block)
+ if (if_stmt->else_part)
{
- gsk_spv_writer_push_code_block (writer, else_block);
- gsk_spv_writer_commit_code_block (writer);
+ gsk_spv_writer_start_code_block (writer, else_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, else_id);
+ if (!gsk_sl_statement_write_spv (if_stmt->else_part, writer))
+ gsk_spv_writer_branch (writer, after_id);
}
- gsk_spv_writer_push_code_block (writer, after_block);
- gsk_spv_writer_commit_code_block (writer);
+ gsk_spv_writer_start_code_block (writer, after_id, 0, 0);
+ gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, after_id);
return FALSE;
}
diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c
index 3bfb3ded5e..625d1eb06d 100644
--- a/gsk/gskspvwriter.c
+++ b/gsk/gskspvwriter.c
@@ -27,6 +27,7 @@
#include "gskslvalueprivate.h"
#include "gskslvariableprivate.h"
+typedef struct _GskSpvCodeBlock GskSpvCodeBlock;
typedef struct _GskSpvPointerType GskSpvPointerType;
struct _GskSpvPointerType
@@ -39,7 +40,9 @@ struct _GskSpvCodeBlock
{
GArray *code[GSK_SPV_WRITER_N_BLOCK_SECTIONS];
- guint32 label;
+ guint32 label_id;
+ guint32 continue_id;
+ guint32 break_id;
};
struct _GskSpvWriter
@@ -199,13 +202,11 @@ gsk_spv_writer_write_function (GskSpvWriter *writer,
g_assert (g_hash_table_lookup (writer->functions, function) == NULL);
block = gsk_spv_code_block_new ();
- gsk_spv_writer_push_code_block (writer, block);
+ writer->blocks = g_slist_prepend (writer->blocks, block);
result = gsk_sl_function_write_spv (function, writer, initializer, initializer_data);
g_hash_table_insert (writer->functions, gsk_sl_function_ref (function), GUINT_TO_POINTER (result));
- if (block != gsk_spv_writer_pop_code_block (writer))
- {
- g_assert_not_reached ();
- }
+ g_assert (writer->blocks->data == block);
+ writer->blocks = g_slist_remove (writer->blocks, block);
writer->pending_blocks = g_slist_prepend (writer->pending_blocks, block);
return result;
@@ -544,67 +545,45 @@ gsk_spv_writer_get_bytes (GskSpvWriter *writer,
return ((GskSpvCodeBlock *) writer->blocks->data)->code[section - GSK_SPV_WRITER_SECTION_BLOCK_FIRST];
}
-guint32
-gsk_spv_writer_push_new_code_block (GskSpvWriter *writer)
+void
+gsk_spv_writer_start_code_block (GskSpvWriter *writer,
+ guint32 label_id,
+ guint32 continue_id,
+ guint32 break_id)
{
GskSpvCodeBlock *block;
- GskSpvWriterSection label_section;
-
- block = gsk_spv_code_block_new ();
- /* This is ugly code that ensures the function block label
- * goes before variables but subblock labels do not.
- */
- if (writer->blocks && writer->blocks->next)
- label_section = GSK_SPV_WRITER_SECTION_CODE;
- else
- label_section = GSK_SPV_WRITER_SECTION_DECLARE;
-
- gsk_spv_writer_push_code_block (writer, block);
- block->label = gsk_spv_writer_label (writer, label_section);
+ block = writer->blocks->data;
- return block->label;
+ block->label_id = label_id;
+ if (continue_id != 0)
+ block->continue_id = continue_id;
+ if (break_id != 0)
+ block->break_id = break_id;
}
-void
-gsk_spv_writer_push_code_block (GskSpvWriter *writer,
- GskSpvCodeBlock *block)
-{
- writer->blocks = g_slist_prepend (writer->blocks, block);
-}
-
-GskSpvCodeBlock *
-gsk_spv_writer_pop_code_block (GskSpvWriter *writer)
+guint32
+gsk_spv_writer_get_label_id (GskSpvWriter *writer)
{
- GskSpvCodeBlock *result;
-
- result = writer->blocks->data;
- g_assert (result);
+ GskSpvCodeBlock *block = writer->blocks->data;
- writer->blocks = g_slist_remove (writer->blocks, result);
-
- return result;
+ return block->label_id;
}
-void
-gsk_spv_writer_commit_code_block (GskSpvWriter *writer)
+guint32
+gsk_spv_writer_get_continue_id (GskSpvWriter *writer)
{
- GskSpvCodeBlock *block, *target;
- guint i;
-
- block = gsk_spv_writer_pop_code_block (writer);
- target = writer->blocks->data;
+ GskSpvCodeBlock *block = writer->blocks->data;
- for (i = 0; i < GSK_SPV_WRITER_N_BLOCK_SECTIONS; i++)
- g_array_append_vals (target->code[i], block->code[i]->data, block->code[i]->len);
-
- gsk_spv_code_block_free (block);
+ return block->continue_id;
}
guint32
-gsk_spv_code_block_get_label (GskSpvCodeBlock *block)
+gsk_spv_writer_get_break_id (GskSpvWriter *writer)
{
- return block->label;
+ GskSpvCodeBlock *block = writer->blocks->data;
+
+ return block->break_id;
}
static void
diff --git a/gsk/gskspvwritergeneratedprivate.h b/gsk/gskspvwritergeneratedprivate.h
index 5985b01f1b..469ba56265 100644
--- a/gsk/gskspvwritergeneratedprivate.h
+++ b/gsk/gskspvwritergeneratedprivate.h
@@ -4511,19 +4511,17 @@ gsk_spv_writer_selection_merge (GskSpvWriter *writer,
g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | GSK_SPV_OP_SELECTION_MERGE;
}
-static inline guint32
+static inline void
gsk_spv_writer_label (GskSpvWriter *writer,
- GskSpvWriterSection section)
+ GskSpvWriterSection section,
+ guint32 result)
{
GArray *bytes = gsk_spv_writer_get_bytes (writer, section);
- guint32 result_id = gsk_spv_writer_make_id (writer);
guint start_index = bytes->len;
g_array_append_val (bytes, (guint32) { 0 });
- g_array_append_val (bytes, result_id);
+ g_array_append_val (bytes, result);
g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | GSK_SPV_OP_LABEL;
-
- return result_id;
}
static inline void
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index e7b541b297..f745362340 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -32,8 +32,6 @@ G_BEGIN_DECLS
#define GSK_SPV_VERSION_MINOR 0
#define GSK_SPV_GENERATOR 0
-typedef struct _GskSpvCodeBlock GskSpvCodeBlock;
-
typedef enum {
GSK_SPV_WRITER_SECTION_HEADER,
GSK_SPV_WRITER_SECTION_DEBUG,
@@ -88,13 +86,13 @@ guint32 gsk_spv_writer_convert (GskSpvWriter
GskSlType *type,
GskSlType *new_type);
-guint32 gsk_spv_writer_push_new_code_block (GskSpvWriter *writer);
-void gsk_spv_writer_push_code_block (GskSpvWriter *writer,
- GskSpvCodeBlock *block);
-GskSpvCodeBlock * gsk_spv_writer_pop_code_block (GskSpvWriter *writer);
-void gsk_spv_writer_commit_code_block (GskSpvWriter *writer);
-
-guint32 gsk_spv_code_block_get_label (GskSpvCodeBlock *block);
+guint32 gsk_spv_writer_get_label_id (GskSpvWriter *writer);
+guint32 gsk_spv_writer_get_continue_id (GskSpvWriter *writer);
+guint32 gsk_spv_writer_get_break_id (GskSpvWriter *writer);
+void gsk_spv_writer_start_code_block (GskSpvWriter *writer,
+ guint32 label_id,
+ guint32 continue_id,
+ guint32 break_id);
GskSpvAccessChain * gsk_spv_access_chain_new (GskSpvWriter *writer,
GskSlVariable *variable);
diff --git a/gsk/spirv.js b/gsk/spirv.js
index c67451abcd..acef648eef 100644
--- a/gsk/spirv.js
+++ b/gsk/spirv.js
@@ -91,7 +91,8 @@ var SpecialTypes = {
"OpPtrCastToGeneric": { "result_type": "IdResultPointerType" },
"OpGenericCastToPtr": { "result_type": "IdResultPointerType" },
"OpGenericCastToPtrExplicit": { "result_type": "IdResultPointerType" },
- "OpFunctionParameter": { "result_type": "IdRef" }
+ "OpFunctionParameter": { "result_type": "IdRef" },
+ "OpLabel": { "result": "IdRef" }
};
var ExtraOperands = {
@@ -497,18 +498,17 @@ function fix_operand (ins, o)
}
if (!o.varname)
throw new TypeError (o.name + " of type " + o.kind + " has no variable name");
+ let operand;
+ if (SpecialTypes[ins.opname] &&
+ SpecialTypes[ins.opname][o.varname])
+ o.kind = SpecialTypes[ins.opname][o.varname];
+ operand = Operands[o.kind];
+
if (o.varname == "default")
o.varname += "_";
if (o.kind == "IdResult")
ins.result = true;
- let operand;
- if (SpecialTypes[ins.opname] &&
- SpecialTypes[ins.opname][o.varname])
- operand = Operands[SpecialTypes[ins.opname][o.varname]];
- else
- operand = Operands[o.kind];
-
o.ctype = operand.ctype;
if (operand.append_one)
o.append_one = operand.append_one;