Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:14

0001 //===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//
0002 //
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 //
0010 // This file declares some helpers classes to handle Linker Optimization Hint
0011 // (LOH).
0012 //
0013 // FIXME: LOH interface supports only MachO format at the moment.
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
0017 #define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H
0018 
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/ADT/StringSwitch.h"
0022 #include <cassert>
0023 #include <cstdint>
0024 
0025 namespace llvm {
0026 
0027 class MachObjectWriter;
0028 class MCAssembler;
0029 class MCSymbol;
0030 class raw_ostream;
0031 
0032 /// Linker Optimization Hint Type.
0033 enum MCLOHType {
0034   MCLOH_AdrpAdrp = 0x1u,      ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.
0035   MCLOH_AdrpLdr = 0x2u,       ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.
0036   MCLOH_AdrpAddLdr = 0x3u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.
0037   MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.
0038   MCLOH_AdrpAddStr = 0x5u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.
0039   MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.
0040   MCLOH_AdrpAdd = 0x7u,       ///< Adrp _v@PAGE -> Add _v@PAGEOFF.
0041   MCLOH_AdrpLdrGot = 0x8u     ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.
0042 };
0043 
0044 static inline StringRef MCLOHDirectiveName() {
0045   return StringRef(".loh");
0046 }
0047 
0048 static inline bool isValidMCLOHType(unsigned Kind) {
0049   return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;
0050 }
0051 
0052 static inline int MCLOHNameToId(StringRef Name) {
0053 #define MCLOHCaseNameToId(Name)     .Case(#Name, MCLOH_ ## Name)
0054   return StringSwitch<int>(Name)
0055     MCLOHCaseNameToId(AdrpAdrp)
0056     MCLOHCaseNameToId(AdrpLdr)
0057     MCLOHCaseNameToId(AdrpAddLdr)
0058     MCLOHCaseNameToId(AdrpLdrGotLdr)
0059     MCLOHCaseNameToId(AdrpAddStr)
0060     MCLOHCaseNameToId(AdrpLdrGotStr)
0061     MCLOHCaseNameToId(AdrpAdd)
0062     MCLOHCaseNameToId(AdrpLdrGot)
0063     .Default(-1);
0064 #undef MCLOHCaseNameToId
0065 }
0066 
0067 static inline StringRef MCLOHIdToName(MCLOHType Kind) {
0068 #define MCLOHCaseIdToName(Name)      case MCLOH_ ## Name: return StringRef(#Name);
0069   switch (Kind) {
0070     MCLOHCaseIdToName(AdrpAdrp);
0071     MCLOHCaseIdToName(AdrpLdr);
0072     MCLOHCaseIdToName(AdrpAddLdr);
0073     MCLOHCaseIdToName(AdrpLdrGotLdr);
0074     MCLOHCaseIdToName(AdrpAddStr);
0075     MCLOHCaseIdToName(AdrpLdrGotStr);
0076     MCLOHCaseIdToName(AdrpAdd);
0077     MCLOHCaseIdToName(AdrpLdrGot);
0078   }
0079   return StringRef();
0080 #undef MCLOHCaseIdToName
0081 }
0082 
0083 static inline int MCLOHIdToNbArgs(MCLOHType Kind) {
0084   switch (Kind) {
0085     // LOH with two arguments
0086   case MCLOH_AdrpAdrp:
0087   case MCLOH_AdrpLdr:
0088   case MCLOH_AdrpAdd:
0089   case MCLOH_AdrpLdrGot:
0090     return 2;
0091     // LOH with three arguments
0092   case MCLOH_AdrpAddLdr:
0093   case MCLOH_AdrpLdrGotLdr:
0094   case MCLOH_AdrpAddStr:
0095   case MCLOH_AdrpLdrGotStr:
0096     return 3;
0097   }
0098   return -1;
0099 }
0100 
0101 /// Store Linker Optimization Hint information (LOH).
0102 class MCLOHDirective {
0103   MCLOHType Kind;
0104 
0105   /// Arguments of this directive. Order matters.
0106   SmallVector<MCSymbol *, 3> Args;
0107 
0108   /// Emit this directive in \p OutStream using the information available
0109   /// in the given \p ObjWriter and \p Layout to get the address of the
0110   /// arguments within the object file.
0111   void emit_impl(const MCAssembler &Asm, raw_ostream &OutStream,
0112                  const MachObjectWriter &ObjWriter) const;
0113 
0114 public:
0115   using LOHArgs = SmallVectorImpl<MCSymbol *>;
0116 
0117   MCLOHDirective(MCLOHType Kind, const LOHArgs &Args)
0118       : Kind(Kind), Args(Args.begin(), Args.end()) {
0119     assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");
0120   }
0121 
0122   MCLOHType getKind() const { return Kind; }
0123 
0124   const LOHArgs &getArgs() const { return Args; }
0125 
0126   /// Emit this directive as:
0127   /// <kind, numArgs, addr1, ..., addrN>
0128   void emit(const MCAssembler &Asm, MachObjectWriter &ObjWriter) const;
0129 
0130   /// Get the size in bytes of this directive if emitted in \p ObjWriter with
0131   /// the given \p Layout.
0132   uint64_t getEmitSize(const MCAssembler &Asm,
0133                        const MachObjectWriter &ObjWriter) const;
0134 };
0135 
0136 class MCLOHContainer {
0137   /// Keep track of the emit size of all the LOHs.
0138   mutable uint64_t EmitSize = 0;
0139 
0140   /// Keep track of all LOH directives.
0141   SmallVector<MCLOHDirective, 32> Directives;
0142 
0143 public:
0144   using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
0145 
0146   MCLOHContainer() = default;
0147 
0148   /// Const accessor to the directives.
0149   const LOHDirectives &getDirectives() const {
0150     return Directives;
0151   }
0152 
0153   /// Add the directive of the given kind \p Kind with the given arguments
0154   /// \p Args to the container.
0155   void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
0156     Directives.push_back(MCLOHDirective(Kind, Args));
0157   }
0158 
0159   /// Get the size of the directives if emitted.
0160   uint64_t getEmitSize(const MCAssembler &Asm,
0161                        const MachObjectWriter &ObjWriter) const {
0162     if (!EmitSize) {
0163       for (const MCLOHDirective &D : Directives)
0164         EmitSize += D.getEmitSize(Asm, ObjWriter);
0165     }
0166     return EmitSize;
0167   }
0168 
0169   /// Emit all Linker Optimization Hint in one big table.
0170   /// Each line of the table is emitted by LOHDirective::emit.
0171   void emit(const MCAssembler &Asm, MachObjectWriter &ObjWriter) const {
0172     for (const MCLOHDirective &D : Directives)
0173       D.emit(Asm, ObjWriter);
0174   }
0175 
0176   void reset() {
0177     Directives.clear();
0178     EmitSize = 0;
0179   }
0180 };
0181 
0182 // Add types for specialized template using MCSymbol.
0183 using MCLOHArgs = MCLOHDirective::LOHArgs;
0184 using MCLOHDirectives = MCLOHContainer::LOHDirectives;
0185 
0186 } // end namespace llvm
0187 
0188 #endif // LLVM_MC_MCLINKEROPTIMIZATIONHINT_H