nv50/ir: Fold IMM into MAD
Add a specific optimisation pass for NV50 to check whether SRC0 or SRC1 is a MOV dst, IMM. If so: fold the IMM in and try to drop the MOV. Must be done post-RA because it requires that SDST == SSRC2. V2: improve readability and add comments to clarify decisions V3: Remove redundant code... compiler already attempts to put the IMM in SSRC1 Signed-off-by: Roy Spliet <rspliet@eclipso.eu> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
@@ -2259,6 +2259,56 @@ FlatteningPass::tryPredicateConditional(BasicBlock *bb)
|
|||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
|
// Fold Immediate into MAD; must be done after register allocation due to
|
||||||
|
// constraint SDST == SSRC2
|
||||||
|
// TODO:
|
||||||
|
// Does NVC0+ have other situations where this pass makes sense?
|
||||||
|
class NV50PostRaConstantFolding : public Pass
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
virtual bool visit(BasicBlock *);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
NV50PostRaConstantFolding::visit(BasicBlock *bb)
|
||||||
|
{
|
||||||
|
Value *vtmp;
|
||||||
|
Instruction *def;
|
||||||
|
|
||||||
|
for (Instruction *i = bb->getFirst(); i; i = i->next) {
|
||||||
|
switch (i->op) {
|
||||||
|
case OP_MAD:
|
||||||
|
if (i->def(0).getFile() != FILE_GPR ||
|
||||||
|
i->src(0).getFile() != FILE_GPR ||
|
||||||
|
i->src(1).getFile() != FILE_GPR ||
|
||||||
|
i->src(2).getFile() != FILE_GPR ||
|
||||||
|
i->getDef(0)->reg.data.id != i->getSrc(2)->reg.data.id)
|
||||||
|
break;
|
||||||
|
|
||||||
|
def = i->getSrc(1)->getInsn();
|
||||||
|
if (def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) {
|
||||||
|
vtmp = i->getSrc(1);
|
||||||
|
i->setSrc(1, def->getSrc(0));
|
||||||
|
|
||||||
|
/* There's no post-RA dead code elimination, so do it here
|
||||||
|
* XXX: if we add more code-removing post-RA passes, we might
|
||||||
|
* want to create a post-RA dead-code elim pass */
|
||||||
|
if (vtmp->refCount() == 0)
|
||||||
|
delete_Instruction(bb->getProgram(), def);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
// Common subexpression elimination. Stupid O^2 implementation.
|
// Common subexpression elimination. Stupid O^2 implementation.
|
||||||
class LocalCSE : public Pass
|
class LocalCSE : public Pass
|
||||||
{
|
{
|
||||||
@@ -2629,6 +2679,9 @@ bool
|
|||||||
Program::optimizePostRA(int level)
|
Program::optimizePostRA(int level)
|
||||||
{
|
{
|
||||||
RUN_PASS(2, FlatteningPass, run);
|
RUN_PASS(2, FlatteningPass, run);
|
||||||
|
if (getTarget()->getChipset() < 0xc0)
|
||||||
|
RUN_PASS(2, NV50PostRaConstantFolding, run);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user