80#define DEBUG_TYPE "machine-cp" 
   82STATISTIC(NumDeletes, 
"Number of dead copies deleted");
 
   83STATISTIC(NumCopyForwards, 
"Number of copy uses forwarded");
 
   84STATISTIC(NumCopyBackwardPropagated, 
"Number of copy defs backward propagated");
 
   85STATISTIC(SpillageChainsLength, 
"Length of spillage chains");
 
   86STATISTIC(NumSpillageChains, 
"Number of spillage chains");
 
   88              "Controls which register COPYs are forwarded");
 
   97static std::optional<DestSourcePair> isCopyInstr(
const MachineInstr &
MI,
 
  101    return TII.isCopyInstr(
MI);
 
  104    return std::optional<DestSourcePair>(
 
  112    MachineInstr *MI = 
nullptr;
 
  113    MachineInstr *LastSeenUseInCopy = 
nullptr;
 
  114    SmallPtrSet<MachineInstr *, 4> SrcUsers;
 
  119  DenseMap<MCRegUnit, CopyInfo> Copies;
 
  124  DenseMap<const uint32_t *, BitVector> RegMaskToPreservedRegUnits;
 
  128  BitVector &getPreservedRegUnits(
const MachineOperand &RegMaskOp,
 
  129                                  const TargetRegisterInfo &
TRI) {
 
  130    const uint32_t *RegMask = RegMaskOp.
getRegMask();
 
  131    auto [It, 
Inserted] = RegMaskToPreservedRegUnits.try_emplace(RegMask);
 
  135      BitVector &PreservedRegUnits = It->second;
 
  137      PreservedRegUnits.
resize(
TRI.getNumRegUnits());
 
  138      for (
unsigned SafeReg = 0, 
E = 
TRI.getNumRegs(); SafeReg < 
E; ++SafeReg)
 
  140          for (
auto SafeUnit : 
TRI.regunits(SafeReg))
 
  141            PreservedRegUnits.
set(SafeUnit);
 
  143      return PreservedRegUnits;
 
  150                           const TargetRegisterInfo &
TRI) {
 
  151    for (MCRegister 
Reg : Regs) {
 
  154        auto CI = Copies.find(Unit);
 
  155        if (CI != Copies.end())
 
  156          CI->second.Avail = 
false;
 
  162  void invalidateRegister(MCRegister 
Reg, 
const TargetRegisterInfo &
TRI,
 
  163                          const TargetInstrInfo &
TII, 
bool UseCopyInstr) {
 
  168    SmallSet<MCRegUnit, 8> RegUnitsToInvalidate;
 
  169    auto InvalidateCopy = [&](MachineInstr *
MI) {
 
  170      std::optional<DestSourcePair> CopyOperands =
 
  171          isCopyInstr(*
MI, 
TII, UseCopyInstr);
 
  172      assert(CopyOperands && 
"Expect copy");
 
  174      auto Dest = 
TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
 
  175      auto Src = 
TRI.regunits(CopyOperands->Source->getReg().asMCReg());
 
  181      auto I = Copies.find(Unit);
 
  182      if (
I != Copies.end()) {
 
  183        if (MachineInstr *
MI = 
I->second.MI)
 
  185        if (MachineInstr *
MI = 
I->second.LastSeenUseInCopy)
 
  189    for (
MCRegUnit Unit : RegUnitsToInvalidate)
 
  194  void clobberRegUnit(
MCRegUnit Unit, 
const TargetRegisterInfo &
TRI,
 
  195                      const TargetInstrInfo &
TII, 
bool UseCopyInstr) {
 
  196    auto I = Copies.find(Unit);
 
  197    if (
I != Copies.end()) {
 
  200      markRegsUnavailable(
I->second.DefRegs, 
TRI);
 
  203      if (MachineInstr *
MI = 
I->second.MI) {
 
  204        std::optional<DestSourcePair> CopyOperands =
 
  205            isCopyInstr(*
MI, 
TII, UseCopyInstr);
 
  207        MCRegister 
Def = CopyOperands->Destination->getReg().asMCReg();
 
  208        MCRegister Src = CopyOperands->Source->getReg().asMCReg();
 
  210        markRegsUnavailable(Def, 
TRI);
 
  225          auto SrcCopy = Copies.find(SrcUnit);
 
  226          if (SrcCopy != Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
 
  229            for (
auto itr = SrcCopy->second.DefRegs.begin();
 
  230                 itr != SrcCopy->second.DefRegs.end(); itr++) {
 
  232                SrcCopy->second.DefRegs.erase(itr);
 
  238                if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
 
  239                  Copies.erase(SrcCopy);
 
  253  void clobberRegister(MCRegister 
Reg, 
const TargetRegisterInfo &
TRI,
 
  254                       const TargetInstrInfo &
TII, 
bool UseCopyInstr) {
 
  256      clobberRegUnit(Unit, 
TRI, 
TII, UseCopyInstr);
 
  263  bool trackSrcUsers(MCRegister 
Reg, MachineInstr &
MI,
 
  264                     const TargetRegisterInfo &
TRI, 
const TargetInstrInfo &
TII,
 
  267    MachineInstr *AvailCopy = findCopyDefViaUnit(RU, 
TRI);
 
  271    std::optional<DestSourcePair> CopyOperands =
 
  272        isCopyInstr(*AvailCopy, 
TII, UseCopyInstr);
 
  273    Register Src = CopyOperands->Source->getReg();
 
  279    auto I = Copies.find(RU);
 
  280    if (
I == Copies.end())
 
  283    I->second.SrcUsers.insert(&
MI);
 
  288  SmallPtrSet<MachineInstr *, 4> getSrcUsers(MCRegister 
Reg,
 
  289                                             const TargetRegisterInfo &
TRI) {
 
  291    auto I = Copies.find(RU);
 
  292    if (
I == Copies.end())
 
  294    return I->second.SrcUsers;
 
  298  void trackCopy(MachineInstr *
MI, 
const TargetRegisterInfo &
TRI,
 
  299                 const TargetInstrInfo &
TII, 
bool UseCopyInstr) {
 
  300    std::optional<DestSourcePair> CopyOperands =
 
  301        isCopyInstr(*
MI, 
TII, UseCopyInstr);
 
  302    assert(CopyOperands && 
"Tracking non-copy?");
 
  304    MCRegister Src = CopyOperands->Source->getReg().asMCReg();
 
  305    MCRegister 
Def = CopyOperands->Destination->getReg().asMCReg();
 
  309      Copies[
Unit] = {
MI, 
nullptr, {}, {}, 
true};
 
  316        Copy.DefRegs.push_back(Def);
 
  317      Copy.LastSeenUseInCopy = 
MI;
 
  321  bool hasAnyCopies() {
 
  322    return !Copies.empty();
 
  325  MachineInstr *findCopyForUnit(
MCRegUnit RegUnit,
 
  326                                const TargetRegisterInfo &
TRI,
 
  327                                bool MustBeAvailable = 
false) {
 
  328    auto CI = Copies.find(RegUnit);
 
  329    if (CI == Copies.end())
 
  331    if (MustBeAvailable && !CI->second.Avail)
 
  333    return CI->second.MI;
 
  336  MachineInstr *findCopyDefViaUnit(
MCRegUnit RegUnit,
 
  337                                   const TargetRegisterInfo &
TRI) {
 
  338    auto CI = Copies.find(RegUnit);
 
  339    if (CI == Copies.end())
 
  341    if (CI->second.DefRegs.size() != 1)
 
  343    MCRegUnit RU = *
TRI.regunits(CI->second.DefRegs[0]).begin();
 
  344    return findCopyForUnit(RU, 
TRI, 
true);
 
  347  MachineInstr *findAvailBackwardCopy(MachineInstr &
I, MCRegister 
Reg,
 
  348                                      const TargetRegisterInfo &
TRI,
 
  349                                      const TargetInstrInfo &
TII,
 
  352    MachineInstr *AvailCopy = findCopyDefViaUnit(RU, 
TRI);
 
  357    std::optional<DestSourcePair> CopyOperands =
 
  358        isCopyInstr(*AvailCopy, 
TII, UseCopyInstr);
 
  359    Register AvailSrc = CopyOperands->Source->getReg();
 
  360    Register AvailDef = CopyOperands->Destination->getReg();
 
  361    if (!
TRI.isSubRegisterEq(AvailSrc, 
Reg))
 
  364    for (
const MachineInstr &
MI :
 
  366      for (
const MachineOperand &MO : 
MI.operands())
 
  369          if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
 
  375  MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister 
Reg,
 
  376                              const TargetRegisterInfo &
TRI,
 
  377                              const TargetInstrInfo &
TII, 
bool UseCopyInstr) {
 
  381    MachineInstr *AvailCopy =
 
  382        findCopyForUnit(RU, 
TRI, 
true);
 
  387    std::optional<DestSourcePair> CopyOperands =
 
  388        isCopyInstr(*AvailCopy, 
TII, UseCopyInstr);
 
  389    Register AvailSrc = CopyOperands->Source->getReg();
 
  390    Register AvailDef = CopyOperands->Destination->getReg();
 
  391    if (!
TRI.isSubRegisterEq(AvailDef, 
Reg))
 
  396    for (
const MachineInstr &
MI :
 
  398      for (
const MachineOperand &MO : 
MI.operands())
 
  400          if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
 
  407  MachineInstr *findLastSeenDefInCopy(
const MachineInstr &Current,
 
  409                                      const TargetRegisterInfo &
TRI,
 
  410                                      const TargetInstrInfo &
TII,
 
  413    auto CI = Copies.find(RU);
 
  414    if (CI == Copies.end() || !CI->second.Avail)
 
  417    MachineInstr *DefCopy = CI->second.MI;
 
  418    std::optional<DestSourcePair> CopyOperands =
 
  419        isCopyInstr(*DefCopy, 
TII, UseCopyInstr);
 
  420    Register Def = CopyOperands->Destination->getReg();
 
  421    if (!
TRI.isSubRegisterEq(Def, 
Reg))
 
  424    for (
const MachineInstr &
MI :
 
  425         make_range(
static_cast<const MachineInstr *
>(DefCopy)->getIterator(),
 
  427      for (
const MachineOperand &MO : 
MI.operands())
 
  429          if (MO.clobbersPhysReg(Def)) {
 
  439  MachineInstr *findLastSeenUseInCopy(MCRegister 
Reg,
 
  440                                      const TargetRegisterInfo &
TRI) {
 
  442    auto CI = Copies.find(RU);
 
  443    if (CI == Copies.end())
 
  445    return CI->second.LastSeenUseInCopy;
 
  453class MachineCopyPropagation {
 
  454  const TargetRegisterInfo *TRI = 
nullptr;
 
  455  const TargetInstrInfo *TII = 
nullptr;
 
  456  const MachineRegisterInfo *MRI = 
nullptr;
 
  462  MachineCopyPropagation(
bool CopyInstr = 
false)
 
  465  bool run(MachineFunction &MF);
 
  468  typedef enum { DebugUse = 
false, RegularUse = 
true } DebugType;
 
  470  void ReadRegister(MCRegister 
Reg, MachineInstr &Reader, DebugType DT);
 
  471  void readSuccessorLiveIns(
const MachineBasicBlock &
MBB);
 
  472  void ForwardCopyPropagateBlock(MachineBasicBlock &
MBB);
 
  473  void BackwardCopyPropagateBlock(MachineBasicBlock &
MBB);
 
  474  void EliminateSpillageCopies(MachineBasicBlock &
MBB);
 
  475  bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
 
  476  void forwardUses(MachineInstr &
MI);
 
  477  void propagateDefs(MachineInstr &
MI);
 
  478  bool isForwardableRegClassCopy(
const MachineInstr &Copy,
 
  479                                 const MachineInstr &UseI, 
unsigned UseIdx);
 
  480  bool isBackwardPropagatableRegClassCopy(
const MachineInstr &Copy,
 
  481                                          const MachineInstr &UseI,
 
  483  bool hasImplicitOverlap(
const MachineInstr &
MI, 
const MachineOperand &Use);
 
  484  bool hasOverlappingMultipleDef(
const MachineInstr &
MI,
 
  485                                 const MachineOperand &MODef, 
Register Def);
 
  486  bool canUpdateSrcUsers(
const MachineInstr &Copy,
 
  487                         const MachineOperand &CopySrc);
 
  490  SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
 
  493  DenseMap<MachineInstr *, SmallPtrSet<MachineInstr *, 2>> CopyDbgUsers;
 
  497  bool Changed = 
false;
 
  506  MachineCopyPropagationLegacy(
bool UseCopyInstr = 
false)
 
  507      : MachineFunctionPass(ID), UseCopyInstr(UseCopyInstr) {}
 
  509  void getAnalysisUsage(AnalysisUsage &AU)
 const override {
 
  514  bool runOnMachineFunction(MachineFunction &MF) 
override;
 
  516  MachineFunctionProperties getRequiredProperties()
 const override {
 
  517    return MachineFunctionProperties().setNoVRegs();
 
  523char MachineCopyPropagationLegacy::ID = 0;
 
  528                "Machine Copy Propagation Pass", 
false, 
false)
 
  536    if (MachineInstr *Copy = Tracker.findCopyForUnit(Unit, *TRI)) {
 
  537      if (DT == RegularUse) {
 
  538        LLVM_DEBUG(dbgs() << 
"MCP: Copy is used - not dead: "; Copy->dump());
 
  539        MaybeDeadCopies.remove(Copy);
 
  541        CopyDbgUsers[Copy].insert(&Reader);
 
 
  547void MachineCopyPropagation::readSuccessorLiveIns(
 
  549  if (MaybeDeadCopies.empty())
 
  554    for (
const auto &LI : Succ->liveins()) {
 
  555      for (MCRegUnitMaskIterator 
U(LI.PhysReg, 
TRI); 
U.isValid(); ++U) {
 
  557        if ((Mask & LI.LaneMask).any()) {
 
  558          if (MachineInstr *Copy = Tracker.findCopyForUnit(Unit, *
TRI))
 
  559            MaybeDeadCopies.remove(Copy);
 
  576  std::optional<DestSourcePair> CopyOperands =
 
  577      isCopyInstr(PreviousCopy, *
TII, UseCopyInstr);
 
  578  MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
 
  579  MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
 
  580  if (Src == PreviousSrc && Def == PreviousDef)
 
  582  if (!
TRI->isSubRegister(PreviousSrc, Src))
 
  584  unsigned SubIdx = 
TRI->getSubRegIndex(PreviousSrc, Src);
 
  585  return SubIdx == 
TRI->getSubRegIndex(PreviousDef, Def);
 
 
  591bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
 
  592                                              MCRegister Src, MCRegister Def) {
 
  595  if (
MRI->isReserved(Src) || 
MRI->isReserved(Def))
 
  599  MachineInstr *PrevCopy =
 
  600      Tracker.findAvailCopy(Copy, Def, *
TRI, *
TII, UseCopyInstr);
 
  604  auto PrevCopyOperands = isCopyInstr(*PrevCopy, *
TII, UseCopyInstr);
 
  606  if (PrevCopyOperands->Destination->isDead())
 
  615  std::optional<DestSourcePair> CopyOperands =
 
  616      isCopyInstr(Copy, *
TII, UseCopyInstr);
 
  619  Register CopyDef = CopyOperands->Destination->getReg();
 
  620  assert(CopyDef == Src || CopyDef == Def);
 
  621  for (MachineInstr &
MI :
 
  623    MI.clearRegisterKills(CopyDef, 
TRI);
 
  626  if (!CopyOperands->Source->isUndef()) {
 
  627    PrevCopy->
getOperand(PrevCopyOperands->Source->getOperandNo())
 
  631  Copy.eraseFromParent();
 
  637bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
 
  638    const MachineInstr &Copy, 
const MachineInstr &UseI, 
unsigned UseIdx) {
 
  639  std::optional<DestSourcePair> CopyOperands =
 
  640      isCopyInstr(Copy, *
TII, UseCopyInstr);
 
  641  Register Def = CopyOperands->Destination->getReg();
 
  643  if (
const TargetRegisterClass *URC =
 
  645    return URC->contains(Def);
 
  655bool MachineCopyPropagation::isForwardableRegClassCopy(
const MachineInstr &Copy,
 
  656                                                       const MachineInstr &UseI,
 
  658  std::optional<DestSourcePair> CopyOperands =
 
  659      isCopyInstr(Copy, *
TII, UseCopyInstr);
 
  660  Register CopySrcReg = CopyOperands->Source->getReg();
 
  664  if (
const TargetRegisterClass *URC =
 
  666    return URC->contains(CopySrcReg);
 
  668  auto UseICopyOperands = isCopyInstr(UseI, *
TII, UseCopyInstr);
 
  669  if (!UseICopyOperands)
 
  692  Register UseDstReg = UseICopyOperands->Destination->getReg();
 
  694  bool IsCrossClass = 
false;
 
  695  for (
const TargetRegisterClass *RC : 
TRI->regclasses()) {
 
  696    if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
 
  698      if (
TRI->getCrossCopyRegClass(RC) != RC) {
 
  710  Register CopyDstReg = CopyOperands->Destination->getReg();
 
  711  for (
const TargetRegisterClass *RC : 
TRI->regclasses()) {
 
  712    if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
 
  713        TRI->getCrossCopyRegClass(RC) != RC)
 
  727bool MachineCopyPropagation::hasImplicitOverlap(
const MachineInstr &
MI,
 
  728                                                const MachineOperand &Use) {
 
  729  for (
const MachineOperand &MIUse : 
MI.uses())
 
  730    if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() &&
 
  731        MIUse.isUse() && 
TRI->regsOverlap(
Use.getReg(), MIUse.getReg()))
 
  741bool MachineCopyPropagation::hasOverlappingMultipleDef(
 
  742    const MachineInstr &
MI, 
const MachineOperand &MODef, 
Register Def) {
 
  743  for (
const MachineOperand &MIDef : 
MI.all_defs()) {
 
  744    if ((&MIDef != &MODef) && MIDef.isReg() &&
 
  745        TRI->regsOverlap(Def, MIDef.getReg()))
 
  754bool MachineCopyPropagation::canUpdateSrcUsers(
const MachineInstr &Copy,
 
  755                                               const MachineOperand &CopySrc) {
 
  756  assert(CopySrc.
isReg() && 
"Expected a register operand");
 
  757  for (
auto *SrcUser : Tracker.getSrcUsers(CopySrc.
getReg(), *
TRI)) {
 
  758    if (hasImplicitOverlap(*SrcUser, CopySrc))
 
  761    for (MachineOperand &MO : SrcUser->uses()) {
 
  762      if (!MO.isReg() || !MO.isUse() || MO.getReg() != CopySrc.
getReg())
 
  764      if (MO.isTied() || !MO.isRenamable() ||
 
  765          !isBackwardPropagatableRegClassCopy(Copy, *SrcUser,
 
  775void MachineCopyPropagation::forwardUses(MachineInstr &
MI) {
 
  776  if (!Tracker.hasAnyCopies())
 
  782  for (
unsigned OpIdx = 0, OpEnd = 
MI.getNumOperands(); 
OpIdx < OpEnd;
 
  784    MachineOperand &MOUse = 
MI.getOperand(
OpIdx);
 
  804                                               *
TRI, *
TII, UseCopyInstr);
 
  808    std::optional<DestSourcePair> CopyOperands =
 
  809        isCopyInstr(*Copy, *
TII, UseCopyInstr);
 
  810    Register CopyDstReg = CopyOperands->Destination->getReg();
 
  811    const MachineOperand &CopySrc = *CopyOperands->Source;
 
  817    if (MOUse.
getReg() != CopyDstReg) {
 
  818      unsigned SubRegIdx = 
TRI->getSubRegIndex(CopyDstReg, MOUse.
getReg());
 
  820             "MI source is not a sub-register of Copy destination");
 
  821      ForwardedReg = 
TRI->getSubReg(CopySrcReg, SubRegIdx);
 
  823        LLVM_DEBUG(
dbgs() << 
"MCP: Copy source does not have sub-register " 
  824                          << 
TRI->getSubRegIndexName(SubRegIdx) << 
'\n');
 
  830    if (
MRI->isReserved(CopySrcReg) && !
MRI->isConstantPhysReg(CopySrcReg))
 
  833    if (!isForwardableRegClassCopy(*Copy, 
MI, 
OpIdx))
 
  836    if (hasImplicitOverlap(
MI, MOUse))
 
  842    if (isCopyInstr(
MI, *
TII, UseCopyInstr) &&
 
  843        MI.modifiesRegister(CopySrcReg, 
TRI) &&
 
  844        !
MI.definesRegister(CopySrcReg, 
nullptr)) {
 
  850      LLVM_DEBUG(
dbgs() << 
"MCP: Skipping forwarding due to debug counter:\n  " 
  857                      << 
"\n     in " << 
MI << 
"     from " << *Copy);
 
  859    MOUse.
setReg(ForwardedReg);
 
  868    for (MachineInstr &KMI :
 
  870      KMI.clearRegisterKills(CopySrcReg, 
TRI);
 
  877void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &
MBB) {
 
  883    std::optional<DestSourcePair> CopyOperands =
 
  884        isCopyInstr(
MI, *
TII, UseCopyInstr);
 
  886      Register RegSrc = CopyOperands->Source->getReg();
 
  887      Register RegDef = CopyOperands->Destination->getReg();
 
  888      if (!
TRI->regsOverlap(RegDef, RegSrc)) {
 
  890              "MachineCopyPropagation should be run after register allocation!");
 
  893        MCRegister Src = RegSrc.
asMCReg();
 
  910        if (eraseIfRedundant(
MI, Def, Src) || eraseIfRedundant(
MI, Src, Def))
 
  916    for (
const MachineOperand &MO : 
MI.operands())
 
  917      if (MO.isReg() && MO.isEarlyClobber()) {
 
  923          ReadRegister(
Reg, 
MI, RegularUse);
 
  924        Tracker.clobberRegister(
Reg, *
TRI, *
TII, UseCopyInstr);
 
  931    if (
TII->simplifyInstruction(
MI)) {
 
  936    CopyOperands = isCopyInstr(
MI, *
TII, UseCopyInstr);
 
  938      Register RegSrc = CopyOperands->Source->getReg();
 
  939      Register RegDef = CopyOperands->Destination->getReg();
 
  944      if (RegSrc == RegDef && !
MRI->isReserved(RegSrc)) {
 
  945        MI.eraseFromParent();
 
  951      if (!
TRI->regsOverlap(RegDef, RegSrc)) {
 
  954        if (!
MRI->isReserved(Def))
 
  955          MaybeDeadCopies.insert(&
MI);
 
  960    const MachineOperand *RegMask = 
nullptr;
 
  961    for (
const MachineOperand &MO : 
MI.operands()) {
 
  971             "MachineCopyPropagation should be run after register allocation!");
 
  973      if (MO.isDef() && !MO.isEarlyClobber()) {
 
  975        if (!
MRI->isConstantPhysReg(
Reg)) {
 
  979      } 
else if (MO.readsReg())
 
  980        ReadRegister(
Reg.
asMCReg(), 
MI, MO.isDebug() ? DebugUse : RegularUse);
 
  987      BitVector &PreservedRegUnits =
 
  988          Tracker.getPreservedRegUnits(*RegMask, *
TRI);
 
  991      for (SmallSetVector<MachineInstr *, 8>::iterator DI =
 
  992               MaybeDeadCopies.begin();
 
  993           DI != MaybeDeadCopies.end();) {
 
  994        MachineInstr *MaybeDead = *DI;
 
  995        std::optional<DestSourcePair> CopyOperands =
 
  996            isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
 
  997        MCRegister 
Reg = CopyOperands->Destination->getReg().asMCReg();
 
 1007        bool MIRefedinCopyInfo = 
false;
 
 1008        for (
unsigned RegUnit : 
TRI->regunits(
Reg)) {
 
 1009          if (!PreservedRegUnits.
test(RegUnit))
 
 1010            Tracker.clobberRegUnit(RegUnit, *
TRI, *
TII, UseCopyInstr);
 
 1012            if (MaybeDead == Tracker.findCopyForUnit(RegUnit, *
TRI)) {
 
 1013              MIRefedinCopyInfo = 
true;
 
 1020        DI = MaybeDeadCopies.erase(DI);
 
 1023        if (MIRefedinCopyInfo)
 
 1026        LLVM_DEBUG(
dbgs() << 
"MCP: Removing copy due to regmask clobbering: " 
 1036    for (MCRegister 
Reg : Defs)
 
 1037      Tracker.clobberRegister(
Reg, *
TRI, *
TII, UseCopyInstr);
 
 1040      Register RegSrc = CopyOperands->Source->getReg();
 
 1041      Register RegDef = CopyOperands->Destination->getReg();
 
 1042      if (!
TRI->regsOverlap(RegDef, RegSrc)) {
 
 1043        Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
 
 1048  bool TracksLiveness = 
MRI->tracksLiveness();
 
 1053    readSuccessorLiveIns(
MBB);
 
 1059    for (MachineInstr *MaybeDead : MaybeDeadCopies) {
 
 1060      LLVM_DEBUG(
dbgs() << 
"MCP: Removing copy due to no live-out succ: ";
 
 1063      std::optional<DestSourcePair> CopyOperands =
 
 1064          isCopyInstr(*MaybeDead, *
TII, UseCopyInstr);
 
 1067      Register SrcReg = CopyOperands->Source->getReg();
 
 1068      Register DestReg = CopyOperands->Destination->getReg();
 
 1072      const auto &DbgUsers = CopyDbgUsers[MaybeDead];
 
 1084  MaybeDeadCopies.clear();
 
 1085  CopyDbgUsers.clear();
 
 1097  if (
MRI.isReserved(Def) || 
MRI.isReserved(Src))
 
 
 1103void MachineCopyPropagation::propagateDefs(MachineInstr &
MI) {
 
 1104  if (!Tracker.hasAnyCopies())
 
 1107  for (
unsigned OpIdx = 0, OpEnd = 
MI.getNumOperands(); 
OpIdx != OpEnd;
 
 1109    MachineOperand &MODef = 
MI.getOperand(
OpIdx);
 
 1125    MachineInstr *
Copy = Tracker.findAvailBackwardCopy(
 
 1130    std::optional<DestSourcePair> CopyOperands =
 
 1131        isCopyInstr(*Copy, *
TII, UseCopyInstr);
 
 1132    Register Def = CopyOperands->Destination->getReg();
 
 1133    Register Src = CopyOperands->Source->getReg();
 
 1135    if (MODef.
getReg() != Src)
 
 1138    if (!isBackwardPropagatableRegClassCopy(*Copy, 
MI, 
OpIdx))
 
 1141    if (hasImplicitOverlap(
MI, MODef))
 
 1144    if (hasOverlappingMultipleDef(
MI, MODef, Def))
 
 1147    if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
 
 1152                      << 
MI << 
"     from " << *Copy);
 
 1157    for (
auto *SrcUser : Tracker.getSrcUsers(Src, *
TRI)) {
 
 1158      for (MachineOperand &MO : SrcUser->uses()) {
 
 1159        if (!MO.isReg() || !MO.isUse() || MO.getReg() != Src)
 
 1162        MO.setIsRenamable(CopyOperands->Destination->isRenamable());
 
 1167    MaybeDeadCopies.insert(Copy);
 
 1169    ++NumCopyBackwardPropagated;
 
 1173void MachineCopyPropagation::BackwardCopyPropagateBlock(
 
 1174    MachineBasicBlock &
MBB) {
 
 1180    std::optional<DestSourcePair> CopyOperands =
 
 1181        isCopyInstr(
MI, *
TII, UseCopyInstr);
 
 1182    if (CopyOperands && 
MI.getNumImplicitOperands() == 0) {
 
 1183      Register DefReg = CopyOperands->Destination->getReg();
 
 1184      Register SrcReg = CopyOperands->Source->getReg();
 
 1186      if (!
TRI->regsOverlap(DefReg, SrcReg)) {
 
 1194          Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
 
 1201    for (
const MachineOperand &MO : 
MI.operands())
 
 1202      if (MO.isReg() && MO.isEarlyClobber()) {
 
 1206        Tracker.invalidateRegister(
Reg, *
TRI, *
TII, UseCopyInstr);
 
 1210    for (
const MachineOperand &MO : 
MI.operands()) {
 
 1218        Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
 
 1221      if (MO.readsReg()) {
 
 1226          for (
MCRegUnit Unit : 
TRI->regunits(MO.getReg().asMCReg())) {
 
 1227            if (
auto *Copy = Tracker.findCopyDefViaUnit(Unit, *
TRI)) {
 
 1228              CopyDbgUsers[
Copy].insert(&
MI);
 
 1231        } 
else if (!Tracker.trackSrcUsers(MO.getReg().asMCReg(), 
MI, *
TRI, *
TII,
 
 1234          Tracker.invalidateRegister(MO.getReg().asMCReg(), *
TRI, *
TII,
 
 1241  for (
auto *Copy : MaybeDeadCopies) {
 
 1242    std::optional<DestSourcePair> CopyOperands =
 
 1243        isCopyInstr(*Copy, *
TII, UseCopyInstr);
 
 1244    Register Src = CopyOperands->Source->getReg();
 
 1245    Register Def = CopyOperands->Destination->getReg();
 
 1246    const auto &DbgUsers = CopyDbgUsers[
Copy];
 
 1250    MRI->updateDbgUsersToReg(Src.asMCReg(), 
Def.asMCReg(), MaybeDeadDbgUsers);
 
 1251    Copy->eraseFromParent();
 
 1255  MaybeDeadCopies.clear();
 
 1256  CopyDbgUsers.clear();
 
 1264  auto &SC = SpillChain[Leader];
 
 1265  auto &RC = ReloadChain[Leader];
 
 1266  for (
auto I = SC.rbegin(), 
E = SC.rend(); 
I != 
E; ++
I)
 
 
 1310void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &
MBB) {
 
 1313  DenseMap<MachineInstr *, MachineInstr *> ChainLeader;
 
 1318  DenseMap<MachineInstr *, SmallVector<MachineInstr *>> SpillChain, ReloadChain;
 
 1321  DenseSet<const MachineInstr *> CopySourceInvalid;
 
 1323  auto TryFoldSpillageCopies =
 
 1324      [&, 
this](
const SmallVectorImpl<MachineInstr *> &SC,
 
 1325                const SmallVectorImpl<MachineInstr *> &RC) {
 
 1326        assert(SC.
size() == RC.size() && 
"Spill-reload should be paired");
 
 1341        for (
const MachineInstr *Spill : 
drop_begin(SC))
 
 1342          if (CopySourceInvalid.
count(Spill))
 
 1345        for (
const MachineInstr *Reload : 
drop_end(RC))
 
 1346          if (CopySourceInvalid.
count(Reload))
 
 1350          for (
const TargetRegisterClass *RC : 
TRI->regclasses()) {
 
 1351            if (RC->contains(Def) && RC->contains(Src))
 
 1357        auto UpdateReg = [](MachineInstr *
MI, 
const MachineOperand *Old,
 
 1358                            const MachineOperand *
New) {
 
 1359          for (MachineOperand &MO : 
MI->operands()) {
 
 1361              MO.setReg(
New->getReg());
 
 1365        std::optional<DestSourcePair> InnerMostSpillCopy =
 
 1366            isCopyInstr(*SC[0], *
TII, UseCopyInstr);
 
 1367        std::optional<DestSourcePair> OuterMostSpillCopy =
 
 1368            isCopyInstr(*SC.
back(), *
TII, UseCopyInstr);
 
 1369        std::optional<DestSourcePair> InnerMostReloadCopy =
 
 1370            isCopyInstr(*RC[0], *
TII, UseCopyInstr);
 
 1371        std::optional<DestSourcePair> OuterMostReloadCopy =
 
 1372            isCopyInstr(*RC.back(), *
TII, UseCopyInstr);
 
 1373        if (!CheckCopyConstraint(OuterMostSpillCopy->Source->getReg(),
 
 1374                                 InnerMostSpillCopy->Source->getReg()) ||
 
 1375            !CheckCopyConstraint(InnerMostReloadCopy->Destination->getReg(),
 
 1376                                 OuterMostReloadCopy->Destination->getReg()))
 
 1379        SpillageChainsLength += SC.
size() + RC.size();
 
 1380        NumSpillageChains += 1;
 
 1381        UpdateReg(SC[0], InnerMostSpillCopy->Destination,
 
 1382                  OuterMostSpillCopy->Source);
 
 1383        UpdateReg(RC[0], InnerMostReloadCopy->Source,
 
 1384                  OuterMostReloadCopy->Destination);
 
 1386        for (
size_t I = 1; 
I < SC.
size() - 1; ++
I) {
 
 1387          SC[
I]->eraseFromParent();
 
 1388          RC[
I]->eraseFromParent();
 
 1393  auto IsFoldableCopy = [
this](
const MachineInstr &MaybeCopy) {
 
 1394    if (MaybeCopy.getNumImplicitOperands() > 0)
 
 1396    std::optional<DestSourcePair> CopyOperands =
 
 1397        isCopyInstr(MaybeCopy, *
TII, UseCopyInstr);
 
 1400    Register Src = CopyOperands->Source->getReg();
 
 1401    Register Def = CopyOperands->Destination->getReg();
 
 1402    return Src && 
Def && !
TRI->regsOverlap(Src, Def) &&
 
 1403           CopyOperands->Source->isRenamable() &&
 
 1404           CopyOperands->Destination->isRenamable();
 
 1407  auto IsSpillReloadPair = [&, 
this](
const MachineInstr &
Spill,
 
 1408                                     const MachineInstr &Reload) {
 
 1409    if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
 
 1411    std::optional<DestSourcePair> SpillCopy =
 
 1412        isCopyInstr(Spill, *
TII, UseCopyInstr);
 
 1413    std::optional<DestSourcePair> ReloadCopy =
 
 1414        isCopyInstr(Reload, *
TII, UseCopyInstr);
 
 1415    if (!SpillCopy || !ReloadCopy)
 
 1417    return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
 
 1418           SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
 
 1421  auto IsChainedCopy = [&, 
this](
const MachineInstr &Prev,
 
 1422                                 const MachineInstr &Current) {
 
 1423    if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
 
 1425    std::optional<DestSourcePair> PrevCopy =
 
 1426        isCopyInstr(Prev, *
TII, UseCopyInstr);
 
 1427    std::optional<DestSourcePair> CurrentCopy =
 
 1428        isCopyInstr(Current, *
TII, UseCopyInstr);
 
 1429    if (!PrevCopy || !CurrentCopy)
 
 1431    return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
 
 1435    std::optional<DestSourcePair> CopyOperands =
 
 1436        isCopyInstr(
MI, *
TII, UseCopyInstr);
 
 1439    SmallSet<Register, 8> RegsToClobber;
 
 1440    if (!CopyOperands) {
 
 1441      for (
const MachineOperand &MO : 
MI.operands()) {
 
 1447        MachineInstr *LastUseCopy =
 
 1454          CopySourceInvalid.
insert(LastUseCopy);
 
 1468        Tracker.clobberRegister(
Reg, *
TRI, *
TII, UseCopyInstr);
 
 1475    Register Src = CopyOperands->Source->getReg();
 
 1476    Register Def = CopyOperands->Destination->getReg();
 
 1478    LLVM_DEBUG(
dbgs() << 
"MCP: Searching paired spill for reload: ");
 
 1480    MachineInstr *MaybeSpill =
 
 1481        Tracker.findLastSeenDefInCopy(
MI, Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
 
 1482    bool MaybeSpillIsChained = ChainLeader.
count(MaybeSpill);
 
 1483    if (!MaybeSpillIsChained && MaybeSpill &&
 
 1484        IsSpillReloadPair(*MaybeSpill, 
MI)) {
 
 1519      MachineInstr *MaybePrevReload =
 
 1520          Tracker.findLastSeenUseInCopy(
Def.asMCReg(), *
TRI);
 
 1521      auto Leader = ChainLeader.
find(MaybePrevReload);
 
 1522      MachineInstr *
L = 
nullptr;
 
 1523      if (Leader == ChainLeader.
end() ||
 
 1524          (MaybePrevReload && !IsChainedCopy(*MaybePrevReload, 
MI))) {
 
 1527               "SpillChain should not have contained newly found chain");
 
 1529        assert(MaybePrevReload &&
 
 1530               "Found a valid leader through nullptr should not happend");
 
 1533               "Existing chain's length should be larger than zero");
 
 1536             "Newly found paired spill-reload should not belong to any chain " 
 1538      ChainLeader.
insert({MaybeSpill, 
L});
 
 1540      SpillChain[
L].push_back(MaybeSpill);
 
 1541      ReloadChain[
L].push_back(&
MI);
 
 1544    } 
else if (MaybeSpill && !MaybeSpillIsChained) {
 
 1561      Tracker.clobberRegister(Src.asMCReg(), *
TRI, *
TII, UseCopyInstr);
 
 1565    Tracker.trackCopy(&
MI, *
TRI, *
TII, UseCopyInstr);
 
 1568  for (
auto I = SpillChain.
begin(), 
E = SpillChain.
end(); 
I != 
E; ++
I) {
 
 1569    auto &SC = 
I->second;
 
 1571           "Reload chain of the same leader should exist");
 
 1572    auto &RC = ReloadChain[
I->first];
 
 1573    TryFoldSpillageCopies(SC, RC);
 
 1576  MaybeDeadCopies.clear();
 
 1577  CopyDbgUsers.clear();
 
 1581bool MachineCopyPropagationLegacy::runOnMachineFunction(MachineFunction &MF) {
 
 1585  return MachineCopyPropagation(UseCopyInstr).run(MF);
 
 1592  if (!MachineCopyPropagation(UseCopyInstr).
run(MF))
 
 
 1600  bool isSpillageCopyElimEnabled = 
false;
 
 1603    isSpillageCopyElimEnabled =
 
 1607    isSpillageCopyElimEnabled = 
true;
 
 1610    isSpillageCopyElimEnabled = 
false;
 
 1621    if (isSpillageCopyElimEnabled)
 
 1622      EliminateSpillageCopies(
MBB);
 
 1623    BackwardCopyPropagateBlock(
MBB);
 
 1624    ForwardCopyPropagateBlock(
MBB);
 
 1630MachineFunctionPass *
 
 1632  return new MachineCopyPropagationLegacy(UseCopyInstr);
 
 
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static cl::opt< cl::boolOrDefault > EnableSpillageCopyElimination("enable-spill-copy-elim", cl::Hidden)
static bool isBackwardPropagatableCopy(const DestSourcePair &CopyOperands, const MachineRegisterInfo &MRI)
static void printSpillReloadChain(DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &SpillChain, DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &ReloadChain, MachineInstr *Leader)
static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src, MCRegister Def, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, bool UseCopyInstr)
Return true if PreviousCopy did copy register Src to register Def.
static cl::opt< bool > MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false), cl::Hidden)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Represents analyses that only rely on functions' control flow.
static bool shouldExecute(unsigned CounterName)
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Wrapper class representing physical registers. Should be passed by value.
An RAII based helper class to modify MachineFunctionProperties when running pass.
iterator_range< succ_iterator > successors()
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
LLVM_ABI bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
void insert_range(Range &&R)
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool enableSpillageCopyElimination() const
Enable spillage copy elimination in MachineCopyPropagation pass.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned MCRegUnit
Register units are used to compute register aliasing.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
const MachineOperand * Source
const MachineOperand * Destination