80 unsigned Opc =
MI->getOpcode();
82 case TargetOpcode::COPY: {
89 if (HRI.isFakeReg(DstR.
Id) || HRI.isFakeReg(SrcR.
Id))
91 if (TRI.getMinimalPhysRegClass(DstR.
Id) !=
92 TRI.getMinimalPhysRegClass(SrcR.
Id))
94 if (!
DFG.isTracked(SrcR) || !
DFG.isTracked(DstR))
96 EM.insert(std::make_pair(DstR, SrcR));
99 case TargetOpcode::REG_SEQUENCE:
113 CopyMap.insert(std::make_pair(SA.
Id, EM));
122 if (FS !=
DefM.
end() && !FS->second.empty()) {
123 auto Def = FS->second.top()->Addr->getRegRef(
DFG);
126 TRI.isSuperRegister(
Def.Id,
I.second.Id))
128 RDefId = FS->second.top()->Id;
134 auto FR = EM.find(DR);
141 auto FR = EM.find(SubDR);
148 for (
NodeId N = DA.Addr->getReachedUse(), NextN;
N;
N = NextN) {
164 if (ReachedUseToCopyMap.find(UA.Id) != ReachedUseToCopyMap.end())
166 ReachedUseToCopyMap.insert(
167 std::make_pair(UA.Id, std::make_pair(DA, SR)));
178 for (NodeAddr<UseNode *> UA :
IA.Addr->members_if(
DFG.IsUse,
DFG)) {
180 auto CopyUseIt = ReachedUseToCopyMap.find(UA.Id);
181 if (CopyUseIt == ReachedUseToCopyMap.end())
183 [[maybe_unused]]
auto UseReg = UA.Addr->getRegRef(
DFG);
184 auto DA = CopyUseIt->second.first;
185 auto SR = CopyUseIt->second.second;
186 [[maybe_unused]]
auto DefReg =
DA.Addr->getRegRef(
DFG);
188 NodeAddr<InstrNode *> DefI =
DA.Addr->getOwner(
DFG);
190 RegisterAggr RRs(PRI);
192 SmallVector<RegisterRef, 4> UseRefs;
194 auto SRef =
DFG.makeRegRef(S, 0);
198 auto RDefIt =
RDefMap.find(SRef);
201 auto DefIIt = RDefIt->second.find(DefI.
Id);
202 if (DefIIt == RDefIt->second.end())
206 auto IAIt = RDefIt->second.find(
IA.Id);
207 if (IAIt != RDefIt->second.end()) {
208 RDefId = IAIt->second;
210 auto F =
DefM.find(S);
211 if (
F !=
DefM.end() && !
F->second.empty()) {
215 TRI.isSuperRegister(
Def.
Id, S))
217 RDefId =
F->second.top()->Id;
222 if (DefIIt->second != RDefId)
226 RDefIt->second[
IA.Id] = RDefId;
229 if (RRs.hasCoverOf(SR))
233 if (RRs.hasCoverOf(SR))
234 ReplacableUses.push_back(std::make_pair(UA, UseRefs));
240void AggressiveCopyPropagation::scanBlock(MachineBasicBlock *
B) {
241 NodeAddr<BlockNode *> BA =
DFG.findBlock(
B);
244 for (NodeAddr<InstrNode *> IA : BA.
Addr->members(
DFG)) {
246 NodeAddr<StmtNode *> SA =
IA;
250 recordReplacableUses(IA);
257 scanBlock(
I->getBlock());
264 scanBlock(
MDT.getRootNode()->getBlock());
267 dbgs() <<
"Copies:\n";
271 for (
auto J :
C.second)
276 dbgs() <<
"\nCopy def-use:\n";
277 for (
auto &U : ReachedUseToCopyMap) {
278 auto DA = U.second.first;
279 auto DefI = DA.Addr->getOwner(
DFG);
284 dbgs() <<
"\nRDef map:\n";
287 for (
auto &M : R.second)
296 bool HasLimit =
RDFCpLimit.getNumOccurrences() > 0;
299 auto MinPhysReg = [
this](
RegisterRef RR) ->
unsigned {
304 if (RR.Mask == TRI.getSubRegIndexLaneMask(S.getSubRegIndex()))
305 return S.getSubReg();
312 for (
auto P : ReplacableUses) {
322 "UseRefs should not be empty for replaceable use");
324 auto IA = UA.
Addr->getOwner(
DFG);
325 auto DR = UA.
Addr->getRegRef(
DFG);
326 auto SR = ReachedUseToCopyMap[UA.
Id].second;
327 if (HRI.isFakeReg(SR.
Id))
338 unsigned NewReg = MinPhysReg(SR);
341 DFG.unlinkUse(UA,
false);
342 bool firstUseNode =
true;
344 for (
auto UR : UseRefs) {
349 UA =
DFG.getNextShadow(IA, UA,
true);
355 UA.
Addr->setReachingDef(0);
356 UA.
Addr->setSibling(0);
358 firstUseNode =
false;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 find(const_arg_type_t< KeyT > Val)
const LaneBitmask LaneMask
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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
MCRegisterClass TargetRegisterClass
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