nvc0/ir: don't dual-issue ops that depend or interfere with each other
Signed-off-by: Karol Herbst <karolherbst@gmail.com> Reviewed-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de> [imirkin: rewrite to split up the helpers and move more logic to target] Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
aad4f15506
commit
d0cf7a6beb
|
@ -870,22 +870,22 @@ Instruction::writesPredicate() const
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
insnCheckCommutationDefSrc(const Instruction *a, const Instruction *b)
|
||||
bool
|
||||
Instruction::canCommuteDefSrc(const Instruction *i) const
|
||||
{
|
||||
for (int d = 0; a->defExists(d); ++d)
|
||||
for (int s = 0; b->srcExists(s); ++s)
|
||||
if (a->getDef(d)->interfers(b->getSrc(s)))
|
||||
for (int d = 0; defExists(d); ++d)
|
||||
for (int s = 0; i->srcExists(s); ++s)
|
||||
if (getDef(d)->interfers(i->getSrc(s)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
insnCheckCommutationDefDef(const Instruction *a, const Instruction *b)
|
||||
bool
|
||||
Instruction::canCommuteDefDef(const Instruction *i) const
|
||||
{
|
||||
for (int d = 0; a->defExists(d); ++d)
|
||||
for (int c = 0; b->defExists(c); ++c)
|
||||
if (a->getDef(d)->interfers(b->getDef(c)))
|
||||
for (int d = 0; defExists(d); ++d)
|
||||
for (int c = 0; i->defExists(c); ++c)
|
||||
if (getDef(d)->interfers(i->getDef(c)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -893,10 +893,9 @@ insnCheckCommutationDefDef(const Instruction *a, const Instruction *b)
|
|||
bool
|
||||
Instruction::isCommutationLegal(const Instruction *i) const
|
||||
{
|
||||
bool ret = insnCheckCommutationDefDef(this, i);
|
||||
ret = ret && insnCheckCommutationDefSrc(this, i);
|
||||
ret = ret && insnCheckCommutationDefSrc(i, this);
|
||||
return ret;
|
||||
return canCommuteDefDef(i) &&
|
||||
canCommuteDefSrc(i) &&
|
||||
i->canCommuteDefSrc(this);
|
||||
}
|
||||
|
||||
TexInstruction::TexInstruction(Function *fn, operation op)
|
||||
|
|
|
@ -834,6 +834,10 @@ public:
|
|||
bool isActionEqual(const Instruction *) const;
|
||||
bool isResultEqual(const Instruction *) const;
|
||||
|
||||
// check whether the defs interfere with srcs and defs of another instruction
|
||||
bool canCommuteDefDef(const Instruction *) const;
|
||||
bool canCommuteDefSrc(const Instruction *) const;
|
||||
|
||||
void print() const;
|
||||
|
||||
inline CmpInstruction *asCmp();
|
||||
|
|
|
@ -615,6 +615,12 @@ bool TargetNVC0::canDualIssue(const Instruction *a, const Instruction *b) const
|
|||
// not if the 2nd instruction isn't necessarily executed
|
||||
if (clA == OPCLASS_TEXTURE || clA == OPCLASS_FLOW)
|
||||
return false;
|
||||
|
||||
// Check that a and b don't write to the same sources, nor that b reads
|
||||
// anything that a writes.
|
||||
if (!a->canCommuteDefDef(b) || !a->canCommuteDefSrc(b))
|
||||
return false;
|
||||
|
||||
// anything with MOV
|
||||
if (a->op == OP_MOV || b->op == OP_MOV)
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue