[PATCH] D41765: [CodeGen] Provide an advanced shrink-wrapping interface

Francis Visoiu Mistrih via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 07:24:10 PST 2018


thegameg created this revision.
thegameg added reviewers: MatzeB, qcolombet, kbarton, gberry, junbuml.
Herald added a subscriber: mgorny.

In order to extend shrink-wrapping we need to make some changes to the interface.

When trying to extend shrink-wrapping I came across the following limitations in terms of interface:

- We cannot have multiple save points.
- We cannot have multiple restore points.
- We cannot choose which registers are being saved / restored for each block.
- We cannot separate the Prologue / Epilogue emission from the callee saved register storing / loading.
- We cannot reuse the same algorithm to shrink-wrap anything else than CSRs and stack usage.

The goal here would be to provide an interface that would allow us to develop shrink-wrapping extensions in-tree, and being able to switch between implementations without actually having to handle both interfaces in PEI.

In order to be able to simply re-use this, we need to know which basic blocks **use** which element (as an input), and which basic blocks are the best suited for saving / restoring each element (as an output).

For that, the interface is split in two parts:

**ShrinkWrapInfo**: it is an interface that determines the "uses" to be used by the shrink-wrapping algorithm.
Example of uses:

- For shrink-wrapping CSR save / restore points: uses/defs of CSRs
- For shrink-wrapping stack setup code: uses/defs of SP, FP, FrameIndex operands

In order to have individual shrink-wrapping for each element, we map every different element to an index and store it in a BitVector. If there is an use of the element in a basic block, the bit at the index of the element is set. The interface provides uses per basic block:

  const BitVector *getUses(unsigned MBBNum) const

In order to choose what a "use" is, this class has to be sub-classed and it has to compute the uses per basic block that are consumed by `getUses()`.

- Example 1: Callee saved registers:

  0:
      elements:         r0 r1 r2 r3 r4 r5 r6 r7 r8 r9
      BitVector index:  0  1  2  3  4  5  6  7  8  9
      BitVector values: 1  0  0  0  0  0  0  0  0  1
      This means that r0 and r9 are used in %bb.0.



- Example 2: Stack + CSRs:

  0:
        elements:         Stack r0 r1
        BitVector index:  0     1  2
        BitVector values: 1     0  1
  4:
        elements:         Stack r0 r1
        BitVector index:  0     1  2
        BitVector values: 0     1  0

This means that r0 is used in %bb.4 and the Stack and r0 are used in %bb.0.

Providing this as an input to the shrink-wrapping algorithm allows the algorithm to be independent of the meaning of the input.

**ShrinkWrapper**: it is an interface for the shrink-wrapping algorithm. It makes it easy to switch between the current one (dominator-based) and other ones like Fred Chow's. This interface provides a result in the following format:

- DenseMap<unsigned, BitVector> Saves, Restores.
- It maps a MachineBasicBlock number to a BitVector containing the elements that need to be saved / restored.

- Example 1: Saves:

  0:
      elements:         r0 r1 r2 r3 r4 r5 r6 r7 r8 r9
      BitVector index:  0  1  2  3  4  5  6  7  8  9
      BitVector values: 1  0  0  0  0  0  0  0  0  1

This means that r0 and r9 need to be saved in %bb.0.

- Example 2: Saves:

  0:
        elements:         Stack r0 r1
        BitVector index:  0     1  2
        BitVector values: 1     0  1
  4:
        elements:         Stack r0 r1
        BitVector index:  0     1  2
        BitVector values: 0     1  0

This means that we have to set up the stack and save r1 in %bb.0, and save r0 in %bb.4.

In order to implement an algorithm, this class has to be sub-classed and compute the results of Saves and Restores in the constructor.

The current dominator-based algorithm port to this interface can allow us to experiment with shrink-wrapping registers and stack uses individually, through the ShrinkWrapInfo class.

This class is meant to be used from PEI to collect better save / restore points, but for now I'll keep it in the ShrinkWrap pass to simplify the review of the patch and focus on the design of the interface.

For this review, I recommend to start by reviewing ShrinkWrapper.h and the ShrinkWrapper / ShrinkWrapInfo abstract classes. The DefaultShrinkWrapper is the port of the current shrink-wrapper to this new interface.


https://reviews.llvm.org/D41765

Files:
  include/llvm/CodeGen/ShrinkWrapper.h
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/DefaultShrinkWrapper.cpp
  lib/CodeGen/DefaultShrinkWrapper.h
  lib/CodeGen/ShrinkWrap.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41765.128749.patch
Type: text/x-patch
Size: 48801 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180105/2df411bb/attachment.bin>


More information about the llvm-commits mailing list