]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
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 a84493bd97bae025e9078953d900c602621201ff..6aea46ef781b590be0f573a07b085f598c221671 100644 (file)
@@ -103,19 +103,20 @@ install-doc:
 
 # DO NOT DELETE
 
 
 # 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
 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
 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
 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
 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 4444566cd93d7c4417e6ea7fc5085203fe4014d3..b2dc72daca33fefa941f3c4bbb978b26c7dffa29 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
 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
 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
 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 22150a3110439977c8f39ce2ec522b7619413040..9220e242eca811432d11e41b7f36fe8b2c956643 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.
 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
 .El
 .Sh CONFIG
 The configuration file is similar to regular .ini files. Comments
diff --git a/fold.c b/fold.c
index c8996cfb6ee80a1fe92af5b612c91515c8b061ef..d0802f4e0288915926814e7653e2f63f9f89538e 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);
 }
 
     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)
 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;
 }
 
     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)
 #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) {
 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;
         ast_expression_codegen *cgen;
         ir_block               *elide;
         ir_value               *dummy;
index 61226ae3719a52d7bbc2dbe3d2890b86322f26bb..1f61ec556ab9aabf250fd767206addc495e1cb6c 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(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
 #endif
 
 #ifdef GMQCC_TYPE_OPTIONS