[PATCH] D110789: BPF: implement TTI->getGEPCost() properly

Yonghong Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 29 16:40:22 PDT 2021


yonghong-song created this revision.
yonghong-song added reviewers: ast, anakryiko.
Herald added a subscriber: hiraditya.
yonghong-song requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Latest upstream llvm caused the kernel bpf selftest emitting the
following warnings:

  In file included from progs/profiler3.c:6:
  progs/profiler.inc.h:489:2: warning: loop not unrolled:
    the optimizer was unable to perform the requested transformation;
    the transformation might be disabled or specified as part of an unsupported
    transformation ordering [-Wpass-failed=transform-warning]
          for (int i = 0; i < MAX_PATH_DEPTH; i++) {
          ^

Further bisecting shows this SimplifyCFG patch ([1]) changed
the condition on how to fold branch to common dest. This caused
some unroll pragma is not honored in selftests/bpf.

The patch [1] test getUserCost() as the condition to
perform the certain basic block folding transformation.
For the above example, before the loop unroll pass, the control flow
looks like:

  cond_block:
     branch target: body_block, cleanup_block
  body_block:
     branch target: cleanup_block, end_block
  end_block:
     branch target: cleanup_block, end10_block
  end10_block:
     %add.ptr = getelementptr i8, i8* %payload.addr.0, i64 %call2
     %inc = add nuw nsw i32 %i.0, 1
     branch target: cond_block

In the above, %call2 is an unknown scalar.

Before patch [1], end10_block will be folded into end_block, forming
the code like

  cond_block:
     branch target: body_block, cleanup_block 
  body_block:
     branch target: cleanup_block, end_block
  end_block:
     branch target: cleanup_block, cond_block

and the compiler is happy to perform unrolling.

With patch [1], getUserCost(), which calls getGEPCost(), considers IR

  %add.ptr = getelementptr i8, i8* %payload.addr.0, i64 %call2

is free, so the above transformation is not performed and unrolling
does not happen.

For BPF target, the IR

  %add.ptr = getelementptr i8, i8* %payload.addr.0, i64 %call2

is not free, and this patch properly implemented getGEPCost()
and tested with kernel bpf selftests. All loop not unrolled warnings
are gone and all selftests run successfully.

  [1] https://reviews.llvm.org/D108837


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110789

Files:
  llvm/lib/Target/BPF/BPFTargetTransformInfo.h


Index: llvm/lib/Target/BPF/BPFTargetTransformInfo.h
===================================================================
--- llvm/lib/Target/BPF/BPFTargetTransformInfo.h
+++ llvm/lib/Target/BPF/BPFTargetTransformInfo.h
@@ -71,6 +71,15 @@
                                            Opd2Info, Opd1PropInfo,
                                            Opd2PropInfo);
   }
+
+  InstructionCost getGEPCost(Type *PointeeType, const Value *Ptr,
+                             ArrayRef<const Value *> Operands,
+                             TTI::TargetCostKind CostKind) {
+    for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx)
+      if (!isa<Constant>(Operands[Idx]))
+        return TTI::TCC_Basic;
+    return TTI::TCC_Free;
+  }
 };
 
 } // end namespace llvm


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110789.376068.patch
Type: text/x-patch
Size: 773 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210929/6e463560/attachment.bin>


More information about the llvm-commits mailing list