add initial xop codepaths, still need to finish the rest of the compares, and then do shifts, rotates, and PERMUTE

Add vector simplification pass, so far it only recognizes whether VECTOR_DENORMFLUSH is useless and optimizes them away
Tag restgplr/savegplr/restvmx/savevmx/restfpr/savefpr with useful information, i intend to inline them (they tend to be the most heavily called guest functions)
This commit is contained in:
chss95cs@gmail.com
2022-08-21 08:55:42 -07:00
parent 0b013fdc6b
commit 0ebc109d4d
8 changed files with 574 additions and 78 deletions

View File

@@ -84,7 +84,7 @@ bool SimplificationPass::Run(HIRBuilder* builder, bool& result) {
iter_result |= EliminateConversions(builder);
iter_result |= SimplifyAssignments(builder);
iter_result |= SimplifyBasicArith(builder);
iter_result |= SimplifyVectorOps(builder);
result |= iter_result;
} while (iter_result);
return true;
@@ -1393,6 +1393,65 @@ bool SimplificationPass::SimplifyBasicArith(hir::HIRBuilder* builder) {
return result;
}
static bool CouldEverProduceDenormal(hir::Instr* i) {
if (!i) {
return false;
}
Opcode denflushed_opcode = i->GetOpcodeNum();
if (denflushed_opcode == OPCODE_VECTOR_DENORMFLUSH) {
return false;
} else if (denflushed_opcode == OPCODE_UNPACK) {
// todo: more unpack operations likely cannot produce denormals
if (i->flags == PACK_TYPE_FLOAT16_4 || i->flags == PACK_TYPE_FLOAT16_2) {
return false; // xenos half float format does not support denormals
}
} else if (denflushed_opcode == OPCODE_VECTOR_CONVERT_I2F) {
return false;
}
return true; // todo: recurse, check values for min/max, abs, and others
}
bool SimplificationPass::SimplifyVectorOps(hir::Instr* i,
hir::HIRBuilder* builder) {
Opcode opc = i->GetOpcodeNum();
/*
if the input to an unconditional denormal flush is an output of an
unconditional denormal flush, it is a pointless instruction and should be
elimed
*/
if (opc == OPCODE_VECTOR_DENORMFLUSH) {
hir::Instr* denflushed_def = i->src1.value->GetDefSkipAssigns();
if (denflushed_def) {
if (!CouldEverProduceDenormal(denflushed_def)) {
i->opcode = &OPCODE_ASSIGN_info;
return true;
}
}
}
return false;
}
bool SimplificationPass::SimplifyVectorOps(hir::HIRBuilder* builder) {
bool result = false;
auto block = builder->first_block();
while (block) {
auto i = block->instr_head;
while (i) {
bool looks_vectory = false;
i->VisitValueOperands([&looks_vectory](Value* val, uint32_t idx) {
if (val->type == VEC128_TYPE) {
looks_vectory = true;
}
});
result |= SimplifyVectorOps(i, builder);
i = i->next;
}
block = block->next;
}
return result;
}
/*
todo: add load-store simplification pass

View File

@@ -35,6 +35,9 @@ class SimplificationPass : public ConditionalGroupSubpass {
// handles simple multiplication/addition rules
bool SimplifyBasicArith(hir::HIRBuilder* builder);
bool SimplifyVectorOps(hir::HIRBuilder* builder);
bool SimplifyVectorOps(hir::Instr* i, hir::HIRBuilder* builder);
bool SimplifyBasicArith(hir::Instr* i, hir::HIRBuilder* builder);
bool SimplifyAddWithSHL(hir::Instr* i, hir::HIRBuilder* builder);
bool SimplifyAddToSelf(hir::Instr* i, hir::HIRBuilder* builder);