[gtk+/wip/otte/shader: 47/55] gskslstatement: Add gsk_sl_Stement_get_jump()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 47/55] gskslstatement: Add gsk_sl_Stement_get_jump()
- Date: Mon, 2 Oct 2017 03:39:39 +0000 (UTC)
commit b0e37747ccbd6e5c89c84f9b10816e11984e3bf3
Author: Benjamin Otte <otte redhat com>
Date: Sun Oct 1 05:07:48 2017 +0200
gskslstatement: Add gsk_sl_Stement_get_jump()
This queries where a statement jumps to after it is done. The enum is
sorted by importance, larger values jump further.
We use this to do 3 things:
1. Error out if the function body statement does not return a value from
a non-void function.
2. Make sure to emit a Return as last instruction in a function body
3. Print a warning about dead code when statements follow a jump.
gsk/gskslcompiler.h | 1 +
gsk/gskslfunction.c | 14 +++++++++
gsk/gskslstatement.c | 68 +++++++++++++++++++++++++++++++++++++++++++
gsk/gskslstatementprivate.h | 10 ++++++
4 files changed, 93 insertions(+), 0 deletions(-)
---
diff --git a/gsk/gskslcompiler.h b/gsk/gskslcompiler.h
index ea56d27..6f0d741 100644
--- a/gsk/gskslcompiler.h
+++ b/gsk/gskslcompiler.h
@@ -42,6 +42,7 @@ typedef enum {
typedef enum {
GSK_SL_COMPILER_WARNING_CONSTANT,
+ GSK_SL_COMPILER_WARNING_DEAD_CODE,
GSK_SL_COMPILER_WARNING_SHADOW
} GskSlCompilerWarning;
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index bbcf0cc..bd9a0f3 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -429,6 +429,14 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
gsk_sl_statement_write_spv (declared->statement, writer);
+ if (gsk_sl_type_is_void (declared->return_type) &&
+ gsk_sl_statement_get_jump (declared->statement) < GSK_SL_JUMP_RETURN)
+ {
+ gsk_spv_writer_add (writer,
+ GSK_SPV_WRITER_SECTION_CODE,
+ 1, GSK_SPV_OP_RETURN,
+ NULL);
+ }
gsk_spv_writer_add (writer,
GSK_SPV_WRITER_SECTION_CODE,
1, GSK_SPV_OP_FUNCTION_END,
@@ -594,6 +602,12 @@ gsk_sl_function_new_parse (GskSlScope *scope,
function->statement = gsk_sl_statement_parse_compound (function->scope, preproc, FALSE);
+ if (!gsk_sl_type_is_void (function->return_type) &&
+ gsk_sl_statement_get_jump (function->statement) < GSK_SL_JUMP_RETURN)
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Function does not return a value.");
+ }
+
return (GskSlFunction *) function;
}
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index 2932196..6cb8ad8 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -46,6 +46,7 @@ struct _GskSlStatementClass {
void (* print) (const GskSlStatement *statement,
GskSlPrinter *printer);
+ GskSlJump (* get_jump) (const GskSlStatement *statement);
void (* write_spv) (const GskSlStatement *statement,
GskSpvWriter *writer);
};
@@ -88,6 +89,12 @@ gsk_sl_statement_empty_print (const GskSlStatement *statement,
gsk_sl_printer_append (printer, ";");
}
+static GskSlJump
+gsk_sl_statement_empty_get_jump (const GskSlStatement *statement)
+{
+ return GSK_SL_JUMP_NONE;
+}
+
static void
gsk_sl_statement_empty_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
@@ -97,6 +104,7 @@ gsk_sl_statement_empty_write_spv (const GskSlStatement *statement,
static const GskSlStatementClass GSK_SL_STATEMENT_EMPTY = {
gsk_sl_statement_empty_free,
gsk_sl_statement_empty_print,
+ gsk_sl_statement_empty_get_jump,
gsk_sl_statement_empty_write_spv
};
@@ -142,6 +150,20 @@ gsk_sl_statement_compound_print (const GskSlStatement *statement,
gsk_sl_printer_append (printer, "}");
}
+static GskSlJump
+gsk_sl_statement_compound_get_jump (const GskSlStatement *statement)
+{
+ GskSlStatementCompound *compound = (GskSlStatementCompound *) statement;
+ GSList *last;
+
+ if (compound->statements == NULL)
+ return GSK_SL_JUMP_NONE;
+
+ last = g_slist_last (compound->statements);
+
+ return gsk_sl_statement_get_jump (last->data);
+}
+
static void
gsk_sl_statement_compound_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
@@ -158,6 +180,7 @@ gsk_sl_statement_compound_write_spv (const GskSlStatement *statement,
static const GskSlStatementClass GSK_SL_STATEMENT_COMPOUND = {
gsk_sl_statement_compound_free,
gsk_sl_statement_compound_print,
+ gsk_sl_statement_compound_get_jump,
gsk_sl_statement_compound_write_spv
};
@@ -199,6 +222,12 @@ gsk_sl_statement_declaration_print (const GskSlStatement *statement,
gsk_sl_printer_append (printer, ";");
}
+static GskSlJump
+gsk_sl_statement_declaration_get_jump (const GskSlStatement *statement)
+{
+ return GSK_SL_JUMP_NONE;
+}
+
static void
gsk_sl_statement_declaration_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
@@ -221,6 +250,7 @@ gsk_sl_statement_declaration_write_spv (const GskSlStatement *statement,
static const GskSlStatementClass GSK_SL_STATEMENT_DECLARATION = {
gsk_sl_statement_declaration_free,
gsk_sl_statement_declaration_print,
+ gsk_sl_statement_declaration_get_jump,
gsk_sl_statement_declaration_write_spv
};
@@ -260,6 +290,12 @@ gsk_sl_statement_return_print (const GskSlStatement *statement,
gsk_sl_printer_append (printer, ";");
}
+static GskSlJump
+gsk_sl_statement_return_get_jump (const GskSlStatement *statement)
+{
+ return GSK_SL_JUMP_RETURN;
+}
+
static void
gsk_sl_statement_return_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
@@ -270,6 +306,7 @@ gsk_sl_statement_return_write_spv (const GskSlStatement *statement,
static const GskSlStatementClass GSK_SL_STATEMENT_RETURN = {
gsk_sl_statement_return_free,
gsk_sl_statement_return_print,
+ gsk_sl_statement_return_get_jump,
gsk_sl_statement_return_write_spv
};
@@ -329,6 +366,18 @@ gsk_sl_statement_if_print (const GskSlStatement *statement,
}
}
+static GskSlJump
+gsk_sl_statement_if_get_jump (const GskSlStatement *statement)
+{
+ GskSlStatementIf *if_stmt = (GskSlStatementIf *) statement;
+
+ if (if_stmt->else_part == NULL)
+ return GSK_SL_JUMP_NONE;
+
+ return MIN (gsk_sl_statement_get_jump (if_stmt->if_part),
+ gsk_sl_statement_get_jump (if_stmt->else_part));
+}
+
static void
gsk_sl_statement_if_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
@@ -388,6 +437,7 @@ gsk_sl_statement_if_write_spv (const GskSlStatement *statement,
static const GskSlStatementClass GSK_SL_STATEMENT_IF = {
gsk_sl_statement_if_free,
gsk_sl_statement_if_print,
+ gsk_sl_statement_if_get_jump,
gsk_sl_statement_if_write_spv
};
@@ -421,6 +471,12 @@ gsk_sl_statement_expression_print (const GskSlStatement *statement,
gsk_sl_printer_append (printer, ";");
}
+static GskSlJump
+gsk_sl_statement_expression_get_jump (const GskSlStatement *statement)
+{
+ return GSK_SL_JUMP_NONE;
+}
+
static void
gsk_sl_statement_expression_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
@@ -433,6 +489,7 @@ gsk_sl_statement_expression_write_spv (const GskSlStatement *statement,
static const GskSlStatementClass GSK_SL_STATEMENT_EXPRESSION = {
gsk_sl_statement_expression_free,
gsk_sl_statement_expression_print,
+ gsk_sl_statement_expression_get_jump,
gsk_sl_statement_expression_write_spv
};
@@ -562,6 +619,7 @@ gsk_sl_statement_parse_compound (GskSlScope *scope,
{
GskSlStatementCompound *compound;
const GskSlToken *token;
+ GskSlJump jump = GSK_SL_JUMP_NONE;
compound = gsk_sl_statement_new (GskSlStatementCompound, &GSK_SL_STATEMENT_COMPOUND);
if (new_scope)
@@ -584,8 +642,12 @@ gsk_sl_statement_parse_compound (GskSlScope *scope,
{
GskSlStatement *statement;
+ if (jump != GSK_SL_JUMP_NONE)
+ gsk_sl_preprocessor_warn (preproc, DEAD_CODE, "Statement cannot be reached.");
+
statement = gsk_sl_statement_parse (scope, preproc);
compound->statements = g_slist_prepend (compound->statements, statement);
+ jump = gsk_sl_statement_get_jump (statement);
}
compound->statements = g_slist_reverse (compound->statements);
@@ -824,6 +886,12 @@ gsk_sl_statement_print (const GskSlStatement *statement,
statement->class->print (statement, printer);
}
+GskSlJump
+gsk_sl_statement_get_jump (const GskSlStatement *statement)
+{
+ return statement->class->get_jump (statement);
+}
+
void
gsk_sl_statement_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer)
diff --git a/gsk/gskslstatementprivate.h b/gsk/gskslstatementprivate.h
index 1e4098f..99d48df 100644
--- a/gsk/gskslstatementprivate.h
+++ b/gsk/gskslstatementprivate.h
@@ -25,6 +25,14 @@
G_BEGIN_DECLS
+typedef enum {
+ GSK_SL_JUMP_NONE,
+ GSK_SL_JUMP_BREAK,
+ GSK_SL_JUMP_CONTINUE,
+ GSK_SL_JUMP_RETURN,
+ GSK_SL_JUMP_DISCARD
+} GskSlJump;
+
GskSlStatement * gsk_sl_statement_parse (GskSlScope *scope,
GskSlPreprocessor *preproc);
GskSlStatement * gsk_sl_statement_parse_compound (GskSlScope *scope,
@@ -37,6 +45,8 @@ void gsk_sl_statement_unref (GskSlStatement
void gsk_sl_statement_print (const GskSlStatement *statement,
GskSlPrinter *printer);
+GskSlJump gsk_sl_statement_get_jump (const GskSlStatement *statement);
+
void gsk_sl_statement_write_spv (const GskSlStatement *statement,
GskSpvWriter *writer);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]