mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-31 12:00:38 +00:00
Optimize for superfluous cases of NOT, i.e !!!!x can be simplified to !!x.
This commit is contained in:
parent
0d1f20fea3
commit
2b3663e18d
2 changed files with 37 additions and 1 deletions
8
gmqcc.h
8
gmqcc.h
|
@ -726,7 +726,13 @@ enum {
|
|||
VINSTR_BITXOR,
|
||||
VINSTR_BITXOR_V,
|
||||
VINSTR_BITXOR_VF,
|
||||
VINSTR_CROSS
|
||||
VINSTR_CROSS,
|
||||
|
||||
/*
|
||||
* An instruction that is never emitted, useful for marking ir_instr
|
||||
* to not be generated (just set the ->opcode member to it).
|
||||
*/
|
||||
VINSTR_NOP
|
||||
};
|
||||
|
||||
/* TODO: elide */
|
||||
|
|
30
ir.c
30
ir.c
|
@ -2799,6 +2799,10 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
|
|||
{
|
||||
instr = block->instr[i];
|
||||
|
||||
/* Ignore NOP instruction */
|
||||
if (instr->opcode == VINSTR_NOP)
|
||||
continue;
|
||||
|
||||
if (instr->opcode == VINSTR_PHI) {
|
||||
irerror(block->context, "cannot generate virtual instruction (phi)");
|
||||
return false;
|
||||
|
@ -3174,6 +3178,32 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
|
|||
if (instr->_ops[2])
|
||||
stmt.o2.u1 = ir_value_code_addr(instr->_ops[2]);
|
||||
|
||||
if (stmt.opcode == INSTR_NOT_F) {
|
||||
/*
|
||||
* We can optimize for superfluous cases of not. Consider
|
||||
*/
|
||||
if (i + 4 <= vec_size(block->instr)) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (ir_value_code_addr(block->instr[i+j]->_ops[0]) != ir_value_code_addr(block->instr[i+j]->_ops[1]))
|
||||
break;
|
||||
}
|
||||
if (--j && block->instr[i+2]->_ops[0] && block->instr[i+2]->_ops[1]
|
||||
&& block->instr[i+3]->_ops[0] && block->instr[i+2]->_ops[1]
|
||||
&& ir_value_code_addr(block->instr[i+2]->_ops[1]) == ir_value_code_addr(block->instr[i+3]->_ops[0])
|
||||
&& ir_value_code_addr(block->instr[i+2]->_ops[0]) == ir_value_code_addr(block->instr[i+3]->_ops[1]))
|
||||
{
|
||||
code_push_statement(code, &stmt, instr->context);
|
||||
code_push_statement(code, &stmt, instr->context);
|
||||
for (j = 1; j < 4; j++)
|
||||
block->instr[i+j]->opcode = VINSTR_NOP;
|
||||
++opts_optimizationcount[OPTIM_PEEPHOLE];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
code_push_statement(code, &stmt, instr->context);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stmt.opcode == INSTR_RETURN || stmt.opcode == INSTR_DONE)
|
||||
{
|
||||
stmt.o1.u1 = stmt.o3.u1;
|
||||
|
|
Loading…
Reference in a new issue