//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "machine-licm"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/MC/MCInstrItineraries.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
+#define DEBUG_TYPE "machine-licm"
+
static cl::opt<bool>
AvoidSpeculation("avoid-speculation",
cl::desc("MachineLICM should avoid speculation"),
cl::init(true), cl::Hidden);
+static cl::opt<bool>
+HoistCheapInsts("hoist-cheap-insts",
+ cl::desc("MachineLICM should hoist even cheap instructions"),
+ cl::init(false), cl::Hidden);
+
STATISTIC(NumHoisted,
"Number of machine instructions hoisted out of loops");
STATISTIC(NumLowRP,
namespace {
class MachineLICM : public MachineFunctionPass {
- const TargetMachine *TM;
const TargetInstrInfo *TII;
- const TargetLowering *TLI;
+ const TargetLoweringBase *TLI;
const TargetRegisterInfo *TRI;
const MachineFrameInfo *MFI;
MachineRegisterInfo *MRI;
initializeMachineLICMPass(*PassRegistry::getPassRegistry());
}
- virtual bool runOnMachineFunction(MachineFunction &MF);
+ bool runOnMachineFunction(MachineFunction &MF) override;
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineLoopInfo>();
AU.addRequired<MachineDominatorTree>();
AU.addRequired<AliasAnalysis>();
MachineFunctionPass::getAnalysisUsage(AU);
}
- virtual void releaseMemory() {
+ void releaseMemory() override {
RegSeen.clear();
RegPressure.clear();
RegLimit.clear();
BackTrace.clear();
- for (DenseMap<unsigned,std::vector<const MachineInstr*> >::iterator
- CI = CSEMap.begin(), CE = CSEMap.end(); CI != CE; ++CI)
- CI->second.clear();
CSEMap.clear();
}
BitVector &PhysRegDefs,
BitVector &PhysRegClobbers,
SmallSet<int, 32> &StoredFIs,
- SmallVector<CandidateInfo, 32> &Candidates);
+ SmallVectorImpl<CandidateInfo> &Candidates);
/// AddToLiveIns - Add register 'Reg' to the livein sets of BBs in the
/// current loop.
}
bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
+ if (skipOptnoneFunction(*MF.getFunction()))
+ return false;
+
Changed = FirstInLoop = false;
- TM = &MF.getTarget();
- TII = TM->getInstrInfo();
- TLI = TM->getTargetLowering();
- TRI = TM->getRegisterInfo();
+ TII = MF.getSubtarget().getInstrInfo();
+ TLI = MF.getSubtarget().getTargetLowering();
+ TRI = MF.getSubtarget().getRegisterInfo();
MFI = MF.getFrameInfo();
MRI = &MF.getRegInfo();
- InstrItins = TM->getInstrItineraryData();
+ InstrItins = MF.getSubtarget().getInstrItineraryData();
PreRegAlloc = MRI->isSSA();
DEBUG(dbgs() << "******** Pre-regalloc Machine LICM: ");
else
DEBUG(dbgs() << "******** Post-regalloc Machine LICM: ");
- DEBUG(dbgs() << MF.getFunction()->getName() << " ********\n");
+ DEBUG(dbgs() << MF.getName() << " ********\n");
if (PreRegAlloc) {
// Estimate register pressure during pre-regalloc pass.
SmallVector<MachineLoop *, 8> Worklist(MLI->begin(), MLI->end());
while (!Worklist.empty()) {
CurLoop = Worklist.pop_back_val();
- CurPreheader = 0;
+ CurPreheader = nullptr;
ExitBlocks.clear();
// If this is done before regalloc, only visit outer-most preheader-sporting
static bool InstructionStoresToFI(const MachineInstr *MI, int FI) {
for (MachineInstr::mmo_iterator o = MI->memoperands_begin(),
oe = MI->memoperands_end(); o != oe; ++o) {
- if (!(*o)->isStore() || !(*o)->getValue())
+ if (!(*o)->isStore() || !(*o)->getPseudoValue())
continue;
if (const FixedStackPseudoSourceValue *Value =
- dyn_cast<const FixedStackPseudoSourceValue>((*o)->getValue())) {
+ dyn_cast<FixedStackPseudoSourceValue>((*o)->getPseudoValue())) {
if (Value->getFrameIndex() == FI)
return true;
}
BitVector &PhysRegDefs,
BitVector &PhysRegClobbers,
SmallSet<int, 32> &StoredFIs,
- SmallVector<CandidateInfo, 32> &Candidates) {
+ SmallVectorImpl<CandidateInfo> &Candidates) {
bool RuledOut = false;
bool HasNonInvariantUse = false;
unsigned Def = 0;
}
if (MO.isImplicit()) {
- for (const uint16_t *AS = TRI->getOverlaps(Reg); *AS; ++AS)
- PhysRegClobbers.set(*AS);
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
+ PhysRegClobbers.set(*AI);
if (!MO.isDead())
// Non-dead implicit def? This cannot be hoisted.
RuledOut = true;
// If we have already seen another instruction that defines the same
// register, then this is not safe. Two defs is indicated by setting a
// PhysRegClobbers bit.
- for (const uint16_t *AS = TRI->getOverlaps(Reg); *AS; ++AS) {
+ for (MCRegAliasIterator AS(Reg, TRI, true); AS.isValid(); ++AS) {
if (PhysRegDefs.test(*AS))
PhysRegClobbers.set(*AS);
- if (PhysRegClobbers.test(*AS))
- // MI defined register is seen defined by another instruction in
- // the loop, it cannot be a LICM candidate.
- RuledOut = true;
PhysRegDefs.set(*AS);
}
+ if (PhysRegClobbers.test(Reg))
+ // MI defined register is seen defined by another instruction in
+ // the loop, it cannot be a LICM candidate.
+ RuledOut = true;
}
// Only consider reloads for now and remats which do not have register
// Walk the entire region, count number of defs for each register, and
// collect potential LICM candidates.
- const std::vector<MachineBasicBlock*> Blocks = CurLoop->getBlocks();
+ const std::vector<MachineBasicBlock *> &Blocks = CurLoop->getBlocks();
for (unsigned i = 0, e = Blocks.size(); i != e; ++i) {
MachineBasicBlock *BB = Blocks[i];
for (MachineBasicBlock::livein_iterator I = BB->livein_begin(),
E = BB->livein_end(); I != E; ++I) {
unsigned Reg = *I;
- for (const uint16_t *AS = TRI->getOverlaps(Reg); *AS; ++AS)
- PhysRegDefs.set(*AS);
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
+ PhysRegDefs.set(*AI);
}
SpeculationState = SpeculateUnknown;
unsigned Reg = MO.getReg();
if (!Reg)
continue;
- for (const uint16_t *AS = TRI->getOverlaps(Reg); *AS; ++AS)
- TermRegs.set(*AS);
+ for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
+ TermRegs.set(*AI);
}
}
/// AddToLiveIns - Add register 'Reg' to the livein sets of BBs in the current
/// loop, and make sure it is not killed by any instructions in the loop.
void MachineLICM::AddToLiveIns(unsigned Reg) {
- const std::vector<MachineBasicBlock*> Blocks = CurLoop->getBlocks();
+ const std::vector<MachineBasicBlock *> &Blocks = CurLoop->getBlocks();
for (unsigned i = 0, e = Blocks.size(); i != e; ++i) {
MachineBasicBlock *BB = Blocks[i];
if (!BB->isLiveIn(Reg))
/// one pass without iteration.
///
void MachineLICM::HoistOutOfLoop(MachineDomTreeNode *HeaderN) {
+ MachineBasicBlock *Preheader = getCurPreheader();
+ if (!Preheader)
+ return;
+
SmallVector<MachineDomTreeNode*, 32> Scopes;
SmallVector<MachineDomTreeNode*, 8> WorkList;
DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap;
// Perform a DFS walk to determine the order of visit.
WorkList.push_back(HeaderN);
- do {
+ while (!WorkList.empty()) {
MachineDomTreeNode *Node = WorkList.pop_back_val();
- assert(Node != 0 && "Null dominator tree node?");
+ assert(Node && "Null dominator tree node?");
MachineBasicBlock *BB = Node->getBlock();
// If the header of the loop containing this basic block is a landing pad,
ParentMap[Child] = Node;
WorkList.push_back(Child);
}
- } while (!WorkList.empty());
+ }
- if (Scopes.size() != 0) {
- MachineBasicBlock *Preheader = getCurPreheader();
- if (!Preheader)
- return;
+ if (Scopes.size() == 0)
+ return;
- // Compute registers which are livein into the loop headers.
- RegSeen.clear();
- BackTrace.clear();
- InitRegPressure(Preheader);
- }
+ // Compute registers which are livein into the loop headers.
+ RegSeen.clear();
+ BackTrace.clear();
+ InitRegPressure(Preheader);
// Now perform LICM.
for (unsigned i = 0, e = Scopes.size(); i != e; ++i) {
MachineDomTreeNode *Node = Scopes[i];
MachineBasicBlock *MBB = Node->getBlock();
- MachineBasicBlock *Preheader = getCurPreheader();
- if (!Preheader)
- continue;
-
EnterScope(MBB);
// Process the block
unsigned Reg, unsigned OpIdx,
unsigned &RCId, unsigned &RCCost) const {
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
- EVT VT = *RC->vt_begin();
+ MVT VT = *RC->vt_begin();
if (VT == MVT::Untyped) {
RCId = RC->getID();
RCCost = 1;
// defs as well. This happens whenever the preheader is created by splitting
// the critical edge from the loop predecessor to the loop header.
if (BB->pred_size() == 1) {
- MachineBasicBlock *TBB = 0, *FBB = 0;
+ MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
SmallVector<MachineOperand, 4> Cond;
if (!TII->AnalyzeBranch(*BB, TBB, FBB, Cond, false) && Cond.empty())
InitRegPressure(*BB->pred_begin());
if (!TargetRegisterInfo::isVirtualRegister(Reg))
continue;
- bool isNew = RegSeen.insert(Reg);
+ bool isNew = RegSeen.insert(Reg).second;
unsigned RCId, RCCost;
getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost);
if (MO.isDef())
if (!TargetRegisterInfo::isVirtualRegister(Reg))
continue;
- bool isNew = RegSeen.insert(Reg);
+ bool isNew = RegSeen.insert(Reg).second;
if (MO.isDef())
Defs.push_back(Reg);
else if (!isNew && isOperandKill(MO, MRI)) {
assert (MI.mayLoad() && "Expected MI that loads!");
for (MachineInstr::mmo_iterator I = MI.memoperands_begin(),
E = MI.memoperands_end(); I != E; ++I) {
- if (const Value *V = (*I)->getValue()) {
- if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V))
- if (PSV == PSV->getGOT() || PSV == PSV->getConstantPool())
- return true;
+ if (const PseudoSourceValue *PSV = (*I)->getPseudoValue()) {
+ if (PSV == PSV->getGOT() || PSV == PSV->getConstantPool())
+ return true;
}
}
return false;
unsigned Reg = MO->getReg();
if (!TargetRegisterInfo::isVirtualRegister(Reg))
continue;
- for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
- UE = MRI->use_end(); UI != UE; ++UI) {
- MachineInstr *UseMI = &*UI;
+ for (MachineInstr &UseMI : MRI->use_instructions(Reg)) {
// A PHI may cause a copy to be inserted.
- if (UseMI->isPHI()) {
+ if (UseMI.isPHI()) {
// A PHI inside the loop causes a copy because the live range of Reg is
// extended across the PHI.
- if (CurLoop->contains(UseMI))
+ if (CurLoop->contains(&UseMI))
return true;
// A PHI in an exit block can cause a copy to be inserted if the PHI
// has multiple predecessors in the loop with different values.
// For now, approximate by rejecting all exit blocks.
- if (isExitBlock(UseMI->getParent()))
+ if (isExitBlock(UseMI.getParent()))
return true;
continue;
}
// Look past copies as well.
- if (UseMI->isCopy() && CurLoop->contains(UseMI))
- Work.push_back(UseMI);
+ if (UseMI.isCopy() && CurLoop->contains(&UseMI))
+ Work.push_back(&UseMI);
}
}
} while (!Work.empty());
if (!InstrItins || InstrItins->isEmpty() || MRI->use_nodbg_empty(Reg))
return false;
- for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg),
- E = MRI->use_nodbg_end(); I != E; ++I) {
- MachineInstr *UseMI = &*I;
- if (UseMI->isCopyLike())
+ for (MachineInstr &UseMI : MRI->use_nodbg_instructions(Reg)) {
+ if (UseMI.isCopyLike())
continue;
- if (!CurLoop->contains(UseMI->getParent()))
+ if (!CurLoop->contains(UseMI.getParent()))
continue;
- for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = UseMI->getOperand(i);
+ for (unsigned i = 0, e = UseMI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = UseMI.getOperand(i);
if (!MO.isReg() || !MO.isUse())
continue;
unsigned MOReg = MO.getReg();
if (MOReg != Reg)
continue;
- if (TII->hasHighOperandLatency(InstrItins, MRI, &MI, DefIdx, UseMI, i))
+ if (TII->hasHighOperandLatency(InstrItins, MRI, &MI, DefIdx, &UseMI, i))
return true;
}
/// IsCheapInstruction - Return true if the instruction is marked "cheap" or
/// the operand latency between its def and a use is one or less.
bool MachineLICM::IsCheapInstruction(MachineInstr &MI) const {
- if (MI.isAsCheapAsAMove() || MI.isCopyLike())
+ if (TII->isAsCheapAsAMove(&MI) || MI.isCopyLike())
return true;
if (!InstrItins || InstrItins->isEmpty())
return false;
// Don't hoist cheap instructions if they would increase register pressure,
// even if we're under the limit.
- if (CheapInstr)
+ if (CheapInstr && !HoistCheapInsts)
return true;
for (unsigned i = BackTrace.size(); i != 0; --i) {
- SmallVector<unsigned, 8> &RP = BackTrace[i-1];
+ SmallVectorImpl<unsigned> &RP = BackTrace[i-1];
if (RP[RCId] + Cost >= Limit)
return true;
}
// Update register pressure of blocks from loop header to current block.
for (unsigned i = 0, e = BackTrace.size(); i != e; ++i) {
- SmallVector<unsigned, 8> &RP = BackTrace[i];
+ SmallVectorImpl<unsigned> &RP = BackTrace[i];
for (DenseMap<unsigned, int>::iterator CI = Cost.begin(), CE = Cost.end();
CI != CE; ++CI) {
unsigned RCId = CI->first;
MachineInstr *MachineLICM::ExtractHoistableLoad(MachineInstr *MI) {
// Don't unfold simple loads.
if (MI->canFoldAsLoad())
- return 0;
+ return nullptr;
// If not, we may be able to unfold a load and hoist that.
// First test whether the instruction is loading from an amenable
// memory location.
if (!MI->isInvariantLoad(AA))
- return 0;
+ return nullptr;
// Next determine the register class for a temporary register.
unsigned LoadRegIndex;
/*UnfoldLoad=*/true,
/*UnfoldStore=*/false,
&LoadRegIndex);
- if (NewOpc == 0) return 0;
+ if (NewOpc == 0) return nullptr;
const MCInstrDesc &MID = TII->get(NewOpc);
- if (MID.getNumDefs() != 1) return 0;
- const TargetRegisterClass *RC = TII->getRegClass(MID, LoadRegIndex, TRI);
+ if (MID.getNumDefs() != 1) return nullptr;
+ MachineFunction &MF = *MI->getParent()->getParent();
+ const TargetRegisterClass *RC = TII->getRegClass(MID, LoadRegIndex, TRI, MF);
// Ok, we're unfolding. Create a temporary register and do the unfold.
unsigned Reg = MRI->createVirtualRegister(RC);
- MachineFunction &MF = *MI->getParent()->getParent();
SmallVector<MachineInstr *, 2> NewMIs;
bool Success =
TII->unfoldMemoryOperand(MF, MI, Reg,
if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) {
NewMIs[0]->eraseFromParent();
NewMIs[1]->eraseFromParent();
- return 0;
+ return nullptr;
}
// Update register pressure for the unfolded instruction.
for (MachineBasicBlock::iterator I = BB->begin(),E = BB->end(); I != E; ++I) {
const MachineInstr *MI = &*I;
unsigned Opcode = MI->getOpcode();
- DenseMap<unsigned, std::vector<const MachineInstr*> >::iterator
- CI = CSEMap.find(Opcode);
- if (CI != CSEMap.end())
- CI->second.push_back(MI);
- else {
- std::vector<const MachineInstr*> CSEMIs;
- CSEMIs.push_back(MI);
- CSEMap.insert(std::make_pair(Opcode, CSEMIs));
- }
+ CSEMap[Opcode].push_back(MI);
}
}
std::vector<const MachineInstr*> &PrevMIs) {
for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) {
const MachineInstr *PrevMI = PrevMIs[i];
- if (TII->produceSameValue(MI, PrevMI, (PreRegAlloc ? MRI : 0)))
+ if (TII->produceSameValue(MI, PrevMI, (PreRegAlloc ? MRI : nullptr)))
return PrevMI;
}
- return 0;
+ return nullptr;
}
bool MachineLICM::EliminateCSE(MachineInstr *MI,
if (CI == CSEMap.end() || MI->isImplicitDef())
return false;
- return LookForDuplicate(MI, CI->second) != 0;
+ return LookForDuplicate(MI, CI->second) != nullptr;
}
/// Hoist - When an instruction is found to use only loop invariant operands
// Add to the CSE map.
if (CI != CSEMap.end())
CI->second.push_back(MI);
- else {
- std::vector<const MachineInstr*> CSEMIs;
- CSEMIs.push_back(MI);
- CSEMap.insert(std::make_pair(Opcode, CSEMIs));
- }
+ else
+ CSEMap[Opcode].push_back(MI);
}
++NumHoisted;
// If we've tried to get a preheader and failed, don't try again.
if (CurPreheader == reinterpret_cast<MachineBasicBlock *>(-1))
- return 0;
+ return nullptr;
if (!CurPreheader) {
CurPreheader = CurLoop->getLoopPreheader();
MachineBasicBlock *Pred = CurLoop->getLoopPredecessor();
if (!Pred) {
CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
- return 0;
+ return nullptr;
}
CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), this);
if (!CurPreheader) {
CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
- return 0;
+ return nullptr;
}
}
}