Skip to content
  1. Oct 25, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Track values fused into stack spills · ee3eee71
      Jeremy Morse authored
      During register allocation, some instructions can have stack spills fused
      into them. It means that when vregs are allocated on the stack we can
      convert:
      
          SETCCr %0
          DBG_VALUE %0
      
      to
      
          SETCCm %stack.0
          DBG_VALUE %stack.0
      
      Unfortunately instruction referencing finds this harder: a store to the
      stack doesn't have a specific operand number, therefore we don't substitute
      the old operand for a new operand, and the location is dropped. This patch
      implements a solution: just recognise the memory operand attached to an
      instruction with a Special Number (TM), and record a substitution between
      the old value and the new one.
      
      This patch adds substitution code to InlineSpiller to record such fused
      spills, and tracking in InstrRefBasedLDV to recognise such values, and
      produce the value numbers for them. Everything to do with the movement of
      stack-defined values is already handled in InstrRefBasedLDV.
      
      Differential Revision: https://reviews.llvm.org/D111317
      ee3eee71
  2. Oct 22, 2021
    • Jeremy Morse's avatar
      [DebugInfo][Instr] Track subregisters across stack spills/restores · e7084cea
      Jeremy Morse authored
      Sometimes we generate code that writes to a subregister, then spills /
      restores a super-register to the stack, for example:
      
          $eax = MOV32ri 0
          MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax
          $rcx = MOV64rm $rsp, 1, $noreg, 8, $noreg
      
      This patch takes a different approach: it adds another index to
      MLocTracker that identifies a size/offset within a stack slot. A location
      on the stack is then a pari of {FrameIndex, SlotNum}. Spilling and
      restoring now involves pairing up the src/dest register numbers, and the
      dest/src stack position to be transferred to/from. Location coverage
      improves as a result, compile-time performance decreases, alas.
      
      One limitation is that if a PHI occurs inside a stack slot:
      
          DBG_PHI %stack.0, 1
      
      We don't know how large the resulting value is, and so might have
      difficulty picking which value to use. DBG_PHI might need to be augmented
      in the future with such a size.
      
      Unit tests added ensure that spills and restores correctly transfer to
      positions in the Location => Value map, and that different register classes
      written to the stack will correctly clobber all other positions in the
      stack slot.
      
      Differential Revision: https://reviews.llvm.org/D112133
      e7084cea
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Add unit tests for transfer-function building · d9eebe3c
      Jeremy Morse authored
      This patch adds some unit tests for the machine-location transfer-function
      building parts of InstrRefBasedLDV: i.e., test that if we feed some MIR
      into the transfer-function building code, does it create the correct
      transfer function.
      
      There are a number of minor defects that get corrected in the process:
       * The unit test was selecting the x86 (i.e. 32 bit) backend rather than
         x86_64's 64 bit backend,
       * COPY instructions weren't actually having their subregister values
         correctly represented in the transfer function. Subregisters were being
         defined by the COPY, rather than taking the value in the source register.
       * SP aliases were at risk of being clobbered, if an SP subregister was
         clobbered.
      
      Differential Revision: https://reviews.llvm.org/D112006
      d9eebe3c
  3. Oct 20, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Track a single variable at a time · 89950ade
      Jeremy Morse authored
      Here's another performance patch for InstrRefBasedLDV: rather than
      processing all variable values in a scope at a time, instead, process one
      variable at a time. The benefits are twofold:
       * It's easier to reason about one variable at a time in your mind,
       * It improves performance, apparently from increased locality.
      
      The downside is that the value-propagation code gets indented one level
      further, plus there's some churn in the unit tests.
      
      Differential Revision: https://reviews.llvm.org/D111799
      89950ade
  4. Oct 19, 2021
  5. Oct 14, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Place variable-values PHI using LLVM utilities · b5426ced
      Jeremy Morse authored
      This patch is very similar to D110173 / a3936a6c, but for variable
      values rather than machine values. This is for the second instr-ref
      problem, calculating the correct variable value on entry to each block.
      The previous lattice based implementation was broken; we now use LLVMs
      existing PHI placement utilities to work out where values need to merge,
      then eliminate un-necessary ones through value propagation.
      
      Most of the deletions here happen in vlocJoin: it was trying to pick a
      location for PHIs to happen in, badly, leading to an infinite loop in the
      MIR test added, where it would repeatedly switch between register
      locations. The new approach is simpler: either PHIs can be eliminated, or
      they can't, and the location of the value is a different problem.
      
      Various bits and pieces move to the header so that they can be tested in
      the unit tests. The DbgValue class grows a "VPHI" kind to represent
      variable value PHIS that haven't been eliminated yet.
      
      Differential Revision: https://reviews.llvm.org/D110630
      b5426ced
  6. Oct 13, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Only calculate IDF for reg units · fbf269c7
      Jeremy Morse authored
      In D110173 we start using the existing LLVM IDF calculator to place PHIs as
      we reconstruct an SSA form of machine-code program. Sadly that's slower
      than the old (but broken) way, this patch attempts to recover some of that
      performance.
      
      The key observation: every time we def a register, we also have to def it's
      register units. If we def'd $rax, in the current implementation we
      independently calculate PHI locations for {al, ah, ax, eax, hax, rax}, and
      they will all have the same PHI positions. Instead of doing that, we can
      calculate the PHI positions for {al, ah} and place PHIs for any aliasing
      registers in the same positions. Any def of a super-register has to def
      the unit, and vice versa, so this is sound. It cuts down the SSA placement
      we need to do significantly.
      
      This doesn't work for stack slots, or registers we only ever read, so place
      PHIs normally for those. LiveDebugValues choses to ignore writes to SP at
      calls, and now have to ignore writes to SP register units too.
      
      Differential Revision: https://reviews.llvm.org/D111627
      fbf269c7
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Use PHI placement utilities for machine locations · a3936a6c
      Jeremy Morse authored
      InstrRefBasedLDV used to try and determine which values are in which
      registers using a lattice approach; however this is hard to understand, and
      broken in various ways. This patch replaces that approach with a standard
      SSA approach using existing LLVM utilities. PHIs are placed at dominance
      frontiers; value propagation then eliminates un-necessary PHIs.
      
      This patch also adds a bunch of unit tests that should cover many of the
      weirder forms of control flow.
      
      Differential Revision: https://reviews.llvm.org/D110173
      a3936a6c
  7. Oct 12, 2021
Loading