#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
const TargetRegisterInfo *TRI;
const MachineFrameInfo *MFI;
MachineRegisterInfo *MRI;
- const InstrItineraryData *InstrItins;
+ TargetSchedModel SchedModel;
bool PreRegAlloc;
// Various analyses that we use...
SmallSet<unsigned, 32> RegSeen;
SmallVector<unsigned, 8> RegPressure;
- // Register pressure "limit" per register class. If the pressure
+ // Register pressure "limit" per register pressure set. If the pressure
// is higher than the limit, then it's considered high.
SmallVector<unsigned, 8> RegLimit;
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineLoopInfo>();
AU.addRequired<MachineDominatorTree>();
- AU.addRequired<AliasAnalysis>();
+ AU.addRequired<AAResultsWrapperPass>();
AU.addPreserved<MachineLoopInfo>();
AU.addPreserved<MachineDominatorTree>();
MachineFunctionPass::getAnalysisUsage(AU);
/// if there is little to no overhead moving instructions into loops.
void SinkIntoLoop();
- /// getRegisterClassIDAndCost - For a given register return the ID and cost
- /// of its representative register class by reference.
- void getRegisterClassIDAndCost(unsigned Reg, unsigned &RCId,
- unsigned &RCCost) const;
-
/// InitRegPressure - Find all virtual register references that are liveout
/// of the preheader to initialize the starting "register pressure". Note
/// this does not count live through (livein but not used) registers.
"Machine Loop Invariant Code Motion", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
+INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(MachineLICM, "machinelicm",
"Machine Loop Invariant Code Motion", false, false)
return false;
Changed = FirstInLoop = false;
- TII = MF.getSubtarget().getInstrInfo();
- TLI = MF.getSubtarget().getTargetLowering();
- TRI = MF.getSubtarget().getRegisterInfo();
+ const TargetSubtargetInfo &ST = MF.getSubtarget();
+ TII = ST.getInstrInfo();
+ TLI = ST.getTargetLowering();
+ TRI = ST.getRegisterInfo();
MFI = MF.getFrameInfo();
MRI = &MF.getRegInfo();
- InstrItins = MF.getSubtarget().getInstrItineraryData();
+ SchedModel.init(ST.getSchedModel(), &ST, TII);
PreRegAlloc = MRI->isSSA();
if (PreRegAlloc) {
// Estimate register pressure during pre-regalloc pass.
- unsigned NumRC = TRI->getNumRegClasses();
- RegPressure.resize(NumRC);
+ unsigned NumRPS = TRI->getNumRegPressureSets();
+ RegPressure.resize(NumRPS);
std::fill(RegPressure.begin(), RegPressure.end(), 0);
- RegLimit.resize(NumRC);
- for (TargetRegisterInfo::regclass_iterator I = TRI->regclass_begin(),
- E = TRI->regclass_end(); I != E; ++I)
- RegLimit[(*I)->getID()] = TRI->getRegPressureLimit(*I, MF);
+ RegLimit.resize(NumRPS);
+ for (unsigned i = 0, e = NumRPS; i != e; ++i)
+ RegLimit[i] = TRI->getRegPressureSetLimit(MF, i);
}
// Get our Loop information...
MLI = &getAnalysis<MachineLoopInfo>();
DT = &getAnalysis<MachineDominatorTree>();
- AA = &getAnalysis<AliasAnalysis>();
+ AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end());
while (!Worklist.empty()) {
// If the header of the loop containing this basic block is a landing pad,
// then don't try to hoist instructions out of this loop.
const MachineLoop *ML = MLI->getLoopFor(BB);
- if (ML && ML->getHeader()->isLandingPad()) continue;
+ if (ML && ML->getHeader()->isEHPad()) continue;
// Conservatively treat live-in's as an external def.
// FIXME: That means a reload that're reused in successor block(s) will not
// be LICM'ed.
- for (MachineBasicBlock::livein_iterator I = BB->livein_begin(),
- E = BB->livein_end(); I != E; ++I) {
- unsigned Reg = *I;
- for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
+ for (const auto &LI : BB->liveins()) {
+ for (MCRegAliasIterator AI(LI.PhysReg, TRI, true); AI.isValid(); ++AI)
PhysRegDefs.set(*AI);
}
// If the header of the loop containing this basic block is a landing pad,
// then don't try to hoist instructions out of this loop.
const MachineLoop *ML = MLI->getLoopFor(BB);
- if (ML && ML->getHeader()->isLandingPad())
+ if (ML && ML->getHeader()->isEHPad())
continue;
// If this subregion is not in the top level loop at all, exit.
return MO.isKill() || MRI->hasOneNonDBGUse(MO.getReg());
}
-void MachineLICM::getRegisterClassIDAndCost(unsigned Reg, unsigned &RCId,
- unsigned &RCCost) const {
- const TargetRegisterClass *RC = MRI->getRegClass(Reg);
- MVT VT = *RC->vt_begin();
- if (VT == MVT::Untyped) {
- RCId = RC->getID();
- RCCost = 1;
- } else {
- RCId = TLI->getRepRegClassFor(VT)->getID();
- RCCost = TLI->getRepRegClassCostFor(VT);
- }
-}
-
/// InitRegPressure - Find all virtual register references that are liveout of
/// the preheader to initialize the starting "register pressure". Note this
/// does not count live through (livein but not used) registers.
void MachineLICM::UpdateRegPressure(const MachineInstr *MI,
bool ConsiderUnseenAsDef) {
auto Cost = calcRegisterCost(MI, /*ConsiderSeen=*/true, ConsiderUnseenAsDef);
- for (const auto &ClassAndCost : Cost) {
- unsigned Class = ClassAndCost.first;
- if (static_cast<int>(RegPressure[Class]) < -ClassAndCost.second)
+ for (const auto &RPIdAndCost : Cost) {
+ unsigned Class = RPIdAndCost.first;
+ if (static_cast<int>(RegPressure[Class]) < -RPIdAndCost.second)
RegPressure[Class] = 0;
else
- RegPressure[Class] += ClassAndCost.second;
+ RegPressure[Class] += RPIdAndCost.second;
}
}
// FIXME: It seems bad to use RegSeen only for some of these calculations.
bool isNew = ConsiderSeen ? RegSeen.insert(Reg).second : false;
- unsigned RCId, RCCost;
- getRegisterClassIDAndCost(Reg, RCId, RCCost);
- int PriorCost = 0;
- if (Cost.find(RCId) != Cost.end())
- PriorCost = Cost[RCId];
+ const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+
+ RegClassWeight W = TRI->getRegClassWeight(RC);
+ int RCCost = 0;
if (MO.isDef())
- Cost[RCId] = PriorCost + RCCost;
+ RCCost = W.RegWeight;
else {
bool isKill = isOperandKill(MO, MRI);
if (isNew && !isKill && ConsiderUnseenAsDef)
// Haven't seen this, it must be a livein.
- Cost[RCId] = PriorCost + RCCost;
+ RCCost = W.RegWeight;
else if (!isNew && isKill)
- Cost[RCId] = PriorCost - RCCost;
+ RCCost = -W.RegWeight;
+ }
+ if (RCCost == 0)
+ continue;
+ const int *PS = TRI->getRegClassPressureSets(RC);
+ for (; *PS != -1; ++PS) {
+ if (Cost.find(*PS) == Cost.end())
+ Cost[*PS] = RCCost;
+ else
+ Cost[*PS] += RCCost;
}
}
return Cost;
for (MachineInstr::mmo_iterator I = MI.memoperands_begin(),
E = MI.memoperands_end(); I != E; ++I) {
if (const PseudoSourceValue *PSV = (*I)->getPseudoValue()) {
- if (PSV == PSV->getGOT() || PSV == PSV->getConstantPool())
+ if (PSV->isGOT() || PSV->isConstantPool())
return true;
}
}
bool MachineLICM::IsLICMCandidate(MachineInstr &I) {
// Check if it's safe to move the instruction.
bool DontMoveAcrossStore = true;
- if (!I.isSafeToMove(TII, AA, DontMoveAcrossStore))
+ if (!I.isSafeToMove(AA, DontMoveAcrossStore))
return false;
// If it is load then check if it is guaranteed to execute by making sure that
SmallVector<const MachineInstr*, 8> Work(1, MI);
do {
MI = Work.pop_back_val();
- for (ConstMIOperands MO(MI); MO.isValid(); ++MO) {
- if (!MO->isReg() || !MO->isDef())
+ for (const MachineOperand &MO : MI->operands()) {
+ if (!MO.isReg() || !MO.isDef())
continue;
- unsigned Reg = MO->getReg();
+ unsigned Reg = MO.getReg();
if (!TargetRegisterInfo::isVirtualRegister(Reg))
continue;
for (MachineInstr &UseMI : MRI->use_instructions(Reg)) {
/// it 'high'.
bool MachineLICM::HasHighOperandLatency(MachineInstr &MI,
unsigned DefIdx, unsigned Reg) const {
- if (!InstrItins || InstrItins->isEmpty() || MRI->use_nodbg_empty(Reg))
+ if (MRI->use_nodbg_empty(Reg))
return false;
for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
if (MOReg != Reg)
continue;
- if (TII->hasHighOperandLatency(InstrItins, MRI, &MI, DefIdx, &UseMI, i))
+ if (TII->hasHighOperandLatency(SchedModel, MRI, &MI, DefIdx, &UseMI, i))
return true;
}
bool MachineLICM::IsCheapInstruction(MachineInstr &MI) const {
if (TII->isAsCheapAsAMove(&MI) || MI.isCopyLike())
return true;
- if (!InstrItins || InstrItins->isEmpty())
- return false;
bool isCheap = false;
unsigned NumDefs = MI.getDesc().getNumDefs();
if (TargetRegisterInfo::isPhysicalRegister(Reg))
continue;
- if (!TII->hasLowDefLatency(InstrItins, &MI, i))
+ if (!TII->hasLowDefLatency(SchedModel, &MI, i))
return false;
isCheap = true;
}
/// register pressure.
bool MachineLICM::CanCauseHighRegPressure(const DenseMap<unsigned, int>& Cost,
bool CheapInstr) {
- for (const auto &ClassAndCost : Cost) {
- if (ClassAndCost.second <= 0)
+ for (const auto &RPIdAndCost : Cost) {
+ if (RPIdAndCost.second <= 0)
continue;
- unsigned Class = ClassAndCost.first;
+ unsigned Class = RPIdAndCost.first;
int Limit = RegLimit[Class];
// Don't hoist cheap instructions if they would increase register pressure,
return true;
for (const auto &RP : BackTrace)
- if (static_cast<int>(RP[Class]) + ClassAndCost.second >= Limit)
+ if (static_cast<int>(RP[Class]) + RPIdAndCost.second >= Limit)
return true;
}
// Update register pressure of blocks from loop header to current block.
for (auto &RP : BackTrace)
- for (const auto &ClassAndCost : Cost)
- RP[ClassAndCost.first] += ClassAndCost.second;
+ for (const auto &RPIdAndCost : Cost)
+ RP[RPIdAndCost.first] += RPIdAndCost.second;
}
/// IsProfitableToHoist - Return true if it is potentially profitable to hoist