forked from OSchip/llvm-project
update PPC 940 hazard rec. to function in postRA mode
llvm-svn: 145676
This commit is contained in:
parent
596ab8ee08
commit
58ca360081
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue