Skip to content
  1. Nov 30, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Avoid dropping fragment info during PHI elimination · 8dda516b
      Jeremy Morse authored
      InstrRefBasedLDV used to crash on the added test -- the exit block is not
      in scope for the variable being propagated, but is still considered because
      it contains an assignment. The failure-mode was vlocJoin ignoring
      assign-only blocks and not updating DIExpressions, but pickVPHILoc would
      still find a variable location for it. That led to DBG_VALUEs created with
      the wrong fragment information.
      
      Fix this by removing a filter inherited from VarLocBasedLDV: vlocJoin will
      now consider assign-only blocks and will update their expressions.
      
      Differential Revision: https://reviews.llvm.org/D114727
      8dda516b
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Terminate overlapping variable fragments · 0eee8445
      Jeremy Morse authored
      If we have a variable where its fragments are split into overlapping
      segments:
      
          DBG_VALUE $ax, $noreg, !123, !DIExpression(DW_OP_LLVM_fragment_0, 16)
          ...
          DBG_VALUE $eax, $noreg, !123, !DIExpression(DW_OP_LLVM_fragment_0, 32)
      
      we should only propagate the most recently assigned fragment out of a
      block. LiveDebugValues only deals with live-in variable locations, as
      overlaps within blocks is DbgEntityHistoryCalculators domain.
      
      InstrRefBasedLDV has kept the accumulateFragmentMap method from
      VarLocBasedLDV, we just need it to recognise DBG_INSTR_REFs. Once it's
      produced a mapping of variable / fragments to the overlapped variable /
      fragments, VLocTracker uses it to identify when a debug instruction needs
      to terminate the other parts it overlaps with. The test is updated for
      some standard "InstrRef picks different registers" variation, and the
      order of some unrelated DBG_VALUEs changes.
      
      Differential Revision: https://reviews.llvm.org/D114603
      0eee8445
  2. Nov 24, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Cope with win32 calls changing SP in LiveDebugValues · bfadc5dc
      Jeremy Morse authored
      Almost all of the time, call instructions don't actually lead to SP being
      different after they return. An exception is win32's _chkstk, which which
      implements stack probes. We need to recognise that as modifying SP, so
      that copies of the value are tracked as distinct vla pointers.
      
      This patch adds a target frame-lowering hook to see whether stack probe
      functions will modify the stack pointer, store that in an internal flag,
      and if it's true then scan CALL instructions to see whether they're a
      stack probe. If they are, recognise them as defining a new stack-pointer
      value.
      
      The added test exercises this behaviour: two calls to _chkstk should be
      considered as producing two different values.
      
      Differential Revision: https://reviews.llvm.org/D114443
      bfadc5dc
  3. Oct 25, 2021
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef][NFC] Switch to using DenseMaps and similar · 4136897b
      Jeremy Morse authored
      There are a few STL containers hanging around that can become DenseMaps,
      SmallVectors and similar. This recovers a modest amount of compile time
      performance.
      
      While I'm here, adjust the bit layout of ValueIDNum: this was always
      supposed to act like a value type, however it seems that clang doesn't
      compile the comparison functions to act that way. Add a uint64_t to a
      union that explicitly aliases the bitfields, so that we can compare the
      whole value as a single integer.
      
      Differential Revision: https://reviews.llvm.org/D112333
      4136897b
    • Jeremy Morse's avatar
      [DebugInfo][InstrRef] Recover stack-slot tracking performance · 97ddf49e
      Jeremy Morse authored
      This patch is like D111627 -- instead of calculating IDF for every location
      on the stack, only do it for the smallest units of interference, and copy
      the PHIs for those units to any aliases.
      
      The test added runs placeMLocPHIs directly, and tests that:
       * A def of the lower 8 bits of a stack slot causes all aliasing regs to
         have PHIs placed,
       * It doesn't cause the equivalent location to x86's $ah, which isn't
         aliased, to have a PHI placed.
      
      Differential Revision: https://reviews.llvm.org/D112324
      97ddf49e
    • 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
  4. 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
  5. 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
  6. Oct 19, 2021
  7. 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
  8. 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
  9. Oct 12, 2021
Loading