[clang] [lld] [llvm] Run ObjCContractPass in Default Codegen Pipeline (PR #92331)

Nuri Amari via cfe-commits cfe-commits at lists.llvm.org
Wed May 22 18:35:54 PDT 2024


https://github.com/NuriAmari updated https://github.com/llvm/llvm-project/pull/92331

>From 66ddf609c0e77867ec48c17136fb80d1e482041d Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Wed, 15 May 2024 16:33:03 -0700
Subject: [PATCH 1/7] Run ObjCContractPass in Distributed Thin-LTO Pipeline

Prior to this patch, when using -fthinlto-index= the
ObjCARCContractPass isn't run prior to CodeGen, and
instruction selection fails on IR containing
arc intrinstics.
---
 clang/lib/CodeGen/BackendUtil.cpp             |  3 +++
 .../thinlto-distributed-objc-contract-pass.ll | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 90985c08fe7f8..03dd1df281d80 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1289,6 +1289,9 @@ static void runThinLTOBackend(
     };
     break;
   default:
+    Conf.PreCodeGenPassesHook = [](legacy::PassManager &Pm) {
+      Pm.add(createObjCARCContractPass());
+    };
     Conf.CGFileType = getCodeGenFileType(Action);
     break;
   }
diff --git a/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll
new file mode 100644
index 0000000000000..7d0247555b5c8
--- /dev/null
+++ b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll
@@ -0,0 +1,19 @@
+; RUN: opt -thinlto-bc -o %t.o %s
+
+; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \
+; RUN:   -o %t2.index \
+; RUN:   -r=%t.o,_use_arc,px
+
+; RUN: %clang_cc1 -triple x86_64-apple-darwin \
+; RUN:   -emit-obj -fthinlto-index=%t.o.thinlto.bc \
+; RUN:   -o %t.native.o -x ir %t.o
+
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-darwin"
+
+define void @use_arc(ptr %a, ptr %b) {
+  call void (...) @llvm.objc.clang.arc.use(i8* %a, i8* %b) nounwind
+  ret void
+}
+
+declare void @llvm.objc.clang.arc.use(...) nounwind

>From 142174dff7b12827f7af187e4ff08b3e75486923 Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Fri, 17 May 2024 11:38:16 -0700
Subject: [PATCH 2/7] Address PR Feedback

- Adjust test
- Unconditionally include ARC pass in ThinLTO pipeline
---
 clang/lib/CodeGen/BackendUtil.cpp                            | 3 ---
 clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll | 2 +-
 lld/MachO/LTO.cpp                                            | 3 ---
 llvm/lib/LTO/LTOBackend.cpp                                  | 2 ++
 4 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 03dd1df281d80..90985c08fe7f8 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1289,9 +1289,6 @@ static void runThinLTOBackend(
     };
     break;
   default:
-    Conf.PreCodeGenPassesHook = [](legacy::PassManager &Pm) {
-      Pm.add(createObjCARCContractPass());
-    };
     Conf.CGFileType = getCodeGenFileType(Action);
     break;
   }
diff --git a/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll
index 7d0247555b5c8..a2a7b62cb7f93 100644
--- a/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll
+++ b/clang/test/CodeGen/thinlto-distributed-objc-contract-pass.ll
@@ -12,7 +12,7 @@ target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
 target triple = "x86_64-apple-darwin"
 
 define void @use_arc(ptr %a, ptr %b) {
-  call void (...) @llvm.objc.clang.arc.use(i8* %a, i8* %b) nounwind
+  call void (...) @llvm.objc.clang.arc.use(ptr %a, ptr %b) nounwind
   ret void
 }
 
diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index 7a9a9223a0322..6527cbb68f249 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -48,9 +48,6 @@ static lto::Config createConfig() {
   c.CPU = getCPUStr();
   c.MAttrs = getMAttrs();
   c.DiagHandler = diagnosticHandler;
-  c.PreCodeGenPassesHook = [](legacy::PassManager &pm) {
-    pm.add(createObjCARCContractPass());
-  };
 
   c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty();
 
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index d4b89ede2d713..aef3a7575dfdf 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -42,6 +42,7 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
+#include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar/LoopPassManager.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
 #include "llvm/Transforms/Utils/SplitModule.h"
@@ -415,6 +416,7 @@ static void codegen(const Config &Conf, TargetMachine *TM,
   CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
   CodeGenPasses.add(
       createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex));
+  CodeGenPasses.add(createObjCARCContractPass());
   if (Conf.PreCodeGenPassesHook)
     Conf.PreCodeGenPassesHook(CodeGenPasses);
   if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS,

>From 336c4709d44b4d5b716ecc12033a410dfea3d364 Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Mon, 20 May 2024 14:44:16 -0700
Subject: [PATCH 3/7] PR Feedback #2

- Include Pass in default codegen pipeline
- Delete all other places the pass is added
- Bail early if no arc Intrinsics are found in the module
---
 clang/lib/CodeGen/BackendUtil.cpp                   |  6 ------
 llvm/include/llvm/IR/Intrinsics.h                   | 10 ++++++++++
 llvm/lib/CodeGen/TargetPassConfig.cpp               |  3 +++
 llvm/lib/IR/Function.cpp                            |  5 +++++
 llvm/lib/LTO/LTOBackend.cpp                         |  1 -
 llvm/lib/LTO/LTOCodeGenerator.cpp                   |  4 ----
 llvm/lib/LTO/ThinLTOCodeGenerator.cpp               |  4 ----
 llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h | 13 +++++++++++++
 llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp     |  9 +++++++++
 9 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 90985c08fe7f8..1f778099a48c1 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -587,12 +587,6 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
   // this also adds codegenerator level optimization passes.
   CodeGenFileType CGFT = getCodeGenFileType(Action);
 
-  // Add ObjC ARC final-cleanup optimizations. This is done as part of the
-  // "codegen" passes so that it isn't run multiple times when there is
-  // inlining happening.
-  if (CodeGenOpts.OptimizationLevel > 0)
-    CodeGenPasses.add(createObjCARCContractPass());
-
   if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
                               /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
     Diags.Report(diag::err_fe_unable_to_interface_with_target);
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index f79df522dc805..c4131c7671088 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -82,6 +82,16 @@ namespace Intrinsic {
   /// Return the attributes for an intrinsic.
   AttributeList getAttributes(LLVMContext &C, ID id);
 
+  /// Lookup a LLVM Function declaration for an intrinsic, returning it if
+  /// found in Module M.
+  ///
+  /// The Tys parameter is for intrinsics with overloaded types (e.g., those
+  /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
+  /// intrinsic, Tys must provide exactly one type for each overloaded type in
+  /// the intrinsic.
+  Function *lookupDeclaration(Module *M, ID id,
+                              ArrayRef<Type *> Tys = std::nullopt);
+
   /// Create or insert an LLVM Function declaration for an intrinsic, and return
   /// it.
   ///
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 8832b51333d91..bc868d468ac50 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -46,6 +46,7 @@
 #include "llvm/Support/WithColor.h"
 #include "llvm/Target/CGPassBuilderOption.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils.h"
 #include <cassert>
@@ -946,6 +947,8 @@ void TargetPassConfig::addCodeGenPrepare() {
 void TargetPassConfig::addISelPrepare() {
   addPreISel();
 
+  addPass(createObjCARCContractPass());
+
   // Force codegen to run according to the callgraph.
   if (requiresCodeGenSCCOrder())
     addPass(new DummyCGSCCPass);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index bd06ff82a15a5..7feb352176b2c 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -1466,6 +1466,11 @@ bool Intrinsic::isOverloaded(ID id) {
 #include "llvm/IR/IntrinsicImpl.inc"
 #undef GET_INTRINSIC_ATTRIBUTES
 
+Function *Intrinsic::lookupDeclaration(Module *M, ID id, ArrayRef<Type *> Tys) {
+  auto *FT = getType(M->getContext(), id, Tys);
+  return M->getFunction(Tys.empty() ? getName(id) : getName(id, Tys, M, FT));
+}
+
 Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
   // There can never be multiple globals with the same name of different types,
   // because intrinsics must be a specific type.
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index aef3a7575dfdf..3beb8acf9bede 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -416,7 +416,6 @@ static void codegen(const Config &Conf, TargetMachine *TM,
   CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
   CodeGenPasses.add(
       createImmutableModuleSummaryIndexWrapperPass(&CombinedIndex));
-  CodeGenPasses.add(createObjCARCContractPass());
   if (Conf.PreCodeGenPassesHook)
     Conf.PreCodeGenPassesHook(CodeGenPasses);
   if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS,
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 0611099c4690d..4e928ae5cc303 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -137,10 +137,6 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
 
   Config.CodeModel = std::nullopt;
   Config.StatsFile = LTOStatsFile;
-  Config.PreCodeGenPassesHook = [](legacy::PassManager &PM) {
-    PM.add(createObjCARCContractPass());
-  };
-
   Config.RunCSIRInstr = LTORunCSIRInstr;
   Config.CSIRProfile = LTOCSIRProfile;
 }
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 8f517eb50dc76..1bf23bf665c86 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -334,10 +334,6 @@ std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
     raw_svector_ostream OS(OutputBuffer);
     legacy::PassManager PM;
 
-    // If the bitcode files contain ARC code and were compiled with optimization,
-    // the ObjCARCContractPass must be run, so do it unconditionally here.
-    PM.add(createObjCARCContractPass());
-
     // Setup the codegen now.
     if (TM.addPassesToEmitFile(PM, OS, nullptr, CodeGenFileType::ObjectFile,
                                /* DisableVerify */ true))
diff --git a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
index c11691c613ac7..aa3167eaa1105 100644
--- a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
+++ b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
@@ -101,6 +101,19 @@ class ARCRuntimeEntryPoints {
     llvm_unreachable("Switch should be a covered switch.");
   }
 
+  bool moduleContainsARCEntryPoints() {
+    assert(TheModule != nullptr && "Not initialized.");
+
+    for (auto ARCInstricID :
+         enum_seq_inclusive(Intrinsic::objc_arc_annotation_bottomup_bbend,
+                            Intrinsic::objc_unsafeClaimAutoreleasedReturnValue,
+                            force_iteration_on_noniterable_enum)) {
+      if (Intrinsic::lookupDeclaration(TheModule, ARCInstricID))
+        return true;
+    }
+    return false;
+  }
+
 private:
   /// Cached reference to the module which we will insert declarations into.
   Module *TheModule = nullptr;
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 0d0f5c72928ab..01f3fa06ecbdd 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -97,6 +97,7 @@ class ObjCARCContract {
 
 public:
   bool init(Module &M);
+  bool moduleUsesARCIntrinsics();
   bool run(Function &F, AAResults *AA, DominatorTree *DT);
   bool hasCFGChanged() const { return CFGChanged; }
 };
@@ -535,6 +536,10 @@ bool ObjCARCContract::init(Module &M) {
   return false;
 }
 
+bool ObjCARCContract::moduleUsesARCIntrinsics() {
+  return EP.moduleContainsARCEntryPoints();
+}
+
 bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
   if (!EnableARCOpts)
     return false;
@@ -739,6 +744,8 @@ Pass *llvm::createObjCARCContractPass() {
 bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
   ObjCARCContract OCARCC;
   OCARCC.init(*F.getParent());
+  if (!OCARCC.moduleUsesARCIntrinsics())
+    return false;
   auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
   auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
   return OCARCC.run(F, AA, DT);
@@ -748,6 +755,8 @@ PreservedAnalyses ObjCARCContractPass::run(Function &F,
                                            FunctionAnalysisManager &AM) {
   ObjCARCContract OCAC;
   OCAC.init(*F.getParent());
+  if (!OCAC.moduleUsesARCIntrinsics())
+    return PreservedAnalyses::all();
 
   bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
                           &AM.getResult<DominatorTreeAnalysis>(F));

>From b1f9a1f33b7691414375fe4c42b40dce1166af60 Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Mon, 20 May 2024 15:51:14 -0700
Subject: [PATCH 4/7] PR Feedback #3

- Replace custom predicate for arc intrinsics in a module with existing
  ModuleHasARC
- Remove unused include introduced by earlier commit
---
 llvm/include/llvm/IR/Intrinsics.h             | 10 ----------
 llvm/lib/IR/Function.cpp                      |  5 -----
 .../ObjCARC/ARCRuntimeEntryPoints.h           | 13 -------------
 .../Transforms/ObjCARC/ObjCARCContract.cpp    | 19 ++++++++++---------
 4 files changed, 10 insertions(+), 37 deletions(-)

diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index c4131c7671088..f79df522dc805 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -82,16 +82,6 @@ namespace Intrinsic {
   /// Return the attributes for an intrinsic.
   AttributeList getAttributes(LLVMContext &C, ID id);
 
-  /// Lookup a LLVM Function declaration for an intrinsic, returning it if
-  /// found in Module M.
-  ///
-  /// The Tys parameter is for intrinsics with overloaded types (e.g., those
-  /// using iAny, fAny, vAny, or iPTRAny).  For a declaration of an overloaded
-  /// intrinsic, Tys must provide exactly one type for each overloaded type in
-  /// the intrinsic.
-  Function *lookupDeclaration(Module *M, ID id,
-                              ArrayRef<Type *> Tys = std::nullopt);
-
   /// Create or insert an LLVM Function declaration for an intrinsic, and return
   /// it.
   ///
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 7feb352176b2c..bd06ff82a15a5 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -1466,11 +1466,6 @@ bool Intrinsic::isOverloaded(ID id) {
 #include "llvm/IR/IntrinsicImpl.inc"
 #undef GET_INTRINSIC_ATTRIBUTES
 
-Function *Intrinsic::lookupDeclaration(Module *M, ID id, ArrayRef<Type *> Tys) {
-  auto *FT = getType(M->getContext(), id, Tys);
-  return M->getFunction(Tys.empty() ? getName(id) : getName(id, Tys, M, FT));
-}
-
 Function *Intrinsic::getDeclaration(Module *M, ID id, ArrayRef<Type*> Tys) {
   // There can never be multiple globals with the same name of different types,
   // because intrinsics must be a specific type.
diff --git a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
index aa3167eaa1105..c11691c613ac7 100644
--- a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
+++ b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
@@ -101,19 +101,6 @@ class ARCRuntimeEntryPoints {
     llvm_unreachable("Switch should be a covered switch.");
   }
 
-  bool moduleContainsARCEntryPoints() {
-    assert(TheModule != nullptr && "Not initialized.");
-
-    for (auto ARCInstricID :
-         enum_seq_inclusive(Intrinsic::objc_arc_annotation_bottomup_bbend,
-                            Intrinsic::objc_unsafeClaimAutoreleasedReturnValue,
-                            force_iteration_on_noniterable_enum)) {
-      if (Intrinsic::lookupDeclaration(TheModule, ARCInstricID))
-        return true;
-    }
-    return false;
-  }
-
 private:
   /// Cached reference to the module which we will insert declarations into.
   Module *TheModule = nullptr;
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 01f3fa06ecbdd..72ed57015e053 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -71,6 +71,9 @@ class ObjCARCContract {
   ARCRuntimeEntryPoints EP;
   BundledRetainClaimRVs *BundledInsts = nullptr;
 
+  /// A flag indicating whether this optimization pass should run.
+  bool Run;
+
   /// The inline asm string to insert between calls and RetainRV calls to make
   /// the optimization work on targets which need it.
   const MDString *RVInstMarker;
@@ -97,7 +100,6 @@ class ObjCARCContract {
 
 public:
   bool init(Module &M);
-  bool moduleUsesARCIntrinsics();
   bool run(Function &F, AAResults *AA, DominatorTree *DT);
   bool hasCFGChanged() const { return CFGChanged; }
 };
@@ -528,6 +530,10 @@ bool ObjCARCContract::tryToPeepholeInstruction(
 //===----------------------------------------------------------------------===//
 
 bool ObjCARCContract::init(Module &M) {
+  Run = ModuleHasARC(M);
+  if (!Run)
+    return false;
+
   EP.init(&M);
 
   // Initialize RVInstMarker.
@@ -536,14 +542,13 @@ bool ObjCARCContract::init(Module &M) {
   return false;
 }
 
-bool ObjCARCContract::moduleUsesARCIntrinsics() {
-  return EP.moduleContainsARCEntryPoints();
-}
-
 bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
   if (!EnableARCOpts)
     return false;
 
+  if (!Run)
+    return false;
+
   Changed = CFGChanged = false;
   AA = A;
   DT = D;
@@ -744,8 +749,6 @@ Pass *llvm::createObjCARCContractPass() {
 bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
   ObjCARCContract OCARCC;
   OCARCC.init(*F.getParent());
-  if (!OCARCC.moduleUsesARCIntrinsics())
-    return false;
   auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
   auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
   return OCARCC.run(F, AA, DT);
@@ -755,8 +758,6 @@ PreservedAnalyses ObjCARCContractPass::run(Function &F,
                                            FunctionAnalysisManager &AM) {
   ObjCARCContract OCAC;
   OCAC.init(*F.getParent());
-  if (!OCAC.moduleUsesARCIntrinsics())
-    return PreservedAnalyses::all();
 
   bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
                           &AM.getResult<DominatorTreeAnalysis>(F));

>From 39052466801c299127ffd6342c58f17b78c72aaf Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Mon, 20 May 2024 16:28:53 -0700
Subject: [PATCH 5/7] Remove unused include statement

---
 llvm/lib/LTO/LTOBackend.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 3beb8acf9bede..d4b89ede2d713 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -42,7 +42,6 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/TargetParser/SubtargetFeature.h"
 #include "llvm/Transforms/IPO/WholeProgramDevirt.h"
-#include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar/LoopPassManager.h"
 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
 #include "llvm/Transforms/Utils/SplitModule.h"

>From 92ccb202e35420b6893f12d385c566dc848b022a Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Tue, 21 May 2024 10:50:17 -0700
Subject: [PATCH 6/7] Fix pipeline tests to reflect changes

---
 llvm/test/CodeGen/AArch64/O0-pipeline.ll    |  4 ++++
 llvm/test/CodeGen/AArch64/O3-pipeline.ll    |  4 ++++
 llvm/test/CodeGen/AMDGPU/llc-pipeline.ll    | 19 +++++++++++++++++++
 llvm/test/CodeGen/ARM/O3-pipeline.ll        |  4 ++++
 llvm/test/CodeGen/LoongArch/O0-pipeline.ll  |  4 ++++
 llvm/test/CodeGen/LoongArch/opt-pipeline.ll |  4 ++++
 llvm/test/CodeGen/PowerPC/O0-pipeline.ll    |  4 ++++
 llvm/test/CodeGen/PowerPC/O3-pipeline.ll    |  4 ++++
 llvm/test/CodeGen/RISCV/O0-pipeline.ll      |  4 ++++
 llvm/test/CodeGen/RISCV/O3-pipeline.ll      |  4 ++++
 llvm/test/CodeGen/X86/O0-pipeline.ll        |  4 ++++
 llvm/test/CodeGen/X86/opt-pipeline.ll       |  4 ++++
 12 files changed, 63 insertions(+)

diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll
index d1e38b85fa9c3..11b354b1fb49b 100644
--- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll
+++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll
@@ -31,6 +31,10 @@
 ; CHECK-NEXT:       AArch64 Stack Tagging
 ; CHECK-NEXT:       SME ABI Pass
 ; CHECK-NEXT:       Exception handling preparation
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll
index d3c8e3b7e805c..4d12a41663039 100644
--- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll
+++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll
@@ -103,6 +103,10 @@
 ; CHECK-NEXT:         Dominator Tree Construction
 ; CHECK-NEXT:     FunctionPass Manager
 ; CHECK-NEXT:       Merge internal globals
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
index 0ff5dd3680dfa..72af4abde27ee 100644
--- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
+++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
@@ -87,6 +87,9 @@
 ; GCN-O0-NEXT:        AMDGPU Rewrite Undef for PHI
 ; GCN-O0-NEXT:        LCSSA Verifier
 ; GCN-O0-NEXT:        Loop-Closed SSA Form Pass
+; GCN-O0-NEXT:        Basic Alias Analysis (stateless AA impl)
+; GCN-O0-NEXT:        Function Alias Analysis Results
+; GCN-O0-NEXT:        ObjC ARC contraction
 ; GCN-O0-NEXT:      DummyCGSCCPass
 ; GCN-O0-NEXT:      FunctionPass Manager
 ; GCN-O0-NEXT:        Prepare callbr
@@ -282,6 +285,9 @@
 ; GCN-O1-NEXT:        AMDGPU Rewrite Undef for PHI
 ; GCN-O1-NEXT:        LCSSA Verifier
 ; GCN-O1-NEXT:        Loop-Closed SSA Form Pass
+; GCN-O1-NEXT:        Basic Alias Analysis (stateless AA impl)
+; GCN-O1-NEXT:        Function Alias Analysis Results
+; GCN-O1-NEXT:        ObjC ARC contraction
 ; GCN-O1-NEXT:      DummyCGSCCPass
 ; GCN-O1-NEXT:      FunctionPass Manager
 ; GCN-O1-NEXT:        Prepare callbr
@@ -577,6 +583,9 @@
 ; GCN-O1-OPTS-NEXT:        AMDGPU Rewrite Undef for PHI
 ; GCN-O1-OPTS-NEXT:        LCSSA Verifier
 ; GCN-O1-OPTS-NEXT:        Loop-Closed SSA Form Pass
+; GCN-O1-OPTS-NEXT:        Basic Alias Analysis (stateless AA impl)
+; GCN-O1-OPTS-NEXT:        Function Alias Analysis Results
+; GCN-O1-OPTS-NEXT:        ObjC ARC contraction
 ; GCN-O1-OPTS-NEXT:      DummyCGSCCPass
 ; GCN-O1-OPTS-NEXT:      FunctionPass Manager
 ; GCN-O1-OPTS-NEXT:        Prepare callbr
@@ -885,6 +894,11 @@
 ; GCN-O2-NEXT:        LCSSA Verifier
 ; GCN-O2-NEXT:        Loop-Closed SSA Form Pass
 ; GCN-O2-NEXT:      Analysis if a function is memory bound
+; GCN-O2-NEXT:      FunctionPass Manager
+; GCN-O2-NEXT:        Dominator Tree Construction
+; GCN-O2-NEXT:        Basic Alias Analysis (stateless AA impl)
+; GCN-O2-NEXT:        Function Alias Analysis Results
+; GCN-O2-NEXT:        ObjC ARC contraction
 ; GCN-O2-NEXT:      DummyCGSCCPass
 ; GCN-O2-NEXT:      FunctionPass Manager
 ; GCN-O2-NEXT:        Prepare callbr
@@ -1206,6 +1220,11 @@
 ; GCN-O3-NEXT:        LCSSA Verifier
 ; GCN-O3-NEXT:        Loop-Closed SSA Form Pass
 ; GCN-O3-NEXT:      Analysis if a function is memory bound
+; GCN-O3-NEXT:      FunctionPass Manager
+; GCN-O3-NEXT:        Dominator Tree Construction
+; GCN-O3-NEXT:        Basic Alias Analysis (stateless AA impl)
+; GCN-O3-NEXT:        Function Alias Analysis Results
+; GCN-O3-NEXT:        ObjC ARC contraction
 ; GCN-O3-NEXT:      DummyCGSCCPass
 ; GCN-O3-NEXT:      FunctionPass Manager
 ; GCN-O3-NEXT:        Prepare callbr
diff --git a/llvm/test/CodeGen/ARM/O3-pipeline.ll b/llvm/test/CodeGen/ARM/O3-pipeline.ll
index 5914e98549fcc..e8caddbff2574 100644
--- a/llvm/test/CodeGen/ARM/O3-pipeline.ll
+++ b/llvm/test/CodeGen/ARM/O3-pipeline.ll
@@ -65,6 +65,10 @@
 ; CHECK-NEXT:        Transform predicated vector loops to use MVE tail predication
 ; CHECK-NEXT:      A No-Op Barrier Pass
 ; CHECK-NEXT:      FunctionPass Manager
+; CHECK-NEXT:      Dominator Tree Construction
+; CHECK-NEXT:      Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:      Function Alias Analysis Results
+; CHECK-NEXT:      ObjC ARC contraction
 ; CHECK-NEXT:      Prepare callbr
 ; CHECK-NEXT:      Safe Stack instrumentation pass
 ; CHECK-NEXT:      Insert stack protectors
diff --git a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
index 38c3291b63677..0b923a942a5b3 100644
--- a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
+++ b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
@@ -31,6 +31,10 @@
 ; CHECK-NEXT:       Scalarize Masked Memory Intrinsics
 ; CHECK-NEXT:       Expand reduction intrinsics
 ; CHECK-NEXT:       Exception handling preparation
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
index f976dd8f98686..ed1bf1441587c 100644
--- a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
+++ b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll
@@ -70,10 +70,14 @@
 ; LAXX-NEXT:       CodeGen Prepare
 ; LAXX-NEXT:       Dominator Tree Construction
 ; LAXX-NEXT:       Exception handling preparation
+; LAXX-NEXT:       Basic Alias Analysis (stateless AA impl)
+; LAXX-NEXT:       Function Alias Analysis Results
+; LAXX-NEXT:       ObjC ARC contraction
 ; LAXX-NEXT:       Prepare callbr
 ; LAXX-NEXT:       Safe Stack instrumentation pass
 ; LAXX-NEXT:       Insert stack protectors
 ; LAXX-NEXT:       Module Verifier
+; LAXX-NEXT:       Dominator Tree Construction
 ; LAXX-NEXT:       Basic Alias Analysis (stateless AA impl)
 ; LAXX-NEXT:       Function Alias Analysis Results
 ; LAXX-NEXT:       Natural Loop Information
diff --git a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
index 56ed3ffe98642..5470a218dbe8d 100644
--- a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
+++ b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
@@ -30,6 +30,10 @@
 ; CHECK-NEXT:       Scalarize Masked Memory Intrinsics
 ; CHECK-NEXT:       Expand reduction intrinsics
 ; CHECK-NEXT:       Exception handling preparation
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll
index f94f91b38fecc..6441d178c0beb 100644
--- a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll
+++ b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll
@@ -82,10 +82,14 @@
 ; CHECK-NEXT:       Lazy Block Frequency Analysis
 ; CHECK-NEXT:       Optimization Remark Emitter
 ; CHECK-NEXT:       Hardware Loop Insertion
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
 ; CHECK-NEXT:       Module Verifier
+; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
 ; CHECK-NEXT:       Function Alias Analysis Results
 ; CHECK-NEXT:       Natural Loop Information
diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
index 3aaa5dc03a7dc..18dced591879f 100644
--- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
@@ -31,6 +31,10 @@
 ; CHECK-NEXT:       Scalarize Masked Memory Intrinsics
 ; CHECK-NEXT:       Expand reduction intrinsics
 ; CHECK-NEXT:       Exception handling preparation
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
index 52634b2a81629..f7d5ba5571ad3 100644
--- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll
@@ -74,6 +74,10 @@
 ; CHECK-NEXT:       Exception handling preparation
 ; CHECK-NEXT:     A No-Op Barrier Pass
 ; CHECK-NEXT:     FunctionPass Manager
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll
index 11025b0e6bf22..d72e71d9528b4 100644
--- a/llvm/test/CodeGen/X86/O0-pipeline.ll
+++ b/llvm/test/CodeGen/X86/O0-pipeline.ll
@@ -32,6 +32,10 @@
 ; CHECK-NEXT:       Expand reduction intrinsics
 ; CHECK-NEXT:       Expand indirectbr instructions
 ; CHECK-NEXT:       Exception handling preparation
+; CHECK-NEXT:       Dominator Tree Construction
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
diff --git a/llvm/test/CodeGen/X86/opt-pipeline.ll b/llvm/test/CodeGen/X86/opt-pipeline.ll
index 43589dc993dab..44e0cda5fbeac 100644
--- a/llvm/test/CodeGen/X86/opt-pipeline.ll
+++ b/llvm/test/CodeGen/X86/opt-pipeline.ll
@@ -72,10 +72,14 @@
 ; CHECK-NEXT:       CodeGen Prepare
 ; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Exception handling preparation
+; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
+; CHECK-NEXT:       Function Alias Analysis Results
+; CHECK-NEXT:       ObjC ARC contraction
 ; CHECK-NEXT:       Prepare callbr
 ; CHECK-NEXT:       Safe Stack instrumentation pass
 ; CHECK-NEXT:       Insert stack protectors
 ; CHECK-NEXT:       Module Verifier
+; CHECK-NEXT:       Dominator Tree Construction
 ; CHECK-NEXT:       Basic Alias Analysis (stateless AA impl)
 ; CHECK-NEXT:       Function Alias Analysis Results
 ; CHECK-NEXT:       Natural Loop Information

>From 430deb9ffbe1f271462b1c903b89e741efd670f8 Mon Sep 17 00:00:00 2001
From: Nuri Amari <nuriamari at fb.com>
Date: Wed, 22 May 2024 17:57:58 -0700
Subject: [PATCH 7/7] Add 'llvm.objc.clang.arc.noop.use' to ModuleHasARC
 Predicate

This intrinsic was missing from the list the predicate checks a module
for in order to determine if ARC passes need to run. This results in
instruction selection failure if this instrinsic is left behind.

Add the intrinsic to the predicate to fix.
---
 .../llvm/Analysis/ObjCARCAnalysisUtils.h      | 40 +++++++++----------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
index ccf859922e163..5ac6ad47f7799 100644
--- a/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
+++ b/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
@@ -41,26 +41,26 @@ extern bool EnableARCOpts;
 /// Test if the given module looks interesting to run ARC optimization
 /// on.
 inline bool ModuleHasARC(const Module &M) {
-  return
-    M.getNamedValue("llvm.objc.retain") ||
-    M.getNamedValue("llvm.objc.release") ||
-    M.getNamedValue("llvm.objc.autorelease") ||
-    M.getNamedValue("llvm.objc.retainAutoreleasedReturnValue") ||
-    M.getNamedValue("llvm.objc.unsafeClaimAutoreleasedReturnValue") ||
-    M.getNamedValue("llvm.objc.retainBlock") ||
-    M.getNamedValue("llvm.objc.autoreleaseReturnValue") ||
-    M.getNamedValue("llvm.objc.autoreleasePoolPush") ||
-    M.getNamedValue("llvm.objc.loadWeakRetained") ||
-    M.getNamedValue("llvm.objc.loadWeak") ||
-    M.getNamedValue("llvm.objc.destroyWeak") ||
-    M.getNamedValue("llvm.objc.storeWeak") ||
-    M.getNamedValue("llvm.objc.initWeak") ||
-    M.getNamedValue("llvm.objc.moveWeak") ||
-    M.getNamedValue("llvm.objc.copyWeak") ||
-    M.getNamedValue("llvm.objc.retainedObject") ||
-    M.getNamedValue("llvm.objc.unretainedObject") ||
-    M.getNamedValue("llvm.objc.unretainedPointer") ||
-    M.getNamedValue("llvm.objc.clang.arc.use");
+  return M.getNamedValue("llvm.objc.retain") ||
+         M.getNamedValue("llvm.objc.release") ||
+         M.getNamedValue("llvm.objc.autorelease") ||
+         M.getNamedValue("llvm.objc.retainAutoreleasedReturnValue") ||
+         M.getNamedValue("llvm.objc.unsafeClaimAutoreleasedReturnValue") ||
+         M.getNamedValue("llvm.objc.retainBlock") ||
+         M.getNamedValue("llvm.objc.autoreleaseReturnValue") ||
+         M.getNamedValue("llvm.objc.autoreleasePoolPush") ||
+         M.getNamedValue("llvm.objc.loadWeakRetained") ||
+         M.getNamedValue("llvm.objc.loadWeak") ||
+         M.getNamedValue("llvm.objc.destroyWeak") ||
+         M.getNamedValue("llvm.objc.storeWeak") ||
+         M.getNamedValue("llvm.objc.initWeak") ||
+         M.getNamedValue("llvm.objc.moveWeak") ||
+         M.getNamedValue("llvm.objc.copyWeak") ||
+         M.getNamedValue("llvm.objc.retainedObject") ||
+         M.getNamedValue("llvm.objc.unretainedObject") ||
+         M.getNamedValue("llvm.objc.unretainedPointer") ||
+         M.getNamedValue("llvm.objc.clang.arc.noop.use") ||
+         M.getNamedValue("llvm.objc.clang.arc.use");
 }
 
 /// This is a wrapper around getUnderlyingObject which also knows how to



More information about the cfe-commits mailing list