Added -Oconst-fold-dce (dead code elimination optimization for when constant expressi...
authorDale Weiler <killfieldengine@gmail.com>
Thu, 1 Aug 2013 07:07:59 +0000 (07:07 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Thu, 1 Aug 2013 07:07:59 +0000 (07:07 +0000)
BSDmakefile
Makefile
doc/gmqcc.1
fold.c
opts.def

index a84493b..6aea46e 100644 (file)
@@ -103,19 +103,20 @@ install-doc:
 
 # DO NOT DELETE
 
-ast.o: gmqcc.h opts.def ast.h ir.h
-code.o: gmqcc.h opts.def
-conout.o: gmqcc.h opts.def
-correct.o: gmqcc.h opts.def
+util.o: gmqcc.h opts.def
 fs.o: gmqcc.h opts.def
-ftepp.o: gmqcc.h opts.def lexer.h
-ir.o: gmqcc.h opts.def ir.h
-lexer.o: gmqcc.h opts.def lexer.h
-main.o: gmqcc.h opts.def lexer.h
+conout.o: gmqcc.h opts.def
 opts.o: gmqcc.h opts.def
 pak.o: gmqcc.h opts.def
-parser.o: gmqcc.h opts.def lexer.h ast.h ir.h intrin.h
 stat.o: gmqcc.h opts.def
 test.o: gmqcc.h opts.def
+main.o: gmqcc.h opts.def lexer.h
+lexer.o: gmqcc.h opts.def lexer.h
+parser.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h intrin.h
+code.o: gmqcc.h opts.def
+ast.o: gmqcc.h opts.def ast.h ir.h parser.h lexer.h
+ir.o: gmqcc.h opts.def ir.h
+ftepp.o: gmqcc.h opts.def lexer.h
 utf8.o: gmqcc.h opts.def
-util.o: gmqcc.h opts.def
+correct.o: gmqcc.h opts.def
+fold.o: ast.h ir.h gmqcc.h opts.def parser.h lexer.h
index 4444566..b2dc72d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -150,10 +150,11 @@ stat.o: gmqcc.h opts.def
 test.o: gmqcc.h opts.def
 main.o: gmqcc.h opts.def lexer.h
 lexer.o: gmqcc.h opts.def lexer.h
-parser.o: gmqcc.h opts.def lexer.h ast.h ir.h intrin.h
+parser.o: parser.h gmqcc.h opts.def lexer.h ast.h ir.h intrin.h
 code.o: gmqcc.h opts.def
-ast.o: gmqcc.h opts.def ast.h ir.h
+ast.o: gmqcc.h opts.def ast.h ir.h parser.h lexer.h
 ir.o: gmqcc.h opts.def ir.h
 ftepp.o: gmqcc.h opts.def lexer.h
 utf8.o: gmqcc.h opts.def
 correct.o: gmqcc.h opts.def
+fold.o: ast.h ir.h gmqcc.h opts.def parser.h lexer.h
index 22150a3..9220e24 100644 (file)
@@ -606,6 +606,10 @@ in this case, the y component of a vector. This optimization will turn
 such a multiplication into a direct component access. If the factor is
 anything other than 1, a float-multiplication will be added, which is
 still faster than a vector multiplication.
+.It Fl O Ns Cm const-fold-dce
+For constant expressions that result in dead code (such as a branch whos
+condition can be evaluated at compile-time), this will eliminate the branch
+and else body (if present) to produce more optimal code.
 .El
 .Sh CONFIG
 The configuration file is similar to regular .ini files. Comments
diff --git a/fold.c b/fold.c
index c8996cf..d0802f4 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -123,15 +123,6 @@ static GMQCC_INLINE bool vec3_pbool(vec3_t a) {
     return (a.x && a.y && a.z);
 }
 
-static GMQCC_INLINE bool fold_can_1(const ast_value *val) {
-    return (ast_istype(((ast_expression*)(val)), ast_value) && val->hasvalue && (val->cvq == CV_CONST) &&
-              ((ast_expression*)(val))->vtype != TYPE_FUNCTION);
-}
-
-static GMQCC_INLINE bool fold_can_2(const ast_value *v1, const ast_value *v2) {
-    return fold_can_1(v1) && fold_can_1(v2);
-}
-
 static lex_ctx_t fold_ctx(fold_t *fold) {
     lex_ctx_t ctx;
     if (fold->parser->lex)
@@ -164,6 +155,13 @@ static GMQCC_INLINE bool fold_immediate_true(fold_t *fold, ast_value *v) {
     return !!v->constval.vfunc;
 }
 
+/* Handy macros to determine if an ast_value can be constant folded. */
+#define fold_can_1(X)  \
+    (ast_istype(((ast_expression*)(X)), ast_value) && (X)->hasvalue && ((X)->cvq == CV_CONST) && \
+                ((ast_expression*)(X))->vtype != TYPE_FUNCTION)
+
+#define fold_can_2(X, Y) (fold_can_1(X) && fold_can_1(Y))
+
 #define fold_immvalue_float(E)  ((E)->constval.vfloat)
 #define fold_immvalue_vector(E) ((E)->constval.vvec)
 #define fold_immvalue_string(E) ((E)->constval.vstring)
@@ -590,12 +588,32 @@ ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **op
 }
 
 /*
- * These are all the actual constant folding methods that happen in the AST
- * stage of the compiler, i.e eliminating branches for const expressions,
- * which is the only supported thing so far.
+ * These are all the actual constant folding methods that happen in between
+ * the AST/IR stage of the compiler , i.e eliminating branches for const
+ * expressions, which is the only supported thing so far. We undefine the
+ * testing macros here because an ir_value is differant than an ast_value.
  */
+#undef isfloat
+#undef isstring
+#undef isvector
+#undef fold_immvalue_float
+#undef fold_immvalue_string
+#undef fold_immvalue_vector
+#undef fold_can_1
+#undef fold_can_2
+
+#define isfloat(X)              ((X)->vtype == TYPE_FLOAT)
+#define isstring(X)             ((X)->vtype == TYPE_STRING)
+#define isvector(X)             ((X)->vtype == TYPE_VECTOR)
+#define fold_immvalue_float(X)  ((X)->constval.vfloat)
+#define fold_immvalue_vector(X) ((X)->constval.vvec)
+#define fold_immvalue_string(X) ((X)->constval.vstring)
+#define fold_can_1(X)           ((X)->hasvalue && (X)->cvq == CV_CONST)
+#define fold_can_2(X,Y)         (fold_can_1(X) && fold_can_1(Y))
+
+
 int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
-    if (condval->vtype == TYPE_FLOAT && condval->hasvalue && condval->cvq == CV_CONST) {
+    if (isfloat(condval) && fold_can_1(condval) && OPTS_OPTIMIZATION(OPTIM_CONST_FOLD_DCE)) {
         ast_expression_codegen *cgen;
         ir_block               *elide;
         ir_value               *dummy;
index 61226ae..1f61ec5 100644 (file)
--- a/opts.def
+++ b/opts.def
     GMQCC_DEFINE_FLAG(CALL_STORES,          3)
     GMQCC_DEFINE_FLAG(VOID_RETURN,          1)
     GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS,    1)
+    GMQCC_DEFINE_FLAG(CONST_FOLD_DCE,       2)
 #endif
 
 #ifdef GMQCC_TYPE_OPTIONS