return false;
}
-static bool GMQCC_WARN vec_ir_block_find(ir_block **vec, ir_block *what, size_t *idx)
+static bool GMQCC_WARN vec_ir_block_find(std::vector<ir_block *> &vec, ir_block *what, size_t *idx)
{
- size_t i;
- size_t len = vec_size(vec);
- for (i = 0; i < len; ++i) {
- if (vec[i] == what) {
- if (idx) *idx = i;
- return true;
- }
+ for (auto &it : vec) {
+ if (it != what)
+ continue;
+ if (idx)
+ *idx = &it - &vec[0];
+ return true;
}
return false;
}
if (self->m_builtin)
return true;
+ for (auto& lp : self->m_locals) {
+ ir_value *v = lp.get();
+ 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)
+ {
+ size_t mask = (1 << 3) - 1, bits = 0;
+ for (size_t i = 0; i < 3; i++)
+ if (!v->m_members[i] || (v->m_members[i]->m_reads.empty()
+ && v->m_members[i]->m_writes.size()))
+ bits |= (1 << i);
+ // all components are unused so just report the vector
+ if (bits == mask && irwarning(v->m_context, WARN_UNUSED_VARIABLE,
+ "unused variable: `%s`", v->m_name.c_str()))
+ return false;
+ else if (bits != mask)
+ // individual components are unused so mention them
+ for (size_t i = 0; i < 3; i++)
+ if ((bits & (1 << i))
+ && irwarning(v->m_context, WARN_UNUSED_COMPONENT,
+ "unused vector component: `%s.%c`", v->m_name.c_str(), "xyz"[i]))
+ return false;
+ }
+ // just a standard variable
+ else if (irwarning(v->m_context, WARN_UNUSED_VARIABLE,
+ "unused variable: `%s`", v->m_name.c_str())) return false;
+ }
+ }
+
if (OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) {
if (!ir_function_pass_peephole(self)) {
irerror(self->m_context, "generic optimization pass broke something in `%s`", self->m_name.c_str());
for (size_t i = 0; i != vec_size(m_instr); ++i)
delete m_instr[i];
vec_free(m_instr);
- vec_free(m_entries);
- vec_free(m_exits);
}
static void ir_block_delete_quick(ir_block* self)
vec_push(self->m_instr, in);
- vec_push(self->m_exits, ontrue);
- vec_push(self->m_exits, onfalse);
- vec_push(ontrue->m_entries, self);
- vec_push(onfalse->m_entries, self);
+ self->m_exits.push_back(ontrue);
+ self->m_exits.push_back(onfalse);
+ ontrue->m_entries.push_back(self);
+ onfalse->m_entries.push_back(self);
return true;
}
in->m_bops[0] = to;
vec_push(self->m_instr, in);
- vec_push(self->m_exits, to);
- vec_push(to->m_entries, self);
+ self->m_exits.push_back(to);
+ to->m_entries.push_back(self);
return true;
}
{
ir_instr *instr;
ir_value *value;
- size_t i, o, p, mem;
+ size_t i, o, mem;
// bitmasks which operands are read from or written to
size_t read, write;
self->m_living.clear();
- p = vec_size(self->m_exits);
- for (i = 0; i < p; ++i) {
- ir_block *prev = self->m_exits[i];
+ for (auto &prev : self->m_exits) {
for (auto &it : prev->m_living)
if (!vec_ir_value_find(self->m_living, it, nullptr))
self->m_living.push_back(it);