Change the scheduler's physical register dependency tracking from registers-and-their-aliases to regunits. This has a couple of advantages when subregisters are used: - The dependency tracking is more accurate and creates fewer useless edges in the dependency graph. An AMDGPU example, edited for clarity: SU(0): $vgpr1 = V_MOV_B32 $sgpr0 SU(1): $vgpr1 = V_ADDC_U32 0, $vgpr1 SU(2): $vgpr0_vgpr1 = FLAT_LOAD_DWORDX2 $vgpr0_vgpr1, 0, 0 There is a data dependency on $vgpr1 from SU(0) to SU(1) and from SU(1) to SU(2). But the old dependency tracking code also added a useless edge from SU(0) to SU(2) because it thought that SU(0)'s def of $vgpr1 aliased with SU(2)'s use of $vgpr0_vgpr1. - On targets like AMDGPU that make heavy use of subregisters, each register can have a huge number of aliases - it can be quadratic in the size of the largest defined register tuple. There is a much lower bound on the number of regunits per register, so iterating over regunits is faster than iterating over aliases. The LLVM compile-time tracker shows a tiny overall improvement of 0.03% on X86. I expect a larger compile-time improvement on targets like AMDGPU. Recommit after fixing AggressiveAntiDepBreaker in D156880.
Details
- Reviewers
fhahn qcolombet nikic craig.topper RKSimon kparzysz hfinkel uweigand rengolin t.p.northover asl MatzeB arsenm - Group Reviewers
Restricted Project - Commits
- rG56d92c17583e: [MachineScheduler] Track physical register dependencies per-regunit
rG1a54671d5405: [MachineScheduler] Track physical register dependencies per-regunit
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
60,030 ms | x64 debian > MLIR.Examples/standalone::test.toy |
Event Timeline
llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | ||
---|---|---|
226–229 | Not that I know off the top of my head. Should at least add a fixme here |
llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | ||
---|---|---|
226–229 | I think you need to use MCRegUnitMaskIterator |
llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h | ||
---|---|---|
91 | This should perhaps be renamed as RegUnit2SUnitsMap now when when spare set key is a RegUnit and not a Reg. Caused me some head-ache downstream until I found out that for (Reg2SUnitsMap::iterator I = DAG->Uses.find(*Subreg); I != DAG->Uses.end(); ++I) { probably isn't working any longer unless I make some changes to use a RegUnit in that find call. |
llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h | ||
---|---|---|
91 | Good idea. Done in d9c0166f12f0231df0893a397326efb93935ed26. |
This should perhaps be renamed as RegUnit2SUnitsMap now when when spare set key is a RegUnit and not a Reg.
Caused me some head-ache downstream until I found out that
probably isn't working any longer unless I make some changes to use a RegUnit in that find call.