OSDN Git Service

[SROA] enable splitting for non-whole-alloca loads and stores
authorHiroshi Inoue <inouehrs@jp.ibm.com>
Thu, 30 Nov 2017 07:44:46 +0000 (07:44 +0000)
committerHiroshi Inoue <inouehrs@jp.ibm.com>
Thu, 30 Nov 2017 07:44:46 +0000 (07:44 +0000)
commit39be023c86c10a935045a3b98dd978b182815375
tree09384e70c98758145ac30e08a9f8f501ed479d88
parentf6395de02662b7a3efa59d1a7ad6356171e8098a
[SROA] enable splitting for non-whole-alloca loads and stores

Currently, SROA splits loads and stores only when they are accessing the whole alloca.
This patch relaxes this limitation to allow splitting a load/store if all other loads and stores to the alloca are disjoint to or fully included in the current load/store. If there is no other load or store that crosses the boundary of the current load/store, the current splitting implementation works as is.
The whole-alloca loads and stores meet this new condition and so they are still splittable.

Here is a simplified motivating example.

struct record {
    long long a;
    int b;
    int c;
};

int func(struct record r) {
    for (int i = 0; i < r.c; i++)
        r.b++;
    return r.b;
}

When updating r.b (or r.c as well), LLVM generates redundant instructions on some platforms (such as x86_64, ppc64); here, r.b and r.c are packed into one 64-bit GPR when the struct is passed as a method argument.

With this patch, the above example is compiled into only few instructions without loop.
Without the patch, unnecessary loop-carried dependency is introduced by SROA and the loop cannot be eliminated by the later optimizers.

Differential Revision: https://reviews.llvm.org/D32998

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319407 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/Scalar/SROA.cpp
test/DebugInfo/X86/sroasplit-2.ll
test/Transforms/SROA/basictest.ll
test/Transforms/SROA/big-endian.ll