From: Dale Weiler Date: Thu, 24 Nov 2016 15:33:58 +0000 (+0000) Subject: Remove parser m_uses in favor of {IR,AST}_FLAG_NOREF instead X-Git-Tag: xonotic-v0.8.5~49 X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=commitdiff_plain;h=3a7848d67c76cba48dfea49b56354e18c254600e;ds=sidebyside Remove parser m_uses in favor of {IR,AST}_FLAG_NOREF instead --- diff --git a/ast.cpp b/ast.cpp index 7529acd..b507a6b 100644 --- a/ast.cpp +++ b/ast.cpp @@ -1132,6 +1132,8 @@ bool ast_value::generateGlobal(ir_builder *ir, bool isfield) m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF; if (m_flags & AST_FLAG_ERASEABLE) m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; /* initialize */ if (m_hasvalue) { @@ -1236,6 +1238,8 @@ bool ast_value::generateGlobalField(ir_builder *ir) m_ir_v->m_flags |= IR_FLAG_INCLUDE_DEF; if (m_flags & AST_FLAG_ERASEABLE) m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; const size_t namelen = m_name.length(); std::unique_ptr name(new char[namelen+16]); @@ -1254,7 +1258,9 @@ bool ast_value::generateGlobalField(ir_builder *ir) array->m_ir_values[ai]->m_unique_life = true; array->m_ir_values[ai]->m_locked = true; if (m_flags & AST_FLAG_INCLUDE_DEF) - m_ir_values[ai]->m_flags |= IR_FLAG_INCLUDE_DEF; + array->m_ir_values[ai]->m_flags |= IR_FLAG_INCLUDE_DEF; + if (m_flags & AST_FLAG_NOREF) + array->m_ir_values[ai]->m_flags |= IR_FLAG_NOREF; } } else @@ -1266,9 +1272,10 @@ 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) m_ir_v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; } return true; } @@ -1299,7 +1306,9 @@ 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) - m_ir_v->m_flags |= IR_FLAG_ERASABLE; + v->m_flags |= IR_FLAG_ERASABLE; + if (m_flags & AST_FLAG_NOREF) + v->m_flags |= IR_FLAG_NOREF; const size_t namelen = m_name.length(); std::unique_ptr name(new char[namelen+16]); @@ -1319,6 +1328,8 @@ ir_value *ast_value::prepareGlobalArray(ir_builder *ir) m_ir_values[ai]->m_locked = true; if (m_flags & AST_FLAG_INCLUDE_DEF) m_ir_values[ai]->m_flags |= IR_FLAG_INCLUDE_DEF; + if (m_flags & AST_FLAG_NOREF) + m_ir_values[ai]->m_flags |= IR_FLAG_NOREF; } return v; @@ -1365,6 +1376,9 @@ bool ast_value::generateLocal(ir_function *func, bool param) v->m_unique_life = true; v->m_locked = true; + if (m_flags & AST_FLAG_NOREF) + v->m_flags |= IR_FLAG_NOREF; + const size_t namelen = m_name.length(); std::unique_ptr name(new char[namelen+16]); util_strncpy(name.get(), m_name.c_str(), namelen); @@ -1379,7 +1393,10 @@ bool ast_value::generateLocal(ir_function *func, bool param) } m_ir_values[ai]->m_context = m_context; m_ir_values[ai]->m_unique_life = true; - m_ir_values[ai]->m_locked = true; + m_ir_values[ai]->m_locked = true; + + if (m_flags & AST_FLAG_NOREF) + m_ir_values[ai]->m_flags |= IR_FLAG_NOREF; } } else @@ -1418,6 +1435,9 @@ bool ast_value::generateLocal(ir_function *func, bool param) v->m_cvq = m_cvq; m_ir_v = v; + if (m_flags & AST_FLAG_NOREF) + m_ir_v->m_flags |= IR_FLAG_NOREF; + if (!generateAccessors(func->m_owner)) return false; return true; diff --git a/ast.h b/ast.h index b305dac..04fa4d8 100644 --- a/ast.h +++ b/ast.h @@ -62,6 +62,12 @@ enum { AST_FLAG_COVERAGE = 1 << 12, AST_FLAG_BLOCK_COVERAGE = 1 << 13, + /* + * Propagates norefness to the IR so the unused (read/write) check can be + * more intelligently done. + */ + AST_FLAG_NOREF = 1 << 14, + AST_FLAG_LAST, AST_FLAG_TYPE_MASK = (AST_FLAG_VARIADIC | AST_FLAG_NORETURN), AST_FLAG_COVERAGE_MASK = (AST_FLAG_BLOCK_COVERAGE) @@ -223,9 +229,6 @@ struct ast_value : ast_expression */ std::vector m_initlist; - /* usecount for the parser */ - size_t m_uses = 0; - ir_value *m_ir_v = nullptr; std::vector m_ir_values; size_t m_ir_value_count = 0; diff --git a/ir.cpp b/ir.cpp index c71cad8..3b78c35 100644 --- a/ir.cpp +++ b/ir.cpp @@ -633,7 +633,7 @@ bool ir_function_finalize(ir_function *self) for (auto& lp : self->m_locals) { ir_value *v = lp.get(); - if (v->m_reads.empty() && v->m_writes.size()) { + if (v->m_reads.empty() && v->m_writes.size() && !(v->m_flags & IR_FLAG_NOREF)) { // if it's a vector check to ensure all it's members are unused before // claiming it's unused, otherwise skip the vector entierly if (v->m_vtype == TYPE_VECTOR) diff --git a/ir.h b/ir.h index 9fa8ab5..fe07198 100644 --- a/ir.h +++ b/ir.h @@ -27,8 +27,8 @@ enum { IR_FLAG_INCLUDE_DEF = 1 << 3, IR_FLAG_ERASABLE = 1 << 4, IR_FLAG_BLOCK_COVERAGE = 1 << 5, - - IR_FLAG_SPLIT_VECTOR = 1 << 6, + IR_FLAG_NOREF = 1 << 6, + IR_FLAG_SPLIT_VECTOR = 1 << 7, IR_FLAG_LAST, IR_FLAG_MASK_NO_OVERLAP = (IR_FLAG_HAS_ARRAYS | IR_FLAG_HAS_UNINITIALIZED), diff --git a/parser.cpp b/parser.cpp index 518a06d..ed5bde1 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1668,13 +1668,16 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels) } else { - if (ast_istype(var, ast_value)) { - ((ast_value*)var)->m_uses++; + // promote these to norefs + if (ast_istype(var, ast_value)) + { + ((ast_value *)var)->m_flags |= AST_FLAG_NOREF; } - else if (ast_istype(var, ast_member)) { - ast_member *mem = (ast_member*)var; + else if (ast_istype(var, ast_member)) + { + ast_member *mem = (ast_member *)var; if (ast_istype(mem->m_owner, ast_value)) - ((ast_value*)(mem->m_owner))->m_uses++; + ((ast_value *)mem->m_owner)->m_flags |= AST_FLAG_NOREF; } } sy->out.push_back(syexp(parser_ctx(parser), var)); @@ -2020,15 +2023,8 @@ static bool parser_leaveblock(parser_t *parser) locals = vec_last(parser->_blocklocals); vec_pop(parser->_blocklocals); - while (vec_size(parser->_locals) != locals) { - ast_expression *e = vec_last(parser->_locals); - ast_value *v = (ast_value*)e; + while (vec_size(parser->_locals) != locals) vec_pop(parser->_locals); - if (ast_istype(e, ast_value) && !v->m_uses) { - if (compile_warning(v->m_context, WARN_UNUSED_VARIABLE, "unused variable: `%s`", v->m_name)) - rv = false; - } - } typedefs = vec_last(parser->_blocktypedefs); while (vec_size(parser->_typedefs) != typedefs) { @@ -5232,12 +5228,12 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield /* Deal with end_sys_ vars */ was_end = false; if (var->m_name == "end_sys_globals") { - var->m_uses++; + var->m_flags |= AST_FLAG_NOREF; parser->crc_globals = parser->globals.size(); was_end = true; } else if (var->m_name == "end_sys_fields") { - var->m_uses++; + var->m_flags |= AST_FLAG_NOREF; parser->crc_fields = parser->fields.size(); was_end = true; } @@ -5397,9 +5393,8 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield } } - /* in a noref section we simply bump the usecount */ if (noref || parser->noref) - var->m_uses++; + var->m_flags |= AST_FLAG_NOREF; /* Part 2: * Create the global/local, and deal with vector types. @@ -5800,7 +5795,10 @@ skipvar: var->m_cvq = CV_CONST; } if (cval == parser->nil) + { var->m_flags |= AST_FLAG_INITIALIZED; + var->m_flags |= AST_FLAG_NOREF; + } else { var->m_hasvalue = true; @@ -6075,6 +6073,7 @@ parser_t *parser_create() parser->reserved_version->m_cvq = CV_CONST; parser->reserved_version->m_hasvalue = true; parser->reserved_version->m_flags |= AST_FLAG_INCLUDE_DEF; + parser->reserved_version->m_flags |= AST_FLAG_NOREF; parser->reserved_version->m_constval.vstring = util_strdup(GMQCC_FULL_VERSION_STRING); } else { parser->reserved_version = nullptr; @@ -6272,7 +6271,7 @@ bool parser_finish(parser_t *parser, const char *output) if (!ast_istype(it, ast_value)) continue; asvalue = (ast_value*)it; - if (!asvalue->m_uses && asvalue->m_cvq != CV_CONST && asvalue->m_vtype != TYPE_FUNCTION) { + if (!(asvalue->m_flags & AST_FLAG_NOREF) && asvalue->m_cvq != CV_CONST && asvalue->m_vtype != TYPE_FUNCTION) { retval = retval && !compile_warning(asvalue->m_context, WARN_UNUSED_VARIABLE, "unused global: `%s`", asvalue->m_name); }