[BOLT] Restrict ICP for functions with unknown control flow
authorAmir Ayupov <aaupov@fb.com>
Thu, 8 Sep 2022 22:50:25 +0000 (15:50 -0700)
committerAmir Ayupov <aaupov@fb.com>
Thu, 8 Sep 2022 22:50:40 +0000 (15:50 -0700)
ICP has two modes: jump table promotion and indirect call promotion.
The selection is based on whether an instruction has a jump table or not.
An instruction with unknown control flow doesn't have a jump table and will
fall under indirect call promotion policy which might be incorrect/unsafe
(if an instruction is not a tail call, i.e. has local jump targets).

Prevent ICP for functions containing instructions with unknown control flow.

Follow-up to https://reviews.llvm.org/D128870.

Reviewed By: maksfb

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

bolt/include/bolt/Passes/IndirectCallPromotion.h
bolt/lib/Passes/IndirectCallPromotion.cpp

index 9c1a41c..397a386 100644 (file)
@@ -217,6 +217,10 @@ public:
   bool shouldPrint(const BinaryFunction &BF) const override {
     return BinaryFunctionPass::shouldPrint(BF) && Modified.count(&BF) > 0;
   }
+  bool shouldOptimize(const BinaryFunction &BF) const override {
+    return BF.isSimple() && !BF.isIgnored() && BF.hasProfile() &&
+           !BF.hasUnknownControlFlow();
+  }
   void runOnFunctions(BinaryContext &BC) override;
 };
 
index b6b30e7..e4b577a 100644 (file)
@@ -1158,8 +1158,7 @@ void IndirectCallPromotion::runOnFunctions(BinaryContext &BC) {
     for (auto &BFIt : BFs) {
       BinaryFunction &Function = BFIt.second;
 
-      if (!Function.isSimple() || Function.isIgnored() ||
-          !Function.hasProfile())
+      if (!shouldOptimize(Function))
         continue;
 
       const bool HasLayout = !Function.getLayout().block_empty();
@@ -1219,7 +1218,7 @@ void IndirectCallPromotion::runOnFunctions(BinaryContext &BC) {
   for (BinaryFunction *FuncPtr : Functions) {
     BinaryFunction &Function = *FuncPtr;
 
-    if (!Function.isSimple() || Function.isIgnored() || !Function.hasProfile())
+    if (!shouldOptimize(Function))
       continue;
 
     const bool HasLayout = !Function.getLayout().block_empty();