File indexing completed on 2026-05-10 08:44:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
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
0033 enum MCLOHType {
0034 MCLOH_AdrpAdrp = 0x1u,
0035 MCLOH_AdrpLdr = 0x2u,
0036 MCLOH_AdrpAddLdr = 0x3u,
0037 MCLOH_AdrpLdrGotLdr = 0x4u,
0038 MCLOH_AdrpAddStr = 0x5u,
0039 MCLOH_AdrpLdrGotStr = 0x6u,
0040 MCLOH_AdrpAdd = 0x7u,
0041 MCLOH_AdrpLdrGot = 0x8u
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
0086 case MCLOH_AdrpAdrp:
0087 case MCLOH_AdrpLdr:
0088 case MCLOH_AdrpAdd:
0089 case MCLOH_AdrpLdrGot:
0090 return 2;
0091
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
0102 class MCLOHDirective {
0103 MCLOHType Kind;
0104
0105
0106 SmallVector<MCSymbol *, 3> Args;
0107
0108
0109
0110
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
0127
0128 void emit(const MCAssembler &Asm, MachObjectWriter &ObjWriter) const;
0129
0130
0131
0132 uint64_t getEmitSize(const MCAssembler &Asm,
0133 const MachObjectWriter &ObjWriter) const;
0134 };
0135
0136 class MCLOHContainer {
0137
0138 mutable uint64_t EmitSize = 0;
0139
0140
0141 SmallVector<MCLOHDirective, 32> Directives;
0142
0143 public:
0144 using LOHDirectives = SmallVectorImpl<MCLOHDirective>;
0145
0146 MCLOHContainer() = default;
0147
0148
0149 const LOHDirectives &getDirectives() const {
0150 return Directives;
0151 }
0152
0153
0154
0155 void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) {
0156 Directives.push_back(MCLOHDirective(Kind, Args));
0157 }
0158
0159
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
0170
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
0183 using MCLOHArgs = MCLOHDirective::LOHArgs;
0184 using MCLOHDirectives = MCLOHContainer::LOHDirectives;
0185
0186 }
0187
0188 #endif