mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[Hexagon] Referencify MachineInstr in HexagonInstrInfo, NFC
llvm-svn: 277220
This commit is contained in:
parent
20f3abeefd
commit
846bd7b26a
@ -104,7 +104,7 @@ void HexagonBranchRelaxation::computeOffset(MachineFunction &MF,
|
||||
}
|
||||
OffsetMap[&B] = InstOffset;
|
||||
for (auto &MI : B.instrs())
|
||||
InstOffset += HII->getSize(&MI);
|
||||
InstOffset += HII->getSize(MI);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,13 +152,13 @@ bool HexagonBranchRelaxation::isJumpOutOfRange(MachineInstr &MI,
|
||||
// Could not analyze it. See if this is something we can recognize.
|
||||
// If it is a NVJ, it should always have its target in
|
||||
// a fixed location.
|
||||
if (HII->isNewValueJump(&*FirstTerm))
|
||||
TBB = FirstTerm->getOperand(HII->getCExtOpNum(&*FirstTerm)).getMBB();
|
||||
if (HII->isNewValueJump(*FirstTerm))
|
||||
TBB = FirstTerm->getOperand(HII->getCExtOpNum(*FirstTerm)).getMBB();
|
||||
}
|
||||
if (TBB && &MI == &*FirstTerm) {
|
||||
Distance = std::abs((long long)InstOffset - BlockToInstOffset[TBB])
|
||||
+ BranchRelaxSafetyBuffer;
|
||||
return !HII->isJumpWithinBranchRange(&*FirstTerm, Distance);
|
||||
return !HII->isJumpWithinBranchRange(*FirstTerm, Distance);
|
||||
}
|
||||
if (FBB) {
|
||||
// Look for second terminator.
|
||||
@ -171,7 +171,7 @@ bool HexagonBranchRelaxation::isJumpOutOfRange(MachineInstr &MI,
|
||||
// Analyze the second branch in the BB.
|
||||
Distance = std::abs((long long)InstOffset - BlockToInstOffset[FBB])
|
||||
+ BranchRelaxSafetyBuffer;
|
||||
return !HII->isJumpWithinBranchRange(&*SecondTerm, Distance);
|
||||
return !HII->isJumpWithinBranchRange(*SecondTerm, Distance);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -186,16 +186,16 @@ bool HexagonBranchRelaxation::reGenerateBranch(MachineFunction &MF,
|
||||
if (!MI.isBranch() || !isJumpOutOfRange(MI, BlockToInstOffset))
|
||||
continue;
|
||||
DEBUG(dbgs() << "Long distance jump. isExtendable("
|
||||
<< HII->isExtendable(&MI) << ") isConstExtended("
|
||||
<< HII->isConstExtended(&MI) << ") " << MI);
|
||||
<< HII->isExtendable(MI) << ") isConstExtended("
|
||||
<< HII->isConstExtended(MI) << ") " << MI);
|
||||
|
||||
// Since we have not merged HW loops relaxation into
|
||||
// this code (yet), soften our approach for the moment.
|
||||
if (!HII->isExtendable(&MI) && !HII->isExtended(&MI)) {
|
||||
if (!HII->isExtendable(MI) && !HII->isExtended(MI)) {
|
||||
DEBUG(dbgs() << "\tUnderimplemented relax branch instruction.\n");
|
||||
} else {
|
||||
// Find which operand is expandable.
|
||||
int ExtOpNum = HII->getCExtOpNum(&MI);
|
||||
int ExtOpNum = HII->getCExtOpNum(MI);
|
||||
MachineOperand &MO = MI.getOperand(ExtOpNum);
|
||||
// This need to be something we understand. So far we assume all
|
||||
// branches have only MBB address as expandable field.
|
||||
|
@ -385,7 +385,7 @@ HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {
|
||||
continue;
|
||||
|
||||
// Mark TFRs that feed a potential new value store as such.
|
||||
if (TII->mayBeNewStore(&MI)) {
|
||||
if (TII->mayBeNewStore(MI)) {
|
||||
// Look for uses of TFR instructions.
|
||||
for (unsigned OpdIdx = 0, OpdE = MI.getNumOperands(); OpdIdx != OpdE;
|
||||
++OpdIdx) {
|
||||
|
@ -125,7 +125,7 @@ bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {
|
||||
|
||||
BlockToInstOffset[&MBB] = InstOffset;
|
||||
for (const MachineInstr &MI : MBB)
|
||||
InstOffset += HII->getSize(&MI);
|
||||
InstOffset += HII->getSize(MI);
|
||||
}
|
||||
|
||||
// Second pass - check each loop instruction to see if it needs to be
|
||||
@ -138,7 +138,7 @@ bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {
|
||||
MachineBasicBlock::iterator MII = MBB.begin();
|
||||
MachineBasicBlock::iterator MIE = MBB.end();
|
||||
while (MII != MIE) {
|
||||
InstOffset += HII->getSize(&*MII);
|
||||
InstOffset += HII->getSize(*MII);
|
||||
if (MII->isDebugValue()) {
|
||||
++MII;
|
||||
continue;
|
||||
|
@ -2001,7 +2001,7 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
|
||||
// this restriction.
|
||||
if (Load || Store) {
|
||||
int TFI = Load ? LFI : SFI;
|
||||
unsigned AM = HII.getAddrMode(&In);
|
||||
unsigned AM = HII.getAddrMode(In);
|
||||
SlotInfo &SI = FIRangeMap[TFI];
|
||||
bool Bad = (AM != HexagonII::BaseImmOffset);
|
||||
if (!Bad) {
|
||||
@ -2016,7 +2016,7 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
|
||||
}
|
||||
if (!Bad) {
|
||||
// Check sizes.
|
||||
unsigned S = (1U << (HII.getMemAccessSize(&In) - 1));
|
||||
unsigned S = (1U << (HII.getMemAccessSize(In) - 1));
|
||||
if (SI.Size != 0 && SI.Size != S)
|
||||
Bad = true;
|
||||
else
|
||||
@ -2166,15 +2166,15 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
|
||||
if (!IndexType::isInstr(Range.start()) ||
|
||||
!IndexType::isInstr(Range.end()))
|
||||
continue;
|
||||
MachineInstr *SI = IM.getInstr(Range.start());
|
||||
MachineInstr *EI = IM.getInstr(Range.end());
|
||||
assert(SI->mayStore() && "Unexpected start instruction");
|
||||
assert(EI->mayLoad() && "Unexpected end instruction");
|
||||
MachineOperand &SrcOp = SI->getOperand(2);
|
||||
MachineInstr &SI = *IM.getInstr(Range.start());
|
||||
MachineInstr &EI = *IM.getInstr(Range.end());
|
||||
assert(SI.mayStore() && "Unexpected start instruction");
|
||||
assert(EI.mayLoad() && "Unexpected end instruction");
|
||||
MachineOperand &SrcOp = SI.getOperand(2);
|
||||
|
||||
HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.getReg(),
|
||||
SrcOp.getSubReg() };
|
||||
auto *RC = HII.getRegClass(SI->getDesc(), 2, &HRI, MF);
|
||||
auto *RC = HII.getRegClass(SI.getDesc(), 2, &HRI, MF);
|
||||
// The this-> is needed to unconfuse MSVC.
|
||||
unsigned FoundR = this->findPhysReg(MF, Range, IM, DM, RC);
|
||||
DEBUG(dbgs() << "Replacement reg:" << PrintReg(FoundR, &HRI) << '\n');
|
||||
@ -2189,10 +2189,10 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
|
||||
#endif
|
||||
|
||||
// Generate the copy-in: "FoundR = COPY SrcR" at the store location.
|
||||
MachineBasicBlock::iterator StartIt = SI, NextIt;
|
||||
MachineBasicBlock::iterator StartIt = SI.getIterator(), NextIt;
|
||||
MachineInstr *CopyIn = nullptr;
|
||||
if (SrcRR.Reg != FoundR || SrcRR.Sub != 0) {
|
||||
const DebugLoc &DL = SI->getDebugLoc();
|
||||
const DebugLoc &DL = SI.getDebugLoc();
|
||||
CopyIn = BuildMI(B, StartIt, DL, HII.get(TargetOpcode::COPY), FoundR)
|
||||
.addOperand(SrcOp);
|
||||
}
|
||||
@ -2209,33 +2209,33 @@ void HexagonFrameLowering::optimizeSpillSlots(MachineFunction &MF,
|
||||
// We are keeping this register live.
|
||||
SrcOp.setIsKill(false);
|
||||
} else {
|
||||
B.erase(SI);
|
||||
IM.replaceInstr(SI, CopyIn);
|
||||
B.erase(&SI);
|
||||
IM.replaceInstr(&SI, CopyIn);
|
||||
}
|
||||
|
||||
auto EndIt = std::next(MachineBasicBlock::iterator(EI));
|
||||
auto EndIt = std::next(EI.getIterator());
|
||||
for (auto It = StartIt; It != EndIt; It = NextIt) {
|
||||
MachineInstr *MI = &*It;
|
||||
MachineInstr &MI = *It;
|
||||
NextIt = std::next(It);
|
||||
int TFI;
|
||||
if (!HII.isLoadFromStackSlot(*MI, TFI) || TFI != FI)
|
||||
if (!HII.isLoadFromStackSlot(MI, TFI) || TFI != FI)
|
||||
continue;
|
||||
unsigned DstR = MI->getOperand(0).getReg();
|
||||
assert(MI->getOperand(0).getSubReg() == 0);
|
||||
unsigned DstR = MI.getOperand(0).getReg();
|
||||
assert(MI.getOperand(0).getSubReg() == 0);
|
||||
MachineInstr *CopyOut = nullptr;
|
||||
if (DstR != FoundR) {
|
||||
DebugLoc DL = MI->getDebugLoc();
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
unsigned MemSize = (1U << (HII.getMemAccessSize(MI) - 1));
|
||||
assert(HII.getAddrMode(MI) == HexagonII::BaseImmOffset);
|
||||
unsigned CopyOpc = TargetOpcode::COPY;
|
||||
if (HII.isSignExtendingLoad(*MI))
|
||||
if (HII.isSignExtendingLoad(MI))
|
||||
CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
|
||||
else if (HII.isZeroExtendingLoad(*MI))
|
||||
else if (HII.isZeroExtendingLoad(MI))
|
||||
CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
|
||||
CopyOut = BuildMI(B, It, DL, HII.get(CopyOpc), DstR)
|
||||
.addReg(FoundR, getKillRegState(MI == EI));
|
||||
.addReg(FoundR, getKillRegState(&MI == &EI));
|
||||
}
|
||||
IM.replaceInstr(MI, CopyOut);
|
||||
IM.replaceInstr(&MI, CopyOut);
|
||||
B.erase(It);
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ void HexagonGenInsert::pruneCoveredSets(unsigned VR) {
|
||||
// If there exists a candidate with a non-empty set, the ones with empty
|
||||
// sets will not be used and can be removed.
|
||||
MachineInstr *DefVR = MRI->getVRegDef(VR);
|
||||
bool DefEx = HII->isConstExtended(DefVR);
|
||||
bool DefEx = HII->isConstExtended(*DefVR);
|
||||
bool HasNE = false;
|
||||
for (unsigned i = 0, n = LL.size(); i < n; ++i) {
|
||||
if (LL[i].second.empty())
|
||||
|
@ -42,7 +42,7 @@ HexagonHazardRecognizer::getHazardType(SUnit *SU, int stalls) {
|
||||
if (!Resources->canReserveResources(*MI)) {
|
||||
DEBUG(dbgs() << "*** Hazard in cycle " << PacketNum << ", " << *MI);
|
||||
HazardType RetVal = Hazard;
|
||||
if (TII->mayBeNewStore(MI)) {
|
||||
if (TII->mayBeNewStore(*MI)) {
|
||||
// Make sure the register to be stored is defined by an instruction in the
|
||||
// packet.
|
||||
MachineOperand &MO = MI->getOperand(MI->getNumOperands() - 1);
|
||||
@ -52,7 +52,7 @@ HexagonHazardRecognizer::getHazardType(SUnit *SU, int stalls) {
|
||||
// causes a hazard.
|
||||
MachineFunction *MF = MI->getParent()->getParent();
|
||||
MachineInstr *NewMI =
|
||||
MF->CreateMachineInstr(TII->get(TII->getDotNewOp(MI)),
|
||||
MF->CreateMachineInstr(TII->get(TII->getDotNewOp(*MI)),
|
||||
MI->getDebugLoc());
|
||||
if (Resources->canReserveResources(*NewMI))
|
||||
RetVal = NoHazard;
|
||||
@ -106,10 +106,11 @@ void HexagonHazardRecognizer::EmitInstruction(SUnit *SU) {
|
||||
if (!Resources->canReserveResources(*MI)) {
|
||||
// It must be a .new store since other instructions must be able to be
|
||||
// reserved at this point.
|
||||
assert(TII->mayBeNewStore(MI) && "Expecting .new store");
|
||||
assert(TII->mayBeNewStore(*MI) && "Expecting .new store");
|
||||
MachineFunction *MF = MI->getParent()->getParent();
|
||||
MachineInstr *NewMI = MF->CreateMachineInstr(TII->get(TII->getDotNewOp(MI)),
|
||||
MI->getDebugLoc());
|
||||
MachineInstr *NewMI =
|
||||
MF->CreateMachineInstr(TII->get(TII->getDotNewOp(*MI)),
|
||||
MI->getDebugLoc());
|
||||
assert(Resources->canReserveResources(*NewMI));
|
||||
Resources->reserveResources(*NewMI);
|
||||
MF->DeleteMachineInstr(NewMI);
|
||||
@ -123,7 +124,7 @@ void HexagonHazardRecognizer::EmitInstruction(SUnit *SU) {
|
||||
// schedule it before other instructions. We only do this if the use has
|
||||
// the same height as the dot cur. Otherwise, we may miss scheduling an
|
||||
// instruction with a greater height, which is more important.
|
||||
if (TII->mayBeCurLoad(MI))
|
||||
if (TII->mayBeCurLoad(*MI))
|
||||
for (auto &S : SU->Succs)
|
||||
if (S.isAssignedRegDep() && S.getLatency() == 0 &&
|
||||
SU->getHeight() == S.getSUnit()->getHeight()) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -205,6 +205,9 @@ public:
|
||||
/// Returns true if the instruction is already predicated.
|
||||
bool isPredicated(const MachineInstr &MI) const override;
|
||||
|
||||
/// Return true for post-incremented instructions.
|
||||
bool isPostIncrement(const MachineInstr *MI) const override;
|
||||
|
||||
/// Convert the instruction into a predicated instruction.
|
||||
/// It returns true if the operation was successful.
|
||||
bool PredicateInstruction(MachineInstr &MI,
|
||||
@ -284,49 +287,48 @@ public:
|
||||
|
||||
unsigned createVR(MachineFunction* MF, MVT VT) const;
|
||||
|
||||
bool isAbsoluteSet(const MachineInstr* MI) const;
|
||||
bool isAccumulator(const MachineInstr *MI) const;
|
||||
bool isComplex(const MachineInstr *MI) const;
|
||||
bool isCompoundBranchInstr(const MachineInstr *MI) const;
|
||||
bool isCondInst(const MachineInstr *MI) const;
|
||||
bool isConditionalALU32 (const MachineInstr* MI) const;
|
||||
bool isConditionalLoad(const MachineInstr* MI) const;
|
||||
bool isConditionalStore(const MachineInstr* MI) const;
|
||||
bool isConditionalTransfer(const MachineInstr* MI) const;
|
||||
bool isConstExtended(const MachineInstr *MI) const;
|
||||
bool isDeallocRet(const MachineInstr *MI) const;
|
||||
bool isDependent(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) const;
|
||||
bool isDotCurInst(const MachineInstr* MI) const;
|
||||
bool isDotNewInst(const MachineInstr* MI) const;
|
||||
bool isDuplexPair(const MachineInstr *MIa, const MachineInstr *MIb) const;
|
||||
bool isEarlySourceInstr(const MachineInstr *MI) const;
|
||||
bool isAbsoluteSet(const MachineInstr &MI) const;
|
||||
bool isAccumulator(const MachineInstr &MI) const;
|
||||
bool isComplex(const MachineInstr &MI) const;
|
||||
bool isCompoundBranchInstr(const MachineInstr &MI) const;
|
||||
bool isCondInst(const MachineInstr &MI) const;
|
||||
bool isConditionalALU32 (const MachineInstr &MI) const;
|
||||
bool isConditionalLoad(const MachineInstr &MI) const;
|
||||
bool isConditionalStore(const MachineInstr &MI) const;
|
||||
bool isConditionalTransfer(const MachineInstr &MI) const;
|
||||
bool isConstExtended(const MachineInstr &MI) const;
|
||||
bool isDeallocRet(const MachineInstr &MI) const;
|
||||
bool isDependent(const MachineInstr &ProdMI,
|
||||
const MachineInstr &ConsMI) const;
|
||||
bool isDotCurInst(const MachineInstr &MI) const;
|
||||
bool isDotNewInst(const MachineInstr &MI) const;
|
||||
bool isDuplexPair(const MachineInstr &MIa, const MachineInstr &MIb) const;
|
||||
bool isEarlySourceInstr(const MachineInstr &MI) const;
|
||||
bool isEndLoopN(unsigned Opcode) const;
|
||||
bool isExpr(unsigned OpType) const;
|
||||
bool isExtendable(const MachineInstr* MI) const;
|
||||
bool isExtended(const MachineInstr* MI) const;
|
||||
bool isFloat(const MachineInstr *MI) const;
|
||||
bool isHVXMemWithAIndirect(const MachineInstr *I,
|
||||
const MachineInstr *J) const;
|
||||
bool isIndirectCall(const MachineInstr *MI) const;
|
||||
bool isIndirectL4Return(const MachineInstr *MI) const;
|
||||
bool isJumpR(const MachineInstr *MI) const;
|
||||
bool isJumpWithinBranchRange(const MachineInstr *MI, unsigned offset) const;
|
||||
bool isLateInstrFeedsEarlyInstr(const MachineInstr *LRMI,
|
||||
const MachineInstr *ESMI) const;
|
||||
bool isLateResultInstr(const MachineInstr *MI) const;
|
||||
bool isLateSourceInstr(const MachineInstr *MI) const;
|
||||
bool isLoopN(const MachineInstr *MI) const;
|
||||
bool isMemOp(const MachineInstr *MI) const;
|
||||
bool isNewValue(const MachineInstr* MI) const;
|
||||
bool isExtendable(const MachineInstr &MI) const;
|
||||
bool isExtended(const MachineInstr &MI) const;
|
||||
bool isFloat(const MachineInstr &MI) const;
|
||||
bool isHVXMemWithAIndirect(const MachineInstr &I,
|
||||
const MachineInstr &J) const;
|
||||
bool isIndirectCall(const MachineInstr &MI) const;
|
||||
bool isIndirectL4Return(const MachineInstr &MI) const;
|
||||
bool isJumpR(const MachineInstr &MI) const;
|
||||
bool isJumpWithinBranchRange(const MachineInstr &MI, unsigned offset) const;
|
||||
bool isLateInstrFeedsEarlyInstr(const MachineInstr &LRMI,
|
||||
const MachineInstr &ESMI) const;
|
||||
bool isLateResultInstr(const MachineInstr &MI) const;
|
||||
bool isLateSourceInstr(const MachineInstr &MI) const;
|
||||
bool isLoopN(const MachineInstr &MI) const;
|
||||
bool isMemOp(const MachineInstr &MI) const;
|
||||
bool isNewValue(const MachineInstr &MI) const;
|
||||
bool isNewValue(unsigned Opcode) const;
|
||||
bool isNewValueInst(const MachineInstr* MI) const;
|
||||
bool isNewValueJump(const MachineInstr* MI) const;
|
||||
bool isNewValueInst(const MachineInstr &MI) const;
|
||||
bool isNewValueJump(const MachineInstr &MI) const;
|
||||
bool isNewValueJump(unsigned Opcode) const;
|
||||
bool isNewValueStore(const MachineInstr* MI) const;
|
||||
bool isNewValueStore(const MachineInstr &MI) const;
|
||||
bool isNewValueStore(unsigned Opcode) const;
|
||||
bool isOperandExtended(const MachineInstr *MI, unsigned OperandNum) const;
|
||||
bool isPostIncrement(const MachineInstr* MI) const override;
|
||||
bool isOperandExtended(const MachineInstr &MI, unsigned OperandNum) const;
|
||||
bool isPredicatedNew(const MachineInstr &MI) const;
|
||||
bool isPredicatedNew(unsigned Opcode) const;
|
||||
bool isPredicatedTrue(const MachineInstr &MI) const;
|
||||
@ -334,85 +336,85 @@ public:
|
||||
bool isPredicated(unsigned Opcode) const;
|
||||
bool isPredicateLate(unsigned Opcode) const;
|
||||
bool isPredictedTaken(unsigned Opcode) const;
|
||||
bool isSaveCalleeSavedRegsCall(const MachineInstr *MI) const;
|
||||
bool isSaveCalleeSavedRegsCall(const MachineInstr &MI) const;
|
||||
bool isSignExtendingLoad(const MachineInstr &MI) const;
|
||||
bool isSolo(const MachineInstr* MI) const;
|
||||
bool isSpillPredRegOp(const MachineInstr *MI) const;
|
||||
bool isTailCall(const MachineInstr *MI) const;
|
||||
bool isTC1(const MachineInstr *MI) const;
|
||||
bool isTC2(const MachineInstr *MI) const;
|
||||
bool isTC2Early(const MachineInstr *MI) const;
|
||||
bool isTC4x(const MachineInstr *MI) const;
|
||||
bool isToBeScheduledASAP(const MachineInstr *MI1,
|
||||
const MachineInstr *MI2) const;
|
||||
bool isV60VectorInstruction(const MachineInstr *MI) const;
|
||||
bool isSolo(const MachineInstr &MI) const;
|
||||
bool isSpillPredRegOp(const MachineInstr &MI) const;
|
||||
bool isTailCall(const MachineInstr &MI) const;
|
||||
bool isTC1(const MachineInstr &MI) const;
|
||||
bool isTC2(const MachineInstr &MI) const;
|
||||
bool isTC2Early(const MachineInstr &MI) const;
|
||||
bool isTC4x(const MachineInstr &MI) const;
|
||||
bool isToBeScheduledASAP(const MachineInstr &MI1,
|
||||
const MachineInstr &MI2) const;
|
||||
bool isV60VectorInstruction(const MachineInstr &MI) const;
|
||||
bool isValidAutoIncImm(const EVT VT, const int Offset) const;
|
||||
bool isValidOffset(unsigned Opcode, int Offset, bool Extend = true) const;
|
||||
bool isVecAcc(const MachineInstr *MI) const;
|
||||
bool isVecALU(const MachineInstr *MI) const;
|
||||
bool isVecUsableNextPacket(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) const;
|
||||
bool isVecAcc(const MachineInstr &MI) const;
|
||||
bool isVecALU(const MachineInstr &MI) const;
|
||||
bool isVecUsableNextPacket(const MachineInstr &ProdMI,
|
||||
const MachineInstr &ConsMI) const;
|
||||
bool isZeroExtendingLoad(const MachineInstr &MI) const;
|
||||
|
||||
bool addLatencyToSchedule(const MachineInstr *MI1,
|
||||
const MachineInstr *MI2) const;
|
||||
bool canExecuteInBundle(const MachineInstr *First,
|
||||
const MachineInstr *Second) const;
|
||||
bool addLatencyToSchedule(const MachineInstr &MI1,
|
||||
const MachineInstr &MI2) const;
|
||||
bool canExecuteInBundle(const MachineInstr &First,
|
||||
const MachineInstr &Second) const;
|
||||
bool hasEHLabel(const MachineBasicBlock *B) const;
|
||||
bool hasNonExtEquivalent(const MachineInstr *MI) const;
|
||||
bool hasPseudoInstrPair(const MachineInstr *MI) const;
|
||||
bool hasNonExtEquivalent(const MachineInstr &MI) const;
|
||||
bool hasPseudoInstrPair(const MachineInstr &MI) const;
|
||||
bool hasUncondBranch(const MachineBasicBlock *B) const;
|
||||
bool mayBeCurLoad(const MachineInstr* MI) const;
|
||||
bool mayBeNewStore(const MachineInstr* MI) const;
|
||||
bool producesStall(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) const;
|
||||
bool producesStall(const MachineInstr *MI,
|
||||
bool mayBeCurLoad(const MachineInstr &MI) const;
|
||||
bool mayBeNewStore(const MachineInstr &MI) const;
|
||||
bool producesStall(const MachineInstr &ProdMI,
|
||||
const MachineInstr &ConsMI) const;
|
||||
bool producesStall(const MachineInstr &MI,
|
||||
MachineBasicBlock::const_instr_iterator MII) const;
|
||||
bool predCanBeUsedAsDotNew(const MachineInstr *MI, unsigned PredReg) const;
|
||||
bool predCanBeUsedAsDotNew(const MachineInstr &MI, unsigned PredReg) const;
|
||||
bool PredOpcodeHasJMP_c(unsigned Opcode) const;
|
||||
bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const;
|
||||
|
||||
|
||||
short getAbsoluteForm(const MachineInstr *MI) const;
|
||||
unsigned getAddrMode(const MachineInstr* MI) const;
|
||||
unsigned getBaseAndOffset(const MachineInstr *MI, int &Offset,
|
||||
short getAbsoluteForm(const MachineInstr &MI) const;
|
||||
unsigned getAddrMode(const MachineInstr &MI) const;
|
||||
unsigned getBaseAndOffset(const MachineInstr &MI, int &Offset,
|
||||
unsigned &AccessSize) const;
|
||||
short getBaseWithLongOffset(short Opcode) const;
|
||||
short getBaseWithLongOffset(const MachineInstr *MI) const;
|
||||
short getBaseWithRegOffset(const MachineInstr *MI) const;
|
||||
short getBaseWithLongOffset(const MachineInstr &MI) const;
|
||||
short getBaseWithRegOffset(const MachineInstr &MI) const;
|
||||
SmallVector<MachineInstr*,2> getBranchingInstrs(MachineBasicBlock& MBB) const;
|
||||
unsigned getCExtOpNum(const MachineInstr *MI) const;
|
||||
unsigned getCExtOpNum(const MachineInstr &MI) const;
|
||||
HexagonII::CompoundGroup
|
||||
getCompoundCandidateGroup(const MachineInstr *MI) const;
|
||||
unsigned getCompoundOpcode(const MachineInstr *GA,
|
||||
const MachineInstr *GB) const;
|
||||
getCompoundCandidateGroup(const MachineInstr &MI) const;
|
||||
unsigned getCompoundOpcode(const MachineInstr &GA,
|
||||
const MachineInstr &GB) const;
|
||||
int getCondOpcode(int Opc, bool sense) const;
|
||||
int getDotCurOp(const MachineInstr* MI) const;
|
||||
int getDotNewOp(const MachineInstr* MI) const;
|
||||
int getDotNewPredJumpOp(const MachineInstr *MI,
|
||||
int getDotCurOp(const MachineInstr &MI) const;
|
||||
int getDotNewOp(const MachineInstr &MI) const;
|
||||
int getDotNewPredJumpOp(const MachineInstr &MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const;
|
||||
int getDotNewPredOp(const MachineInstr *MI,
|
||||
int getDotNewPredOp(const MachineInstr &MI,
|
||||
const MachineBranchProbabilityInfo *MBPI) const;
|
||||
int getDotOldOp(const int opc) const;
|
||||
HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr *MI)
|
||||
HexagonII::SubInstructionGroup getDuplexCandidateGroup(const MachineInstr &MI)
|
||||
const;
|
||||
short getEquivalentHWInstr(const MachineInstr *MI) const;
|
||||
short getEquivalentHWInstr(const MachineInstr &MI) const;
|
||||
MachineInstr *getFirstNonDbgInst(MachineBasicBlock *BB) const;
|
||||
unsigned getInstrTimingClassLatency(const InstrItineraryData *ItinData,
|
||||
const MachineInstr *MI) const;
|
||||
const MachineInstr &MI) const;
|
||||
bool getInvertedPredSense(SmallVectorImpl<MachineOperand> &Cond) const;
|
||||
unsigned getInvertedPredicatedOpcode(const int Opc) const;
|
||||
int getMaxValue(const MachineInstr *MI) const;
|
||||
unsigned getMemAccessSize(const MachineInstr* MI) const;
|
||||
int getMinValue(const MachineInstr *MI) const;
|
||||
short getNonExtOpcode(const MachineInstr *MI) const;
|
||||
int getMaxValue(const MachineInstr &MI) const;
|
||||
unsigned getMemAccessSize(const MachineInstr &MI) const;
|
||||
int getMinValue(const MachineInstr &MI) const;
|
||||
short getNonExtOpcode(const MachineInstr &MI) const;
|
||||
bool getPredReg(ArrayRef<MachineOperand> Cond, unsigned &PredReg,
|
||||
unsigned &PredRegPos, unsigned &PredRegFlags) const;
|
||||
short getPseudoInstrPair(const MachineInstr *MI) const;
|
||||
short getRegForm(const MachineInstr *MI) const;
|
||||
unsigned getSize(const MachineInstr *MI) const;
|
||||
uint64_t getType(const MachineInstr* MI) const;
|
||||
unsigned getUnits(const MachineInstr* MI) const;
|
||||
short getPseudoInstrPair(const MachineInstr &MI) const;
|
||||
short getRegForm(const MachineInstr &MI) const;
|
||||
unsigned getSize(const MachineInstr &MI) const;
|
||||
uint64_t getType(const MachineInstr &MI) const;
|
||||
unsigned getUnits(const MachineInstr &MI) const;
|
||||
unsigned getValidSubTargets(const unsigned Opcode) const;
|
||||
|
||||
|
||||
@ -422,14 +424,14 @@ public:
|
||||
unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const;
|
||||
|
||||
|
||||
void immediateExtend(MachineInstr *MI) const;
|
||||
bool invertAndChangeJumpTarget(MachineInstr* MI,
|
||||
void immediateExtend(MachineInstr &MI) const;
|
||||
bool invertAndChangeJumpTarget(MachineInstr &MI,
|
||||
MachineBasicBlock* NewTarget) const;
|
||||
void genAllInsnTimingClasses(MachineFunction &MF) const;
|
||||
bool reversePredSense(MachineInstr* MI) const;
|
||||
bool reversePredSense(MachineInstr &MI) const;
|
||||
unsigned reversePrediction(unsigned Opcode) const;
|
||||
bool validateBranchCond(const ArrayRef<MachineOperand> &Cond) const;
|
||||
short xformRegToImmOffset(const MachineInstr *MI) const;
|
||||
short xformRegToImmOffset(const MachineInstr &MI) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ bool HexagonCallMutation::shouldTFRICallBind(const HexagonInstrInfo &HII,
|
||||
return false;
|
||||
|
||||
// TypeXTYPE are 64 bit operations.
|
||||
if (HII.getType(Inst2.getInstr()) == HexagonII::TypeXTYPE)
|
||||
if (HII.getType(*Inst2.getInstr()) == HexagonII::TypeXTYPE)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -168,7 +168,7 @@ bool VLIWResourceModel::isResourceAvailable(SUnit *SU) {
|
||||
continue;
|
||||
|
||||
// Enable .cur formation.
|
||||
if (QII.mayBeCurLoad(Packet[i]->getInstr()))
|
||||
if (QII.mayBeCurLoad(*Packet[i]->getInstr()))
|
||||
continue;
|
||||
|
||||
for (SUnit::const_succ_iterator I = Packet[i]->Succs.begin(),
|
||||
@ -616,7 +616,7 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
|
||||
if (!SU || SU->isScheduled)
|
||||
return ResCount;
|
||||
|
||||
MachineInstr *Instr = SU->getInstr();
|
||||
MachineInstr &Instr = *SU->getInstr();
|
||||
|
||||
DEBUG(if (verbose) dbgs() << ((Q.getID() == TopQID) ? "(top|" : "(bot|"));
|
||||
// Forced priority is high.
|
||||
@ -705,7 +705,7 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
|
||||
// available for it.
|
||||
auto &QST = DAG->MF.getSubtarget<HexagonSubtarget>();
|
||||
auto &QII = *QST.getInstrInfo();
|
||||
if (SU->isInstr() && QII.mayBeCurLoad(SU->getInstr())) {
|
||||
if (SU->isInstr() && QII.mayBeCurLoad(*SU->getInstr())) {
|
||||
if (Q.getID() == TopQID && Top.ResourceModel->isResourceAvailable(SU)) {
|
||||
ResCount += PriorityTwo;
|
||||
DEBUG(if (verbose) dbgs() << "C|");
|
||||
@ -744,11 +744,11 @@ int ConvergingVLIWScheduler::SchedulingCost(ReadyQueue &Q, SUnit *SU,
|
||||
// Check for stalls in the previous packet.
|
||||
if (Q.getID() == TopQID) {
|
||||
for (auto J : Top.ResourceModel->OldPacket)
|
||||
if (QII.producesStall(J->getInstr(), Instr))
|
||||
if (QII.producesStall(*J->getInstr(), Instr))
|
||||
ResCount -= PriorityOne;
|
||||
} else {
|
||||
for (auto J : Bot.ResourceModel->OldPacket)
|
||||
if (QII.producesStall(Instr, J->getInstr()))
|
||||
if (QII.producesStall(Instr, *J->getInstr()))
|
||||
ResCount -= PriorityOne;
|
||||
}
|
||||
}
|
||||
@ -841,8 +841,8 @@ pickNodeFromQueue(ReadyQueue &Q, const RegPressureTracker &RPTracker,
|
||||
const MachineInstr *CandI = Candidate.SU->getInstr();
|
||||
const InstrItineraryData *InstrItins = QST.getInstrItineraryData();
|
||||
|
||||
unsigned InstrLatency = QII.getInstrTimingClassLatency(InstrItins, MI);
|
||||
unsigned CandLatency = QII.getInstrTimingClassLatency(InstrItins, CandI);
|
||||
unsigned InstrLatency = QII.getInstrTimingClassLatency(InstrItins, *MI);
|
||||
unsigned CandLatency = QII.getInstrTimingClassLatency(InstrItins, *CandI);
|
||||
DEBUG(dbgs() << "TC Tie Breaker Cand: "
|
||||
<< CandLatency << " Instr:" << InstrLatency << "\n"
|
||||
<< *MI << *CandI << "\n");
|
||||
|
@ -79,12 +79,12 @@ private:
|
||||
NodeAddr<UseNode *> UseN, unsigned UseMOnum);
|
||||
bool analyzeUses(unsigned DefR, const NodeList &UNodeList,
|
||||
InstrEvalMap &InstrEvalResult, short &SizeInc);
|
||||
bool hasRepForm(MachineInstr *MI, unsigned TfrDefR);
|
||||
bool canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, MachineInstr *MI,
|
||||
bool hasRepForm(MachineInstr &MI, unsigned TfrDefR);
|
||||
bool canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN, MachineInstr &MI,
|
||||
const NodeList &UNodeList);
|
||||
void getAllRealUses(NodeAddr<StmtNode *> SN, NodeList &UNodeList);
|
||||
bool allValidCandidates(NodeAddr<StmtNode *> SA, NodeList &UNodeList);
|
||||
short getBaseWithLongOffset(const MachineInstr *MI) const;
|
||||
short getBaseWithLongOffset(const MachineInstr &MI) const;
|
||||
void updateMap(NodeAddr<InstrNode *> IA);
|
||||
bool constructDefMap(MachineBasicBlock *B);
|
||||
bool changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
@ -104,14 +104,14 @@ INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier)
|
||||
INITIALIZE_PASS_END(HexagonOptAddrMode, "opt-amode", "Optimize addressing mode",
|
||||
false, false)
|
||||
|
||||
bool HexagonOptAddrMode::hasRepForm(MachineInstr *MI, unsigned TfrDefR) {
|
||||
const MCInstrDesc &MID = MI->getDesc();
|
||||
bool HexagonOptAddrMode::hasRepForm(MachineInstr &MI, unsigned TfrDefR) {
|
||||
const MCInstrDesc &MID = MI.getDesc();
|
||||
|
||||
if ((!MID.mayStore() && !MID.mayLoad()) || HII->isPredicated(*MI))
|
||||
if ((!MID.mayStore() && !MID.mayLoad()) || HII->isPredicated(MI))
|
||||
return false;
|
||||
|
||||
if (MID.mayStore()) {
|
||||
MachineOperand StOp = MI->getOperand(MI->getNumOperands() - 1);
|
||||
MachineOperand StOp = MI.getOperand(MI.getNumOperands() - 1);
|
||||
if (StOp.isReg() && StOp.getReg() == TfrDefR)
|
||||
return false;
|
||||
}
|
||||
@ -137,14 +137,14 @@ bool HexagonOptAddrMode::hasRepForm(MachineInstr *MI, unsigned TfrDefR) {
|
||||
// Above three instructions can be replaced with Rd = memw(Rt<<#2 + ##foo+28)
|
||||
|
||||
bool HexagonOptAddrMode::canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN,
|
||||
MachineInstr *MI,
|
||||
MachineInstr &MI,
|
||||
const NodeList &UNodeList) {
|
||||
// check offset size in addasl. if 'offset > 3' return false
|
||||
const MachineOperand &OffsetOp = MI->getOperand(3);
|
||||
const MachineOperand &OffsetOp = MI.getOperand(3);
|
||||
if (!OffsetOp.isImm() || OffsetOp.getImm() > 3)
|
||||
return false;
|
||||
|
||||
unsigned OffsetReg = MI->getOperand(2).getReg();
|
||||
unsigned OffsetReg = MI.getOperand(2).getReg();
|
||||
RegisterRef OffsetRR;
|
||||
NodeId OffsetRegRD = 0;
|
||||
for (NodeAddr<UseNode *> UA : AddAslSN.Addr->members_if(DFG->IsUse, *DFG)) {
|
||||
@ -162,25 +162,25 @@ bool HexagonOptAddrMode::canRemoveAddasl(NodeAddr<StmtNode *> AddAslSN,
|
||||
RDefMap[OffsetRR][IA.Id] != OffsetRegRD)
|
||||
return false;
|
||||
|
||||
MachineInstr *UseMI = NodeAddr<StmtNode *>(IA).Addr->getCode();
|
||||
MachineInstr &UseMI = *NodeAddr<StmtNode *>(IA).Addr->getCode();
|
||||
NodeAddr<DefNode *> OffsetRegDN = DFG->addr<DefNode *>(OffsetRegRD);
|
||||
// Reaching Def to an offset register can't be a phi.
|
||||
if ((OffsetRegDN.Addr->getFlags() & NodeAttrs::PhiRef) &&
|
||||
MI->getParent() != UseMI->getParent())
|
||||
MI.getParent() != UseMI.getParent())
|
||||
return false;
|
||||
|
||||
const MCInstrDesc &UseMID = UseMI->getDesc();
|
||||
const MCInstrDesc &UseMID = UseMI.getDesc();
|
||||
if ((!UseMID.mayLoad() && !UseMID.mayStore()) ||
|
||||
HII->getAddrMode(UseMI) != HexagonII::BaseImmOffset ||
|
||||
getBaseWithLongOffset(UseMI) < 0)
|
||||
return false;
|
||||
|
||||
// Addasl output can't be a store value.
|
||||
if (UseMID.mayStore() && UseMI->getOperand(2).isReg() &&
|
||||
UseMI->getOperand(2).getReg() == MI->getOperand(0).getReg())
|
||||
if (UseMID.mayStore() && UseMI.getOperand(2).isReg() &&
|
||||
UseMI.getOperand(2).getReg() == MI.getOperand(0).getReg())
|
||||
return false;
|
||||
|
||||
for (auto &Mo : UseMI->operands())
|
||||
for (auto &Mo : UseMI.operands())
|
||||
if (Mo.isFI())
|
||||
return false;
|
||||
}
|
||||
@ -261,8 +261,8 @@ bool HexagonOptAddrMode::analyzeUses(unsigned tfrDefR,
|
||||
bool CanBeReplaced = false;
|
||||
NodeAddr<UseNode *> UN = *I;
|
||||
NodeAddr<StmtNode *> SN = UN.Addr->getOwner(*DFG);
|
||||
MachineInstr *MI = SN.Addr->getCode();
|
||||
const MCInstrDesc &MID = MI->getDesc();
|
||||
MachineInstr &MI = *SN.Addr->getCode();
|
||||
const MCInstrDesc &MID = MI.getDesc();
|
||||
if ((MID.mayLoad() || MID.mayStore())) {
|
||||
if (!hasRepForm(MI, tfrDefR)) {
|
||||
KeepTfr = true;
|
||||
@ -270,10 +270,10 @@ bool HexagonOptAddrMode::analyzeUses(unsigned tfrDefR,
|
||||
}
|
||||
SizeInc++;
|
||||
CanBeReplaced = true;
|
||||
} else if (MI->getOpcode() == Hexagon::S2_addasl_rrri) {
|
||||
} else if (MI.getOpcode() == Hexagon::S2_addasl_rrri) {
|
||||
NodeList AddaslUseList;
|
||||
|
||||
DEBUG(dbgs() << "\nGetting ReachedUses for === " << *MI << "\n");
|
||||
DEBUG(dbgs() << "\nGetting ReachedUses for === " << MI << "\n");
|
||||
getAllRealUses(SN, AddaslUseList);
|
||||
// Process phi nodes.
|
||||
if (allValidCandidates(SN, AddaslUseList) &&
|
||||
@ -290,7 +290,7 @@ bool HexagonOptAddrMode::analyzeUses(unsigned tfrDefR,
|
||||
// M4_mpyrr_addr -> M4_mpyrr_addi
|
||||
KeepTfr = true;
|
||||
|
||||
InstrEvalResult[MI] = CanBeReplaced;
|
||||
InstrEvalResult[&MI] = CanBeReplaced;
|
||||
HasRepInstr |= CanBeReplaced;
|
||||
}
|
||||
|
||||
@ -313,8 +313,8 @@ bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
MachineInstrBuilder MIB;
|
||||
|
||||
if (ImmOpNum == 1) {
|
||||
if (HII->getAddrMode(OldMI) == HexagonII::BaseRegOffset) {
|
||||
short NewOpCode = HII->getBaseWithLongOffset(OldMI);
|
||||
if (HII->getAddrMode(*OldMI) == HexagonII::BaseRegOffset) {
|
||||
short NewOpCode = HII->getBaseWithLongOffset(*OldMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
|
||||
MIB.addOperand(OldMI->getOperand(0));
|
||||
@ -323,8 +323,8 @@ bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
MIB.addOperand(ImmOp);
|
||||
OpStart = 4;
|
||||
Changed = true;
|
||||
} else if (HII->getAddrMode(OldMI) == HexagonII::BaseImmOffset) {
|
||||
short NewOpCode = HII->getAbsoluteForm(OldMI);
|
||||
} else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) {
|
||||
short NewOpCode = HII->getAbsoluteForm(*OldMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode))
|
||||
.addOperand(OldMI->getOperand(0));
|
||||
@ -340,7 +340,7 @@ bool HexagonOptAddrMode::changeLoad(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
|
||||
DEBUG(dbgs() << "[TO]: " << MIB << "\n");
|
||||
} else if (ImmOpNum == 2 && OldMI->getOperand(3).getImm() == 0) {
|
||||
short NewOpCode = HII->xformRegToImmOffset(OldMI);
|
||||
short NewOpCode = HII->xformRegToImmOffset(*OldMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
|
||||
MIB.addOperand(OldMI->getOperand(0));
|
||||
@ -370,8 +370,8 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
++InsertPt;
|
||||
MachineInstrBuilder MIB;
|
||||
if (ImmOpNum == 0) {
|
||||
if (HII->getAddrMode(OldMI) == HexagonII::BaseRegOffset) {
|
||||
short NewOpCode = HII->getBaseWithLongOffset(OldMI);
|
||||
if (HII->getAddrMode(*OldMI) == HexagonII::BaseRegOffset) {
|
||||
short NewOpCode = HII->getBaseWithLongOffset(*OldMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
|
||||
MIB.addOperand(OldMI->getOperand(1));
|
||||
@ -379,8 +379,8 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
MIB.addOperand(ImmOp);
|
||||
MIB.addOperand(OldMI->getOperand(3));
|
||||
OpStart = 4;
|
||||
} else if (HII->getAddrMode(OldMI) == HexagonII::BaseImmOffset) {
|
||||
short NewOpCode = HII->getAbsoluteForm(OldMI);
|
||||
} else if (HII->getAddrMode(*OldMI) == HexagonII::BaseImmOffset) {
|
||||
short NewOpCode = HII->getAbsoluteForm(*OldMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
|
||||
const GlobalValue *GV = ImmOp.getGlobal();
|
||||
@ -393,7 +393,7 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
DEBUG(dbgs() << "[Changing]: " << *OldMI << "\n");
|
||||
DEBUG(dbgs() << "[TO]: " << MIB << "\n");
|
||||
} else if (ImmOpNum == 1 && OldMI->getOperand(2).getImm() == 0) {
|
||||
short NewOpCode = HII->xformRegToImmOffset(OldMI);
|
||||
short NewOpCode = HII->xformRegToImmOffset(*OldMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
MIB = BuildMI(*BB, InsertPt, OldMI->getDebugLoc(), HII->get(NewOpCode));
|
||||
MIB.addOperand(OldMI->getOperand(0));
|
||||
@ -411,7 +411,7 @@ bool HexagonOptAddrMode::changeStore(MachineInstr *OldMI, MachineOperand ImmOp,
|
||||
return Changed;
|
||||
}
|
||||
|
||||
short HexagonOptAddrMode::getBaseWithLongOffset(const MachineInstr *MI) const {
|
||||
short HexagonOptAddrMode::getBaseWithLongOffset(const MachineInstr &MI) const {
|
||||
if (HII->getAddrMode(MI) == HexagonII::BaseImmOffset) {
|
||||
short TempOpCode = HII->getBaseWithRegOffset(MI);
|
||||
return HII->getBaseWithLongOffset(TempOpCode);
|
||||
@ -442,11 +442,11 @@ bool HexagonOptAddrMode::changeAddAsl(NodeAddr<UseNode *> AddAslUN,
|
||||
DEBUG(dbgs() << "[MI <BB#" << UseMI->getParent()->getNumber()
|
||||
<< ">]: " << *UseMI << "\n");
|
||||
const MCInstrDesc &UseMID = UseMI->getDesc();
|
||||
assert(HII->getAddrMode(UseMI) == HexagonII::BaseImmOffset);
|
||||
assert(HII->getAddrMode(*UseMI) == HexagonII::BaseImmOffset);
|
||||
|
||||
auto UsePos = MachineBasicBlock::iterator(UseMI);
|
||||
MachineBasicBlock::instr_iterator InsertPt = UsePos.getInstrIterator();
|
||||
short NewOpCode = getBaseWithLongOffset(UseMI);
|
||||
short NewOpCode = getBaseWithLongOffset(*UseMI);
|
||||
assert(NewOpCode >= 0 && "Invalid New opcode\n");
|
||||
|
||||
unsigned OpStart;
|
||||
|
@ -202,11 +202,11 @@ bool HexagonDCE::rewrite(NodeAddr<InstrNode*> IA, SetVector<NodeId> &Remove) {
|
||||
if (!getDFG().IsCode<NodeAttrs::Stmt>(IA))
|
||||
return false;
|
||||
DataFlowGraph &DFG = getDFG();
|
||||
MachineInstr *MI = NodeAddr<StmtNode*>(IA).Addr->getCode();
|
||||
MachineInstr &MI = *NodeAddr<StmtNode*>(IA).Addr->getCode();
|
||||
auto &HII = static_cast<const HexagonInstrInfo&>(DFG.getTII());
|
||||
if (HII.getAddrMode(MI) != HexagonII::PostInc)
|
||||
return false;
|
||||
unsigned Opc = MI->getOpcode();
|
||||
unsigned Opc = MI.getOpcode();
|
||||
unsigned OpNum, NewOpc;
|
||||
switch (Opc) {
|
||||
case Hexagon::L2_loadri_pi:
|
||||
@ -240,7 +240,7 @@ bool HexagonDCE::rewrite(NodeAddr<InstrNode*> IA, SetVector<NodeId> &Remove) {
|
||||
return getDeadNodes().count(DA.Id);
|
||||
};
|
||||
NodeList Defs;
|
||||
MachineOperand &Op = MI->getOperand(OpNum);
|
||||
MachineOperand &Op = MI.getOperand(OpNum);
|
||||
for (NodeAddr<DefNode*> DA : IA.Addr->members_if(DFG.IsDef, DFG)) {
|
||||
if (&DA.Addr->getOp() != &Op)
|
||||
continue;
|
||||
@ -255,12 +255,12 @@ bool HexagonDCE::rewrite(NodeAddr<InstrNode*> IA, SetVector<NodeId> &Remove) {
|
||||
Remove.insert(D.Id);
|
||||
|
||||
if (trace())
|
||||
dbgs() << "Rewriting: " << *MI;
|
||||
MI->setDesc(HII.get(NewOpc));
|
||||
MI->getOperand(OpNum+2).setImm(0);
|
||||
dbgs() << "Rewriting: " << MI;
|
||||
MI.setDesc(HII.get(NewOpc));
|
||||
MI.getOperand(OpNum+2).setImm(0);
|
||||
removeOperand(IA, OpNum);
|
||||
if (trace())
|
||||
dbgs() << " to: " << *MI;
|
||||
dbgs() << " to: " << MI;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -155,19 +155,19 @@ void HexagonSubtarget::HexagonDAGMutation::apply(ScheduleDAGInstrs *DAG) {
|
||||
// Update the latency of chain edges between v60 vector load or store
|
||||
// instructions to be 1. These instructions cannot be scheduled in the
|
||||
// same packet.
|
||||
MachineInstr *MI1 = SU.getInstr();
|
||||
MachineInstr &MI1 = *SU.getInstr();
|
||||
auto *QII = static_cast<const HexagonInstrInfo*>(DAG->TII);
|
||||
bool IsStoreMI1 = MI1->mayStore();
|
||||
bool IsLoadMI1 = MI1->mayLoad();
|
||||
bool IsStoreMI1 = MI1.mayStore();
|
||||
bool IsLoadMI1 = MI1.mayLoad();
|
||||
if (!QII->isV60VectorInstruction(MI1) || !(IsStoreMI1 || IsLoadMI1))
|
||||
continue;
|
||||
for (auto &SI : SU.Succs) {
|
||||
if (SI.getKind() != SDep::Order || SI.getLatency() != 0)
|
||||
continue;
|
||||
MachineInstr *MI2 = SI.getSUnit()->getInstr();
|
||||
MachineInstr &MI2 = *SI.getSUnit()->getInstr();
|
||||
if (!QII->isV60VectorInstruction(MI2))
|
||||
continue;
|
||||
if ((IsStoreMI1 && MI2->mayStore()) || (IsLoadMI1 && MI2->mayLoad())) {
|
||||
if ((IsStoreMI1 && MI2.mayStore()) || (IsLoadMI1 && MI2.mayLoad())) {
|
||||
SI.setLatency(1);
|
||||
SU.setHeightDirty();
|
||||
// Change the dependence in the opposite direction too.
|
||||
@ -203,8 +203,8 @@ bool HexagonSubtarget::enableSubRegLiveness() const {
|
||||
}
|
||||
|
||||
// This helper function is responsible for increasing the latency only.
|
||||
void HexagonSubtarget::updateLatency(MachineInstr *SrcInst,
|
||||
MachineInstr *DstInst, SDep &Dep) const {
|
||||
void HexagonSubtarget::updateLatency(MachineInstr &SrcInst,
|
||||
MachineInstr &DstInst, SDep &Dep) const {
|
||||
if (!hasV60TOps())
|
||||
return;
|
||||
|
||||
@ -238,19 +238,19 @@ static SUnit *getZeroLatency(SUnit *N, SmallVector<SDep, 4> &Deps) {
|
||||
/// Change the latency between the two SUnits.
|
||||
void HexagonSubtarget::changeLatency(SUnit *Src, SmallVector<SDep, 4> &Deps,
|
||||
SUnit *Dst, unsigned Lat) const {
|
||||
MachineInstr *SrcI = Src->getInstr();
|
||||
MachineInstr &SrcI = *Src->getInstr();
|
||||
for (auto &I : Deps) {
|
||||
if (I.getSUnit() != Dst)
|
||||
continue;
|
||||
I.setLatency(Lat);
|
||||
SUnit *UpdateDst = I.getSUnit();
|
||||
updateLatency(SrcI, UpdateDst->getInstr(), I);
|
||||
updateLatency(SrcI, *UpdateDst->getInstr(), I);
|
||||
// Update the latency of opposite edge too.
|
||||
for (auto &PI : UpdateDst->Preds) {
|
||||
if (PI.getSUnit() != Src || !PI.isAssignedRegDep())
|
||||
continue;
|
||||
PI.setLatency(Lat);
|
||||
updateLatency(SrcI, UpdateDst->getInstr(), PI);
|
||||
updateLatency(SrcI, *UpdateDst->getInstr(), PI);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,10 +261,10 @@ void HexagonSubtarget::changeLatency(SUnit *Src, SmallVector<SDep, 4> &Deps,
|
||||
// ther others, if needed.
|
||||
bool HexagonSubtarget::isBestZeroLatency(SUnit *Src, SUnit *Dst,
|
||||
const HexagonInstrInfo *TII) const {
|
||||
MachineInstr *SrcInst = Src->getInstr();
|
||||
MachineInstr *DstInst = Dst->getInstr();
|
||||
MachineInstr &SrcInst = *Src->getInstr();
|
||||
MachineInstr &DstInst = *Dst->getInstr();
|
||||
|
||||
if (SrcInst->isPHI() || DstInst->isPHI())
|
||||
if (SrcInst.isPHI() || DstInst.isPHI())
|
||||
return false;
|
||||
|
||||
// Check if the Dst instruction is the best candidate first.
|
||||
@ -301,9 +301,9 @@ bool HexagonSubtarget::isBestZeroLatency(SUnit *Src, SUnit *Dst,
|
||||
|
||||
// Update the latency of a Phi when the Phi bridges two instructions that
|
||||
// require a multi-cycle latency.
|
||||
void HexagonSubtarget::changePhiLatency(MachineInstr *SrcInst, SUnit *Dst,
|
||||
void HexagonSubtarget::changePhiLatency(MachineInstr &SrcInst, SUnit *Dst,
|
||||
SDep &Dep) const {
|
||||
if (!SrcInst->isPHI() || Dst->NumPreds == 0 || Dep.getLatency() != 0)
|
||||
if (!SrcInst.isPHI() || Dst->NumPreds == 0 || Dep.getLatency() != 0)
|
||||
return;
|
||||
|
||||
for (const SDep &PI : Dst->Preds) {
|
||||
@ -326,7 +326,7 @@ void HexagonSubtarget::adjustSchedDependency(SUnit *Src, SUnit *Dst,
|
||||
const HexagonInstrInfo *QII = static_cast<const HexagonInstrInfo *>(getInstrInfo());
|
||||
|
||||
// Instructions with .new operands have zero latency.
|
||||
if (QII->canExecuteInBundle(SrcInst, DstInst) &&
|
||||
if (QII->canExecuteInBundle(*SrcInst, *DstInst) &&
|
||||
isBestZeroLatency(Src, Dst, QII)) {
|
||||
Dep.setLatency(0);
|
||||
return;
|
||||
@ -355,7 +355,7 @@ void HexagonSubtarget::adjustSchedDependency(SUnit *Src, SUnit *Dst,
|
||||
|
||||
// Check if we need to change any the latency values when Phis are added.
|
||||
if (useBSBScheduling() && SrcInst->isPHI()) {
|
||||
changePhiLatency(SrcInst, Dst, Dep);
|
||||
changePhiLatency(*SrcInst, Dst, Dep);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -365,13 +365,13 @@ void HexagonSubtarget::adjustSchedDependency(SUnit *Src, SUnit *Dst,
|
||||
DstInst = Dst->Succs[0].getSUnit()->getInstr();
|
||||
|
||||
// Try to schedule uses near definitions to generate .cur.
|
||||
if (EnableDotCurSched && QII->isToBeScheduledASAP(SrcInst, DstInst) &&
|
||||
if (EnableDotCurSched && QII->isToBeScheduledASAP(*SrcInst, *DstInst) &&
|
||||
isBestZeroLatency(Src, Dst, QII)) {
|
||||
Dep.setLatency(0);
|
||||
return;
|
||||
}
|
||||
|
||||
updateLatency(SrcInst, DstInst, Dep);
|
||||
updateLatency(*SrcInst, *DstInst, Dep);
|
||||
}
|
||||
|
||||
unsigned HexagonSubtarget::getL1CacheLineSize() const {
|
||||
|
@ -139,13 +139,13 @@ public:
|
||||
|
||||
private:
|
||||
// Helper function responsible for increasing the latency only.
|
||||
void updateLatency(MachineInstr *SrcInst, MachineInstr *DstInst, SDep &Dep)
|
||||
void updateLatency(MachineInstr &SrcInst, MachineInstr &DstInst, SDep &Dep)
|
||||
const;
|
||||
void changeLatency(SUnit *Src, SmallVector<SDep, 4> &Deps, SUnit *Dst,
|
||||
unsigned Lat) const;
|
||||
bool isBestZeroLatency(SUnit *Src, SUnit *Dst, const HexagonInstrInfo *TII)
|
||||
const;
|
||||
void changePhiLatency(MachineInstr *SrcInst, SUnit *Dst, SDep &Dep) const;
|
||||
void changePhiLatency(MachineInstr &SrcInst, SUnit *Dst, SDep &Dep) const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -126,7 +126,7 @@ static bool hasWriteToReadDep(const MachineInstr &FirstI,
|
||||
}
|
||||
|
||||
|
||||
static MachineBasicBlock::iterator moveInstrOut(MachineInstr *MI,
|
||||
static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI,
|
||||
MachineBasicBlock::iterator BundleIt, bool Before) {
|
||||
MachineBasicBlock::instr_iterator InsertPt;
|
||||
if (Before)
|
||||
@ -134,20 +134,20 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr *MI,
|
||||
else
|
||||
InsertPt = std::next(BundleIt).getInstrIterator();
|
||||
|
||||
MachineBasicBlock &B = *MI->getParent();
|
||||
MachineBasicBlock &B = *MI.getParent();
|
||||
// The instruction should at least be bundled with the preceding instruction
|
||||
// (there will always be one, i.e. BUNDLE, if nothing else).
|
||||
assert(MI->isBundledWithPred());
|
||||
if (MI->isBundledWithSucc()) {
|
||||
MI->clearFlag(MachineInstr::BundledSucc);
|
||||
MI->clearFlag(MachineInstr::BundledPred);
|
||||
assert(MI.isBundledWithPred());
|
||||
if (MI.isBundledWithSucc()) {
|
||||
MI.clearFlag(MachineInstr::BundledSucc);
|
||||
MI.clearFlag(MachineInstr::BundledPred);
|
||||
} else {
|
||||
// If it's not bundled with the successor (i.e. it is the last one
|
||||
// in the bundle), then we can simply unbundle it from the predecessor,
|
||||
// which will take care of updating the predecessor's flag.
|
||||
MI->unbundleFromPred();
|
||||
MI.unbundleFromPred();
|
||||
}
|
||||
B.splice(InsertPt, &B, MI);
|
||||
B.splice(InsertPt, &B, MI.getIterator());
|
||||
|
||||
// Get the size of the bundle without asserting.
|
||||
MachineBasicBlock::const_instr_iterator I = BundleIt.getInstrIterator();
|
||||
@ -163,9 +163,9 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr *MI,
|
||||
|
||||
// Otherwise, extract the single instruction out and delete the bundle.
|
||||
MachineBasicBlock::iterator NextIt = std::next(BundleIt);
|
||||
MachineInstr *SingleI = BundleIt->getNextNode();
|
||||
SingleI->unbundleFromPred();
|
||||
assert(!SingleI->isBundledWithSucc());
|
||||
MachineInstr &SingleI = *BundleIt->getNextNode();
|
||||
SingleI.unbundleFromPred();
|
||||
assert(!SingleI.isBundledWithSucc());
|
||||
BundleIt->eraseFromParent();
|
||||
return NextIt;
|
||||
}
|
||||
@ -266,7 +266,7 @@ bool HexagonPacketizerList::tryAllocateResourcesForConstExt(bool Reserve) {
|
||||
}
|
||||
|
||||
|
||||
bool HexagonPacketizerList::isCallDependent(const MachineInstr* MI,
|
||||
bool HexagonPacketizerList::isCallDependent(const MachineInstr &MI,
|
||||
SDep::Kind DepType, unsigned DepReg) {
|
||||
// Check for LR dependence.
|
||||
if (DepReg == HRI->getRARegister())
|
||||
@ -283,7 +283,7 @@ bool HexagonPacketizerList::isCallDependent(const MachineInstr* MI,
|
||||
|
||||
// Assumes that the first operand of the CALLr is the function address.
|
||||
if (HII->isIndirectCall(MI) && (DepType == SDep::Data)) {
|
||||
MachineOperand MO = MI->getOperand(0);
|
||||
MachineOperand MO = MI.getOperand(0);
|
||||
if (MO.isReg() && MO.isUse() && (MO.getReg() == DepReg))
|
||||
return true;
|
||||
}
|
||||
@ -296,29 +296,29 @@ static bool isRegDependence(const SDep::Kind DepType) {
|
||||
DepType == SDep::Output;
|
||||
}
|
||||
|
||||
static bool isDirectJump(const MachineInstr* MI) {
|
||||
return MI->getOpcode() == Hexagon::J2_jump;
|
||||
static bool isDirectJump(const MachineInstr &MI) {
|
||||
return MI.getOpcode() == Hexagon::J2_jump;
|
||||
}
|
||||
|
||||
static bool isSchedBarrier(const MachineInstr* MI) {
|
||||
switch (MI->getOpcode()) {
|
||||
static bool isSchedBarrier(const MachineInstr &MI) {
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::Y2_barrier:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isControlFlow(const MachineInstr* MI) {
|
||||
return (MI->getDesc().isTerminator() || MI->getDesc().isCall());
|
||||
static bool isControlFlow(const MachineInstr &MI) {
|
||||
return MI.getDesc().isTerminator() || MI.getDesc().isCall();
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if the instruction modifies a callee-saved register.
|
||||
static bool doesModifyCalleeSavedReg(const MachineInstr *MI,
|
||||
static bool doesModifyCalleeSavedReg(const MachineInstr &MI,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
const MachineFunction &MF = *MI->getParent()->getParent();
|
||||
const MachineFunction &MF = *MI.getParent()->getParent();
|
||||
for (auto *CSR = TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
|
||||
if (MI->modifiesRegister(*CSR, TRI))
|
||||
if (MI.modifiesRegister(*CSR, TRI))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -326,30 +326,30 @@ static bool doesModifyCalleeSavedReg(const MachineInstr *MI,
|
||||
// TODO: MI->isIndirectBranch() and IsRegisterJump(MI)
|
||||
// Returns true if an instruction can be promoted to .new predicate or
|
||||
// new-value store.
|
||||
bool HexagonPacketizerList::isNewifiable(const MachineInstr* MI,
|
||||
bool HexagonPacketizerList::isNewifiable(const MachineInstr &MI,
|
||||
const TargetRegisterClass *NewRC) {
|
||||
// Vector stores can be predicated, and can be new-value stores, but
|
||||
// they cannot be predicated on a .new predicate value.
|
||||
if (NewRC == &Hexagon::PredRegsRegClass)
|
||||
if (HII->isV60VectorInstruction(MI) && MI->mayStore())
|
||||
if (HII->isV60VectorInstruction(MI) && MI.mayStore())
|
||||
return false;
|
||||
return HII->isCondInst(MI) || MI->isReturn() || HII->mayBeNewStore(MI);
|
||||
return HII->isCondInst(MI) || MI.isReturn() || HII->mayBeNewStore(MI);
|
||||
}
|
||||
|
||||
// Promote an instructiont to its .cur form.
|
||||
// At this time, we have already made a call to canPromoteToDotCur and made
|
||||
// sure that it can *indeed* be promoted.
|
||||
bool HexagonPacketizerList::promoteToDotCur(MachineInstr* MI,
|
||||
bool HexagonPacketizerList::promoteToDotCur(MachineInstr &MI,
|
||||
SDep::Kind DepType, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC) {
|
||||
assert(DepType == SDep::Data);
|
||||
int CurOpcode = HII->getDotCurOp(MI);
|
||||
MI->setDesc(HII->get(CurOpcode));
|
||||
MI.setDesc(HII->get(CurOpcode));
|
||||
return true;
|
||||
}
|
||||
|
||||
void HexagonPacketizerList::cleanUpDotCur() {
|
||||
MachineInstr *MI = NULL;
|
||||
MachineInstr *MI = nullptr;
|
||||
for (auto BI : CurrentPacketMIs) {
|
||||
DEBUG(dbgs() << "Cleanup packet has "; BI->dump(););
|
||||
if (BI->getOpcode() == Hexagon::V6_vL32b_cur_ai) {
|
||||
@ -370,12 +370,12 @@ void HexagonPacketizerList::cleanUpDotCur() {
|
||||
}
|
||||
|
||||
// Check to see if an instruction can be dot cur.
|
||||
bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
|
||||
bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr &MI,
|
||||
const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass *RC) {
|
||||
if (!HII->isV60VectorInstruction(MI))
|
||||
return false;
|
||||
if (!HII->isV60VectorInstruction(&*MII))
|
||||
if (!HII->isV60VectorInstruction(*MII))
|
||||
return false;
|
||||
|
||||
// Already a dot new instruction.
|
||||
@ -391,14 +391,14 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
|
||||
|
||||
// Make sure candidate instruction uses cur.
|
||||
DEBUG(dbgs() << "Can we DOT Cur Vector MI\n";
|
||||
MI->dump();
|
||||
MI.dump();
|
||||
dbgs() << "in packet\n";);
|
||||
MachineInstr &MJ = *MII;
|
||||
DEBUG({
|
||||
dbgs() << "Checking CUR against ";
|
||||
MJ.dump();
|
||||
});
|
||||
unsigned DestReg = MI->getOperand(0).getReg();
|
||||
unsigned DestReg = MI.getOperand(0).getReg();
|
||||
bool FoundMatch = false;
|
||||
for (auto &MO : MJ.operands())
|
||||
if (MO.isReg() && MO.getReg() == DestReg)
|
||||
@ -414,7 +414,7 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << "Can Dot CUR MI\n"; MI->dump(););
|
||||
DEBUG(dbgs() << "Can Dot CUR MI\n"; MI.dump(););
|
||||
// We can convert the opcode into a .cur.
|
||||
return true;
|
||||
}
|
||||
@ -422,7 +422,7 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr *MI,
|
||||
// Promote an instruction to its .new form. At this time, we have already
|
||||
// made a call to canPromoteToDotNew and made sure that it can *indeed* be
|
||||
// promoted.
|
||||
bool HexagonPacketizerList::promoteToDotNew(MachineInstr* MI,
|
||||
bool HexagonPacketizerList::promoteToDotNew(MachineInstr &MI,
|
||||
SDep::Kind DepType, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC) {
|
||||
assert (DepType == SDep::Data);
|
||||
@ -431,18 +431,18 @@ bool HexagonPacketizerList::promoteToDotNew(MachineInstr* MI,
|
||||
NewOpcode = HII->getDotNewPredOp(MI, MBPI);
|
||||
else
|
||||
NewOpcode = HII->getDotNewOp(MI);
|
||||
MI->setDesc(HII->get(NewOpcode));
|
||||
MI.setDesc(HII->get(NewOpcode));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::demoteToDotOld(MachineInstr* MI) {
|
||||
int NewOpcode = HII->getDotOldOp(MI->getOpcode());
|
||||
MI->setDesc(HII->get(NewOpcode));
|
||||
bool HexagonPacketizerList::demoteToDotOld(MachineInstr &MI) {
|
||||
int NewOpcode = HII->getDotOldOp(MI.getOpcode());
|
||||
MI.setDesc(HII->get(NewOpcode));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::useCallersSP(MachineInstr *MI) {
|
||||
unsigned Opc = MI->getOpcode();
|
||||
bool HexagonPacketizerList::useCallersSP(MachineInstr &MI) {
|
||||
unsigned Opc = MI.getOpcode();
|
||||
switch (Opc) {
|
||||
case Hexagon::S2_storerd_io:
|
||||
case Hexagon::S2_storeri_io:
|
||||
@ -453,7 +453,7 @@ bool HexagonPacketizerList::useCallersSP(MachineInstr *MI) {
|
||||
llvm_unreachable("Unexpected instruction");
|
||||
}
|
||||
unsigned FrameSize = MF.getFrameInfo().getStackSize();
|
||||
MachineOperand &Off = MI->getOperand(1);
|
||||
MachineOperand &Off = MI.getOperand(1);
|
||||
int64_t NewOff = Off.getImm() - (FrameSize + HEXAGON_LRFP_SIZE);
|
||||
if (HII->isValidOffset(Opc, NewOff)) {
|
||||
Off.setImm(NewOff);
|
||||
@ -462,8 +462,8 @@ bool HexagonPacketizerList::useCallersSP(MachineInstr *MI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void HexagonPacketizerList::useCalleesSP(MachineInstr *MI) {
|
||||
unsigned Opc = MI->getOpcode();
|
||||
void HexagonPacketizerList::useCalleesSP(MachineInstr &MI) {
|
||||
unsigned Opc = MI.getOpcode();
|
||||
switch (Opc) {
|
||||
case Hexagon::S2_storerd_io:
|
||||
case Hexagon::S2_storeri_io:
|
||||
@ -474,7 +474,7 @@ void HexagonPacketizerList::useCalleesSP(MachineInstr *MI) {
|
||||
llvm_unreachable("Unexpected instruction");
|
||||
}
|
||||
unsigned FrameSize = MF.getFrameInfo().getStackSize();
|
||||
MachineOperand &Off = MI->getOperand(1);
|
||||
MachineOperand &Off = MI.getOperand(1);
|
||||
Off.setImm(Off.getImm() + FrameSize + HEXAGON_LRFP_SIZE);
|
||||
}
|
||||
|
||||
@ -495,30 +495,30 @@ static PredicateKind getPredicateSense(const MachineInstr &MI,
|
||||
return PK_False;
|
||||
}
|
||||
|
||||
static const MachineOperand &getPostIncrementOperand(const MachineInstr *MI,
|
||||
static const MachineOperand &getPostIncrementOperand(const MachineInstr &MI,
|
||||
const HexagonInstrInfo *HII) {
|
||||
assert(HII->isPostIncrement(MI) && "Not a post increment operation.");
|
||||
assert(HII->isPostIncrement(&MI) && "Not a post increment operation.");
|
||||
#ifndef NDEBUG
|
||||
// Post Increment means duplicates. Use dense map to find duplicates in the
|
||||
// list. Caution: Densemap initializes with the minimum of 64 buckets,
|
||||
// whereas there are at most 5 operands in the post increment.
|
||||
DenseSet<unsigned> DefRegsSet;
|
||||
for (auto &MO : MI->operands())
|
||||
for (auto &MO : MI.operands())
|
||||
if (MO.isReg() && MO.isDef())
|
||||
DefRegsSet.insert(MO.getReg());
|
||||
|
||||
for (auto &MO : MI->operands())
|
||||
for (auto &MO : MI.operands())
|
||||
if (MO.isReg() && MO.isUse() && DefRegsSet.count(MO.getReg()))
|
||||
return MO;
|
||||
#else
|
||||
if (MI->mayLoad()) {
|
||||
const MachineOperand &Op1 = MI->getOperand(1);
|
||||
if (MI.mayLoad()) {
|
||||
const MachineOperand &Op1 = MI.getOperand(1);
|
||||
// The 2nd operand is always the post increment operand in load.
|
||||
assert(Op1.isReg() && "Post increment operand has be to a register.");
|
||||
return Op1;
|
||||
}
|
||||
if (MI->getDesc().mayStore()) {
|
||||
const MachineOperand &Op0 = MI->getOperand(0);
|
||||
if (MI.getDesc().mayStore()) {
|
||||
const MachineOperand &Op0 = MI.getOperand(0);
|
||||
// The 1st operand is always the post increment operand in store.
|
||||
assert(Op0.isReg() && "Post increment operand has be to a register.");
|
||||
return Op0;
|
||||
@ -529,13 +529,13 @@ static const MachineOperand &getPostIncrementOperand(const MachineInstr *MI,
|
||||
}
|
||||
|
||||
// Get the value being stored.
|
||||
static const MachineOperand& getStoreValueOperand(const MachineInstr *MI) {
|
||||
static const MachineOperand& getStoreValueOperand(const MachineInstr &MI) {
|
||||
// value being stored is always the last operand.
|
||||
return MI->getOperand(MI->getNumOperands()-1);
|
||||
return MI.getOperand(MI.getNumOperands()-1);
|
||||
}
|
||||
|
||||
static bool isLoadAbsSet(const MachineInstr *MI) {
|
||||
unsigned Opc = MI->getOpcode();
|
||||
static bool isLoadAbsSet(const MachineInstr &MI) {
|
||||
unsigned Opc = MI.getOpcode();
|
||||
switch (Opc) {
|
||||
case Hexagon::L4_loadrd_ap:
|
||||
case Hexagon::L4_loadrb_ap:
|
||||
@ -548,9 +548,9 @@ static bool isLoadAbsSet(const MachineInstr *MI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static const MachineOperand &getAbsSetOperand(const MachineInstr *MI) {
|
||||
static const MachineOperand &getAbsSetOperand(const MachineInstr &MI) {
|
||||
assert(isLoadAbsSet(MI));
|
||||
return MI->getOperand(1);
|
||||
return MI.getOperand(1);
|
||||
}
|
||||
|
||||
|
||||
@ -571,8 +571,8 @@ static const MachineOperand &getAbsSetOperand(const MachineInstr *MI) {
|
||||
// if there is a new value store in the packet. Corollary: if there is
|
||||
// already a store in a packet, there can not be a new value store.
|
||||
// Arch Spec: 3.4.4.2
|
||||
bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
const MachineInstr *PacketMI, unsigned DepReg) {
|
||||
bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI,
|
||||
const MachineInstr &PacketMI, unsigned DepReg) {
|
||||
// Make sure we are looking at the store, that can be promoted.
|
||||
if (!HII->mayBeNewStore(MI))
|
||||
return false;
|
||||
@ -582,7 +582,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
if (Val.isReg() && Val.getReg() != DepReg)
|
||||
return false;
|
||||
|
||||
const MCInstrDesc& MCID = PacketMI->getDesc();
|
||||
const MCInstrDesc& MCID = PacketMI.getDesc();
|
||||
|
||||
// First operand is always the result.
|
||||
const TargetRegisterClass *PacketRC = HII->getRegClass(MCID, 0, HRI, MF);
|
||||
@ -600,12 +600,12 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
|
||||
// Make sure it's NOT the post increment register that we are going to
|
||||
// new value.
|
||||
if (HII->isPostIncrement(MI) &&
|
||||
if (HII->isPostIncrement(&MI) &&
|
||||
getPostIncrementOperand(MI, HII).getReg() == DepReg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HII->isPostIncrement(PacketMI) && PacketMI->mayLoad() &&
|
||||
if (HII->isPostIncrement(&PacketMI) && PacketMI.mayLoad() &&
|
||||
getPostIncrementOperand(PacketMI, HII).getReg() == DepReg) {
|
||||
// If source is post_inc, or absolute-set addressing, it can not feed
|
||||
// into new value store
|
||||
@ -620,8 +620,8 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
|
||||
// If the source that feeds the store is predicated, new value store must
|
||||
// also be predicated.
|
||||
if (HII->isPredicated(*PacketMI)) {
|
||||
if (!HII->isPredicated(*MI))
|
||||
if (HII->isPredicated(PacketMI)) {
|
||||
if (!HII->isPredicated(MI))
|
||||
return false;
|
||||
|
||||
// Check to make sure that they both will have their predicates
|
||||
@ -631,7 +631,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
const TargetRegisterClass* predRegClass = nullptr;
|
||||
|
||||
// Get predicate register used in the source instruction.
|
||||
for (auto &MO : PacketMI->operands()) {
|
||||
for (auto &MO : PacketMI.operands()) {
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
predRegNumSrc = MO.getReg();
|
||||
@ -643,7 +643,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
"predicate register not found in a predicated PacketMI instruction");
|
||||
|
||||
// Get predicate register used in new-value store instruction.
|
||||
for (auto &MO : MI->operands()) {
|
||||
for (auto &MO : MI.operands()) {
|
||||
if (!MO.isReg())
|
||||
continue;
|
||||
predRegNumDst = MO.getReg();
|
||||
@ -664,7 +664,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
// sense, i.e, either both should be negated or both should be non-negated.
|
||||
if (predRegNumDst != predRegNumSrc ||
|
||||
HII->isDotNewInst(PacketMI) != HII->isDotNewInst(MI) ||
|
||||
getPredicateSense(*MI, HII) != getPredicateSense(*PacketMI, HII))
|
||||
getPredicateSense(MI, HII) != getPredicateSense(PacketMI, HII))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -680,19 +680,19 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
|
||||
for (auto I : CurrentPacketMIs) {
|
||||
SUnit *TempSU = MIToSUnit.find(I)->second;
|
||||
MachineInstr* TempMI = TempSU->getInstr();
|
||||
MachineInstr &TempMI = *TempSU->getInstr();
|
||||
|
||||
// Following condition is true for all the instructions until PacketMI is
|
||||
// reached (StartCheck is set to 0 before the for loop).
|
||||
// StartCheck flag is 1 for all the instructions after PacketMI.
|
||||
if (TempMI != PacketMI && !StartCheck) // Start processing only after
|
||||
continue; // encountering PacketMI.
|
||||
if (&TempMI != &PacketMI && !StartCheck) // Start processing only after
|
||||
continue; // encountering PacketMI.
|
||||
|
||||
StartCheck = 1;
|
||||
if (TempMI == PacketMI) // We don't want to check PacketMI for dependence.
|
||||
if (&TempMI == &PacketMI) // We don't want to check PacketMI for dependence.
|
||||
continue;
|
||||
|
||||
for (auto &MO : MI->operands())
|
||||
for (auto &MO : MI.operands())
|
||||
if (MO.isReg() && TempSU->getInstr()->modifiesRegister(MO.getReg(), HRI))
|
||||
return false;
|
||||
}
|
||||
@ -703,9 +703,9 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
// The following store can not be dot new.
|
||||
// Eg. r0 = add(r0, #3)
|
||||
// memw(r1+r0<<#2) = r0
|
||||
if (!HII->isPostIncrement(MI)) {
|
||||
for (unsigned opNum = 0; opNum < MI->getNumOperands()-1; opNum++) {
|
||||
const MachineOperand &MO = MI->getOperand(opNum);
|
||||
if (!HII->isPostIncrement(&MI)) {
|
||||
for (unsigned opNum = 0; opNum < MI.getNumOperands()-1; opNum++) {
|
||||
const MachineOperand &MO = MI.getOperand(opNum);
|
||||
if (MO.isReg() && MO.getReg() == DepReg)
|
||||
return false;
|
||||
}
|
||||
@ -715,7 +715,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
// do not newify the store. Eg.
|
||||
// %R9<def> = ZXTH %R12, %D6<imp-use>, %R12<imp-def>
|
||||
// S2_storerh_io %R8, 2, %R12<kill>; mem:ST2[%scevgep343]
|
||||
for (auto &MO : PacketMI->operands()) {
|
||||
for (auto &MO : PacketMI.operands()) {
|
||||
if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
|
||||
continue;
|
||||
unsigned R = MO.getReg();
|
||||
@ -728,7 +728,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
// just-in-case. For example, we cannot newify R2 in the following case:
|
||||
// %R3<def> = A2_tfrsi 0;
|
||||
// S2_storeri_io %R0<kill>, 0, %R2<kill>, %D1<imp-use,kill>;
|
||||
for (auto &MO : MI->operands()) {
|
||||
for (auto &MO : MI.operands()) {
|
||||
if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
|
||||
return false;
|
||||
}
|
||||
@ -738,14 +738,14 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr *MI,
|
||||
}
|
||||
|
||||
// Can this MI to promoted to either new value store or new value jump.
|
||||
bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr *MI,
|
||||
bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr &MI,
|
||||
const SUnit *PacketSU, unsigned DepReg,
|
||||
MachineBasicBlock::iterator &MII) {
|
||||
if (!HII->mayBeNewStore(MI))
|
||||
return false;
|
||||
|
||||
// Check to see the store can be new value'ed.
|
||||
MachineInstr *PacketMI = PacketSU->getInstr();
|
||||
MachineInstr &PacketMI = *PacketSU->getInstr();
|
||||
if (canPromoteToNewValueStore(MI, PacketMI, DepReg))
|
||||
return true;
|
||||
|
||||
@ -754,8 +754,8 @@ bool HexagonPacketizerList::canPromoteToNewValue(const MachineInstr *MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isImplicitDependency(const MachineInstr *I, unsigned DepReg) {
|
||||
for (auto &MO : I->operands())
|
||||
static bool isImplicitDependency(const MachineInstr &I, unsigned DepReg) {
|
||||
for (auto &MO : I.operands())
|
||||
if (MO.isReg() && MO.isDef() && (MO.getReg() == DepReg) && MO.isImplicit())
|
||||
return true;
|
||||
return false;
|
||||
@ -766,7 +766,7 @@ static bool isImplicitDependency(const MachineInstr *I, unsigned DepReg) {
|
||||
// 1. dot new on predicate - V2/V3/V4
|
||||
// 2. dot new on stores NV/ST - V4
|
||||
// 3. dot new on jump NV/J - V4 -- This is generated in a pass.
|
||||
bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
|
||||
bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr &MI,
|
||||
const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC) {
|
||||
// Already a dot new instruction.
|
||||
@ -776,15 +776,15 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
|
||||
if (!isNewifiable(MI, RC))
|
||||
return false;
|
||||
|
||||
const MachineInstr *PI = PacketSU->getInstr();
|
||||
const MachineInstr &PI = *PacketSU->getInstr();
|
||||
|
||||
// The "new value" cannot come from inline asm.
|
||||
if (PI->isInlineAsm())
|
||||
if (PI.isInlineAsm())
|
||||
return false;
|
||||
|
||||
// IMPLICIT_DEFs won't materialize as real instructions, so .new makes no
|
||||
// sense.
|
||||
if (PI->isImplicitDef())
|
||||
if (PI.isImplicitDef())
|
||||
return false;
|
||||
|
||||
// If dependency is trough an implicitly defined register, we should not
|
||||
@ -792,7 +792,7 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
|
||||
if (isImplicitDependency(PI, DepReg))
|
||||
return false;
|
||||
|
||||
const MCInstrDesc& MCID = PI->getDesc();
|
||||
const MCInstrDesc& MCID = PI.getDesc();
|
||||
const TargetRegisterClass *VecRC = HII->getRegClass(MCID, 0, HRI, MF);
|
||||
if (DisableVecDblNVStores && VecRC == &Hexagon::VecDblRegsRegClass)
|
||||
return false;
|
||||
@ -801,7 +801,7 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
|
||||
// bug 5670: until that is fixed
|
||||
// TODO: MI->isIndirectBranch() and IsRegisterJump(MI)
|
||||
if (RC == &Hexagon::PredRegsRegClass)
|
||||
if (HII->isCondInst(MI) || MI->isReturn())
|
||||
if (HII->isCondInst(MI) || MI.isReturn())
|
||||
return HII->predCanBeUsedAsDotNew(PI, DepReg);
|
||||
|
||||
if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(MI))
|
||||
@ -837,9 +837,9 @@ bool HexagonPacketizerList::canPromoteToDotNew(const MachineInstr *MI,
|
||||
// The P3 from a) and d) will be complements after
|
||||
// a)'s P3 is converted to .new form
|
||||
// Anti-dep between c) and b) is irrelevant for this case
|
||||
bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr* MI,
|
||||
bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr &MI,
|
||||
unsigned DepReg) {
|
||||
SUnit *PacketSUDep = MIToSUnit.find(MI)->second;
|
||||
SUnit *PacketSUDep = MIToSUnit.find(&MI)->second;
|
||||
|
||||
for (auto I : CurrentPacketMIs) {
|
||||
// We only care for dependencies to predicated instructions
|
||||
@ -931,7 +931,7 @@ bool HexagonPacketizerList::arePredicatesComplements(MachineInstr &MI1,
|
||||
// above example. Now I need to see if there is an anti dependency
|
||||
// from c) to any other instruction in the same packet on the pred
|
||||
// reg of interest.
|
||||
if (restrictingDepExistInPacket(I, Dep.getReg()))
|
||||
if (restrictingDepExistInPacket(*I, Dep.getReg()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -948,7 +948,7 @@ bool HexagonPacketizerList::arePredicatesComplements(MachineInstr &MI1,
|
||||
Hexagon::PredRegsRegClass.contains(PReg1) &&
|
||||
Hexagon::PredRegsRegClass.contains(PReg2) &&
|
||||
getPredicateSense(MI1, HII) != getPredicateSense(MI2, HII) &&
|
||||
HII->isDotNewInst(&MI1) == HII->isDotNewInst(&MI2);
|
||||
HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
|
||||
}
|
||||
|
||||
// Initialize packetizer flags.
|
||||
@ -999,10 +999,10 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
|
||||
// From Hexagon V4 Programmer's Reference Manual 3.4.4 Grouping constraints:
|
||||
// trap, pause, barrier, icinva, isync, and syncht are solo instructions.
|
||||
// They must not be grouped with other instructions in a packet.
|
||||
if (isSchedBarrier(&MI))
|
||||
if (isSchedBarrier(MI))
|
||||
return true;
|
||||
|
||||
if (HII->isSolo(&MI))
|
||||
if (HII->isSolo(MI))
|
||||
return true;
|
||||
|
||||
if (MI.getOpcode() == Hexagon::A2_nop)
|
||||
@ -1019,9 +1019,9 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
|
||||
// cannotCoexistAsymm(MI, MJ) || cannotCoexistAsymm(MJ, MI)
|
||||
// Doing the test only one way saves the amount of code in this function,
|
||||
// since every test would need to be repeated with the MI and MJ reversed.
|
||||
static bool cannotCoexistAsymm(const MachineInstr *MI, const MachineInstr *MJ,
|
||||
static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ,
|
||||
const HexagonInstrInfo &HII) {
|
||||
const MachineFunction *MF = MI->getParent()->getParent();
|
||||
const MachineFunction *MF = MI.getParent()->getParent();
|
||||
if (MF->getSubtarget<HexagonSubtarget>().hasV60TOpsOnly() &&
|
||||
HII.isHVXMemWithAIndirect(MI, MJ))
|
||||
return true;
|
||||
@ -1030,9 +1030,9 @@ static bool cannotCoexistAsymm(const MachineInstr *MI, const MachineInstr *MJ,
|
||||
// able to remove the asm out after packetizing (i.e. if the asm must be
|
||||
// moved past the bundle). Similarly, two asms cannot be together to avoid
|
||||
// complications when determining their relative order outside of a bundle.
|
||||
if (MI->isInlineAsm())
|
||||
return MJ->isInlineAsm() || MJ->isBranch() || MJ->isBarrier() ||
|
||||
MJ->isCall() || MJ->isTerminator();
|
||||
if (MI.isInlineAsm())
|
||||
return MJ.isInlineAsm() || MJ.isBranch() || MJ.isBarrier() ||
|
||||
MJ.isCall() || MJ.isTerminator();
|
||||
|
||||
// "False" really means that the quick check failed to determine if
|
||||
// I and J cannot coexist.
|
||||
@ -1041,8 +1041,8 @@ static bool cannotCoexistAsymm(const MachineInstr *MI, const MachineInstr *MJ,
|
||||
|
||||
|
||||
// Full, symmetric check.
|
||||
bool HexagonPacketizerList::cannotCoexist(const MachineInstr *MI,
|
||||
const MachineInstr *MJ) {
|
||||
bool HexagonPacketizerList::cannotCoexist(const MachineInstr &MI,
|
||||
const MachineInstr &MJ) {
|
||||
return cannotCoexistAsymm(MI, MJ, *HII) || cannotCoexistAsymm(MJ, MI, *HII);
|
||||
}
|
||||
|
||||
@ -1052,10 +1052,10 @@ void HexagonPacketizerList::unpacketizeSoloInstrs(MachineFunction &MF) {
|
||||
MachineBasicBlock::instr_iterator NextI;
|
||||
for (auto I = B.instr_begin(), E = B.instr_end(); I != E; I = NextI) {
|
||||
NextI = std::next(I);
|
||||
MachineInstr *MI = &*I;
|
||||
if (MI->isBundle())
|
||||
MachineInstr &MI = *I;
|
||||
if (MI.isBundle())
|
||||
BundleIt = I;
|
||||
if (!MI->isInsideBundle())
|
||||
if (!MI.isInsideBundle())
|
||||
continue;
|
||||
|
||||
// Decide on where to insert the instruction that we are pulling out.
|
||||
@ -1065,9 +1065,9 @@ void HexagonPacketizerList::unpacketizeSoloInstrs(MachineFunction &MF) {
|
||||
// other instructions in the bundle read, then we need to place it
|
||||
// after the bundle (to preserve the bundle semantics).
|
||||
bool InsertBeforeBundle;
|
||||
if (MI->isInlineAsm())
|
||||
InsertBeforeBundle = !hasWriteToReadDep(*MI, *BundleIt, HRI);
|
||||
else if (MI->isDebugValue())
|
||||
if (MI.isInlineAsm())
|
||||
InsertBeforeBundle = !hasWriteToReadDep(MI, *BundleIt, HRI);
|
||||
else if (MI.isDebugValue())
|
||||
InsertBeforeBundle = true;
|
||||
else
|
||||
continue;
|
||||
@ -1078,8 +1078,8 @@ void HexagonPacketizerList::unpacketizeSoloInstrs(MachineFunction &MF) {
|
||||
}
|
||||
|
||||
// Check if a given instruction is of class "system".
|
||||
static bool isSystemInstr(const MachineInstr *MI) {
|
||||
unsigned Opc = MI->getOpcode();
|
||||
static bool isSystemInstr(const MachineInstr &MI) {
|
||||
unsigned Opc = MI.getOpcode();
|
||||
switch (Opc) {
|
||||
case Hexagon::Y2_barrier:
|
||||
case Hexagon::Y2_dcfetchbo:
|
||||
@ -1088,24 +1088,24 @@ static bool isSystemInstr(const MachineInstr *MI) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::hasDeadDependence(const MachineInstr *I,
|
||||
const MachineInstr *J) {
|
||||
bool HexagonPacketizerList::hasDeadDependence(const MachineInstr &I,
|
||||
const MachineInstr &J) {
|
||||
// The dependence graph may not include edges between dead definitions,
|
||||
// so without extra checks, we could end up packetizing two instruction
|
||||
// defining the same (dead) register.
|
||||
if (I->isCall() || J->isCall())
|
||||
if (I.isCall() || J.isCall())
|
||||
return false;
|
||||
if (HII->isPredicated(*I) || HII->isPredicated(*J))
|
||||
if (HII->isPredicated(I) || HII->isPredicated(J))
|
||||
return false;
|
||||
|
||||
BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
|
||||
for (auto &MO : I->operands()) {
|
||||
for (auto &MO : I.operands()) {
|
||||
if (!MO.isReg() || !MO.isDef() || !MO.isDead())
|
||||
continue;
|
||||
DeadDefs[MO.getReg()] = true;
|
||||
}
|
||||
|
||||
for (auto &MO : J->operands()) {
|
||||
for (auto &MO : J.operands()) {
|
||||
if (!MO.isReg() || !MO.isDef() || !MO.isDead())
|
||||
continue;
|
||||
unsigned R = MO.getReg();
|
||||
@ -1115,8 +1115,8 @@ bool HexagonPacketizerList::hasDeadDependence(const MachineInstr *I,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
|
||||
const MachineInstr *J) {
|
||||
bool HexagonPacketizerList::hasControlDependence(const MachineInstr &I,
|
||||
const MachineInstr &J) {
|
||||
// A save callee-save register function call can only be in a packet
|
||||
// with instructions that don't write to the callee-save registers.
|
||||
if ((HII->isSaveCalleeSavedRegsCall(I) &&
|
||||
@ -1132,10 +1132,10 @@ bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
|
||||
// \ref-manual (7.3.4) A loop setup packet in loopN or spNloop0 cannot
|
||||
// contain a speculative indirect jump,
|
||||
// a new-value compare jump or a dealloc_return.
|
||||
auto isBadForLoopN = [this] (const MachineInstr *MI) -> bool {
|
||||
if (MI->isCall() || HII->isDeallocRet(MI) || HII->isNewValueJump(MI))
|
||||
auto isBadForLoopN = [this] (const MachineInstr &MI) -> bool {
|
||||
if (MI.isCall() || HII->isDeallocRet(MI) || HII->isNewValueJump(MI))
|
||||
return true;
|
||||
if (HII->isPredicated(*MI) && HII->isPredicatedNew(*MI) && HII->isJumpR(MI))
|
||||
if (HII->isPredicated(MI) && HII->isPredicatedNew(MI) && HII->isJumpR(MI))
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
@ -1148,13 +1148,13 @@ bool HexagonPacketizerList::hasControlDependence(const MachineInstr *I,
|
||||
// dealloc_return cannot appear in the same packet as a conditional or
|
||||
// unconditional jump.
|
||||
return HII->isDeallocRet(I) &&
|
||||
(J->isBranch() || J->isCall() || J->isBarrier());
|
||||
(J.isBranch() || J.isCall() || J.isBarrier());
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr *I,
|
||||
const MachineInstr *J) {
|
||||
bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr &I,
|
||||
const MachineInstr &J) {
|
||||
bool SysI = isSystemInstr(I), SysJ = isSystemInstr(J);
|
||||
bool StoreI = I->mayStore(), StoreJ = J->mayStore();
|
||||
bool StoreI = I.mayStore(), StoreJ = J.mayStore();
|
||||
if ((SysI && StoreJ) || (SysJ && StoreI))
|
||||
return true;
|
||||
|
||||
@ -1177,18 +1177,18 @@ bool HexagonPacketizerList::hasV4SpecificDependence(const MachineInstr *I,
|
||||
// SUJ is the current instruction inside the current packet against which that
|
||||
// SUI will be packetized.
|
||||
bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
MachineInstr *I = SUI->getInstr();
|
||||
MachineInstr *J = SUJ->getInstr();
|
||||
assert(I && J && "Unable to packetize null instruction!");
|
||||
assert(SUI->getInstr() && SUJ->getInstr());
|
||||
MachineInstr &I = *SUI->getInstr();
|
||||
MachineInstr &J = *SUJ->getInstr();
|
||||
|
||||
// Clear IgnoreDepMIs when Packet starts.
|
||||
if (CurrentPacketMIs.size() == 1)
|
||||
IgnoreDepMIs.clear();
|
||||
|
||||
MachineBasicBlock::iterator II = I;
|
||||
MachineBasicBlock::iterator II = I.getIterator();
|
||||
|
||||
// Solo instructions cannot go in the packet.
|
||||
assert(!isSoloInstruction(*I) && "Unexpected solo instr!");
|
||||
assert(!isSoloInstruction(I) && "Unexpected solo instr!");
|
||||
|
||||
if (cannotCoexist(I, J))
|
||||
return false;
|
||||
@ -1205,23 +1205,23 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
return false;
|
||||
|
||||
// If an instruction feeds new value jump, glue it.
|
||||
MachineBasicBlock::iterator NextMII = I;
|
||||
MachineBasicBlock::iterator NextMII = I.getIterator();
|
||||
++NextMII;
|
||||
if (NextMII != I->getParent()->end() && HII->isNewValueJump(&*NextMII)) {
|
||||
if (NextMII != I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
|
||||
MachineInstr &NextMI = *NextMII;
|
||||
|
||||
bool secondRegMatch = false;
|
||||
const MachineOperand &NOp0 = NextMI.getOperand(0);
|
||||
const MachineOperand &NOp1 = NextMI.getOperand(1);
|
||||
|
||||
if (NOp1.isReg() && I->getOperand(0).getReg() == NOp1.getReg())
|
||||
if (NOp1.isReg() && I.getOperand(0).getReg() == NOp1.getReg())
|
||||
secondRegMatch = true;
|
||||
|
||||
for (auto I : CurrentPacketMIs) {
|
||||
SUnit *PacketSU = MIToSUnit.find(I)->second;
|
||||
MachineInstr *PI = PacketSU->getInstr();
|
||||
for (auto T : CurrentPacketMIs) {
|
||||
SUnit *PacketSU = MIToSUnit.find(T)->second;
|
||||
MachineInstr &PI = *PacketSU->getInstr();
|
||||
// NVJ can not be part of the dual jump - Arch Spec: section 7.8.
|
||||
if (PI->isCall()) {
|
||||
if (PI.isCall()) {
|
||||
Dependence = true;
|
||||
break;
|
||||
}
|
||||
@ -1233,14 +1233,14 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
// 3. If the second operand of the nvj is newified, (which means
|
||||
// first operand is also a reg), first reg is not defined in
|
||||
// the same packet.
|
||||
if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
|
||||
if (PI.getOpcode() == Hexagon::S2_allocframe || PI.mayStore() ||
|
||||
HII->isLoopN(PI)) {
|
||||
Dependence = true;
|
||||
break;
|
||||
}
|
||||
// Check #2/#3.
|
||||
const MachineOperand &OpR = secondRegMatch ? NOp0 : NOp1;
|
||||
if (OpR.isReg() && PI->modifiesRegister(OpR.getReg(), HRI)) {
|
||||
if (OpR.isReg() && PI.modifiesRegister(OpR.getReg(), HRI)) {
|
||||
Dependence = true;
|
||||
break;
|
||||
}
|
||||
@ -1291,7 +1291,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
RC = HRI->getMinimalPhysRegClass(DepReg);
|
||||
}
|
||||
|
||||
if (I->isCall() || I->isReturn() || HII->isTailCall(I)) {
|
||||
if (I.isCall() || I.isReturn() || HII->isTailCall(I)) {
|
||||
if (!isRegDependence(DepType))
|
||||
continue;
|
||||
if (!isCallDependent(I, DepType, SUJ->Succs[i].getReg()))
|
||||
@ -1324,8 +1324,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
|
||||
// For predicated instructions, if the predicates are complements then
|
||||
// there can be no dependence.
|
||||
if (HII->isPredicated(*I) && HII->isPredicated(*J) &&
|
||||
arePredicatesComplements(*I, *J)) {
|
||||
if (HII->isPredicated(I) && HII->isPredicated(J) &&
|
||||
arePredicatesComplements(I, J)) {
|
||||
// Not always safe to do this translation.
|
||||
// DAG Builder attempts to reduce dependence edges using transitive
|
||||
// nature of dependencies. Here is an example:
|
||||
@ -1338,24 +1338,24 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
// However, there is no dependence edge between (1)->(3). This results
|
||||
// in all 3 instructions going in the same packet. We ignore dependce
|
||||
// only once to avoid this situation.
|
||||
auto Itr = std::find(IgnoreDepMIs.begin(), IgnoreDepMIs.end(), J);
|
||||
auto Itr = std::find(IgnoreDepMIs.begin(), IgnoreDepMIs.end(), &J);
|
||||
if (Itr != IgnoreDepMIs.end()) {
|
||||
Dependence = true;
|
||||
return false;
|
||||
}
|
||||
IgnoreDepMIs.push_back(I);
|
||||
IgnoreDepMIs.push_back(&I);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore Order dependences between unconditional direct branches
|
||||
// and non-control-flow instructions.
|
||||
if (isDirectJump(I) && !J->isBranch() && !J->isCall() &&
|
||||
if (isDirectJump(I) && !J.isBranch() && !J.isCall() &&
|
||||
DepType == SDep::Order)
|
||||
continue;
|
||||
|
||||
// Ignore all dependences for jumps except for true and output
|
||||
// dependences.
|
||||
if (I->isConditionalBranch() && DepType != SDep::Data &&
|
||||
if (I.isConditionalBranch() && DepType != SDep::Data &&
|
||||
DepType != SDep::Output)
|
||||
continue;
|
||||
|
||||
@ -1377,7 +1377,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
unsigned DepReg = SUJ->Succs[i].getReg();
|
||||
|
||||
// Check if I and J really defines DepReg.
|
||||
if (!I->definesRegister(DepReg) && !J->definesRegister(DepReg))
|
||||
if (!I.definesRegister(DepReg) && !J.definesRegister(DepReg))
|
||||
continue;
|
||||
FoundSequentialDependence = true;
|
||||
break;
|
||||
@ -1391,15 +1391,15 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
// 4. Load followed by any memory operation is allowed.
|
||||
if (DepType == SDep::Order) {
|
||||
if (!PacketizeVolatiles) {
|
||||
bool OrdRefs = I->hasOrderedMemoryRef() || J->hasOrderedMemoryRef();
|
||||
bool OrdRefs = I.hasOrderedMemoryRef() || J.hasOrderedMemoryRef();
|
||||
if (OrdRefs) {
|
||||
FoundSequentialDependence = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// J is first, I is second.
|
||||
bool LoadJ = J->mayLoad(), StoreJ = J->mayStore();
|
||||
bool LoadI = I->mayLoad(), StoreI = I->mayStore();
|
||||
bool LoadJ = J.mayLoad(), StoreJ = J.mayStore();
|
||||
bool LoadI = I.mayLoad(), StoreI = I.mayStore();
|
||||
if (StoreJ) {
|
||||
// Two stores are only allowed on V4+. Load following store is never
|
||||
// allowed.
|
||||
@ -1424,14 +1424,14 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
// between ALLOCFRAME and subsequent store, allow it to be packetized
|
||||
// in a same packet. This implies that the store is using the caller's
|
||||
// SP. Hence, offset needs to be updated accordingly.
|
||||
if (DepType == SDep::Data && J->getOpcode() == Hexagon::S2_allocframe) {
|
||||
unsigned Opc = I->getOpcode();
|
||||
if (DepType == SDep::Data && J.getOpcode() == Hexagon::S2_allocframe) {
|
||||
unsigned Opc = I.getOpcode();
|
||||
switch (Opc) {
|
||||
case Hexagon::S2_storerd_io:
|
||||
case Hexagon::S2_storeri_io:
|
||||
case Hexagon::S2_storerh_io:
|
||||
case Hexagon::S2_storerb_io:
|
||||
if (I->getOperand(0).getReg() == HRI->getStackRegister()) {
|
||||
if (I.getOperand(0).getReg() == HRI->getStackRegister()) {
|
||||
// Since this store is to be glued with allocframe in the same
|
||||
// packet, it will use SP of the previous stack frame, i.e.
|
||||
// caller's SP. Therefore, we need to recalculate offset
|
||||
@ -1451,12 +1451,12 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
// R0 = ... ; SUI
|
||||
// Those cannot be packetized together, since the call will observe
|
||||
// the effect of the assignment to R0.
|
||||
if (DepType == SDep::Anti && J->isCall()) {
|
||||
if (DepType == SDep::Anti && J.isCall()) {
|
||||
// Check if I defines any volatile register. We should also check
|
||||
// registers that the call may read, but these happen to be a
|
||||
// subset of the volatile register set.
|
||||
for (const MCPhysReg *P = J->getDesc().ImplicitDefs; P && *P; ++P) {
|
||||
if (!I->modifiesRegister(*P, HRI))
|
||||
for (const MCPhysReg *P = J.getDesc().ImplicitDefs; P && *P; ++P) {
|
||||
if (!I.modifiesRegister(*P, HRI))
|
||||
continue;
|
||||
FoundSequentialDependence = true;
|
||||
break;
|
||||
@ -1484,9 +1484,9 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
|
||||
MachineInstr *I = SUI->getInstr();
|
||||
MachineInstr *J = SUJ->getInstr();
|
||||
assert(I && J && "Unable to packetize null instruction!");
|
||||
assert(SUI->getInstr() && SUJ->getInstr());
|
||||
MachineInstr &I = *SUI->getInstr();
|
||||
MachineInstr &J = *SUJ->getInstr();
|
||||
|
||||
if (cannotCoexist(I, J))
|
||||
return false;
|
||||
@ -1512,7 +1512,7 @@ bool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
|
||||
|
||||
MachineBasicBlock::iterator
|
||||
HexagonPacketizerList::addToPacket(MachineInstr &MI) {
|
||||
MachineBasicBlock::iterator MII = MI;
|
||||
MachineBasicBlock::iterator MII = MI.getIterator();
|
||||
MachineBasicBlock *MBB = MI.getParent();
|
||||
if (MI.isImplicitDef()) {
|
||||
unsigned R = MI.getOperand(0).getReg();
|
||||
@ -1524,7 +1524,7 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
|
||||
}
|
||||
assert(ResourceTracker->canReserveResources(MI));
|
||||
|
||||
bool ExtMI = HII->isExtended(&MI) || HII->isConstExtended(&MI);
|
||||
bool ExtMI = HII->isExtended(MI) || HII->isConstExtended(MI);
|
||||
bool Good = true;
|
||||
|
||||
if (GlueToNewValueJump) {
|
||||
@ -1537,7 +1537,7 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
|
||||
if (ExtMI)
|
||||
Good = tryAllocateResourcesForConstExt(true);
|
||||
|
||||
bool ExtNvjMI = HII->isExtended(&NvjMI) || HII->isConstExtended(&NvjMI);
|
||||
bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
|
||||
if (Good) {
|
||||
if (ResourceTracker->canReserveResources(NvjMI))
|
||||
ResourceTracker->reserveResources(NvjMI);
|
||||
@ -1571,9 +1571,9 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
|
||||
if (ExtMI && !tryAllocateResourcesForConstExt(true)) {
|
||||
endPacket(MBB, MI);
|
||||
if (PromotedToDotNew)
|
||||
demoteToDotOld(&MI);
|
||||
demoteToDotOld(MI);
|
||||
if (GlueAllocframeStore) {
|
||||
useCalleesSP(&MI);
|
||||
useCalleesSP(MI);
|
||||
GlueAllocframeStore = false;
|
||||
}
|
||||
ResourceTracker->reserveResources(MI);
|
||||
@ -1591,18 +1591,18 @@ void HexagonPacketizerList::endPacket(MachineBasicBlock *MBB,
|
||||
}
|
||||
|
||||
bool HexagonPacketizerList::shouldAddToPacket(const MachineInstr &MI) {
|
||||
return !producesStall(&MI);
|
||||
return !producesStall(MI);
|
||||
}
|
||||
|
||||
|
||||
// Return true when ConsMI uses a register defined by ProdMI.
|
||||
static bool isDependent(const MachineInstr *ProdMI,
|
||||
const MachineInstr *ConsMI) {
|
||||
if (!ProdMI->getOperand(0).isReg())
|
||||
static bool isDependent(const MachineInstr &ProdMI,
|
||||
const MachineInstr &ConsMI) {
|
||||
if (!ProdMI.getOperand(0).isReg())
|
||||
return false;
|
||||
unsigned DstReg = ProdMI->getOperand(0).getReg();
|
||||
unsigned DstReg = ProdMI.getOperand(0).getReg();
|
||||
|
||||
for (auto &Op : ConsMI->operands())
|
||||
for (auto &Op : ConsMI.operands())
|
||||
if (Op.isReg() && Op.isUse() && Op.getReg() == DstReg)
|
||||
// The MIs depend on each other.
|
||||
return true;
|
||||
@ -1611,7 +1611,7 @@ static bool isDependent(const MachineInstr *ProdMI,
|
||||
}
|
||||
|
||||
// V60 forward scheduling.
|
||||
bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
|
||||
bool HexagonPacketizerList::producesStall(const MachineInstr &I) {
|
||||
// Check whether the previous packet is in a different loop. If this is the
|
||||
// case, there is little point in trying to avoid a stall because that would
|
||||
// favor the rare case (loop entry) over the common case (loop iteration).
|
||||
@ -1621,7 +1621,7 @@ bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
|
||||
// backedge.
|
||||
if (!OldPacketMIs.empty()) {
|
||||
auto *OldBB = OldPacketMIs.front()->getParent();
|
||||
auto *ThisBB = I->getParent();
|
||||
auto *ThisBB = I.getParent();
|
||||
if (MLI->getLoopFor(OldBB) != MLI->getLoopFor(ThisBB))
|
||||
return false;
|
||||
}
|
||||
@ -1629,9 +1629,9 @@ bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
|
||||
// Check for stall between two vector instructions.
|
||||
if (HII->isV60VectorInstruction(I)) {
|
||||
for (auto J : OldPacketMIs) {
|
||||
if (!HII->isV60VectorInstruction(J))
|
||||
if (!HII->isV60VectorInstruction(*J))
|
||||
continue;
|
||||
if (isDependent(J, I) && !HII->isVecUsableNextPacket(J, I))
|
||||
if (isDependent(*J, I) && !HII->isVecUsableNextPacket(*J, I))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -1641,17 +1641,17 @@ bool HexagonPacketizerList::producesStall(const MachineInstr *I) {
|
||||
// there is no definition of a use in the current packet, because it
|
||||
// may be a candidate for .new.
|
||||
for (auto J : CurrentPacketMIs)
|
||||
if (!HII->isV60VectorInstruction(J) && isDependent(J, I))
|
||||
if (!HII->isV60VectorInstruction(*J) && isDependent(*J, I))
|
||||
return false;
|
||||
|
||||
// Check for stall between I and instructions in the previous packet.
|
||||
if (MF.getSubtarget<HexagonSubtarget>().useBSBScheduling()) {
|
||||
for (auto J : OldPacketMIs) {
|
||||
if (HII->isV60VectorInstruction(J))
|
||||
if (HII->isV60VectorInstruction(*J))
|
||||
continue;
|
||||
if (!HII->isLateInstrFeedsEarlyInstr(J, I))
|
||||
if (!HII->isLateInstrFeedsEarlyInstr(*J, I))
|
||||
continue;
|
||||
if (isDependent(J, I) && !HII->canExecuteInBundle(J, I))
|
||||
if (isDependent(*J, I) && !HII->canExecuteInBundle(*J, I))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -73,44 +73,44 @@ public:
|
||||
void unpacketizeSoloInstrs(MachineFunction &MF);
|
||||
|
||||
protected:
|
||||
bool isCallDependent(const MachineInstr* MI, SDep::Kind DepType,
|
||||
bool isCallDependent(const MachineInstr &MI, SDep::Kind DepType,
|
||||
unsigned DepReg);
|
||||
bool promoteToDotCur(MachineInstr* MI, SDep::Kind DepType,
|
||||
bool promoteToDotCur(MachineInstr &MI, SDep::Kind DepType,
|
||||
MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
bool canPromoteToDotCur(const MachineInstr* MI, const SUnit* PacketSU,
|
||||
const TargetRegisterClass *RC);
|
||||
bool canPromoteToDotCur(const MachineInstr &MI, const SUnit *PacketSU,
|
||||
unsigned DepReg, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
const TargetRegisterClass *RC);
|
||||
void cleanUpDotCur();
|
||||
|
||||
bool promoteToDotNew(MachineInstr* MI, SDep::Kind DepType,
|
||||
bool promoteToDotNew(MachineInstr &MI, SDep::Kind DepType,
|
||||
MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
bool canPromoteToDotNew(const MachineInstr* MI, const SUnit* PacketSU,
|
||||
const TargetRegisterClass *RC);
|
||||
bool canPromoteToDotNew(const MachineInstr &MI, const SUnit *PacketSU,
|
||||
unsigned DepReg, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC);
|
||||
bool canPromoteToNewValue(const MachineInstr* MI, const SUnit* PacketSU,
|
||||
const TargetRegisterClass *RC);
|
||||
bool canPromoteToNewValue(const MachineInstr &MI, const SUnit *PacketSU,
|
||||
unsigned DepReg, MachineBasicBlock::iterator &MII);
|
||||
bool canPromoteToNewValueStore(const MachineInstr* MI,
|
||||
const MachineInstr* PacketMI, unsigned DepReg);
|
||||
bool demoteToDotOld(MachineInstr* MI);
|
||||
bool useCallersSP(MachineInstr *MI);
|
||||
void useCalleesSP(MachineInstr *MI);
|
||||
bool canPromoteToNewValueStore(const MachineInstr &MI,
|
||||
const MachineInstr &PacketMI, unsigned DepReg);
|
||||
bool demoteToDotOld(MachineInstr &MI);
|
||||
bool useCallersSP(MachineInstr &MI);
|
||||
void useCalleesSP(MachineInstr &MI);
|
||||
bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2);
|
||||
bool restrictingDepExistInPacket(MachineInstr*, unsigned);
|
||||
bool isNewifiable(const MachineInstr *MI, const TargetRegisterClass *NewRC);
|
||||
bool isCurifiable(MachineInstr* MI);
|
||||
bool cannotCoexist(const MachineInstr *MI, const MachineInstr *MJ);
|
||||
bool restrictingDepExistInPacket(MachineInstr&, unsigned);
|
||||
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC);
|
||||
bool isCurifiable(MachineInstr &MI);
|
||||
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ);
|
||||
inline bool isPromotedToDotNew() const {
|
||||
return PromotedToDotNew;
|
||||
}
|
||||
bool tryAllocateResourcesForConstExt(bool Reserve);
|
||||
bool canReserveResourcesForConstExt();
|
||||
void reserveResourcesForConstExt();
|
||||
bool hasDeadDependence(const MachineInstr *I, const MachineInstr *J);
|
||||
bool hasControlDependence(const MachineInstr *I, const MachineInstr *J);
|
||||
bool hasV4SpecificDependence(const MachineInstr *I, const MachineInstr *J);
|
||||
bool producesStall(const MachineInstr *MI);
|
||||
bool hasDeadDependence(const MachineInstr &I, const MachineInstr &J);
|
||||
bool hasControlDependence(const MachineInstr &I, const MachineInstr &J);
|
||||
bool hasV4SpecificDependence(const MachineInstr &I, const MachineInstr &J);
|
||||
bool producesStall(const MachineInstr &MI);
|
||||
};
|
||||
} // namespace llvm
|
||||
#endif // HEXAGONVLIWPACKETIZER_H
|
||||
|
Loading…
Reference in New Issue
Block a user