diff options
author | Carl Ritson <carl.ritson@amd.com> | 2022-03-22 11:13:13 +0900 |
---|---|---|
committer | Carl Ritson <carl.ritson@amd.com> | 2022-03-22 11:15:37 +0900 |
commit | 8e64d84995ddb317f8c79825069a3d2b0005551a (patch) | |
tree | b6f8af713f786ebba3cd87a96a5ec06930f6df24 /llvm/lib/CodeGen/MachineSink.cpp | |
parent | 6a7f0551178e966a686dd48dfa2ea045a35addef (diff) | |
download | llvm-8e64d84995ddb317f8c79825069a3d2b0005551a.zip llvm-8e64d84995ddb317f8c79825069a3d2b0005551a.tar.gz llvm-8e64d84995ddb317f8c79825069a3d2b0005551a.tar.bz2 |
[MachineSink] Check block prologue interference
Sinking must check for interference between the block prologue
and the instruction being sunk.
Specifically check for clobbering of uses by the prologue, and
overwrites to prologue defined registers by the sunk instruction.
Reviewed By: rampitec, ruiling
Differential Revision: https://reviews.llvm.org/D121277
Diffstat (limited to 'llvm/lib/CodeGen/MachineSink.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineSink.cpp | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp index 995caae..966b012 100644 --- a/llvm/lib/CodeGen/MachineSink.cpp +++ b/llvm/lib/CodeGen/MachineSink.cpp @@ -1294,6 +1294,45 @@ bool MachineSinking::SinkIntoLoop(MachineLoop *L, MachineInstr &I) { return true; } +/// Return true if a target defined block prologue instruction interferes +/// with a sink candidate. +static bool blockPrologueInterferes(MachineBasicBlock *BB, + MachineBasicBlock::iterator End, + MachineInstr &MI, + const TargetRegisterInfo *TRI, + const TargetInstrInfo *TII, + const MachineRegisterInfo *MRI) { + if (BB->begin() == End) + return false; // no prologue + for (MachineBasicBlock::iterator PI = BB->getFirstNonPHI(); PI != End; ++PI) { + // Only check target defined prologue instructions + if (!TII->isBasicBlockPrologue(*PI)) + continue; + for (auto &MO : MI.operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg) + continue; + if (MO.isUse()) { + if (Register::isPhysicalRegister(Reg) && + (TII->isIgnorableUse(MO) || (MRI && MRI->isConstantPhysReg(Reg)))) + continue; + if (PI->modifiesRegister(Reg, TRI)) + return true; + } else { + if (PI->readsRegister(Reg, TRI)) + return true; + // Check for interference with non-dead defs + auto *DefOp = PI->findRegisterDefOperand(Reg, false, true, TRI); + if (DefOp && !DefOp->isDead()) + return true; + } + } + } + return false; +} + /// SinkInstruction - Determine whether it is safe to sink the specified machine /// instruction out of its current block into a successor. bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore, @@ -1407,6 +1446,10 @@ bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore, // Determine where to insert into. Skip phi nodes. MachineBasicBlock::iterator InsertPos = SuccToSinkTo->SkipPHIsAndLabels(SuccToSinkTo->begin()); + if (blockPrologueInterferes(SuccToSinkTo, InsertPos, MI, TRI, TII, MRI)) { + LLVM_DEBUG(dbgs() << " *** Not sinking: prologue interference\n"); + return false; + } // Collect debug users of any vreg that this inst defines. SmallVector<MIRegs, 4> DbgUsersToSink; @@ -1805,11 +1848,19 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, } auto DbgValsToSink = DbgValsToSinkMap.takeVector(); + LLVM_DEBUG(dbgs() << "Sink instr " << MI << "\tinto block " << *SuccBB); + + MachineBasicBlock::iterator InsertPos = + SuccBB->SkipPHIsAndLabels(SuccBB->begin()); + if (blockPrologueInterferes(SuccBB, InsertPos, MI, TRI, TII, nullptr)) { + LLVM_DEBUG( + dbgs() << " *** Not sinking: prologue interference\n"); + continue; + } + // Clear the kill flag if SrcReg is killed between MI and the end of the // block. clearKillFlags(&MI, CurBB, UsedOpsInCopy, UsedRegUnits, TRI); - MachineBasicBlock::iterator InsertPos = - SuccBB->SkipPHIsAndLabels(SuccBB->begin()); performSink(MI, *SuccBB, InsertPos, DbgValsToSink); updateLiveIn(&MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy); |