refactor section construction in TLOF to be through an explicit
[oota-llvm.git] / include / llvm / Target / TargetLoweringObjectFile.h
1 //===-- llvm/Target/TargetLoweringObjectFile.h - Object Info ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements classes used to handle lowerings specific to common
11 // object file formats.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
16 #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
17
18 // FIXME: Switch to MC.
19 #include "llvm/Target/TargetAsmInfo.h"
20
21 namespace llvm {
22   class MCContext;
23
24 /// SectionKind - This is a simple POD value that classifies the properties of
25 /// a section.  A global variable is classified into the deepest possible
26 /// classification, and then the target maps them onto their sections based on
27 /// what capabilities they have.
28 ///
29 /// The comments below describe these as if they were an inheritance hierarchy
30 /// in order to explain the predicates below.
31 class SectionKind {
32 public:
33   enum Kind {
34     /// Metadata - Debug info sections or other metadata.
35     Metadata,
36     
37     /// Text - Text section, used for functions and other executable code.
38     Text,
39     
40     /// ReadOnly - Data that is never written to at program runtime by the
41     /// program or the dynamic linker.  Things in the top-level readonly
42     /// SectionKind are not mergeable.
43     ReadOnly,
44
45         /// MergeableCString - This is a special section for nul-terminated
46         /// strings.  The linker can unique the C strings, knowing their
47         /// semantics.  Because it uniques based on the nul terminators, the
48         /// compiler can't put strings in this section that have embeded nuls
49         /// in them.
50         MergeableCString,
51     
52         /// MergeableConst - These are sections for merging fixed-length
53         /// constants together.  For example, this can be used to unique
54         /// constant pool entries etc.
55         MergeableConst,
56     
57             /// MergeableConst4 - This is a section used by 4-byte constants,
58             /// for example, floats.
59             MergeableConst4,
60     
61             /// MergeableConst8 - This is a section used by 8-byte constants,
62             /// for example, doubles.
63             MergeableConst8,
64
65             /// MergeableConst16 - This is a section used by 16-byte constants,
66             /// for example, vectors.
67             MergeableConst16,
68     
69     /// Writeable - This is the base of all segments that need to be written
70     /// to during program runtime.
71     
72        /// ThreadLocal - This is the base of all TLS segments.  All TLS
73        /// objects must be writeable, otherwise there is no reason for them to
74        /// be thread local!
75     
76            /// ThreadBSS - Zero-initialized TLS data objects.
77            ThreadBSS,
78     
79            /// ThreadData - Initialized TLS data objects.
80            ThreadData,
81     
82        /// GlobalWriteableData - Writeable data that is global (not thread
83        /// local).
84     
85            /// BSS - Zero initialized writeable data.
86            BSS,
87
88            /// DataRel - This is the most general form of data that is written
89            /// to by the program, it can have random relocations to arbitrary
90            /// globals.
91            DataRel,
92
93                /// DataRelLocal - This is writeable data that has a non-zero
94                /// initializer and has relocations in it, but all of the
95                /// relocations are known to be within the final linked image
96                /// the global is linked into.
97                DataRelLocal,
98
99                    /// DataNoRel - This is writeable data that has a non-zero
100                    /// initializer, but whose initializer is known to have no
101                    /// relocations.
102                    DataNoRel,
103
104            /// ReadOnlyWithRel - These are global variables that are never
105            /// written to by the program, but that have relocations, so they
106            /// must be stuck in a writeable section so that the dynamic linker
107            /// can write to them.  If it chooses to, the dynamic linker can
108            /// mark the pages these globals end up on as read-only after it is
109            /// done with its relocation phase.
110            ReadOnlyWithRel,
111     
112                /// ReadOnlyWithRelLocal - This is data that is readonly by the
113                /// program, but must be writeable so that the dynamic linker
114                /// can perform relocations in it.  This is used when we know
115                /// that all the relocations are to globals in this final
116                /// linked image.
117                ReadOnlyWithRelLocal
118     
119   };
120   
121 private:
122   Kind K : 6;
123   
124   /// Weak - This is true if the referenced symbol is weak (i.e. linkonce,
125   /// weak, weak_odr, etc).  This is orthogonal from the categorization.
126   bool Weak : 1;
127   
128   /// ExplicitSection - This is true if the global had a section explicitly
129   /// specified on it.
130   bool ExplicitSection : 1;
131 public:
132   
133   // FIXME: REMOVE.
134   Kind getKind() const { return K; }
135   
136   bool isWeak() const { return Weak; }
137   bool hasExplicitSection() const { return ExplicitSection; }
138   
139   
140   bool isMetadata() const { return K == Metadata; }
141   bool isText() const { return K == Text; }
142   
143   bool isReadOnly() const {
144     return K == ReadOnly || K == MergeableCString || isMergeableConst();
145   }
146
147   bool isMergeableCString() const { return K == MergeableCString; }
148   bool isMergeableConst() const {
149     return K == MergeableConst || K == MergeableConst4 ||
150            K == MergeableConst8 || K == MergeableConst16;
151   }
152   
153   bool isMergeableConst4() const { return K == MergeableConst4; }
154   bool isMergeableConst8() const { return K == MergeableConst8; }
155   bool isMergeableConst16() const { return K == MergeableConst16; }
156   
157   bool isWriteable() const {
158     return isThreadLocal() || isGlobalWriteableData();
159   }
160   
161   bool isThreadLocal() const {
162     return K == ThreadData || K == ThreadBSS;
163   }
164   
165   bool isThreadBSS() const { return K == ThreadBSS; } 
166   bool isThreadData() const { return K == ThreadData; } 
167
168   bool isGlobalWriteableData() const {
169     return isBSS() || isDataRel() || isReadOnlyWithRel();
170   }
171   
172   bool isBSS() const { return K == BSS; }
173   
174   bool isDataRel() const {
175     return K == DataRel || K == DataRelLocal || K == DataNoRel;
176   }
177   
178   bool isDataRelLocal() const {
179     return K == DataRelLocal || K == DataNoRel;
180   }
181
182   bool isDataNoRel() const { return K == DataNoRel; }
183   
184   bool isReadOnlyWithRel() const {
185     return K == ReadOnlyWithRel || K == ReadOnlyWithRelLocal;
186   }
187
188   bool isReadOnlyWithRelLocal() const {
189     return K == ReadOnlyWithRelLocal;
190   }
191   
192   static SectionKind get(Kind K, bool isWeak = false,
193                          bool hasExplicitSection = false) {
194     SectionKind Res;
195     Res.K = K;
196     Res.Weak = isWeak;
197     Res.ExplicitSection = hasExplicitSection;
198     return Res;
199   }
200 };
201
202 class Section {
203 public:
204
205   std::string Name;
206   SectionKind Kind;
207
208   explicit Section() { }
209   Section(const std::string &N, SectionKind K) : Name(N), Kind(K) {}
210   const std::string &getName() const { return Name; }
211   SectionKind getKind() const { return Kind; }
212 };
213   
214   
215 class TargetLoweringObjectFile {
216 private:
217   mutable StringMap<Section> Sections;
218 protected:
219   
220   TargetLoweringObjectFile();
221   
222   /// TextSection - Section directive for standard text.
223   ///
224   const Section *TextSection;           // Defaults to ".text".
225   
226   /// DataSection - Section directive for standard data.
227   ///
228   const Section *DataSection;           // Defaults to ".data".
229   
230   
231   
232   // FIXME: SINK THESE.
233   const Section *BSSSection_;
234
235   /// ReadOnlySection - This is the directive that is emitted to switch to a
236   /// read-only section for constant data (e.g. data declared const,
237   /// jump tables).
238   const Section *ReadOnlySection;       // Defaults to NULL
239   
240   /// TLSDataSection - Section directive for Thread Local data.
241   ///
242   const Section *TLSDataSection;        // Defaults to ".tdata".
243   
244   /// TLSBSSSection - Section directive for Thread Local uninitialized data.
245   /// Null if this target doesn't support a BSS section.
246   ///
247   const Section *TLSBSSSection;         // Defaults to ".tbss".
248   
249   const Section *CStringSection_;
250   
251 public:
252   // FIXME: NONPUB.
253   const Section *getOrCreateSection(const char *Name,
254                                     bool isDirective,
255                                     SectionKind::Kind K) const;
256 public:
257   
258   virtual ~TargetLoweringObjectFile();
259   
260   /// Initialize - this method must be called before any actual lowering is
261   /// done.  This specifies the current context for codegen, and gives the
262   /// lowering implementations a chance to set up their default sections.
263   virtual void Initialize(MCContext &Ctx, const TargetMachine &TM) {}
264   
265   
266   const Section *getTextSection() const { return TextSection; }
267   const Section *getDataSection() const { return DataSection; }
268   
269   
270   /// getSectionForMergeableConstant - Given a mergeable constant with the
271   /// specified size and relocation information, return a section that it
272   /// should be placed in.
273   virtual const Section *
274   getSectionForMergeableConstant(SectionKind Kind) const;
275   
276   /// getKindForNamedSection - If this target wants to be able to override
277   /// section flags based on the name of the section specified for a global
278   /// variable, it can implement this.  This is used on ELF systems so that
279   /// ".tbss" gets the TLS bit set etc.
280   virtual SectionKind::Kind getKindForNamedSection(const char *Section,
281                                                    SectionKind::Kind K) const{
282     return K;
283   }
284   
285   /// SectionForGlobal - This method computes the appropriate section to emit
286   /// the specified global variable or function definition.  This should not
287   /// be passed external (or available externally) globals.
288   const Section *SectionForGlobal(const GlobalValue *GV,
289                                   Mangler *Mang,
290                                   const TargetMachine &TM) const;
291   
292   /// getSpecialCasedSectionGlobals - Allow the target to completely override
293   /// section assignment of a global.
294   /// FIXME: ELIMINATE this by making PIC16 implement ADDRESS with
295   /// getFlagsForNamedSection.
296   virtual const Section *
297   getSpecialCasedSectionGlobals(const GlobalValue *GV, Mangler *Mang,
298                                 SectionKind Kind) const {
299     return 0;
300   }
301   
302   /// getSectionFlagsAsString - Turn the flags in the specified SectionKind
303   /// into a string that can be printed to the assembly file after the
304   /// ".section foo" part of a section directive.
305   virtual void getSectionFlagsAsString(SectionKind Kind,
306                                        SmallVectorImpl<char> &Str) const {
307   }
308   
309 protected:
310   virtual const Section *
311   SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
312                          Mangler *Mang, const TargetMachine &TM) const;
313 };
314   
315   
316   
317
318 class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
319   bool AtIsCommentChar;  // True if @ is the comment character on this target.
320   bool HasCrazyBSS;
321 public:
322   /// ELF Constructor - AtIsCommentChar is true if the CommentCharacter from TAI
323   /// is "@".
324   TargetLoweringObjectFileELF(bool atIsCommentChar = false,
325                               // FIXME: REMOVE AFTER UNIQUING IS FIXED.
326                               bool hasCrazyBSS = false)
327     : AtIsCommentChar(atIsCommentChar), HasCrazyBSS(hasCrazyBSS) {}
328     
329   virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
330   
331   
332   /// getSectionForMergeableConstant - Given a mergeable constant with the
333   /// specified size and relocation information, return a section that it
334   /// should be placed in.
335   virtual const Section *
336   getSectionForMergeableConstant(SectionKind Kind) const;
337   
338   virtual SectionKind::Kind getKindForNamedSection(const char *Section,
339                                                    SectionKind::Kind K) const;
340   void getSectionFlagsAsString(SectionKind Kind,
341                                SmallVectorImpl<char> &Str) const;
342   
343   virtual const Section *
344   SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
345                          Mangler *Mang, const TargetMachine &TM) const;
346 protected:
347   const Section *DataRelSection;
348   const Section *DataRelLocalSection;
349   const Section *DataRelROSection;
350   const Section *DataRelROLocalSection;
351   
352   const Section *MergeableConst4Section;
353   const Section *MergeableConst8Section;
354   const Section *MergeableConst16Section;
355 };
356
357   
358   
359 class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
360   const Section *TextCoalSection;
361   const Section *ConstTextCoalSection;
362   const Section *ConstDataCoalSection;
363   const Section *ConstDataSection;
364   const Section *DataCoalSection;
365   const Section *FourByteConstantSection;
366   const Section *EightByteConstantSection;
367   const Section *SixteenByteConstantSection;
368 public:
369   
370   virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
371
372   virtual const Section *
373   SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
374                          Mangler *Mang, const TargetMachine &TM) const;
375   
376   virtual const Section *
377   getSectionForMergeableConstant(SectionKind Kind) const;
378 };
379
380
381
382 class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
383 public:
384   virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
385   
386   virtual void getSectionFlagsAsString(SectionKind Kind,
387                                        SmallVectorImpl<char> &Str) const;
388   
389   virtual const Section *
390   SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
391                          Mangler *Mang, const TargetMachine &TM) const;
392 };
393
394 } // end namespace llvm
395
396 #endif