Use ExecutionDepsFix instead of NEONMoveFix.

This enables NEON domain tracking across basic blocks, but should
otherwise do the same thing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140772 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-09-29 02:48:41 +00:00
parent 5219f86a0b
commit 8bb3d3cb30
2 changed files with 21 additions and 11 deletions

View File

@ -2732,9 +2732,11 @@ ARMBaseInstrInfo::isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc,
// //
// We use the following execution domain numbering: // We use the following execution domain numbering:
// //
// 0: Generic enum ARMExeDomain {
// 1: VFP ExeGeneric = 0,
// 2: NEON ExeVFP = 1,
ExeNEON = 2
};
// //
// Also see ARMInstrFormats.td and Domain* enums in ARMBaseInfo.h // Also see ARMInstrFormats.td and Domain* enums in ARMBaseInfo.h
// //
@ -2743,33 +2745,41 @@ ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const {
// VMOVD is a VFP instruction, but can be changed to NEON if it isn't // VMOVD is a VFP instruction, but can be changed to NEON if it isn't
// predicated. // predicated.
if (MI->getOpcode() == ARM::VMOVD && !isPredicated(MI)) if (MI->getOpcode() == ARM::VMOVD && !isPredicated(MI))
return std::make_pair(1, 3); return std::make_pair(ExeVFP, (1<<ExeVFP) | (1<<ExeNEON));
// No other instructions can be swizzled, so just determine their domain. // No other instructions can be swizzled, so just determine their domain.
unsigned Domain = MI->getDesc().TSFlags & ARMII::DomainMask; unsigned Domain = MI->getDesc().TSFlags & ARMII::DomainMask;
if (Domain & ARMII::DomainNEON) if (Domain & ARMII::DomainNEON)
return std::make_pair(2, 0); return std::make_pair(ExeNEON, 0);
// Certain instructions can go either way on Cortex-A8. // Certain instructions can go either way on Cortex-A8.
// Treat them as NEON instructions. // Treat them as NEON instructions.
if ((Domain & ARMII::DomainNEONA8) && Subtarget.isCortexA8()) if ((Domain & ARMII::DomainNEONA8) && Subtarget.isCortexA8())
return std::make_pair(2, 0); return std::make_pair(ExeNEON, 0);
if (Domain & ARMII::DomainVFP) if (Domain & ARMII::DomainVFP)
return std::make_pair(1, 0); return std::make_pair(ExeVFP, 0);
return std::make_pair(0, 0); return std::make_pair(ExeGeneric, 0);
} }
void void
ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const {
// We only know how to change VMOVD into VORR. // We only know how to change VMOVD into VORR.
assert(MI->getOpcode() == ARM::VMOVD && "Can only swizzle VMOVD"); assert(MI->getOpcode() == ARM::VMOVD && "Can only swizzle VMOVD");
if (Domain != 2) if (Domain != ExeNEON)
return; return;
// Zap the predicate operands.
assert(!isPredicated(MI) && "Cannot predicate a VORRd");
MI->RemoveOperand(3);
MI->RemoveOperand(2);
// Change to a VORRd which requires two identical use operands. // Change to a VORRd which requires two identical use operands.
MI->setDesc(get(ARM::VORRd)); MI->setDesc(get(ARM::VORRd));
MachineInstrBuilder(MI).addReg(MI->getOperand(1).getReg());
// Add the extra source operand and new predicates.
// This will go before any implicit ops.
AddDefaultPred(MachineInstrBuilder(MI).addReg(MI->getOperand(1).getReg()));
} }

View File

@ -118,7 +118,7 @@ bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM,
if (!Subtarget.isThumb1Only()) if (!Subtarget.isThumb1Only())
PM.add(createARMLoadStoreOptimizationPass()); PM.add(createARMLoadStoreOptimizationPass());
if (Subtarget.hasNEON()) if (Subtarget.hasNEON())
PM.add(createNEONMoveFixPass()); PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass));
} }
// Expand some pseudo instructions into multiple instructions to allow // Expand some pseudo instructions into multiple instructions to allow