R600/SI: Add promotion of e32 to e64 in operand folding

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176105 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Christian Konig 2013-02-26 17:52:47 +00:00
parent f767018b10
commit 3c980d1632

View File

@ -501,6 +501,13 @@ SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
unsigned NumDefs = Desc->getNumDefs();
unsigned NumOps = Desc->getNumOperands();
// e64 version if available, -1 otherwise
int OpcodeE64 = AMDGPU::getVOPe64(Opcode);
const MCInstrDesc *DescE64 = OpcodeE64 == -1 ? 0 : &TII->get(OpcodeE64);
assert(!DescE64 || DescE64->getNumDefs() == NumDefs);
assert(!DescE64 || DescE64->getNumOperands() == (NumOps + 4));
int32_t Immediate = Desc->getSize() == 4 ? 0 : -1;
bool HaveVSrc = false, HaveSSrc = false;
@ -532,6 +539,7 @@ SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
// Second go over the operands and try to fold them
std::vector<SDValue> Ops;
bool Promote2e64 = false;
for (unsigned i = 0, e = Node->getNumOperands(), Op = NumDefs;
i != e && Op < NumOps; ++i, ++Op) {
@ -558,6 +566,20 @@ SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
SDValue Tmp = Ops[1];
Ops[1] = Ops[0];
Ops[0] = Tmp;
} else if (DescE64 && !Immediate) {
// Test if it makes sense to switch to e64 encoding
RegClass = DescE64->OpInfo[Op].RegClass;
int32_t TmpImm = -1;
if ((isVSrc(RegClass) || isSSrc(RegClass)) &&
foldImm(Ops[i], TmpImm, ScalarSlotUsed)) {
Immediate = -1;
Promote2e64 = true;
Desc = DescE64;
DescE64 = 0;
}
}
continue;
}
@ -569,10 +591,20 @@ SDNode *SITargetLowering::PostISelFolding(MachineSDNode *Node,
}
}
if (Promote2e64) {
// Add the modifier flags while promoting
for (unsigned i = 0; i < 4; ++i)
Ops.push_back(DAG.getTargetConstant(0, MVT::i32));
}
// Add optional chain and glue
for (unsigned i = NumOps - NumDefs, e = Node->getNumOperands(); i < e; ++i)
Ops.push_back(Node->getOperand(i));
// Update the instruction parameters
return DAG.UpdateNodeOperands(Node, Ops.data(), Ops.size());
// Either create a complete new or update the current instruction
if (Promote2e64)
return DAG.getMachineNode(OpcodeE64, Node->getDebugLoc(),
Node->getVTList(), Ops.data(), Ops.size());
else
return DAG.UpdateNodeOperands(Node, Ops.data(), Ops.size());
}