Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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 {
85
  Instruction *Inst;
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 {
93
  SmallVector<TLSUser, 8> 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
 
103
class TLSVariableHoistPass : public PassInfoMixin<TLSVariableHoistPass> {
104
public:
105
  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
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.
115
  using TLSCandMapType = MapVector<GlobalVariable *, tlshoist::TLSCandidate>;
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