[PATCH] D42759: [CGP] Split large structs to sink more GEPs

Haicheng Wu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 12:28:46 PST 2018


haicheng created this revision.
haicheng added reviewers: gberry, qcolombet, skatkov, john.brawn, reames.
Herald added subscribers: javed.absar, mcrosier.

Accessing the members of a large struct needs a lot of GEPs which usually have large offsets due to the size of the struct.  If the offsets are too large to fit into the r+i addressing mode, these GEPs cannot be sunk to their users' blocks and many extra registers are needed then to carry the values of these GEPs.

This patch tries to split a large struct starting from %base like the following.

Before:

  BB0:
    %base     =
  
  BB1:
    %gep0     = gep %base, off0
    %gep1     = gep %base, off1
    %gep2     = gep %base, off2
  
  BB2:
    %load1    = load %gep0
    %load2    = load %gep1
    %load3    = load %gep2

After:

  BB0:
    %base     =
    %new_base = gep %base, off0
  
  BB1:
    %new_gep0 = %new_base
    %new_gep1 = gep %new_base, off1 - off0
    %new_gep2 = gep %new_base, off2 - off0
  
  BB2:
    %load1    = load i32, i32* %new_gep0
    %load2    = load i32, i32* %new_gep1
    %load3    = load i32, i32* %new_gep2

In the above example, the struct is split into two parts.  The first part still starts from %base and the second part starts from %new_base.  After the splitting, %new_gep1 and %new_gep2 have smaller offsets and then can be sunk to BB2 and folded into their users.

The algorithm to split structs is simple and very similar to the work of merging SExts.  First, it collects GEPs that have large offsets when iterating the blocks.  Second, it splits the structs underlying these collected GEPs and replaces these GEPs with new ones which have smaller offsets.

The code size and performance results of spec20xx is listed as below

|                    | Code Size (%)  | Performance (%) |
|                    | (- is smaller) | (+ is faster)   |
| spec2006/bzip2     | -3.47          | +2.89           |
| spec2017/imagick   | -0.01          | +1.02           |
| spec2000/mesa      | -0.76          | +0.71           |
| spec2017/x264      | -0.91          | +0.39           |
| spec2017/leela     | -0.01          | +0.31           |
| spec2000/ammp      | -0.04          | +0.17           |
| spec2017/parest    | 0              | 0               |
| spec2017/xalancbmk | 0              | -0.13           |
| spec2017/blender   | 0              | -0.18           |
| spec2006/xalancbmk | 0              | -0.51           |


Repository:
  rL LLVM

https://reviews.llvm.org/D42759

Files:
  lib/CodeGen/CodeGenPrepare.cpp
  test/Transforms/CodeGenPrepare/AArch64/large-struct.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42759.132235.patch
Type: text/x-patch
Size: 18610 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180131/ab5653cc/attachment.bin>


More information about the llvm-commits mailing list