68 #define DEBUG_TYPE "machine-cp" 70 STATISTIC(NumDeletes,
"Number of dead copies deleted");
71 STATISTIC(NumCopyForwards,
"Number of copy uses forwarded");
73 "Controls which register COPYs are forwarded");
91 for (
unsigned Reg : Regs) {
94 auto CI = Copies.
find(*RUI);
95 if (CI != Copies.
end())
96 CI->second.Avail =
false;
104 auto I = Copies.
find(*RUI);
105 if (
I != Copies.
end()) {
108 markRegsUnavailable(
I->second.DefRegs, TRI);
112 markRegsUnavailable({
MI->getOperand(0).getReg()},
TRI);
128 Copies[*RUI] = {
MI, {},
true};
133 auto I = Copies.
insert({*RUI, {
nullptr, {},
false}});
134 auto &
Copy =
I.first->second;
136 Copy.DefRegs.push_back(Def);
140 bool hasAnyCopies() {
141 return !Copies.
empty();
145 bool MustBeAvailable =
false) {
146 auto CI = Copies.
find(RegUnit);
147 if (CI == Copies.
end())
149 if (MustBeAvailable && !CI->second.Avail)
151 return CI->second.MI;
160 findCopyForUnit(*RUI, TRI,
true);
173 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
209 void ClobberRegister(
unsigned Reg);
210 void ReadRegister(
unsigned Reg);
212 bool eraseIfRedundant(
MachineInstr &Copy,
unsigned Src,
unsigned Def);
214 bool isForwardableRegClassCopy(
const MachineInstr &Copy,
233 "Machine Copy Propagation Pass",
false,
false)
235 void MachineCopyPropagation::ReadRegister(
unsigned Reg) {
239 if (
MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) {
240 LLVM_DEBUG(
dbgs() <<
"MCP: Copy is used - not dead: "; Copy->dump());
241 MaybeDeadCopies.remove(Copy);
256 if (Src == PreviousSrc) {
257 assert(Def == PreviousDef);
269 bool MachineCopyPropagation::eraseIfRedundant(
MachineInstr &Copy,
unsigned Src,
277 MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI);
284 if (!
isNopCopy(*PrevCopy, Src, Def, TRI))
293 assert(CopyDef == Src || CopyDef == Def);
307 bool MachineCopyPropagation::isForwardableRegClassCopy(
const MachineInstr &Copy,
317 return URC->contains(CopySrcReg);
343 SuperRC; SuperRC = *SuperRCI++)
358 bool MachineCopyPropagation::hasImplicitOverlap(
const MachineInstr &MI,
361 if (&MIUse != &Use && MIUse.
isReg() && MIUse.isImplicit() &&
370 void MachineCopyPropagation::forwardUses(
MachineInstr &MI) {
371 if (!Tracker.hasAnyCopies())
377 for (
unsigned OpIdx = 0, OpEnd = MI.
getNumOperands(); OpIdx < OpEnd;
404 unsigned CopySrcReg = CopySrc.
getReg();
407 if (MOUse.
getReg() != CopyDstReg) {
409 dbgs() <<
"MCP: FIXME! Not forwarding COPY to sub-register use:\n " 418 if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
421 if (hasImplicitOverlap(MI, MOUse))
425 LLVM_DEBUG(
dbgs() <<
"MCP: Skipping forwarding due to debug counter:\n " 431 <<
"\n with " <<
printReg(CopySrcReg, TRI)
432 <<
"\n in " << MI <<
" from " << *Copy);
443 KMI.clearRegisterKills(CopySrcReg, TRI);
465 "MachineCopyPropagation should be run after register allocation!");
482 if (eraseIfRedundant(*MI, Def, Src) || eraseIfRedundant(*MI, Src, Def))
494 if (!MO.isReg() || !MO.readsReg())
496 unsigned Reg = MO.getReg();
506 MaybeDeadCopies.insert(MI);
515 Tracker.clobberRegister(Def, *TRI);
517 if (!MO.isReg() || !MO.isDef())
519 unsigned Reg = MO.getReg();
522 Tracker.clobberRegister(Reg, *TRI);
525 Tracker.trackCopy(MI, *TRI);
532 if (MO.isReg() && MO.isEarlyClobber()) {
533 unsigned Reg = MO.getReg();
539 Tracker.clobberRegister(Reg, *TRI);
552 unsigned Reg = MO.getReg();
557 "MachineCopyPropagation should be run after register allocation!");
559 if (MO.isDef() && !MO.isEarlyClobber()) {
562 }
else if (!MO.isDebug() && MO.readsReg())
572 MaybeDeadCopies.
begin();
573 DI != MaybeDeadCopies.end();) {
583 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to regmask clobbering: ";
588 Tracker.clobberRegister(Reg, *TRI);
592 DI = MaybeDeadCopies.erase(DI);
600 for (
unsigned Reg : Defs)
601 Tracker.clobberRegister(Reg, *TRI);
609 LLVM_DEBUG(
dbgs() <<
"MCP: Removing copy due to no live-out succ: ";
614 assert(MaybeDead->isCopy());
615 MaybeDead->changeDebugValuesDefReg(MaybeDead->getOperand(1).getReg());
617 MaybeDead->eraseFromParent();
623 MaybeDeadCopies.clear();
627 bool MachineCopyPropagation::runOnMachineFunction(
MachineFunction &MF) {
638 CopyPropagateBlock(MBB);
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool contains(unsigned Reg) const
Return true if the specified register is included in this register class.
This class represents lattice values for constants.
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
void push_back(const T &Elt)
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
void setIsRenamable(bool Val=true)
INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE, "Machine Copy Propagation Pass", false, false) void MachineCopyPropagation
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A Use represents the edge between a Value definition and its users.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool isSubRegister(unsigned RegA, unsigned RegB) const
Returns true if RegB is a sub-register of RegA.
This file provides an implementation of debug counters.
const TargetRegisterClass *const * sc_iterator
DEBUG_COUNTER(FwdCounter, "machine-cp-fwd", "Controls which register COPYs are forwarded")
iterator begin()
Get an iterator to the beginning of the SetVector.
virtual const TargetInstrInfo * getInstrInfo() const
void clearRegisterKills(unsigned Reg, const TargetRegisterInfo *RegInfo)
Clear all kill flags affecting Reg.
TargetInstrInfo - Interface to description of machine instruction set.
iterator find(const_arg_type_t< KeyT > Val)
sc_iterator getSuperClasses() const
Returns a NULL-terminated list of super-classes.
bool erase(const KeyT &Val)
unsigned const MachineRegisterInfo * MRI
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
self_iterator getIterator()
static bool shouldExecute(unsigned CounterName)
char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isConstantPhysReg(unsigned PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
void initializeMachineCopyPropagationPass(PassRegistry &)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
A SetVector that performs no allocations if smaller than a certain size.
bool isSubRegisterEq(unsigned RegA, unsigned RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
bool regsOverlap(unsigned regA, unsigned regB) const
Returns true if the two registers are equal or alias each other.
MachineOperand class - Representation of each machine instruction operand.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
iterator_range< mop_iterator > implicit_operands()
static void clear(coro::Shape &Shape)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_NODISCARD bool empty() const
const TargetRegisterClass * getMinimalPhysRegClass(unsigned Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src, unsigned Def, const TargetRegisterInfo *TRI)
Return true if PreviousCopy did copy register Src to register Def.
const MachineOperand & getOperand(unsigned i) const
Properties which a MachineFunction may have at a given point in time.
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.