Mercurial > hg > CbC > CbC_llvm
comparison include/llvm/MC/MCLinkerOptimizationHint.h @ 77:54457678186b LLVM3.6
LLVM 3.6
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Sep 2014 22:06:00 +0900 |
parents | |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
34:e874dbf0ad9d | 77:54457678186b |
---|---|
1 //===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===// | |
2 // | |
3 // | |
4 // The LLVM Compiler Infrastructure | |
5 // | |
6 // This file is distributed under the University of Illinois Open Source | |
7 // License. See LICENSE.TXT for details. | |
8 // | |
9 //===----------------------------------------------------------------------===// | |
10 // | |
11 // This file declares some helpers classes to handle Linker Optimization Hint | |
12 // (LOH). | |
13 // | |
14 // FIXME: LOH interface supports only MachO format at the moment. | |
15 //===----------------------------------------------------------------------===// | |
16 | |
17 #ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H | |
18 #define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H | |
19 | |
20 #include "llvm/ADT/SmallVector.h" | |
21 #include "llvm/ADT/StringSwitch.h" | |
22 #include "llvm/ADT/StringRef.h" | |
23 #include "llvm/MC/MCMachObjectWriter.h" | |
24 #include "llvm/Support/raw_ostream.h" | |
25 | |
26 namespace llvm { | |
27 | |
28 // Forward declarations. | |
29 class MCAsmLayout; | |
30 class MCSymbol; | |
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 } | |
65 | |
66 static inline StringRef MCLOHIdToName(MCLOHType Kind) { | |
67 #define MCLOHCaseIdToName(Name) case MCLOH_ ## Name: return StringRef(#Name); | |
68 switch (Kind) { | |
69 MCLOHCaseIdToName(AdrpAdrp); | |
70 MCLOHCaseIdToName(AdrpLdr); | |
71 MCLOHCaseIdToName(AdrpAddLdr); | |
72 MCLOHCaseIdToName(AdrpLdrGotLdr); | |
73 MCLOHCaseIdToName(AdrpAddStr); | |
74 MCLOHCaseIdToName(AdrpLdrGotStr); | |
75 MCLOHCaseIdToName(AdrpAdd); | |
76 MCLOHCaseIdToName(AdrpLdrGot); | |
77 } | |
78 return StringRef(); | |
79 } | |
80 | |
81 static inline int MCLOHIdToNbArgs(MCLOHType Kind) { | |
82 switch (Kind) { | |
83 // LOH with two arguments | |
84 case MCLOH_AdrpAdrp: | |
85 case MCLOH_AdrpLdr: | |
86 case MCLOH_AdrpAdd: | |
87 case MCLOH_AdrpLdrGot: | |
88 return 2; | |
89 // LOH with three arguments | |
90 case MCLOH_AdrpAddLdr: | |
91 case MCLOH_AdrpLdrGotLdr: | |
92 case MCLOH_AdrpAddStr: | |
93 case MCLOH_AdrpLdrGotStr: | |
94 return 3; | |
95 } | |
96 return -1; | |
97 } | |
98 | |
99 /// Store Linker Optimization Hint information (LOH). | |
100 class MCLOHDirective { | |
101 MCLOHType Kind; | |
102 | |
103 /// Arguments of this directive. Order matters. | |
104 SmallVector<MCSymbol *, 3> Args; | |
105 | |
106 /// Emit this directive in @p OutStream using the information available | |
107 /// in the given @p ObjWriter and @p Layout to get the address of the | |
108 /// arguments within the object file. | |
109 void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter, | |
110 const MCAsmLayout &Layout) const; | |
111 | |
112 public: | |
113 typedef SmallVectorImpl<MCSymbol *> LOHArgs; | |
114 | |
115 MCLOHDirective(MCLOHType Kind, const LOHArgs &Args) | |
116 : Kind(Kind), Args(Args.begin(), Args.end()) { | |
117 assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!"); | |
118 } | |
119 | |
120 MCLOHType getKind() const { return Kind; } | |
121 | |
122 const LOHArgs &getArgs() const { return Args; } | |
123 | |
124 /// Emit this directive as: | |
125 /// <kind, numArgs, addr1, ..., addrN> | |
126 void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { | |
127 raw_ostream &OutStream = ObjWriter.getStream(); | |
128 Emit_impl(OutStream, ObjWriter, Layout); | |
129 } | |
130 | |
131 /// Get the size in bytes of this directive if emitted in @p ObjWriter with | |
132 /// the given @p Layout. | |
133 uint64_t getEmitSize(const MachObjectWriter &ObjWriter, | |
134 const MCAsmLayout &Layout) const { | |
135 class raw_counting_ostream : public raw_ostream { | |
136 uint64_t Count; | |
137 | |
138 void write_impl(const char *, size_t size) override { Count += size; } | |
139 | |
140 uint64_t current_pos() const override { return Count; } | |
141 | |
142 public: | |
143 raw_counting_ostream() : Count(0) {} | |
144 ~raw_counting_ostream() { flush(); } | |
145 }; | |
146 | |
147 raw_counting_ostream OutStream; | |
148 Emit_impl(OutStream, ObjWriter, Layout); | |
149 return OutStream.tell(); | |
150 } | |
151 }; | |
152 | |
153 class MCLOHContainer { | |
154 /// Keep track of the emit size of all the LOHs. | |
155 mutable uint64_t EmitSize; | |
156 | |
157 /// Keep track of all LOH directives. | |
158 SmallVector<MCLOHDirective, 32> Directives; | |
159 | |
160 public: | |
161 typedef SmallVectorImpl<MCLOHDirective> LOHDirectives; | |
162 | |
163 MCLOHContainer() : EmitSize(0) {}; | |
164 | |
165 /// Const accessor to the directives. | |
166 const LOHDirectives &getDirectives() const { | |
167 return Directives; | |
168 } | |
169 | |
170 /// Add the directive of the given kind @p Kind with the given arguments | |
171 /// @p Args to the container. | |
172 void addDirective(MCLOHType Kind, const MCLOHDirective::LOHArgs &Args) { | |
173 Directives.push_back(MCLOHDirective(Kind, Args)); | |
174 } | |
175 | |
176 /// Get the size of the directives if emitted. | |
177 uint64_t getEmitSize(const MachObjectWriter &ObjWriter, | |
178 const MCAsmLayout &Layout) const { | |
179 if (!EmitSize) { | |
180 for (const MCLOHDirective &D : Directives) | |
181 EmitSize += D.getEmitSize(ObjWriter, Layout); | |
182 } | |
183 return EmitSize; | |
184 } | |
185 | |
186 /// Emit all Linker Optimization Hint in one big table. | |
187 /// Each line of the table is emitted by LOHDirective::Emit. | |
188 void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const { | |
189 for (const MCLOHDirective &D : Directives) | |
190 D.Emit(ObjWriter, Layout); | |
191 } | |
192 | |
193 void reset() { | |
194 Directives.clear(); | |
195 EmitSize = 0; | |
196 } | |
197 }; | |
198 | |
199 // Add types for specialized template using MCSymbol. | |
200 typedef MCLOHDirective::LOHArgs MCLOHArgs; | |
201 typedef MCLOHContainer::LOHDirectives MCLOHDirectives; | |
202 | |
203 } // end namespace llvm | |
204 | |
205 #endif |