nv50/ir: optimize neg(and(set, 1)) to set

helps shaders in saints row IV, bioshock infinite and shadow warrior

total instructions in shared programs : 1914931 -> 1903900 (-0.58%)
total gprs used in shared programs    : 247920 -> 247785 (-0.05%)
total local used in shared programs   : 5673 -> 5673 (0.00%)
total bytes used in shared programs   : 17558272 -> 17457320 (-0.57%)

                local        gpr       inst      bytes
    helped           0         137         719         719
      hurt           0          12           0           0

v2: remove this opt for OP_SLCT and check against float for OP_SET
v3: simplified the code

Signed-off-by: Karol Herbst <nouveau@karolherbst.de>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Karol Herbst 2016-01-24 00:16:05 +01:00 committed by Ilia Mirkin
parent ca23c8081f
commit 068e9848ba

View file

@ -1539,6 +1539,7 @@ private:
void handleCVT_CVT(Instruction *);
void handleCVT_EXTBF(Instruction *);
void handleSUCLAMP(Instruction *);
void handleNEG(Instruction *);
BuildUtil bld;
};
@ -2011,6 +2012,34 @@ AlgebraicOpt::handleSUCLAMP(Instruction *insn)
insn->setSrc(0, add->getSrc(s));
}
// NEG(AND(SET, 1)) -> SET
void
AlgebraicOpt::handleNEG(Instruction *i) {
Instruction *src = i->getSrc(0)->getInsn();
ImmediateValue imm;
int b;
if (isFloatType(i->sType) || !src || src->op != OP_AND)
return;
if (src->src(0).getImmediate(imm))
b = 1;
else if (src->src(1).getImmediate(imm))
b = 0;
else
return;
if (!imm.isInteger(1))
return;
Instruction *set = src->getSrc(b)->getInsn();
if ((set->op == OP_SET || set->op == OP_SET_AND ||
set->op == OP_SET_OR || set->op == OP_SET_XOR) &&
!isFloatType(set->dType)) {
i->def(0).replace(set->getDef(0), false);
}
}
bool
AlgebraicOpt::visit(BasicBlock *bb)
{
@ -2048,6 +2077,9 @@ AlgebraicOpt::visit(BasicBlock *bb)
case OP_SUCLAMP:
handleSUCLAMP(i);
break;
case OP_NEG:
handleNEG(i);
break;
default:
break;
}