Use instruction itinerary to determine what instructions are 'cheap'.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117348 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-10-26 02:08:50 +00:00
parent 0e9996ca94
commit c8141dfc7f
5 changed files with 69 additions and 4 deletions

View File

@ -639,6 +639,12 @@ public:
const MachineInstr *UseMI, unsigned UseIdx) const {
return false;
}
/// hasLowDefLatency - Compute operand latency of a def of 'Reg', return true
/// if the target considered it 'low'.
virtual
bool hasLowDefLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx) const;
};
/// TargetInstrInfoImpl - This is the default implementation of

View File

@ -173,7 +173,10 @@ namespace {
/// HasHighOperandLatency - Compute operand latency between a def of 'Reg'
/// and an use in the current loop, return true if the target considered
/// it 'high'.
bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx, unsigned Reg);
bool HasHighOperandLatency(MachineInstr &MI, unsigned DefIdx,
unsigned Reg) const;
bool IsCheapInstruction(MachineInstr &MI) const;
/// CanCauseHighRegPressure - Visit BBs from header to current BB,
/// check if hoisting an instruction of the given cost matrix can cause high
@ -795,13 +798,15 @@ bool MachineLICM::isLoadFromConstantMemory(MachineInstr *MI) {
/// and an use in the current loop, return true if the target considered
/// it 'high'.
bool MachineLICM::HasHighOperandLatency(MachineInstr &MI,
unsigned DefIdx, unsigned Reg) {
if (MRI->use_nodbg_empty(Reg))
unsigned DefIdx, unsigned Reg) const {
if (!InstrItins || InstrItins->isEmpty() || MRI->use_nodbg_empty(Reg))
return false;
for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg),
E = MRI->use_nodbg_end(); I != E; ++I) {
MachineInstr *UseMI = &*I;
if (UseMI->isCopyLike())
continue;
if (!CurLoop->contains(UseMI->getParent()))
continue;
for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
@ -823,6 +828,33 @@ bool MachineLICM::HasHighOperandLatency(MachineInstr &MI,
return false;
}
/// IsCheapInstruction - Return true if the instruction is marked "cheap" or
/// the operand latency between its def and a use is one or less.
bool MachineLICM::IsCheapInstruction(MachineInstr &MI) const {
if (MI.getDesc().isAsCheapAsAMove() || MI.isCopyLike())
return true;
if (!InstrItins || InstrItins->isEmpty())
return false;
bool isCheap = false;
unsigned NumDefs = MI.getDesc().getNumDefs();
for (unsigned i = 0, e = MI.getNumOperands(); NumDefs && i != e; ++i) {
MachineOperand &DefMO = MI.getOperand(i);
if (!DefMO.isReg() || !DefMO.isDef())
continue;
--NumDefs;
unsigned Reg = DefMO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg))
continue;
if (!TII->hasLowDefLatency(InstrItins, &MI, i))
return false;
isCheap = true;
}
return isCheap;
}
/// CanCauseHighRegPressure - Visit BBs from header to current BB, check
/// if hoisting an instruction of the given cost matrix can cause high
/// register pressure.
@ -905,7 +937,7 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
// trade off is it may cause spill in high pressure situation. It will end up
// adding a store in the loop preheader. But the reload is no more expensive.
// The side benefit is these loads are frequently CSE'ed.
if (MI.getDesc().isAsCheapAsAMove()) {
if (IsCheapInstruction(MI)) {
if (!TII->isTriviallyReMaterializable(&MI, AA))
return false;
} else {

View File

@ -1951,3 +1951,18 @@ hasHighOperandLatency(const InstrItineraryData *ItinData,
return DDomain == ARMII::DomainVFP || DDomain == ARMII::DomainNEON ||
UDomain == ARMII::DomainVFP || UDomain == ARMII::DomainNEON;
}
bool ARMBaseInstrInfo::
hasLowDefLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx) const {
if (!ItinData || ItinData->isEmpty())
return false;
unsigned DDomain = DefMI->getDesc().TSFlags & ARMII::DomainMask;
if (DDomain == ARMII::DomainGeneral) {
unsigned DefClass = DefMI->getDesc().getSchedClass();
int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
return (DefCycle != -1 && DefCycle <= 2);
}
return false;
}

View File

@ -382,6 +382,8 @@ private:
const MachineRegisterInfo *MRI,
const MachineInstr *DefMI, unsigned DefIdx,
const MachineInstr *UseMI, unsigned UseIdx) const;
bool hasLowDefLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx) const;
};
static inline

View File

@ -94,6 +94,16 @@ TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
}
bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI,
unsigned DefIdx) const {
if (!ItinData || ItinData->isEmpty())
return false;
unsigned DefClass = DefMI->getDesc().getSchedClass();
int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
return (DefCycle != -1 && DefCycle <= 1);
}
/// insertNoop - Insert a noop into the instruction stream at the specified
/// point.