Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  132.