LLVM 19.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"
67#include "llvm/IR/PassManager.h"
68
69namespace llvm {
70
71class BasicBlock;
72class DominatorTree;
73class Function;
74class GlobalVariable;
75class 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.
80namespace tlshoist {
81
82/// Keeps track of the user of a TLS variable and the operand index
83/// where the variable is used.
84struct TLSUser {
86 unsigned OpndIdx;
87
89};
90
91/// Keeps track of a TLS variable candidate and its users.
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
103class TLSVariableHoistPass : public PassInfoMixin<TLSVariableHoistPass> {
104public:
106
107 // Glue for old PM.
108 bool runImpl(Function &F, DominatorTree &DT, LoopInfo &LI);
109
110private:
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
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define F(x, y, z)
Definition: MD5.cpp:55
This file implements a map that provides insertion order iteration.
This header defines various interfaces for pass management in LLVM.
This file defines the SmallVector class.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:321
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:165
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:162
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:44
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
bool runImpl(Function &F, DominatorTree &DT, LoopInfo &LI)
Optimize expensive TLS variables in the given function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:74
Keeps track of a TLS variable candidate and its users.
SmallVector< TLSUser, 8 > Users
void addUser(Instruction *Inst, unsigned Idx)
Add the user to the use list and update the cost.
Keeps track of the user of a TLS variable and the operand index where the variable is used.
TLSUser(Instruction *Inst, unsigned Idx)