LLVM  16.0.0git
TLSVariableHoist.h
Go to the documentation of this file.
1 //==- TLSVariableHoist.h ------ Remove Redundant TLS Loads -------*- C++ -*-==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass identifies/eliminates Redundant TLS Loads if related option is set.
10 // For example:
11 // static __thread int x;
12 // int g();
13 // int f(int c) {
14 // int *px = &x;
15 // while (c--)
16 // *px += g();
17 // return *px;
18 // }
19 //
20 // will generate Redundant TLS Loads by compiling it with
21 // clang++ -fPIC -ftls-model=global-dynamic -O2 -S
22 //
23 // .LBB0_2: # %while.body
24 // # =>This Inner Loop Header: Depth=1
25 // callq _Z1gv@PLT
26 // movl %eax, %ebp
27 // leaq _ZL1x@TLSLD(%rip), %rdi
28 // callq __tls_get_addr@PLT
29 // addl _ZL1x@DTPOFF(%rax), %ebp
30 // movl %ebp, _ZL1x@DTPOFF(%rax)
31 // addl $-1, %ebx
32 // jne .LBB0_2
33 // jmp .LBB0_3
34 // .LBB0_4: # %entry.while.end_crit_edge
35 // leaq _ZL1x@TLSLD(%rip), %rdi
36 // callq __tls_get_addr@PLT
37 // movl _ZL1x@DTPOFF(%rax), %ebp
38 //
39 // The Redundant TLS Loads will hurt the performance, especially in loops.
40 // So we try to eliminate/move them if required by customers, let it be:
41 //
42 // # %bb.0: # %entry
43 // ...
44 // movl %edi, %ebx
45 // leaq _ZL1x@TLSLD(%rip), %rdi
46 // callq __tls_get_addr@PLT
47 // leaq _ZL1x@DTPOFF(%rax), %r14
48 // testl %ebx, %ebx
49 // je .LBB0_1
50 // .LBB0_2: # %while.body
51 // # =>This Inner Loop Header: Depth=1
52 // callq _Z1gv@PLT
53 // addl (%r14), %eax
54 // movl %eax, (%r14)
55 // addl $-1, %ebx
56 // jne .LBB0_2
57 // jmp .LBB0_3
58 //
59 //===----------------------------------------------------------------------===//
60 
61 #ifndef LLVM_TRANSFORMS_SCALAR_TLSVARIABLEHOIST_H
62 #define LLVM_TRANSFORMS_SCALAR_TLSVARIABLEHOIST_H
63 
64 #include "llvm/ADT/MapVector.h"
65 #include "llvm/ADT/SmallVector.h"
66 #include "llvm/Analysis/LoopInfo.h"
67 #include "llvm/IR/PassManager.h"
68 
69 namespace llvm {
70 
71 class BasicBlock;
72 class DominatorTree;
73 class Function;
74 class GlobalVariable;
75 class Instruction;
76 
77 /// A private "module" namespace for types and utilities used by
78 /// TLSVariableHoist. These are implementation details and should
79 /// not be used by clients.
80 namespace tlshoist {
81 
82 /// Keeps track of the user of a TLS variable and the operand index
83 /// where the variable is used.
84 struct TLSUser {
86  unsigned OpndIdx;
87 
88  TLSUser(Instruction *Inst, unsigned Idx) : Inst(Inst), OpndIdx(Idx) {}
89 };
90 
91 /// Keeps track of a TLS variable candidate and its users.
92 struct TLSCandidate {
94 
95  /// Add the user to the use list and update the cost.
96  void addUser(Instruction *Inst, unsigned Idx) {
97  Users.push_back(TLSUser(Inst, Idx));
98  }
99 };
100 
101 } // end namespace tlshoist
102 
103 class TLSVariableHoistPass : public PassInfoMixin<TLSVariableHoistPass> {
104 public:
106 
107  // Glue for old PM.
108  bool runImpl(Function &F, DominatorTree &DT, LoopInfo &LI);
109 
110 private:
111  DominatorTree *DT;
112  LoopInfo *LI;
113 
114  /// Keeps track of TLS variable candidates found in the function.
116  TLSCandMapType TLSCandMap;
117 
118  void collectTLSCandidates(Function &Fn);
119  void collectTLSCandidate(Instruction *Inst);
120  Instruction *getNearestLoopDomInst(BasicBlock *BB, Loop *L);
121  Instruction *getDomInst(Instruction *I1, Instruction *I2);
122  BasicBlock::iterator findInsertPos(Function &Fn, GlobalVariable *GV,
123  BasicBlock *&PosBB);
124  Instruction *genBitCastInst(Function &Fn, GlobalVariable *GV);
125  bool tryReplaceTLSCandidates(Function &Fn);
126  bool tryReplaceTLSCandidate(Function &Fn, GlobalVariable *GV);
127 };
128 
129 } // end namespace llvm
130 
131 #endif // LLVM_TRANSFORMS_SCALAR_TLSVARIABLEHOIST_H
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::tlshoist::TLSUser::TLSUser
TLSUser(Instruction *Inst, unsigned Idx)
Definition: TLSVariableHoist.h:88
llvm::tlshoist::TLSCandidate::Users
SmallVector< TLSUser, 8 > Users
Definition: TLSVariableHoist.h:93
llvm::BasicBlock::iterator
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:87
llvm::PassInfoMixin
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:371
llvm::tlshoist::TLSCandidate::addUser
void addUser(Instruction *Inst, unsigned Idx)
Add the user to the use list and update the cost.
Definition: TLSVariableHoist.h:96
llvm::Function
Definition: Function.h:60
llvm::Loop
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:547
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
MapVector.h
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:166
llvm::MapVector< GlobalVariable *, tlshoist::TLSCandidate >
tlshoist
tlshoist
Definition: TLSVariableHoist.cpp:81
llvm::TLSVariableHoistPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: TLSVariableHoist.cpp:294
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::tlshoist::TLSUser::OpndIdx
unsigned OpndIdx
Definition: TLSVariableHoist.h:86
llvm::Instruction
Definition: Instruction.h:42
LoopInfo.h
llvm::ISD::BasicBlock
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
llvm::tlshoist::TLSUser
Keeps track of the user of a TLS variable and the operand index where the variable is used.
Definition: TLSVariableHoist.h:84
llvm::LoopInfo
Definition: LoopInfo.h:1108
llvm::tlshoist::TLSCandidate
Keeps track of a TLS variable candidate and its users.
Definition: TLSVariableHoist.h:92
llvm::tlshoist::TLSUser::Inst
Instruction * Inst
Definition: TLSVariableHoist.h:85
llvm::TLSVariableHoistPass
Definition: TLSVariableHoist.h:103
PassManager.h
llvm::TLSVariableHoistPass::runImpl
bool runImpl(Function &F, DominatorTree &DT, LoopInfo &LI)
Optimize expensive TLS variables in the given function.
Definition: TLSVariableHoist.cpp:274
SmallVector.h
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::codeview::PublicSymFlags::Function
@ Function