[llvm] Revert "TLS loads opimization (hoist)" (PR #114740)

via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 3 23:00:40 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-powerpc

Author: None (abhishek-kaushik22)

<details>
<summary>Changes</summary>

This reverts commit c31014322c0b5ae596da129cbb844fb2198b4ef4.

Based on the discussions in #<!-- -->112772, this pass is not needed after the introduction of `llvm.threadlocal.address` intrinsic.

Fixes https://github.com/llvm/llvm-project/issues/112771

---

Patch is 50.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/114740.diff


20 Files Affected:

- (modified) llvm/docs/LangRef.rst (-5) 
- (modified) llvm/include/llvm/InitializePasses.h (-1) 
- (modified) llvm/include/llvm/LinkAllPasses.h (-1) 
- (modified) llvm/include/llvm/Transforms/Scalar.h (+9-2) 
- (removed) llvm/include/llvm/Transforms/Scalar/TLSVariableHoist.h (-131) 
- (modified) llvm/lib/CodeGen/TargetPassConfig.cpp (-3) 
- (modified) llvm/lib/Passes/PassBuilder.cpp (-1) 
- (modified) llvm/lib/Passes/PassRegistry.def (-1) 
- (modified) llvm/lib/Transforms/Scalar/CMakeLists.txt (-1) 
- (modified) llvm/lib/Transforms/Scalar/Scalar.cpp (-1) 
- (removed) llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp (-293) 
- (modified) llvm/test/CodeGen/AArch64/O3-pipeline.ll (-2) 
- (modified) llvm/test/CodeGen/AMDGPU/llc-pipeline.ll (+2-7) 
- (modified) llvm/test/CodeGen/ARM/O3-pipeline.ll (-1) 
- (modified) llvm/test/CodeGen/PowerPC/O3-pipeline.ll (-1) 
- (modified) llvm/test/CodeGen/X86/opt-pipeline.ll (-2) 
- (removed) llvm/test/CodeGen/X86/tls-loads-control.ll (-248) 
- (removed) llvm/test/CodeGen/X86/tls-loads-control2.ll (-50) 
- (removed) llvm/test/CodeGen/X86/tls-loads-control3.ll (-354) 
- (modified) llvm/tools/llc/llc.cpp (-1) 


``````````diff
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 566d0d4e4e81a3..e7829a511b8159 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2495,11 +2495,6 @@ example:
     function with a tail call. The prototype of a thunk should not be used for
     optimization purposes. The caller is expected to cast the thunk prototype to
     match the thunk target prototype.
-
-``"tls-load-hoist"``
-    This attribute indicates that the function will try to reduce redundant
-    tls address calculation by hoisting tls variable.
-
 ``uwtable[(sync|async)]``
     This attribute indicates that the ABI being targeted requires that
     an unwind table entry be produced for this function even if we can
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 1374880b6a716b..43a435f9c65b7a 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -303,7 +303,6 @@ void initializeTailDuplicatePass(PassRegistry &);
 void initializeTargetLibraryInfoWrapperPassPass(PassRegistry &);
 void initializeTargetPassConfigPass(PassRegistry &);
 void initializeTargetTransformInfoWrapperPassPass(PassRegistry &);
-void initializeTLSVariableHoistLegacyPassPass(PassRegistry &);
 void initializeTwoAddressInstructionLegacyPassPass(PassRegistry &);
 void initializeTypeBasedAAWrapperPassPass(PassRegistry &);
 void initializeTypePromotionLegacyPass(PassRegistry &);
diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
index 92b59a66567c95..28c26594d7ecae 100644
--- a/llvm/include/llvm/LinkAllPasses.h
+++ b/llvm/include/llvm/LinkAllPasses.h
@@ -112,7 +112,6 @@ struct ForcePassLinking {
     (void)llvm::createSROAPass();
     (void)llvm::createSingleLoopExtractorPass();
     (void)llvm::createTailCallEliminationPass();
-    (void)llvm::createTLSVariableHoistPass();
     (void)llvm::createConstantHoistingPass();
     (void)llvm::createCodeGenPrepareLegacyPass();
     (void)llvm::createPostInlineEntryExitInstrumenterPass();
diff --git a/llvm/include/llvm/Transforms/Scalar.h b/llvm/include/llvm/Transforms/Scalar.h
index 17f4327eb3e1ab..6ee964ac7c0d9d 100644
--- a/llvm/include/llvm/Transforms/Scalar.h
+++ b/llvm/include/llvm/Transforms/Scalar.h
@@ -153,9 +153,16 @@ extern char &InferAddressSpacesID;
 
 //===----------------------------------------------------------------------===//
 //
-// TLSVariableHoist - This pass reduce duplicated TLS address call.
+// LowerExpectIntrinsics - Removes llvm.expect intrinsics and creates
+// "block_weights" metadata.
+FunctionPass *createLowerExpectIntrinsicPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerConstantIntrinsicss - Expand any remaining llvm.objectsize and
+// llvm.is.constant intrinsic calls, even for the unknown cases.
 //
-FunctionPass *createTLSVariableHoistPass();
+FunctionPass *createLowerConstantIntrinsicsPass();
 
 //===----------------------------------------------------------------------===//
 //
diff --git a/llvm/include/llvm/Transforms/Scalar/TLSVariableHoist.h b/llvm/include/llvm/Transforms/Scalar/TLSVariableHoist.h
deleted file mode 100644
index 2a1b02b40eebff..00000000000000
--- a/llvm/include/llvm/Transforms/Scalar/TLSVariableHoist.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//==- TLSVariableHoist.h ------ Remove Redundant TLS Loads -------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass identifies/eliminates Redundant TLS Loads if related option is set.
-// For example:
-// static __thread int x;
-// int g();
-// int f(int c) {
-//   int *px = &x;
-//   while (c--)
-//     *px += g();
-//   return *px;
-// }
-//
-// will generate Redundant TLS Loads by compiling it with
-// clang++ -fPIC -ftls-model=global-dynamic -O2 -S
-//
-// .LBB0_2:                                # %while.body
-//                                         # =>This Inner Loop Header: Depth=1
-//         callq   _Z1gv at PLT
-//         movl    %eax, %ebp
-//         leaq    _ZL1x at TLSLD(%rip), %rdi
-//         callq   __tls_get_addr at PLT
-//         addl    _ZL1x at DTPOFF(%rax), %ebp
-//         movl    %ebp, _ZL1x at DTPOFF(%rax)
-//         addl    $-1, %ebx
-//         jne     .LBB0_2
-//         jmp     .LBB0_3
-// .LBB0_4:                                # %entry.while.end_crit_edge
-//         leaq    _ZL1x at TLSLD(%rip), %rdi
-//         callq   __tls_get_addr at PLT
-//         movl    _ZL1x at DTPOFF(%rax), %ebp
-//
-// The Redundant TLS Loads will hurt the performance, especially in loops.
-// So we try to eliminate/move them if required by customers, let it be:
-//
-// # %bb.0:                                # %entry
-//         ...
-//         movl    %edi, %ebx
-//         leaq    _ZL1x at TLSLD(%rip), %rdi
-//         callq   __tls_get_addr at PLT
-//         leaq    _ZL1x at DTPOFF(%rax), %r14
-//         testl   %ebx, %ebx
-//         je      .LBB0_1
-// .LBB0_2:                                # %while.body
-//                                         # =>This Inner Loop Header: Depth=1
-//         callq   _Z1gv at PLT
-//         addl    (%r14), %eax
-//         movl    %eax, (%r14)
-//         addl    $-1, %ebx
-//         jne     .LBB0_2
-//         jmp     .LBB0_3
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_SCALAR_TLSVARIABLEHOIST_H
-#define LLVM_TRANSFORMS_SCALAR_TLSVARIABLEHOIST_H
-
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/PassManager.h"
-
-namespace llvm {
-
-class BasicBlock;
-class DominatorTree;
-class Function;
-class GlobalVariable;
-class Instruction;
-
-/// A private "module" namespace for types and utilities used by
-/// TLSVariableHoist. These are implementation details and should
-/// not be used by clients.
-namespace tlshoist {
-
-/// Keeps track of the user of a TLS variable and the operand index
-/// where the variable is used.
-struct TLSUser {
-  Instruction *Inst;
-  unsigned OpndIdx;
-
-  TLSUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) {}
-};
-
-/// Keeps track of a TLS variable candidate and its users.
-struct TLSCandidate {
-  SmallVector<TLSUser, 8> Users;
-
-  /// Add the user to the use list and update the cost.
-  void addUser(Instruction *Inst, unsigned Idx) {
-    Users.push_back(TLSUser(Inst, Idx));
-  }
-};
-
-} // end namespace tlshoist
-
-class TLSVariableHoistPass : public PassInfoMixin<TLSVariableHoistPass> {
-public:
-  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-
-  // Glue for old PM.
-  bool runImpl(Function &F, DominatorTree &DT, LoopInfo &LI);
-
-private:
-  DominatorTree *DT;
-  LoopInfo *LI;
-
-  /// Keeps track of TLS variable candidates found in the function.
-  using TLSCandMapType = MapVector<GlobalVariable *, tlshoist::TLSCandidate>;
-  TLSCandMapType TLSCandMap;
-
-  void collectTLSCandidates(Function &Fn);
-  void collectTLSCandidate(Instruction *Inst);
-  Instruction *getNearestLoopDomInst(BasicBlock *BB, Loop *L);
-  Instruction *getDomInst(Instruction *I1, Instruction *I2);
-  BasicBlock::iterator findInsertPos(Function &Fn, GlobalVariable *GV,
-                                     BasicBlock *&PosBB);
-  Instruction *genBitCastInst(Function &Fn, GlobalVariable *GV);
-  bool tryReplaceTLSCandidates(Function &Fn);
-  bool tryReplaceTLSCandidate(Function &Fn, GlobalVariable *GV);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SCALAR_TLSVARIABLEHOIST_H
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp
index 02c3a852697580..e2b6aadbb24fb0 100644
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp
@@ -881,9 +881,6 @@ void TargetPassConfig::addIRPasses() {
   if (!DisableExpandReductions)
     addPass(createExpandReductionsPass());
 
-  if (getOptLevel() != CodeGenOptLevel::None)
-    addPass(createTLSVariableHoistPass());
-
   // Convert conditional moves to conditional jumps when profitable.
   if (getOptLevel() != CodeGenOptLevel::None && !DisableSelectOptimize)
     addPass(createSelectOptimizePass());
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 60ab33bee704c1..abf464825cbd00 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -287,7 +287,6 @@
 #include "llvm/Transforms/Scalar/SpeculativeExecution.h"
 #include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
 #include "llvm/Transforms/Scalar/StructurizeCFG.h"
-#include "llvm/Transforms/Scalar/TLSVariableHoist.h"
 #include "llvm/Transforms/Scalar/TailRecursionElimination.h"
 #include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
 #include "llvm/Transforms/Utils/AddDiscriminators.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 549c1359b5852c..b6f9208fbad0fb 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -468,7 +468,6 @@ FUNCTION_PASS("slsr", StraightLineStrengthReducePass())
 FUNCTION_PASS("stack-protector", StackProtectorPass(TM))
 FUNCTION_PASS("strip-gc-relocates", StripGCRelocates())
 FUNCTION_PASS("tailcallelim", TailCallElimPass())
-FUNCTION_PASS("tlshoist", TLSVariableHoistPass())
 FUNCTION_PASS("transform-warning", WarnMissedTransformationsPass())
 FUNCTION_PASS("trigger-crash-function", TriggerCrashFunctionPass())
 FUNCTION_PASS("trigger-verifier-error", TriggerVerifierErrorPass())
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index 939a1457239567..84a5b02043d012 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -78,7 +78,6 @@ add_llvm_component_library(LLVMScalarOpts
   StraightLineStrengthReduce.cpp
   StructurizeCFG.cpp
   TailRecursionElimination.cpp
-  TLSVariableHoist.cpp
   WarnMissedTransforms.cpp
 
   ADDITIONAL_HEADER_DIRS
diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp
index fa6e671830d962..c7e4a3e824700e 100644
--- a/llvm/lib/Transforms/Scalar/Scalar.cpp
+++ b/llvm/lib/Transforms/Scalar/Scalar.cpp
@@ -44,7 +44,6 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
   initializeStructurizeCFGLegacyPassPass(Registry);
   initializeSinkingLegacyPassPass(Registry);
   initializeTailCallElimPass(Registry);
-  initializeTLSVariableHoistLegacyPassPass(Registry);
   initializeSeparateConstOffsetFromGEPLegacyPassPass(Registry);
   initializeSpeculativeExecutionLegacyPassPass(Registry);
   initializeStraightLineStrengthReduceLegacyPassPass(Registry);
diff --git a/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp b/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp
deleted file mode 100644
index 58ea5b68d5488b..00000000000000
--- a/llvm/lib/Transforms/Scalar/TLSVariableHoist.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-//===- TLSVariableHoist.cpp -------- Remove Redundant TLS Loads ---------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass identifies/eliminate Redundant TLS Loads if related option is set.
-// The example: Please refer to the comment at the head of TLSVariableHoist.h.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Scalar/TLSVariableHoist.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <iterator>
-#include <utility>
-
-using namespace llvm;
-using namespace tlshoist;
-
-#define DEBUG_TYPE "tlshoist"
-
-static cl::opt<bool> TLSLoadHoist(
-    "tls-load-hoist", cl::init(false), cl::Hidden,
-    cl::desc("hoist the TLS loads in PIC model to eliminate redundant "
-             "TLS address calculation."));
-
-namespace {
-
-/// The TLS Variable hoist pass.
-class TLSVariableHoistLegacyPass : public FunctionPass {
-public:
-  static char ID; // Pass identification, replacement for typeid
-
-  TLSVariableHoistLegacyPass() : FunctionPass(ID) {
-    initializeTLSVariableHoistLegacyPassPass(*PassRegistry::getPassRegistry());
-  }
-
-  bool runOnFunction(Function &Fn) override;
-
-  StringRef getPassName() const override { return "TLS Variable Hoist"; }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.setPreservesCFG();
-    AU.addRequired<DominatorTreeWrapperPass>();
-    AU.addRequired<LoopInfoWrapperPass>();
-  }
-
-private:
-  TLSVariableHoistPass Impl;
-};
-
-} // end anonymous namespace
-
-char TLSVariableHoistLegacyPass::ID = 0;
-
-INITIALIZE_PASS_BEGIN(TLSVariableHoistLegacyPass, "tlshoist",
-                      "TLS Variable Hoist", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_END(TLSVariableHoistLegacyPass, "tlshoist",
-                    "TLS Variable Hoist", false, false)
-
-FunctionPass *llvm::createTLSVariableHoistPass() {
-  return new TLSVariableHoistLegacyPass();
-}
-
-/// Perform the TLS Variable Hoist optimization for the given function.
-bool TLSVariableHoistLegacyPass::runOnFunction(Function &Fn) {
-  if (skipFunction(Fn))
-    return false;
-
-  LLVM_DEBUG(dbgs() << "********** Begin TLS Variable Hoist **********\n");
-  LLVM_DEBUG(dbgs() << "********** Function: " << Fn.getName() << '\n');
-
-  bool MadeChange =
-      Impl.runImpl(Fn, getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
-                   getAnalysis<LoopInfoWrapperPass>().getLoopInfo());
-
-  if (MadeChange) {
-    LLVM_DEBUG(dbgs() << "********** Function after TLS Variable Hoist: "
-                      << Fn.getName() << '\n');
-    LLVM_DEBUG(dbgs() << Fn);
-  }
-  LLVM_DEBUG(dbgs() << "********** End TLS Variable Hoist **********\n");
-
-  return MadeChange;
-}
-
-void TLSVariableHoistPass::collectTLSCandidate(Instruction *Inst) {
-  // Skip all cast instructions. They are visited indirectly later on.
-  if (Inst->isCast())
-    return;
-
-  // Scan all operands.
-  for (unsigned Idx = 0, E = Inst->getNumOperands(); Idx != E; ++Idx) {
-    auto *GV = dyn_cast<GlobalVariable>(Inst->getOperand(Idx));
-    if (!GV || !GV->isThreadLocal())
-      continue;
-
-    // Add Candidate to TLSCandMap (GV --> Candidate).
-    TLSCandMap[GV].addUser(Inst, Idx);
-  }
-}
-
-void TLSVariableHoistPass::collectTLSCandidates(Function &Fn) {
-  // First, quickly check if there is TLS Variable.
-  Module *M = Fn.getParent();
-
-  bool HasTLS = llvm::any_of(
-      M->globals(), [](GlobalVariable &GV) { return GV.isThreadLocal(); });
-
-  // If non, directly return.
-  if (!HasTLS)
-    return;
-
-  TLSCandMap.clear();
-
-  // Then, collect TLS Variable info.
-  for (BasicBlock &BB : Fn) {
-    // Ignore unreachable basic blocks.
-    if (!DT->isReachableFromEntry(&BB))
-      continue;
-
-    for (Instruction &Inst : BB)
-      collectTLSCandidate(&Inst);
-  }
-}
-
-static bool oneUseOutsideLoop(tlshoist::TLSCandidate &Cand, LoopInfo *LI) {
-  if (Cand.Users.size() != 1)
-    return false;
-
-  BasicBlock *BB = Cand.Users[0].Inst->getParent();
-  if (LI->getLoopFor(BB))
-    return false;
-
-  return true;
-}
-
-Instruction *TLSVariableHoistPass::getNearestLoopDomInst(BasicBlock *BB,
-                                                         Loop *L) {
-  assert(L && "Unexcepted Loop status!");
-
-  // Get the outermost loop.
-  while (Loop *Parent = L->getParentLoop())
-    L = Parent;
-
-  BasicBlock *PreHeader = L->getLoopPreheader();
-
-  // There is unique predecessor outside the loop.
-  if (PreHeader)
-    return PreHeader->getTerminator();
-
-  BasicBlock *Header = L->getHeader();
-  BasicBlock *Dom = Header;
-  for (BasicBlock *PredBB : predecessors(Header))
-    Dom = DT->findNearestCommonDominator(Dom, PredBB);
-
-  assert(Dom && "Not find dominator BB!");
-  Instruction *Term = Dom->getTerminator();
-
-  return Term;
-}
-
-Instruction *TLSVariableHoistPass::getDomInst(Instruction *I1,
-                                              Instruction *I2) {
-  if (!I1)
-    return I2;
-  return DT->findNearestCommonDominator(I1, I2);
-}
-
-BasicBlock::iterator TLSVariableHoistPass::findInsertPos(Function &Fn,
-                                                         GlobalVariable *GV,
-                                                         BasicBlock *&PosBB) {
-  tlshoist::TLSCandidate &Cand = TLSCandMap[GV];
-
-  // We should hoist the TLS use out of loop, so choose its nearest instruction
-  // which dominate the loop and the outside loops (if exist).
-  Instruction *LastPos = nullptr;
-  for (auto &User : Cand.Users) {
-    BasicBlock *BB = User.Inst->getParent();
-    Instruction *Pos = User.Inst;
-    if (Loop *L = LI->getLoopFor(BB)) {
-      Pos = getNearestLoopDomInst(BB, L);
-      assert(Pos && "Not find insert position out of loop!");
-    }
-    Pos = getDomInst(LastPos, Pos);
-    LastPos = Pos;
-  }
-
-  assert(LastPos && "Unexpected insert position!");
-  BasicBlock *Parent = LastPos->getParent();
-  PosBB = Parent;
-  return LastPos->getIterator();
-}
-
-// Generate a bitcast (no type change) to replace the uses of TLS Candidate.
-Instruction *TLSVariableHoistPass::genBitCastInst(Function &Fn,
-                                                  GlobalVariable *GV) {
-  BasicBlock *PosBB = &Fn.getEntryBlock();
-  BasicBlock::iterator Iter = findInsertPos(Fn, GV, PosBB);
-  Type *Ty = GV->getType();
-  auto *CastInst = new BitCastInst(GV, Ty, "tls_bitcast");
-  CastInst->insertInto(PosBB, Iter);
-  return CastInst;
-}
-
-bool TLSVariableHoistPass::tryReplaceTLSCandidate(Function &Fn,
-                                                  GlobalVariable *GV) {
-
-  tlshoist::TLSCandidate &Cand = TLSCandMap[GV];
-
-  // If only used 1 time and not in loops, we no need to replace it.
-  if (oneUseOutsideLoop(Cand, LI))
-    return false;
-
-  // Generate a bitcast (no type change)
-  auto *CastInst = genBitCastInst(Fn, GV);
-
-  // to replace the uses of TLS Candidate
-  for (auto &User : Cand.Users)
-    User.Inst->setOperand(User.OpndIdx, CastInst);
-
-  return true;
-}
-
-bool TLSVariableHoistPass::tryReplaceTLSCandidates(Function &Fn) {
-  if (TLSCandMap.empty())
-    return false;
-
-  bool Replaced = false;
-  for (auto &GV2Cand : TLSCandMap) {
-    GlobalVariable *GV = GV2Cand.first;
-    Replaced |= tryReplaceTLSCandidate(Fn, GV);
-  }
-
-  return Replaced;
-}
-
-/// Optimize expensive TLS variables in the given function.
-bool TLSVariableHoistPass::runImpl(Function &Fn, DominatorTree &DT,
-                                   LoopInfo &LI) {
-  if (Fn.hasOptNone())
-    return false;
-
-  if (!TLSLoadHoist && !Fn.getAttributes().hasFnAttr("tls-load-hoist"))
-    return false;
-
-  this->LI = &LI;
-  this->DT = &DT;
-  assert(this->LI && this->DT && "Unexcepted requirement!");
-
-  // Collect all TLS variable candidates.
-  collectTLSCandidates(Fn);
-
-  bool MadeChange = tryReplaceTLSCandidates(Fn);
-
-  return MadeChange;
-}
-
-PreservedAnalyses TLSVariableHoistPass::run(Function &F,
-                                            FunctionAnalysisManager &AM) {
-
-  auto &LI = AM.getResult<LoopAnalysis>(F);
-  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
-
-  if (!runImpl(F, DT, LI))
-    return PreservedAnalyses::all();
-
-  PreservedAnalyses PA;
-  PA.preserveSet<CFGAnalyses>();
-  return PA;
-}
diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll
index fb94c040ae341a..de370ac0696f56 100644
--- a/llvm/test/CodeGen/AArch64/O3-pipeli...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/114740


More information about the llvm-commits mailing list