-Ovoid-return - the last INSTR_RETURN of a void functions is replaced by INSTR_DONE...
authorWolfgang Bumiller <blub@speed.at>
Wed, 26 Dec 2012 09:24:33 +0000 (10:24 +0100)
committerWolfgang Bumiller <blub@speed.at>
Wed, 26 Dec 2012 09:24:33 +0000 (10:24 +0100)
ir.c
opts.def

diff --git a/ir.c b/ir.c
index 6f9e488152da330a23ad83e3408ae51247c5369f..ec87bd78cd7edde6dfc3ecf2fbba6fa0962bd6f1 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -2956,7 +2956,7 @@ tailcall:
 static bool gen_function_code(ir_function *self)
 {
     ir_block *block;
-    prog_section_statement stmt;
+    prog_section_statement stmt, *retst;
 
     /* Starting from entry point, we generate blocks "as they come"
      * for now. Dead blocks will not be translated obviously.
@@ -2976,11 +2976,21 @@ static bool gen_function_code(ir_function *self)
     }
 
     /* code_write and qcvm -disasm need to know that the function ends here */
-    stmt.opcode = INSTR_DONE;
-    stmt.o1.u1 = 0;
-    stmt.o2.u1 = 0;
-    stmt.o3.u1 = 0;
-    code_push_statement(&stmt, vec_last(code_linenums));
+    retst = &vec_last(code_statements);
+    if (OPTS_OPTIMIZATION(OPTIM_VOID_RETURN) &&
+        self->outtype == TYPE_VOID &&
+        retst->opcode == INSTR_RETURN &&
+        !retst->o1.u1 && !retst->o2.u1 && !retst->o3.u1)
+    {
+        retst->opcode = INSTR_DONE;
+        ++opts_optimizationcount[OPTIM_VOID_RETURN];
+    } else {
+        stmt.opcode = INSTR_DONE;
+        stmt.o1.u1 = 0;
+        stmt.o2.u1 = 0;
+        stmt.o3.u1 = 0;
+        code_push_statement(&stmt, vec_last(code_linenums));
+    }
     return true;
 }
 
index 3fbe1041e339b829205093a4877f49449e7e0929..5d7603945b875f043152788990bfb76754ea5294 100644 (file)
--- a/opts.def
+++ b/opts.def
@@ -87,6 +87,7 @@
     GMQCC_DEFINE_FLAG(STRIP_CONSTANT_NAMES, 1)
     GMQCC_DEFINE_FLAG(OVERLAP_STRINGS,      2)
     GMQCC_DEFINE_FLAG(CALL_STORES,          1)
+    GMQCC_DEFINE_FLAG(VOID_RETURN,          1)
 #endif
 
 /* some cleanup so we don't have to */