diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-14 21:41:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-06-22 18:20:56 +0000 |
commit | bdd1243df58e60e85101c09001d9812a789b6bc4 (patch) | |
tree | a1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp | |
parent | 781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff) | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp | 79 |
1 files changed, 53 insertions, 26 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp index c6756b1d3737..cd8644029530 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineCSE.cpp @@ -60,6 +60,11 @@ STATISTIC(NumCrossBBCSEs, "Number of cross-MBB physreg referencing CS eliminated"); STATISTIC(NumCommutes, "Number of copies coalesced after commuting"); +// Threshold to avoid excessive cost to compute isProfitableToCSE. +static cl::opt<int> + CSUsesThreshold("csuses-threshold", cl::Hidden, cl::init(1024), + cl::desc("Threshold for the size of CSUses")); + namespace { class MachineCSE : public MachineFunctionPass { @@ -140,7 +145,7 @@ namespace { DenseMap<MachineDomTreeNode*, unsigned> &OpenChildren); bool PerformCSE(MachineDomTreeNode *Node); - bool isPRECandidate(MachineInstr *MI); + bool isPRECandidate(MachineInstr *MI, SmallSet<MCRegister, 8> &PhysRefs); bool ProcessBlockPRE(MachineDominatorTree *MDT, MachineBasicBlock *MBB); bool PerformSimplePRE(MachineDominatorTree *DT); /// Heuristics to see if it's profitable to move common computations of MBB @@ -174,14 +179,14 @@ bool MachineCSE::PerformTrivialCopyPropagation(MachineInstr *MI, if (!MO.isReg() || !MO.isUse()) continue; Register Reg = MO.getReg(); - if (!Register::isVirtualRegister(Reg)) + if (!Reg.isVirtual()) continue; bool OnlyOneUse = MRI->hasOneNonDBGUse(Reg); MachineInstr *DefMI = MRI->getVRegDef(Reg); if (!DefMI->isCopy()) continue; Register SrcReg = DefMI->getOperand(1).getReg(); - if (!Register::isVirtualRegister(SrcReg)) + if (!SrcReg.isVirtual()) continue; if (DefMI->getOperand(0).getSubReg()) continue; @@ -260,8 +265,10 @@ bool MachineCSE::isPhysDefTriviallyDead( } static bool isCallerPreservedOrConstPhysReg(MCRegister Reg, + const MachineOperand &MO, const MachineFunction &MF, - const TargetRegisterInfo &TRI) { + const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII) { // MachineRegisterInfo::isConstantPhysReg directly called by // MachineRegisterInfo::isCallerPreservedOrConstPhysReg expects the // reserved registers to be frozen. That doesn't cause a problem post-ISel as @@ -270,7 +277,7 @@ static bool isCallerPreservedOrConstPhysReg(MCRegister Reg, // It does cause issues mid-GlobalISel, however, hence the additional // reservedRegsFrozen check. const MachineRegisterInfo &MRI = MF.getRegInfo(); - return TRI.isCallerPreservedPhysReg(Reg, MF) || + return TRI.isCallerPreservedPhysReg(Reg, MF) || TII.isIgnorableUse(MO) || (MRI.reservedRegsFrozen() && MRI.isConstantPhysReg(Reg)); } @@ -290,10 +297,11 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI, Register Reg = MO.getReg(); if (!Reg) continue; - if (Register::isVirtualRegister(Reg)) + if (Reg.isVirtual()) continue; // Reading either caller preserved or constant physregs is ok. - if (!isCallerPreservedOrConstPhysReg(Reg.asMCReg(), *MI->getMF(), *TRI)) + if (!isCallerPreservedOrConstPhysReg(Reg.asMCReg(), MO, *MI->getMF(), *TRI, + *TII)) for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) PhysRefs.insert(*AI); } @@ -309,7 +317,7 @@ bool MachineCSE::hasLivePhysRegDefUses(const MachineInstr *MI, Register Reg = MO.getReg(); if (!Reg) continue; - if (Register::isVirtualRegister(Reg)) + if (Reg.isVirtual()) continue; // Check against PhysRefs even if the def is "dead". if (PhysRefs.count(Reg.asMCReg())) @@ -384,7 +392,7 @@ bool MachineCSE::PhysRegDefsReach(MachineInstr *CSMI, MachineInstr *MI, if (!MO.isReg() || !MO.isDef()) continue; Register MOReg = MO.getReg(); - if (Register::isVirtualRegister(MOReg)) + if (MOReg.isVirtual()) continue; if (PhysRefs.count(MOReg.asMCReg())) return false; @@ -440,18 +448,26 @@ bool MachineCSE::isProfitableToCSE(Register CSReg, Register Reg, // If CSReg is used at all uses of Reg, CSE should not increase register // pressure of CSReg. bool MayIncreasePressure = true; - if (Register::isVirtualRegister(CSReg) && Register::isVirtualRegister(Reg)) { + if (CSReg.isVirtual() && Reg.isVirtual()) { MayIncreasePressure = false; SmallPtrSet<MachineInstr*, 8> CSUses; + int NumOfUses = 0; for (MachineInstr &MI : MRI->use_nodbg_instructions(CSReg)) { CSUses.insert(&MI); - } - for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) { - if (!CSUses.count(&MI)) { + // Too costly to compute if NumOfUses is very large. Conservatively assume + // MayIncreasePressure to avoid spending too much time here. + if (++NumOfUses > CSUsesThreshold) { MayIncreasePressure = true; break; } } + if (!MayIncreasePressure) + for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) { + if (!CSUses.count(&MI)) { + MayIncreasePressure = true; + break; + } + } } if (!MayIncreasePressure) return true; @@ -468,7 +484,7 @@ bool MachineCSE::isProfitableToCSE(Register CSReg, Register Reg, // of the redundant computation are copies, do not cse. bool HasVRegUse = false; for (const MachineOperand &MO : MI->operands()) { - if (MO.isReg() && MO.isUse() && Register::isVirtualRegister(MO.getReg())) { + if (MO.isReg() && MO.isUse() && MO.getReg().isVirtual()) { HasVRegUse = true; break; } @@ -632,8 +648,7 @@ bool MachineCSE::ProcessBlockCSE(MachineBasicBlock *MBB) { continue; } - assert(Register::isVirtualRegister(OldReg) && - Register::isVirtualRegister(NewReg) && + assert(OldReg.isVirtual() && NewReg.isVirtual() && "Do not CSE physical register defs!"); if (!isProfitableToCSE(NewReg, OldReg, CSMI->getParent(), &MI)) { @@ -785,22 +800,24 @@ bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) { // We use stronger checks for PRE candidate rather than for CSE ones to embrace // checks inside ProcessBlockCSE(), not only inside isCSECandidate(). This helps // to exclude instrs created by PRE that won't be CSEed later. -bool MachineCSE::isPRECandidate(MachineInstr *MI) { +bool MachineCSE::isPRECandidate(MachineInstr *MI, + SmallSet<MCRegister, 8> &PhysRefs) { if (!isCSECandidate(MI) || MI->isNotDuplicable() || MI->mayLoad() || - MI->isAsCheapAsAMove() || + TII->isAsCheapAsAMove(*MI) || MI->getNumDefs() != 1 || MI->getNumExplicitDefs() != 1) return false; - for (const auto &def : MI->defs()) - if (!Register::isVirtualRegister(def.getReg())) - return false; - - for (const auto &use : MI->uses()) - if (use.isReg() && !Register::isVirtualRegister(use.getReg())) - return false; + for (const MachineOperand &MO : MI->operands()) { + if (MO.isReg() && !MO.getReg().isVirtual()) { + if (MO.isDef()) + return false; + else + PhysRefs.insert(MO.getReg()); + } + } return true; } @@ -809,7 +826,8 @@ bool MachineCSE::ProcessBlockPRE(MachineDominatorTree *DT, MachineBasicBlock *MBB) { bool Changed = false; for (MachineInstr &MI : llvm::make_early_inc_range(*MBB)) { - if (!isPRECandidate(&MI)) + SmallSet<MCRegister, 8> PhysRefs; + if (!isPRECandidate(&MI, PhysRefs)) continue; if (!PREMap.count(&MI)) { @@ -845,6 +863,15 @@ bool MachineCSE::ProcessBlockPRE(MachineDominatorTree *DT, if (MI.isConvergent() && CMBB != MBB) continue; + // If this instruction uses physical registers then we can only do PRE + // if it's using the value that is live at the place we're hoisting to. + bool NonLocal; + PhysDefVector PhysDefs; + if (!PhysRefs.empty() && + !PhysRegDefsReach(&*(CMBB->getFirstTerminator()), &MI, PhysRefs, + PhysDefs, NonLocal)) + continue; + assert(MI.getOperand(0).isDef() && "First operand of instr with one explicit def must be this def"); Register VReg = MI.getOperand(0).getReg(); |