23 #define DEBUG_TYPE "machine-licm"
47 cl::desc(
"MachineLICM should avoid speculation"),
51 "Number of machine instructions hoisted out of loops");
53 "Number of instructions hoisted in low reg pressure situation");
55 "Number of high latency instructions hoisted");
57 "Number of hoisted machine instructions CSEed");
59 "Number of machine instructions hoisted out of loops post regalloc");
87 return std::find(ExitBlocks.begin(), ExitBlocks.end(), MBB) !=
114 unsigned SpeculationState;
123 explicit MachineLICM(
bool PreRA) :
139 virtual void releaseMemory() {
144 for (
DenseMap<
unsigned,std::vector<const MachineInstr*> >::iterator
145 CI = CSEMap.
begin(), CE = CSEMap.end(); CI != CE; ++CI)
152 struct CandidateInfo {
157 :
MI(mi),
Def(def), FI(fi) {}
162 void HoistRegionPostRA();
179 void AddToLiveIns(
unsigned Reg);
247 unsigned Reg,
unsigned OpIdx,
248 unsigned &RCId,
unsigned &RCCost)
const;
268 std::vector<const MachineInstr*> &PrevMIs);
275 DenseMap<
unsigned, std::vector<const MachineInstr*> >::iterator &CI);
300 "Machine Loop Invariant Code Motion",
false,
false)
311 if (!CurLoop->getLoopPredecessor())
315 if (L->getLoopPredecessor())
322 Changed = FirstInLoop =
false;
324 TII =
TM->getInstrInfo();
325 TLI =
TM->getTargetLowering();
326 TRI =
TM->getRegisterInfo();
329 InstrItins =
TM->getInstrItineraryData();
331 PreRegAlloc =
MRI->isSSA();
334 DEBUG(
dbgs() <<
"******** Pre-regalloc Machine LICM: ");
336 DEBUG(
dbgs() <<
"******** Post-regalloc Machine LICM: ");
341 unsigned NumRC = TRI->getNumRegClasses();
344 RegLimit.resize(NumRC);
346 E = TRI->regclass_end();
I != E; ++
I)
347 RegLimit[(*I)->getID()] = TRI->getRegPressureLimit(*
I, MF);
351 MLI = &getAnalysis<MachineLoopInfo>();
352 DT = &getAnalysis<MachineDominatorTree>();
353 AA = &getAnalysis<AliasAnalysis>();
356 while (!Worklist.empty()) {
364 Worklist.append(CurLoop->begin(), CurLoop->end());
368 CurLoop->getExitBlocks(ExitBlocks);
390 if (!(*o)->isStore() || !(*o)->getValue())
393 dyn_cast<const FixedStackPseudoSourceValue>((*o)->getValue())) {
394 if (
Value->getFrameIndex() == FI)
408 bool RuledOut =
false;
409 bool HasNonInvariantUse =
false;
416 if (!StoredFIs.
count(FI) &&
417 MFI->isSpillSlotObjectIndex(FI) &&
420 HasNonInvariantUse =
true;
437 "Not expecting virtual register!");
440 if (Reg && (PhysRegDefs.
test(Reg) || PhysRegClobbers.
test(Reg)))
443 HasNonInvariantUse =
true;
449 PhysRegClobbers.
set(*AI);
469 if (PhysRegDefs.
test(*AS))
470 PhysRegClobbers.
set(*AS);
471 PhysRegDefs.
set(*AS);
473 if (PhysRegClobbers.
test(Reg))
481 if (Def && !RuledOut) {
483 if ((!HasNonInvariantUse && IsLICMCandidate(*MI)) ||
485 Candidates.
push_back(CandidateInfo(MI, Def, FI));
491 void MachineLICM::HoistRegionPostRA() {
496 unsigned NumRegs = TRI->getNumRegs();
505 const std::vector<MachineBasicBlock *> &Blocks = CurLoop->getBlocks();
506 for (
unsigned i = 0, e = Blocks.size(); i != e; ++i) {
512 if (ML && ML->
getHeader()->isLandingPad())
continue;
521 PhysRegDefs.
set(*AI);
524 SpeculationState = SpeculateUnknown;
528 ProcessMI(MI, PhysRegDefs, PhysRegClobbers, StoredFIs, Candidates);
535 if (TI != Preheader->
end()) {
536 for (
unsigned i = 0, e = TI->getNumOperands(); i != e; ++i) {
540 unsigned Reg = MO.
getReg();
556 for (
unsigned i = 0, e = Candidates.
size(); i != e; ++i) {
557 if (Candidates[i].FI != INT_MIN &&
558 StoredFIs.
count(Candidates[i].FI))
561 unsigned Def = Candidates[i].Def;
562 if (!PhysRegClobbers.
test(Def) && !TermRegs.test(Def)) {
569 unsigned Reg = MO.
getReg();
570 if (PhysRegDefs.
test(Reg) ||
571 PhysRegClobbers.
test(Reg)) {
579 HoistPostRA(MI, Candidates[i].Def);
586 void MachineLICM::AddToLiveIns(
unsigned Reg) {
587 const std::vector<MachineBasicBlock *> &Blocks = CurLoop->getBlocks();
588 for (
unsigned i = 0, e = Blocks.size(); i != e; ++i) {
598 if (MO.
getReg() == Reg || TRI->isSuperRegister(Reg, MO.
getReg()))
608 void MachineLICM::HoistPostRA(
MachineInstr *MI,
unsigned Def) {
632 if (SpeculationState != SpeculateUnknown)
633 return SpeculationState == SpeculateFalse;
635 if (BB != CurLoop->getHeader()) {
638 CurLoop->getExitingBlocks(CurrentLoopExitingBlocks);
639 for (
unsigned i = 0, e = CurrentLoopExitingBlocks.
size(); i != e; ++i)
640 if (!DT->dominates(BB, CurrentLoopExitingBlocks[i])) {
641 SpeculationState = SpeculateTrue;
646 SpeculationState = SpeculateFalse;
659 BackTrace.pop_back();
668 if (OpenChildren[Node])
672 ExitScope(Node->getBlock());
676 unsigned Left = --OpenChildren[Parent];
679 ExitScope(Parent->getBlock());
700 assert(Node != 0 &&
"Null dominator tree node?");
706 if (ML && ML->
getHeader()->isLandingPad())
710 if (!CurLoop->contains(BB))
714 const std::vector<MachineDomTreeNode*> &Children = Node->
getChildren();
715 unsigned NumChildren = Children.size();
723 OpenChildren[Node] = NumChildren;
727 for (
int i = (
int)NumChildren-1; i >= 0; --i) {
729 ParentMap[Child] = Node;
732 }
while (!WorkList.
empty());
734 if (Scopes.
size() != 0) {
742 InitRegPressure(Preheader);
746 for (
unsigned i = 0, e = Scopes.
size(); i != e; ++i) {
757 SpeculationState = SpeculateUnknown;
762 if (!Hoist(MI, Preheader))
763 UpdateRegPressure(MI);
768 ExitScopeIfDone(Node, OpenChildren, ParentMap);
779 MachineLICM::getRegisterClassIDAndCost(
const MachineInstr *MI,
780 unsigned Reg,
unsigned OpIdx,
781 unsigned &RCId,
unsigned &RCCost)
const {
788 RCId = TLI->getRepRegClassFor(VT)->getID();
789 RCCost = TLI->getRepRegClassCostFor(VT);
817 unsigned Reg = MO.
getReg();
821 bool isNew = RegSeen.insert(Reg);
822 unsigned RCId, RCCost;
823 getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost);
828 if (isNew && !isKill)
831 else if (!isNew && isKill)
840 void MachineLICM::UpdateRegPressure(
const MachineInstr *MI) {
849 unsigned Reg = MO.
getReg();
853 bool isNew = RegSeen.insert(Reg);
857 unsigned RCId, RCCost;
858 getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost);
867 while (!Defs.
empty()) {
869 unsigned RCId, RCCost;
870 getRegisterClassIDAndCost(MI, Reg, Idx, RCId, RCCost);
879 assert (MI.
mayLoad() &&
"Expected MI that loads!");
882 if (
const Value *V = (*I)->getValue()) {
884 if (PSV == PSV->getGOT() || PSV == PSV->getConstantPool())
896 bool DontMoveAcrossStore =
true;
918 bool MachineLICM::IsLoopInvariantInst(
MachineInstr &I) {
919 if (!IsLICMCandidate(I))
929 unsigned Reg = MO.
getReg();
930 if (Reg == 0)
continue;
942 }
else if (!MO.
isDead()) {
945 }
else if (CurLoop->getHeader()->isLiveIn(Reg)) {
955 assert(
MRI->getVRegDef(Reg) &&
956 "Machine instr not mapped for this vreg?!");
960 if (CurLoop->contains(
MRI->getVRegDef(Reg)))
971 bool MachineLICM::HasLoopPHIUse(
const MachineInstr *MI)
const {
974 MI = Work.pop_back_val();
978 unsigned Reg = MO->
getReg();
982 UE =
MRI->use_end(); UI != UE; ++UI) {
985 if (UseMI->
isPHI()) {
988 if (CurLoop->contains(UseMI))
998 if (UseMI->
isCopy() && CurLoop->contains(UseMI))
999 Work.push_back(UseMI);
1002 }
while (!Work.empty());
1009 bool MachineLICM::HasHighOperandLatency(
MachineInstr &MI,
1010 unsigned DefIdx,
unsigned Reg)
const {
1011 if (!InstrItins || InstrItins->isEmpty() ||
MRI->use_nodbg_empty(Reg))
1015 E =
MRI->use_nodbg_end(); I != E; ++
I) {
1019 if (!CurLoop->contains(UseMI->
getParent()))
1025 unsigned MOReg = MO.
getReg();
1029 if (
TII->hasHighOperandLatency(InstrItins,
MRI, &MI, DefIdx, UseMI, i))
1042 bool MachineLICM::IsCheapInstruction(
MachineInstr &MI)
const {
1045 if (!InstrItins || InstrItins->isEmpty())
1048 bool isCheap =
false;
1050 for (
unsigned i = 0, e = MI.
getNumOperands(); NumDefs && i != e; ++i) {
1055 unsigned Reg = DefMO.
getReg();
1059 if (!
TII->hasLowDefLatency(InstrItins, &MI, i))
1074 if (CI->second <= 0)
1077 unsigned RCId = CI->first;
1078 unsigned Limit = RegLimit[RCId];
1079 int Cost = CI->second;
1086 for (
unsigned i = BackTrace.size(); i != 0; --i) {
1088 if (RP[RCId] + Cost >= Limit)
1099 void MachineLICM::UpdateBackTraceRegPressure(
const MachineInstr *MI) {
1110 unsigned Reg = MO.
getReg();
1114 unsigned RCId, RCCost;
1115 getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost);
1118 if (CI != Cost.
end())
1119 CI->second += RCCost;
1121 Cost.
insert(std::make_pair(RCId, RCCost));
1124 if (CI != Cost.
end())
1125 CI->second -= RCCost;
1127 Cost.
insert(std::make_pair(RCId, -RCCost));
1132 for (
unsigned i = 0, e = BackTrace.size(); i != e; ++i) {
1136 unsigned RCId = CI->first;
1137 RP[RCId] += CI->second;
1144 bool MachineLICM::IsProfitableToHoist(
MachineInstr &MI) {
1160 bool CheapInstr = IsCheapInstruction(MI);
1161 bool CreatesCopy = HasLoopPHIUse(&MI);
1164 if (CheapInstr && CreatesCopy) {
1165 DEBUG(
dbgs() <<
"Won't hoist cheap instr with loop PHI use: " << MI);
1171 if (
TII->isTriviallyReMaterializable(&MI, AA))
1187 unsigned Reg = MO.
getReg();
1191 unsigned RCId, RCCost;
1192 getRegisterClassIDAndCost(&MI, Reg, i, RCId, RCCost);
1194 if (HasHighOperandLatency(MI, i, Reg)) {
1195 DEBUG(
dbgs() <<
"Hoist High Latency: " << MI);
1199 Cost[RCId] += RCCost;
1204 Cost[RCId] -= RCCost;
1210 if (!CanCauseHighRegPressure(Cost, CheapInstr)) {
1211 DEBUG(
dbgs() <<
"Hoist non-reg-pressure: " << MI);
1218 DEBUG(
dbgs() <<
"Won't hoist instr with loop PHI use: " << MI);
1226 (!IsGuaranteedToExecute(MI.
getParent()) && !MayCSE(&MI))) {
1227 DEBUG(
dbgs() <<
"Won't speculate: " << MI);
1233 if (!
TII->isTriviallyReMaterializable(&MI, AA) &&
1235 DEBUG(
dbgs() <<
"Can't remat / high reg-pressure: " << MI);
1254 unsigned LoadRegIndex;
1260 if (NewOpc == 0)
return 0;
1266 unsigned Reg =
MRI->createVirtualRegister(RC);
1270 TII->unfoldMemoryOperand(MF, MI, Reg,
1275 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1277 assert(NewMIs.
size() == 2 &&
1278 "Unfolded a load into multiple instructions!");
1281 MBB->insert(Pos, NewMIs[0]);
1282 MBB->insert(Pos, NewMIs[1]);
1285 if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) {
1286 NewMIs[0]->eraseFromParent();
1287 NewMIs[1]->eraseFromParent();
1292 UpdateRegPressure(NewMIs[1]);
1304 CI = CSEMap.
find(Opcode);
1305 if (CI != CSEMap.
end())
1306 CI->second.push_back(MI);
1308 std::vector<const MachineInstr*> CSEMIs;
1309 CSEMIs.push_back(MI);
1310 CSEMap.
insert(std::make_pair(Opcode, CSEMIs));
1317 std::vector<const MachineInstr*> &PrevMIs) {
1318 for (
unsigned i = 0, e = PrevMIs.size(); i != e; ++i) {
1320 if (
TII->produceSameValue(MI, PrevMI, (PreRegAlloc ?
MRI : 0)))
1327 DenseMap<
unsigned, std::vector<const MachineInstr*> >::iterator &CI) {
1333 if (
const MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
1334 DEBUG(
dbgs() <<
"CSEing " << *MI <<
" with " << *Dup);
1345 MO.
getReg() == Dup->getOperand(i).getReg()) &&
1346 "Instructions with different phys regs are not identical!");
1354 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1355 unsigned Idx = Defs[i];
1357 unsigned DupReg = Dup->getOperand(Idx).getReg();
1362 for (
unsigned j = 0; j != i; ++j)
1363 MRI->setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
1368 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1369 unsigned Idx = Defs[i];
1371 unsigned DupReg = Dup->getOperand(Idx).getReg();
1372 MRI->replaceRegWith(Reg, DupReg);
1373 MRI->clearKillFlags(DupReg);
1388 CI = CSEMap.
find(Opcode);
1394 return LookForDuplicate(MI, CI->second) != 0;
1402 if (!IsLoopInvariantInst(*MI) || !IsProfitableToHoist(*MI)) {
1404 MI = ExtractHoistableLoad(MI);
1405 if (!MI)
return false;
1411 dbgs() <<
"Hoisting " << *
MI;
1413 dbgs() <<
" to MachineBasicBlock "
1416 dbgs() <<
" from MachineBasicBlock "
1424 InitCSEMap(Preheader);
1425 FirstInLoop =
false;
1431 CI = CSEMap.
find(Opcode);
1432 if (!EliminateCSE(MI, CI)) {
1437 UpdateBackTraceRegPressure(MI);
1449 if (CI != CSEMap.
end())
1450 CI->second.push_back(MI);
1452 std::vector<const MachineInstr*> CSEMIs;
1453 CSEMIs.push_back(MI);
1454 CSEMap.
insert(std::make_pair(Opcode, CSEMIs));
1469 if (CurPreheader == reinterpret_cast<MachineBasicBlock *>(-1))
1472 if (!CurPreheader) {
1473 CurPreheader = CurLoop->getLoopPreheader();
1474 if (!CurPreheader) {
1482 if (!CurPreheader) {
1488 return CurPreheader;
unsigned succ_size() const
void push_back(const T &Elt)
const MachineFunction * getParent() const
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions. Register definitions always occur...
char & MachineLICMID
MachineLICM - This pass performs LICM on machine instructions.
std::vector< unsigned >::const_iterator livein_iterator
iterator getFirstTerminator()
static bool isVirtualRegister(unsigned Reg)
INITIALIZE_PASS_BEGIN(MachineLICM,"machinelicm","Machine Loop Invariant Code Motion", false, false) INITIALIZE_PASS_END(MachineLICM
void addLiveIn(unsigned Reg)
void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
const MCInstrDesc & getDesc() const
LoopT * getParentLoop() const
STATISTIC(NumHoisted,"Number of machine instructions hoisted out of loops")
bool canFoldAsLoad(QueryType Type=IgnoreBundle) const
BlockT * getHeader() const
livein_iterator livein_begin() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const HexagonInstrInfo * TII
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val()
static bool isOperandKill(const MachineOperand &MO, MachineRegisterInfo *MRI)
Machine Loop Invariant Code false
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P)
Abstract Stack Frame Information.
ID
LLVM Calling Convention Representation.
static cl::opt< bool > AvoidSpeculation("avoid-speculation", cl::desc("MachineLICM should avoid speculation"), cl::init(true), cl::Hidden)
unsigned getNumOperands() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
COFF::MachineTypes Machine
static bool isLoadFromGOTOrConstantPool(MachineInstr &MI)
const BasicBlock * getBasicBlock() const
const MachineBasicBlock * getParent() const
bool isImplicitDef() const
mmo_iterator memoperands_end() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value. See class MCOperandInfo.
bool isAsCheapAsAMove(QueryType Type=AllInBundle) const
livein_iterator livein_end() const
const MachineOperand & getOperand(unsigned i) const
static bool InstructionStoresToFI(const MachineInstr *MI, int FI)
bool isInvariantLoad(AliasAnalysis *AA) const
#define INITIALIZE_AG_DEPENDENCY(depName)
pred_iterator pred_begin()
void initializeMachineLICMPass(PassRegistry &)
void setIsKill(bool Val=true)
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
const uint32_t * getRegMask() const
bool test(unsigned Idx) const
MachineFrameInfo * getFrameInfo()
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
StringRef getName() const
Machine Loop Invariant Code static false bool LoopIsOuterMostWithPredecessor(MachineLoop *CurLoop)
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA, bool &SawStore) const
bool count(const T &V) const
count - Return true if the element is in the set.
static bool isPhysicalRegister(unsigned Reg)
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
bool isLiveIn(unsigned Reg) const
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
bool hasOneNonDBGUse(unsigned RegNo) const
const TargetMachine & getTarget() const
unsigned getReg() const
getReg - Returns the register number.
Machine Loop Invariant Code Motion
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
LLVM Value Representation.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
static bool isExitBlock(BasicBlock *BB, const SmallVectorImpl< BasicBlock * > &ExitBlocks)
isExitBlock - Return true if the specified block is in the list.
vt_iterator vt_begin() const
const MCRegisterInfo & MRI
StringRef getName() const
iterator find(const KeyT &Val)
unsigned pred_size() const
const TargetRegisterClass *const * regclass_iterator
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.