[PATCH] D122118: [MachineCopyPropagation] Eliminate spillage copies that might be caused by eviction chain
Kai Luo via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 18 00:07:04 PST 2022
lkail added inline comments.
================
Comment at: llvm/lib/CodeGen/MachineCopyPropagation.cpp:196
for (MCRegUnitIterator RUI(Src, &TRI); RUI.isValid(); ++RUI) {
- auto I = Copies.insert({*RUI, {nullptr, {}, false}});
+ auto I = Copies.insert({*RUI, {nullptr, nullptr, {}, false}});
auto &Copy = I.first->second;
----------------
qcolombet wrote:
> Use `MI` directly here instead of adding it line 200.
Correct me if I'm woring, `Copies.insert` insert successfully only when the key doesn't exist before. Suppose we have
```
L0: R0 = COPY R1
L1: R2 = COPY R1
```
`LastUseSeenInCopy` should track MI in `L1` rather than `L0`.
================
Comment at: llvm/lib/CodeGen/MachineCopyPropagation.cpp:309
+ if (MO.isRegMask())
+ if (MO.clobbersPhysReg(Def))
+ return nullptr;
----------------
qcolombet wrote:
> If `Def` is clobbered between `DefCopy` and `Current` I would have expected that `DefCopy` would have been removed from `Copies`.
>
> Put differently, I feel that if we have to check that here, the `Copies` map is holding hard-to-reason-about information.
>
> Are we missing some call to `clobberRegister`?
I can imagine there might be some `RegMask`s doesn't implicit def any registers, just clobber them. When we are traversing the MBB and are encountered with a `RegMask` without any other implicit-def, we don't know which register to clobber directly. I'm not sure we have a way to enumerate registers a `RegMask` clobbers. If there is such a way, I think we should clobber registers when we are traversing the MBB, not checking `RegMask` clobbers here.
================
Comment at: llvm/lib/CodeGen/MachineCopyPropagation.cpp:1092
+void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &MBB) {
+ // FIXME: Not sure why using DenseMap hit assertion inside DenseMap.
+ std::map<MachineInstr *, MachineInstr *> ChainLeader;
----------------
qcolombet wrote:
> That sounds weird.
> Would you mind sharing the assertion?
It hits `DenseMapIterator`'s
```
pointer operator->() const {
assert(isHandleInSync() && "invalid iterator access!");
...
}
```
I dived into it a bit, looks it's checking the validity of the iterator, i.e., if the container is updated, the iterator constructed before the update is invalid.
Code like
```
auto Leader = ChainLeader.find(MaybePrevReload);
...
ChainLeader.insert({MaybeSpill, Leader->second});
ChainLeader.insert({&MI, Leader->second});
```
Should be avoided.
================
Comment at: llvm/lib/CodeGen/MachineCopyPropagation.cpp:1094
+ std::map<MachineInstr *, MachineInstr *> ChainLeader;
+ DenseMap<MachineInstr *, SmallVector<MachineInstr *>> SpillChain, ReloadChain;
+ // If a COPY's Source has use or def untill next COPY defines the Source,
----------------
qcolombet wrote:
> Could you add a comment on what the mappings hold (all three of them)?
>
> I haven't read the code past this point yet, but for instance I would have expected that the key in these maps would be a `Register` not `MachineInstr`.
> I haven't read the code past this point yet, but for instance I would have expected that the key in these maps would be a Register not MachineInstr.
I separate the algorithm implementation in to two stages. stage1: Collect spill-reload chains. stage2: Fold the chains. If using `Register`, we are unable to track different spill-reload chains that share same registers.
================
Comment at: llvm/lib/CodeGen/MachineCopyPropagation.cpp:1097
+ // we put the COPY in this set to keep property#2.
+ DenseSet<MachineInstr *> CopySourceInvalid;
+
----------------
qcolombet wrote:
> Instead of tracking that, should we just invalidate the chain / stop it before that point?
The implementation doesn't invalidate any chain in stage1. Compared to previous implementation, I think current one is easier to reason and easier to maintain. When we are iterating MI inside the MBB, we don't know which `COPY` might be one of the innermost spill-reload pair and we don't want to lose track of the innermost spill-reload pair. The Source of the innermost spill is allowed to be re-use and re-def between the innermost spill-reload pair.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D122118/new/
https://reviews.llvm.org/D122118
More information about the llvm-commits
mailing list