Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//
  2. //
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file declares some helpers classes to handle Linker Optimization Hint
  11. // (LOH).
  12. //
  13. // FIXME: LOH interface supports only MachO format at the moment.
  14. //===----------------------------------------------------------------------===//
  15.  
  16. #ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
  17. #define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
  18.  
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/ADT/StringSwitch.h"
  22. #include <cassert>
  23. #include <cstdint>
  24.  
  25. namespace llvm {
  26.  
  27. class MachObjectWriter;
  28. class MCAsmLayout;
  29. class MCSymbol;
  30. class raw_ostream;
  31.  
  32. /// Linker Optimization Hint Type.
  33. enum MCLOHType {
  34.   MCLOH_AdrpAdrp = 0x1u,      ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
  35.   MCLOH_AdrpLdr = 0x2u,       ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
  36.   MCLOH_AdrpAddLdr = 0x3u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
  37.   MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
  38.   MCLOH_AdrpAddStr = 0x5u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
  39.   MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
  40.   MCLOH_AdrpAdd = 0x7u,       ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
  41.   MCLOH_AdrpLdrGot = 0x8u     ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
  42. };
  43.  
  44. static inline StringRef MCLOHDirectiveName() {
  45.   return StringRef(".loh");
  46. }
  47.  
  48. static inline bool isValidMCLOHType(unsigned Kind) {
  49.   return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
  50. }
  51.  
  52. static inline int MCLOHNameToId(StringRef Name) {
  53. #define MCLOHCaseNameToId(Name)     .Case(#Name, MCLOH_ ## Name)
  54.   return StringSwitch<int>(Name)
  55.     MCLOHCaseNameToId(AdrpAdrp)
  56.     MCLOHCaseNameToId(AdrpLdr)
  57.     MCLOHCaseNameToId(AdrpAddLdr)
  58.     MCLOHCaseNameToId(AdrpLdrGotLdr)
  59.     MCLOHCaseNameToId(AdrpAddStr)
  60.     MCLOHCaseNameToId(AdrpLdrGotStr)
  61.     MCLOHCaseNameToId(AdrpAdd)
  62.     MCLOHCaseNameToId(AdrpLdrGot)
  63.     .Default(-1);
  64. #undef MCLOHCaseNameToId
  65. }
  66.  
  67. static inline StringRef MCLOHIdToName(MCLOHType Kind) {
  68. #define MCLOHCaseIdToName(Name)      case MCLOH_ ## Name: return StringRef(#Name);
  69.   switch (Kind) {
  70.     MCLOHCaseIdToName(AdrpAdrp);
  71.     MCLOHCaseIdToName(AdrpLdr);
  72.     MCLOHCaseIdToName(AdrpAddLdr);
  73.     MCLOHCaseIdToName(AdrpLdrGotLdr);
  74.     MCLOHCaseIdToName(AdrpAddStr);
  75.     MCLOHCaseIdToName(AdrpLdrGotStr);
  76.     MCLOHCaseIdToName(AdrpAdd);
  77.     MCLOHCaseIdToName(AdrpLdrGot);
  78.   }
  79.   return StringRef();
  80. #undef MCLOHCaseIdToName
  81. }
  82.  
  83. static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
  84.   switch (Kind) {
  85.     // LOH with two arguments
  86.   case MCLOH_AdrpAdrp:
  87.   case MCLOH_AdrpLdr:
  88.   case MCLOH_AdrpAdd:
  89.   case MCLOH_AdrpLdrGot:
  90.     return 2;
  91.     // LOH with three arguments
  92.   case MCLOH_AdrpAddLdr:
  93.   case MCLOH_AdrpLdrGotLdr:
  94.   case MCLOH_AdrpAddStr:
  95.   case MCLOH_AdrpLdrGotStr:
  96.     return 3;
  97.   }
  98.   return -1;
  99. }
  100.  
  101. /// Store Linker Optimization Hint information (LOH).
  102. class MCLOHDirective {
  103.   MCLOHType Kind;
  104.  
  105.   /// Arguments of this directive. Order matters.
  106.   SmallVector<MCSymbol *, 3> Args;
  107.  
  108.   /// Emit this directive in \p OutStream using the information available
  109.   /// in the given \p ObjWriter and \p Layout to get the address of the
  110.   /// arguments within the object file.
  111.   void emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,
  112.                  const MCAsmLayout &Layout) const;
  113.  
  114. public:
  115.   using LOHArgs = SmallVectorImpl<MCSymbol *>;
  116.  
  117.   MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
  118.       : Kind(Kind), Args(Args.begin(), Args.end()) {
  119.     assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
  120.   }
  121.  
  122.   MCLOHType getKind() const { return Kind; }
  123.  
  124.   const LOHArgs &getArgs() const { return Args; }
  125.  
  126.   /// Emit this directive as:
  127.   /// <kind, numArgs, addr1, ..., addrN>
  128.   void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const;
  129.  
  130.   /// Get the size in bytes of this directive if emitted in \p ObjWriter with
  131.   /// the given \p Layout.
  132.   uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
  133.                        const MCAsmLayout &Layout) const;
  134. };
  135.  
  136. class MCLOHContainer {
  137.   /// Keep track of the emit size of all the LOHs.
  138.   mutable uint64_t EmitSize = 0;
  139.  
  140.   /// Keep track of all LOH directives.
  141.   SmallVector<MCLOHDirective, 32> Directives;
  142.  
  143. public:
  144.   using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
  145.  
  146.   MCLOHContainer() = default;
  147.  
  148.   /// Const accessor to the directives.
  149.   const LOHDirectives &getDirectives() const {
  150.     return Directives;
  151.   }
  152.  
  153.   /// Add the directive of the given kind \p Kind with the given arguments
  154.   /// \p Args to the container.
  155.   void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
  156.     Directives.push_back(MCLOHDirective(Kind, Args));
  157.   }
  158.  
  159.   /// Get the size of the directives if emitted.
  160.   uint64_t getEmitSize(const MachObjectWriter &ObjWriter,
  161.                        const MCAsmLayout &Layout) const {
  162.     if (!EmitSize) {
  163.       for (const MCLOHDirective &D : Directives)
  164.         EmitSize += D.getEmitSize(ObjWriter, Layout);
  165.     }
  166.     return EmitSize;
  167.   }
  168.  
  169.   /// Emit all Linker Optimization Hint in one big table.
  170.   /// Each line of the table is emitted by LOHDirective::emit.
  171.   void emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {
  172.     for (const MCLOHDirective &D : Directives)
  173.       D.emit(ObjWriter, Layout);
  174.   }
  175.  
  176.   void reset() {
  177.     Directives.clear();
  178.     EmitSize = 0;
  179.   }
  180. };
  181.  
  182. // Add types for specialized template using MCSymbol.
  183. using MCLOHArgs = MCLOHDirective::LOHArgs;
  184. using MCLOHDirectives = MCLOHContainer::LOHDirectives;
  185.  
  186. } // end namespace llvm
  187.  
  188. #endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
  189.