81 unsigned Opc =
MI->getOpcode();
83 case TargetOpcode::COPY: {
90 if (HRI.isFakeReg(DstR.
Id) || HRI.isFakeReg(SrcR.
Id))
92 if (TRI.getMinimalPhysRegClass(DstR.
Id) !=
93 TRI.getMinimalPhysRegClass(SrcR.
Id))
95 if (!
DFG.isTracked(SrcR) || !
DFG.isTracked(DstR))
97 EM.insert(std::make_pair(DstR, SrcR));
100 case TargetOpcode::REG_SEQUENCE:
114 CopyMap.insert(std::make_pair(SA.
Id, EM));
122 auto FS =
DefM.find(
I.second.Id);
123 if (FS !=
DefM.end() && !FS->second.empty()) {
124 auto Def = FS->second.top()->Addr->getRegRef(
DFG);
127 TRI.isSuperRegister(
Def.Id,
I.second.Id))
129 RDefId = FS->second.top()->Id;
135 auto FR = EM.find(DR);
142 auto FR = EM.find(SubDR);
149 for (
NodeId N = DA.Addr->getReachedUse(), NextN;
N;
N = NextN) {
165 if (ReachedUseToCopyMap.find(UA.Id) != ReachedUseToCopyMap.end())
167 ReachedUseToCopyMap.insert(
168 std::make_pair(UA.Id, std::make_pair(DA, SR)));
179 for (NodeAddr<UseNode *> UA :
IA.Addr->members_if(
DFG.IsUse,
DFG)) {
181 auto CopyUseIt = ReachedUseToCopyMap.find(UA.Id);
182 if (CopyUseIt == ReachedUseToCopyMap.end())
184 [[maybe_unused]]
auto UseReg = UA.Addr->getRegRef(
DFG);
185 auto DA = CopyUseIt->second.first;
186 auto SR = CopyUseIt->second.second;
187 [[maybe_unused]]
auto DefReg =
DA.Addr->getRegRef(
DFG);
189 NodeAddr<InstrNode *> DefI =
DA.Addr->getOwner(
DFG);
191 RegisterAggr RRs(PRI);
193 SmallVector<RegisterRef, 4> UseRefs;
195 auto SRef =
DFG.makeRegRef(S, 0);
199 auto RDefIt =
RDefMap.find(SRef);
202 auto DefIIt = RDefIt->second.find(DefI.
Id);
203 if (DefIIt == RDefIt->second.end())
207 auto IAIt = RDefIt->second.find(
IA.Id);
208 if (IAIt != RDefIt->second.end()) {
209 RDefId = IAIt->second;
211 auto F =
DefM.find(S);
212 if (
F !=
DefM.end() && !
F->second.empty()) {
216 TRI.isSuperRegister(
Def.
Id, S))
218 RDefId =
F->second.top()->Id;
223 if (DefIIt->second != RDefId)
227 RDefIt->second[
IA.Id] = RDefId;
230 if (RRs.hasCoverOf(SR))
234 if (RRs.hasCoverOf(SR))
235 ReplacableUses.push_back(std::make_pair(UA, UseRefs));
241void AggressiveCopyPropagation::scanBlock(MachineBasicBlock *
B) {
242 NodeAddr<BlockNode *> BA =
DFG.findBlock(
B);
245 for (NodeAddr<InstrNode *> IA : BA.
Addr->members(
DFG)) {
247 NodeAddr<StmtNode *> SA =
IA;
251 recordReplacableUses(IA);
258 scanBlock(
I->getBlock());
265 scanBlock(
MDT.getRootNode()->getBlock());
268 dbgs() <<
"Copies:\n";
272 for (
auto J :
C.second)
277 dbgs() <<
"\nCopy def-use:\n";
278 for (
auto &U : ReachedUseToCopyMap) {
279 auto DA = U.second.first;
280 auto DefI = DA.Addr->getOwner(
DFG);
285 dbgs() <<
"\nRDef map:\n";
288 for (
auto &M : R.second)
297 bool HasLimit =
RDFCpLimit.getNumOccurrences() > 0;
300 auto MinPhysReg = [
this](
RegisterRef RR) ->
unsigned {
305 if (RR.Mask == TRI.getSubRegIndexLaneMask(S.getSubRegIndex()))
306 return S.getSubReg();
313 for (
auto P : ReplacableUses) {
323 "UseRefs should not be empty for replaceable use");
325 auto IA = UA.
Addr->getOwner(
DFG);
326 auto DR = UA.
Addr->getRegRef(
DFG);
327 auto SR = ReachedUseToCopyMap[UA.
Id].second;
328 if (HRI.isFakeReg(SR.
Id))
339 unsigned NewReg = MinPhysReg(SR);
342 DFG.unlinkUse(UA,
false);
343 bool firstUseNode =
true;
345 for (
auto UR : UseRefs) {
350 UA =
DFG.getNextShadow(IA, UA,
true);
356 UA.
Addr->setReachingDef(0);
357 UA.
Addr->setSibling(0);
359 firstUseNode =
false;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
cl::opt< unsigned > RDFCpLimit
static unsigned RDFCpCount
static Register UseReg(const MachineOperand &MO)
Register const TargetRegisterInfo * TRI
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices.
bool isValid() const
Returns true if this iterator is not yet at the end.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const LaneBitmask LaneMask
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
NodeAddr< DefNode * > Def
Print(const T &, const DataFlowGraph &) -> Print< T >
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
virtual bool interpretAsCopy(const MachineInstr *MI, EqualityMap &EM)
std::map< NodeId, EqualityMap > CopyMap
std::map< RegisterRef, std::map< NodeId, NodeId >, RegisterRefLess > RDefMap
DataFlowGraph::DefStackMap DefM
std::map< RegisterRef, RegisterRef, RegisterRefLess > EqualityMap
const MachineDominatorTree & MDT
LLVM_ABI RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const
static bool IsDef(const Node BA)
NodeAddr< T > addr(NodeId N) const
LLVM_ABI bool equal_to(RegisterRef A, RegisterRef B) const
NodeId getSibling() const
LLVM_ABI RegisterRef getRegRef(const DataFlowGraph &G) const
LLVM_ABI Node getOwner(const DataFlowGraph &G)
MachineInstr * getCode() const