[PATCH] Fix a performance problem in gep(gep ...) merging

Wei Mi wmi at google.com
Mon Apr 13 16:12:32 PDT 2015


> What about something in between:
> if ((!isa<Constant>(GO1) || !isa<Constant>(SO1)) && !Src->hasOneUse())
>
> We still keep the benefice when both are constants and we handle single user case.
>
> http://reviews.llvm.org/D8911
>

For single user case, combining may still hurt performance sometimes
when the src gep is outside a loop and target gep is inside a loop.
gep merging can move an add instruction outside of a loop to a place
inside the loop.

I got a testcase 2.cc which can show the problem. Disabling gep
merging for it can reduce insn number in its kernel loop.

Before gep merging:
  %10 = sext i32 %7 to i64
  %11 = getelementptr inbounds i8, i8* %9, i64 %10  ====> the src gep
  ....
; <label>:16                                      ; preds = %14, %18
  %x.1 = phi i32 [ %x.0, %14 ], [ %27, %18 ]
  %17 = icmp slt i32 %x.1, %2
  br i1 %17, label %18, label %28
; <label>:18                                      ; preds = %16
  %19 = mul nsw i32 %x.1, 2
  %20 = sext i32 %19 to i64
  %21 = getelementptr inbounds i8, i8* %11, i64 %20  ====> the target
gep. %11 is the only use inside loop.
  ...
  br label %16

After gep merging:

; <label>:14                                      ; preds = %12, %16
  %x.1 = phi i32 [ %x.0, %12 ], [ %25, %16 ]
  %15 = icmp slt i32 %x.1, %2
  br i1 %15, label %16, label %26
; <label>:16
  %17 = shl nsw i32 %x.1, 1
  %18 = sext i32 %17 to i64
  %.sum = add nsw i64 %9, %18   ========> the extra add inside loop.
  %19 = getelementptr inbounds i8, i8* %8, i64 %.sum
  ...
  br label %14
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 2.cc
Type: text/x-c++src
Size: 639 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150413/1a1b062b/attachment.cc>


More information about the llvm-commits mailing list