mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2024-11-23 12:22:26 +00:00
added -fdefault-eraseable which is the same as adding [[eraseable]] to all definitions
instead the opposite behavior can be controlled with [[noerase]] attribute
This commit is contained in:
parent
9a21c638fa
commit
092067482f
6 changed files with 32 additions and 14 deletions
12
ast.cpp
12
ast.cpp
|
@ -37,6 +37,8 @@ ast_expression::ast_expression(lex_ctx_t ctx, int nodetype, qc_type type)
|
|||
{
|
||||
if (OPTS_OPTION_BOOL(OPTION_COVERAGE))
|
||||
m_flags |= AST_FLAG_BLOCK_COVERAGE;
|
||||
if (OPTS_FLAG(DEFAULT_ERASEABLE))
|
||||
m_flags |= AST_FLAG_ERASEABLE;
|
||||
}
|
||||
ast_expression::ast_expression(lex_ctx_t ctx, int nodetype)
|
||||
: ast_expression(ctx, nodetype, TYPE_VOID)
|
||||
|
@ -1130,7 +1132,7 @@ bool ast_value::generateGlobal(ir_builder *ir, bool isfield)
|
|||
|
||||
if (m_flags & AST_FLAG_INCLUDE_DEF)
|
||||
m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF;
|
||||
if (m_flags & AST_FLAG_ERASEABLE)
|
||||
if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE))
|
||||
m_ir_v->m_flags |= IR_FLAG_ERASABLE;
|
||||
if (m_flags & AST_FLAG_NOREF)
|
||||
m_ir_v->m_flags |= IR_FLAG_NOREF;
|
||||
|
@ -1194,7 +1196,7 @@ bool ast_value::generateGlobalFunction(ir_builder *ir)
|
|||
m_ir_v = func->m_value;
|
||||
if (m_flags & AST_FLAG_INCLUDE_DEF)
|
||||
m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF;
|
||||
if (m_flags & AST_FLAG_ERASEABLE)
|
||||
if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE))
|
||||
m_ir_v->m_flags |= IR_FLAG_ERASABLE;
|
||||
if (m_flags & AST_FLAG_BLOCK_COVERAGE)
|
||||
func->m_flags |= IR_FLAG_BLOCK_COVERAGE;
|
||||
|
@ -1236,7 +1238,7 @@ bool ast_value::generateGlobalField(ir_builder *ir)
|
|||
|
||||
if (m_flags & AST_FLAG_INCLUDE_DEF)
|
||||
m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF;
|
||||
if (m_flags & AST_FLAG_ERASEABLE)
|
||||
if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE))
|
||||
m_ir_v->m_flags |= IR_FLAG_ERASABLE;
|
||||
if (m_flags & AST_FLAG_NOREF)
|
||||
m_ir_v->m_flags |= IR_FLAG_NOREF;
|
||||
|
@ -1272,7 +1274,7 @@ bool ast_value::generateGlobalField(ir_builder *ir)
|
|||
m_ir_v = v;
|
||||
if (m_flags & AST_FLAG_INCLUDE_DEF)
|
||||
m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF;
|
||||
if (m_flags & AST_FLAG_ERASEABLE)
|
||||
if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE))
|
||||
m_ir_v->m_flags |= IR_FLAG_ERASABLE;
|
||||
if (m_flags & AST_FLAG_NOREF)
|
||||
m_ir_v->m_flags |= IR_FLAG_NOREF;
|
||||
|
@ -1305,7 +1307,7 @@ ir_value *ast_value::prepareGlobalArray(ir_builder *ir)
|
|||
|
||||
if (m_flags & AST_FLAG_INCLUDE_DEF)
|
||||
v->m_flags |= IR_FLAG_INCLUDE_DEF;
|
||||
if (m_flags & AST_FLAG_ERASEABLE)
|
||||
if (m_flags & AST_FLAG_ERASEABLE && !(m_flags & AST_FLAG_NOERASE))
|
||||
v->m_flags |= IR_FLAG_ERASABLE;
|
||||
if (m_flags & AST_FLAG_NOREF)
|
||||
v->m_flags |= IR_FLAG_NOREF;
|
||||
|
|
13
ast.h
13
ast.h
|
@ -43,14 +43,15 @@ enum {
|
|||
AST_FLAG_IS_VARARG = 1 << 6,
|
||||
AST_FLAG_ALIAS = 1 << 7,
|
||||
AST_FLAG_ERASEABLE = 1 << 8,
|
||||
AST_FLAG_ACCUMULATE = 1 << 9,
|
||||
AST_FLAG_NOERASE = 1 << 9, /* Never allow it to be erased, even if ERASEABLE is present */
|
||||
AST_FLAG_ACCUMULATE = 1 << 10,
|
||||
|
||||
/* An array declared as []
|
||||
* so that the size is taken from the initializer
|
||||
*/
|
||||
AST_FLAG_ARRAY_INIT = 1 << 10,
|
||||
AST_FLAG_ARRAY_INIT = 1 << 11,
|
||||
|
||||
AST_FLAG_FINAL_DECL = 1 << 11,
|
||||
AST_FLAG_FINAL_DECL = 1 << 12,
|
||||
|
||||
/* Several coverage options
|
||||
* AST_FLAG_COVERAGE means there was an explicit [[coverage]] attribute,
|
||||
|
@ -59,14 +60,14 @@ enum {
|
|||
* In the future there might be more options like tracking variable access
|
||||
* by creating get/set wrapper functions.
|
||||
*/
|
||||
AST_FLAG_COVERAGE = 1 << 12,
|
||||
AST_FLAG_BLOCK_COVERAGE = 1 << 13,
|
||||
AST_FLAG_COVERAGE = 1 << 13,
|
||||
AST_FLAG_BLOCK_COVERAGE = 1 << 14,
|
||||
|
||||
/*
|
||||
* Propagates norefness to the IR so the unused (read/write) check can be
|
||||
* more intelligently done.
|
||||
*/
|
||||
AST_FLAG_NOREF = 1 << 14,
|
||||
AST_FLAG_NOREF = 1 << 15,
|
||||
|
||||
AST_FLAG_LAST,
|
||||
AST_FLAG_TYPE_MASK = (AST_FLAG_VARIADIC | AST_FLAG_NORETURN),
|
||||
|
|
|
@ -628,6 +628,13 @@ after all limited to 64k. There's at least one known codebase where this
|
|||
lowers the number of globals from over 80k down to around 3k. In other code
|
||||
bases it doesn't reduce the globals at all but only increases code size.
|
||||
Just try it and see whether it helps you.
|
||||
.It Fl f Ns Cm default-eraseable
|
||||
Force all expressions to be "eraseable" which permits the compiler to
|
||||
remove unused functions, variables and statements. This is equivlant to
|
||||
putting [[eraseable]] on all definitions. This is dangerous as it breaks
|
||||
auto cvars, definitions for functions the engine may be looking for and
|
||||
translatable strings. Instead, you can mark a definition with [[noerase]]
|
||||
to prevent this from happening.
|
||||
.El
|
||||
.Sh OPTIMIZATIONS
|
||||
.Bl -tag -width Ds
|
||||
|
|
|
@ -346,6 +346,14 @@
|
|||
#expense of additional instructions.
|
||||
SPLIT_VECTOR_PARAMETERS = false
|
||||
|
||||
#Force all expressions to be "eraseable" which permits the compiler
|
||||
#to remove unused functions, variables and statements. This is
|
||||
#equivlant to putting [[eraseable]] on all definitions. This is
|
||||
#dangerous as it breaks auto cvars, definitions for functions the
|
||||
#engine may be looking for and translatable strings. Instead, you
|
||||
#can mark a definition with [[noerase]] to prevent this from happening.
|
||||
DEFAULT_ERASEABLE = false
|
||||
|
||||
[warnings]
|
||||
#Generate a warning about variables which are declared but never
|
||||
#used. This can be avoided by adding the ‘noref’ keyword in front
|
||||
|
|
1
opts.def
1
opts.def
|
@ -37,6 +37,7 @@
|
|||
GMQCC_DEFINE_FLAG(EMULATE_STATE)
|
||||
GMQCC_DEFINE_FLAG(ARITHMETIC_EXCEPTIONS)
|
||||
GMQCC_DEFINE_FLAG(SPLIT_VECTOR_PARAMETERS)
|
||||
GMQCC_DEFINE_FLAG(DEFAULT_ERASEABLE)
|
||||
#endif
|
||||
|
||||
/* warning flags */
|
||||
|
|
|
@ -2763,6 +2763,7 @@ static bool parse_qualifiers(parser_t *parser, bool with_local, int *cvq, bool *
|
|||
{ "noreturn", AST_FLAG_NORETURN },
|
||||
{ "inline", AST_FLAG_INLINE },
|
||||
{ "eraseable", AST_FLAG_ERASEABLE },
|
||||
{ "noerase", AST_FLAG_NOERASE },
|
||||
{ "accumulate", AST_FLAG_ACCUMULATE },
|
||||
{ "last", AST_FLAG_FINAL_DECL }
|
||||
};
|
||||
|
@ -2796,7 +2797,6 @@ static bool parse_qualifiers(parser_t *parser, bool with_local, int *cvq, bool *
|
|||
if (i != GMQCC_ARRAY_COUNT(attributes))
|
||||
goto leave;
|
||||
|
||||
|
||||
if (!strcmp(parser_tokval(parser), "noref")) {
|
||||
had_noref = true;
|
||||
if (!parser_next(parser) || parser->tok != TOKEN_ATTRIBUTE_CLOSE) {
|
||||
|
@ -5197,8 +5197,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
|
|||
* store the vstring back to var for alias and
|
||||
* deprecation messages.
|
||||
*/
|
||||
if (var->m_flags & AST_FLAG_DEPRECATED ||
|
||||
var->m_flags & AST_FLAG_ALIAS)
|
||||
if (var->m_flags & AST_FLAG_DEPRECATED || var->m_flags & AST_FLAG_ALIAS)
|
||||
var->m_desc = vstring;
|
||||
|
||||
if (parser_find_global(parser, var->m_name) && var->m_flags & AST_FLAG_ALIAS) {
|
||||
|
|
Loading…
Reference in a new issue