Added -Oconst-fold-dce (dead code elimination optimization for when constant expressions form the basis of the dead code, i.e if else with constant expression). Fixed deps and added documentation. Cleaned up folds for ir_value (can now use the same macros as the ast_value ones).

This commit is contained in:
Dale Weiler 2013-08-01 07:07:59 +00:00
parent 24fc2e5146
commit 6f749d61b1
5 changed files with 50 additions and 25 deletions

View file

@ -103,19 +103,20 @@ install-doc:
# DO NOT DELETE # DO NOT DELETE
ast.o: gmqcc.h opts.def ast.h ir.h util.o: gmqcc.h opts.def
code.o: gmqcc.h opts.def
conout.o: gmqcc.h opts.def
correct.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 conout.o: gmqcc.h opts.def
ir.o: gmqcc.h opts.def ir.h
lexer.o: gmqcc.h opts.def lexer.h
main.o: gmqcc.h opts.def lexer.h
opts.o: gmqcc.h opts.def opts.o: gmqcc.h opts.def
pak.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 stat.o: gmqcc.h opts.def
test.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

View file

@ -150,10 +150,11 @@ stat.o: gmqcc.h opts.def
test.o: gmqcc.h opts.def test.o: gmqcc.h opts.def
main.o: gmqcc.h opts.def lexer.h main.o: gmqcc.h opts.def lexer.h
lexer.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 ir.o: gmqcc.h opts.def ir.h
ftepp.o: gmqcc.h opts.def lexer.h ftepp.o: gmqcc.h opts.def lexer.h
utf8.o: gmqcc.h opts.def utf8.o: gmqcc.h opts.def
correct.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

View 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 such a multiplication into a direct component access. If the factor is
anything other than 1, a float-multiplication will be added, which is anything other than 1, a float-multiplication will be added, which is
still faster than a vector multiplication. 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 .El
.Sh CONFIG .Sh CONFIG
The configuration file is similar to regular .ini files. Comments The configuration file is similar to regular .ini files. Comments

44
fold.c
View file

@ -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) { static lex_ctx_t fold_ctx(fold_t *fold) {
lex_ctx_t ctx; lex_ctx_t ctx;
if (fold->parser->lex) 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_float(E) ((E)->constval.vfloat)
#define fold_immvalue_vector(E) ((E)->constval.vvec) #define fold_immvalue_vector(E) ((E)->constval.vvec)
#define fold_immvalue_string(E) ((E)->constval.vstring) #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 * These are all the actual constant folding methods that happen in between
* stage of the compiler, i.e eliminating branches for const expressions, * the AST/IR stage of the compiler , i.e eliminating branches for const
* which is the only supported thing so far. * 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; ast_expression_codegen *cgen;
ir_block *elide; ir_block *elide;
ir_value *dummy; ir_value *dummy;

View file

@ -105,6 +105,7 @@
GMQCC_DEFINE_FLAG(CALL_STORES, 3) GMQCC_DEFINE_FLAG(CALL_STORES, 3)
GMQCC_DEFINE_FLAG(VOID_RETURN, 1) GMQCC_DEFINE_FLAG(VOID_RETURN, 1)
GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS, 1) GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS, 1)
GMQCC_DEFINE_FLAG(CONST_FOLD_DCE, 2)
#endif #endif
#ifdef GMQCC_TYPE_OPTIONS #ifdef GMQCC_TYPE_OPTIONS