update PPC 940 hazard rec. to function in postRA mode

llvm-svn: 145676
This commit is contained in:
Hal Finkel 2011-12-02 04:58:02 +00:00
parent 596ab8ee08
commit 58ca360081
6 changed files with 93 additions and 142 deletions

View File

@ -80,12 +80,6 @@ PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
bool &isFirst, bool &isSingle,
bool &isCracked,
bool &isLoad, bool &isStore) {
if ((int)Opcode >= 0) {
isFirst = isSingle = isCracked = isLoad = isStore = false;
return PPCII::PPC970_Pseudo;
}
Opcode = ~Opcode;
const MCInstrDesc &MCID = TII.get(Opcode);
isLoad = MCID.mayLoad();
@ -102,29 +96,23 @@ PPCHazardRecognizer970::GetInstrType(unsigned Opcode,
/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
bool PPCHazardRecognizer970::
isLoadOfStoredAddress(unsigned LoadSize, SDValue Ptr1, SDValue Ptr2) const {
isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
const Value *LoadValue) const {
for (unsigned i = 0, e = NumStores; i != e; ++i) {
// Handle exact and commuted addresses.
if (Ptr1 == StorePtr1[i] && Ptr2 == StorePtr2[i])
return true;
if (Ptr2 == StorePtr1[i] && Ptr1 == StorePtr2[i])
if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
return true;
// Okay, we don't have an exact match, if this is an indexed offset, see if
// we have overlap (which happens during fp->int conversion for example).
if (StorePtr2[i] == Ptr2) {
if (ConstantSDNode *StoreOffset = dyn_cast<ConstantSDNode>(StorePtr1[i]))
if (ConstantSDNode *LoadOffset = dyn_cast<ConstantSDNode>(Ptr1)) {
// Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check
// to see if the load and store actually overlap.
int StoreOffs = StoreOffset->getZExtValue();
int LoadOffs = LoadOffset->getZExtValue();
if (StoreOffs < LoadOffs) {
if (int(StoreOffs+StoreSize[i]) > LoadOffs) return true;
} else {
if (int(LoadOffs+LoadSize) > StoreOffs) return true;
}
}
if (StoreValue[i] == LoadValue) {
// Okay the base pointers match, so we have [c1+r] vs [c2+r]. Check
// to see if the load and store actually overlap.
if (StoreOffset[i] < LoadOffset) {
if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;
} else {
if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;
}
}
}
return false;
@ -138,13 +126,18 @@ ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
getHazardType(SUnit *SU, int Stalls) {
assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");
const SDNode *Node = SU->getNode()->getGluedMachineNode();
MachineInstr *MI = SU->getInstr();
if (MI->isDebugValue())
return NoHazard;
unsigned Opcode = MI->getOpcode();
bool isFirst, isSingle, isCracked, isLoad, isStore;
PPCII::PPC970_Unit InstrType =
GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked,
GetInstrType(Opcode, isFirst, isSingle, isCracked,
isLoad, isStore);
if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
unsigned Opcode = Node->getMachineOpcode();
// We can only issue a PPC970_First/PPC970_Single instruction (such as
// crand/mtspr/etc) if this is the first cycle of the dispatch group.
@ -181,55 +174,10 @@ getHazardType(SUnit *SU, int Stalls) {
// If this is a load following a store, make sure it's not to the same or
// overlapping address.
if (isLoad && NumStores) {
unsigned LoadSize;
switch (Opcode) {
default: llvm_unreachable("Unknown load!");
case PPC::LBZ: case PPC::LBZU:
case PPC::LBZX:
case PPC::LBZ8: case PPC::LBZU8:
case PPC::LBZX8:
case PPC::LVEBX:
LoadSize = 1;
break;
case PPC::LHA: case PPC::LHAU:
case PPC::LHAX:
case PPC::LHZ: case PPC::LHZU:
case PPC::LHZX:
case PPC::LVEHX:
case PPC::LHBRX:
case PPC::LHA8: case PPC::LHAU8:
case PPC::LHAX8:
case PPC::LHZ8: case PPC::LHZU8:
case PPC::LHZX8:
LoadSize = 2;
break;
case PPC::LFS: case PPC::LFSU:
case PPC::LFSX:
case PPC::LWZ: case PPC::LWZU:
case PPC::LWZX:
case PPC::LWA:
case PPC::LWAX:
case PPC::LVEWX:
case PPC::LWBRX:
case PPC::LWZ8:
case PPC::LWZX8:
LoadSize = 4;
break;
case PPC::LFD: case PPC::LFDU:
case PPC::LFDX:
case PPC::LD: case PPC::LDU:
case PPC::LDX:
LoadSize = 8;
break;
case PPC::LVX:
case PPC::LVXL:
LoadSize = 16;
break;
}
if (isLoadOfStoredAddress(LoadSize,
Node->getOperand(0), Node->getOperand(1)))
if (isLoad && NumStores && !MI->memoperands_empty()) {
MachineMemOperand *MO = *MI->memoperands_begin();
if (isLoadOfStoredAddress(MO->getSize(),
MO->getOffset(), MO->getValue()))
return NoopHazard;
}
@ -237,66 +185,28 @@ getHazardType(SUnit *SU, int Stalls) {
}
void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
const SDNode *Node = SU->getNode()->getGluedMachineNode();
MachineInstr *MI = SU->getInstr();
if (MI->isDebugValue())
return;
unsigned Opcode = MI->getOpcode();
bool isFirst, isSingle, isCracked, isLoad, isStore;
PPCII::PPC970_Unit InstrType =
GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked,
GetInstrType(Opcode, isFirst, isSingle, isCracked,
isLoad, isStore);
if (InstrType == PPCII::PPC970_Pseudo) return;
unsigned Opcode = Node->getMachineOpcode();
// Update structural hazard information.
if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;
// Track the address stored to.
if (isStore) {
unsigned ThisStoreSize;
switch (Opcode) {
default: llvm_unreachable("Unknown store instruction!");
case PPC::STB: case PPC::STB8:
case PPC::STBU: case PPC::STBU8:
case PPC::STBX: case PPC::STBX8:
case PPC::STVEBX:
ThisStoreSize = 1;
break;
case PPC::STH: case PPC::STH8:
case PPC::STHU: case PPC::STHU8:
case PPC::STHX: case PPC::STHX8:
case PPC::STVEHX:
case PPC::STHBRX:
ThisStoreSize = 2;
break;
case PPC::STFS:
case PPC::STFSU:
case PPC::STFSX:
case PPC::STWX: case PPC::STWX8:
case PPC::STWUX:
case PPC::STW: case PPC::STW8:
case PPC::STWU:
case PPC::STVEWX:
case PPC::STFIWX:
case PPC::STWBRX:
ThisStoreSize = 4;
break;
case PPC::STD_32:
case PPC::STDX_32:
case PPC::STD:
case PPC::STDU:
case PPC::STFD:
case PPC::STFDX:
case PPC::STDX:
case PPC::STDUX:
ThisStoreSize = 8;
break;
case PPC::STVX:
case PPC::STVXL:
ThisStoreSize = 16;
break;
}
StoreSize[NumStores] = ThisStoreSize;
StorePtr1[NumStores] = Node->getOperand(1);
StorePtr2[NumStores] = Node->getOperand(2);
if (isStore && NumStores < 4 && !MI->memoperands_empty()) {
MachineMemOperand *MO = *MI->memoperands_begin();
StoreSize[NumStores] = MO->getSize();
StoreOffset[NumStores] = MO->getOffset();
StoreValue[NumStores] = MO->getValue();
++NumStores;
}
@ -319,3 +229,8 @@ void PPCHazardRecognizer970::AdvanceCycle() {
if (NumIssued == 5)
EndDispatchGroup();
}
void PPCHazardRecognizer970::Reset() {
EndDispatchGroup();
}

View File

@ -55,8 +55,9 @@ class PPCHazardRecognizer970 : public ScheduleHazardRecognizer {
//
// This is null if we haven't seen a store yet. We keep track of both
// operands of the store here, since we support [r+r] and [r+i] addressing.
SDValue StorePtr1[4], StorePtr2[4];
unsigned StoreSize[4];
const Value *StoreValue[4];
int64_t StoreOffset[4];
uint64_t StoreSize[4];
unsigned NumStores;
public:
@ -64,6 +65,7 @@ public:
virtual HazardType getHazardType(SUnit *SU, int Stalls);
virtual void EmitInstruction(SUnit *SU);
virtual void AdvanceCycle();
virtual void Reset();
private:
/// EndDispatchGroup - Called when we are finishing a new dispatch group.
@ -76,8 +78,8 @@ private:
bool &isFirst, bool &isSingle,bool &isCracked,
bool &isLoad, bool &isStore);
bool isLoadOfStoredAddress(unsigned LoadSize,
SDValue Ptr1, SDValue Ptr2) const;
bool isLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
const Value *LoadValue) const;
};
} // end namespace llvm

View File

@ -48,25 +48,32 @@ PPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm)
ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer(
const TargetMachine *TM,
const ScheduleDAG *DAG) const {
// Should use subtarget info to pick the right hazard recognizer. For
// now, always return a PPC970 recognizer.
const TargetInstrInfo *TII = TM->getInstrInfo();
(void)TII;
assert(TII && "No InstrInfo?");
unsigned Directive = TM->getSubtarget<PPCSubtarget>().getDarwinDirective();
if (Directive == PPC::DIR_440) {
const InstrItineraryData *II = TM->getInstrItineraryData();
return new PPCHazardRecognizer440(II, DAG);
}
else {
// Disable the hazard recognizer for now, as it doesn't support
// bottom-up scheduling.
//return new PPCHazardRecognizer970(*TII);
return new ScheduleHazardRecognizer();
}
return TargetInstrInfoImpl::CreateTargetHazardRecognizer(TM, DAG);
}
/// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer
/// to use for this target when scheduling the DAG.
ScheduleHazardRecognizer *PPCInstrInfo::CreateTargetPostRAHazardRecognizer(
const InstrItineraryData *II,
const ScheduleDAG *DAG) const {
unsigned Directive = TM.getSubtarget<PPCSubtarget>().getDarwinDirective();
// Most subtargets use a PPC970 recognizer.
if (Directive != PPC::DIR_440) {
const TargetInstrInfo *TII = TM.getInstrInfo();
assert(TII && "No InstrInfo?");
return new PPCHazardRecognizer970(*TII);
}
return TargetInstrInfoImpl::CreateTargetPostRAHazardRecognizer(II, DAG);
}
unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const {
switch (MI->getOpcode()) {

View File

@ -88,6 +88,9 @@ public:
ScheduleHazardRecognizer *
CreateTargetHazardRecognizer(const TargetMachine *TM,
const ScheduleDAG *DAG) const;
ScheduleHazardRecognizer *
CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
const ScheduleDAG *DAG) const;
unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "PPCSubtarget.h"
#include "PPCRegisterInfo.h"
#include "PPC.h"
#include "llvm/GlobalValue.h"
#include "llvm/Target/TargetMachine.h"
@ -140,3 +141,22 @@ bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV,
return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
GV->hasCommonLinkage() || isDecl;
}
bool PPCSubtarget::enablePostRAScheduler(
CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const {
if (DarwinDirective == PPC::DIR_440)
return false;
Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL;
CriticalPathRCs.clear();
if (isPPC64())
CriticalPathRCs.push_back(&PPC::G8RCRegClass);
else
CriticalPathRCs.push_back(&PPC::GPRCRegClass);
return OptLevel >= CodeGenOpt::Default;
}

View File

@ -148,6 +148,10 @@ public:
bool isDarwinABI() const { return isDarwin(); }
bool isSVR4ABI() const { return !isDarwin(); }
/// enablePostRAScheduler - True at 'More' optimization.
bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
TargetSubtargetInfo::AntiDepBreakMode& Mode,
RegClassVector& CriticalPathRCs) const;
};
} // End llvm namespace