Move actual section printing stuff to AsmPrinter from TAI reducing heap traffic.
[oota-llvm.git] / lib / Target / TargetAsmInfo.cpp
1 //===-- TargetAsmInfo.cpp - Asm Info ---------------------------------------==//
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 defines target asm properties related what form asm statements
11 // should take.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Constants.h"
16 #include "llvm/GlobalVariable.h"
17 #include "llvm/Function.h"
18 #include "llvm/Module.h"
19 #include "llvm/Type.h"
20 #include "llvm/Target/TargetAsmInfo.h"
21 #include "llvm/Target/TargetOptions.h"
22 #include "llvm/Support/Dwarf.h"
23 #include <cctype>
24 #include <cstring>
25
26 using namespace llvm;
27
28 TargetAsmInfo::TargetAsmInfo() :
29   TextSection("\t.text"),
30   TextSection_(0),
31   DataSection("\t.data"),
32   DataSection_(0),
33   BSSSection("\t.bss"),
34   BSSSection_(0),
35   ReadOnlySection(0),
36   ReadOnlySection_(0),
37   SmallDataSection(0),
38   SmallBSSSection(0),
39   SmallRODataSection(0),
40   TLSDataSection("\t.section .tdata,\"awT\",@progbits"),
41   TLSDataSection_(0),
42   TLSBSSSection("\t.section .tbss,\"awT\",@nobits"),
43   TLSBSSSection_(0),
44   ZeroFillDirective(0),
45   NonexecutableStackDirective(0),
46   NeedsSet(false),
47   MaxInstLength(4),
48   PCSymbol("$"),
49   SeparatorChar(';'),
50   CommentString("#"),
51   GlobalPrefix(""),
52   PrivateGlobalPrefix("."),
53   LessPrivateGlobalPrefix(""),
54   JumpTableSpecialLabelPrefix(0),
55   GlobalVarAddrPrefix(""),
56   GlobalVarAddrSuffix(""),
57   FunctionAddrPrefix(""),
58   FunctionAddrSuffix(""),
59   PersonalityPrefix(""),
60   PersonalitySuffix(""),
61   NeedsIndirectEncoding(false),
62   InlineAsmStart("#APP"),
63   InlineAsmEnd("#NO_APP"),
64   AssemblerDialect(0),
65   StringConstantPrefix(".str"),
66   ZeroDirective("\t.zero\t"),
67   ZeroDirectiveSuffix(0),
68   AsciiDirective("\t.ascii\t"),
69   AscizDirective("\t.asciz\t"),
70   Data8bitsDirective("\t.byte\t"),
71   Data16bitsDirective("\t.short\t"),
72   Data32bitsDirective("\t.long\t"),
73   Data64bitsDirective("\t.quad\t"),
74   AlignDirective("\t.align\t"),
75   AlignmentIsInBytes(true),
76   TextAlignFillValue(0),
77   SwitchToSectionDirective("\t.section\t"),
78   TextSectionStartSuffix(""),
79   DataSectionStartSuffix(""),
80   SectionEndDirectiveSuffix(0),
81   ConstantPoolSection("\t.section .rodata"),
82   JumpTableDataSection("\t.section .rodata"),
83   JumpTableDirective(0),
84   CStringSection(0),
85   CStringSection_(0),
86   StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"),
87   StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"),
88   FourByteConstantSection(0),
89   FourByteConstantSection_(0),
90   EightByteConstantSection(0),
91   EightByteConstantSection_(0),
92   SixteenByteConstantSection(0),
93   SixteenByteConstantSection_(0),
94   GlobalDirective("\t.globl\t"),
95   SetDirective(0),
96   LCOMMDirective(0),
97   COMMDirective("\t.comm\t"),
98   COMMDirectiveTakesAlignment(true),
99   HasDotTypeDotSizeDirective(true),
100   UsedDirective(0),
101   WeakRefDirective(0),
102   WeakDefDirective(0),
103   HiddenDirective("\t.hidden\t"),
104   ProtectedDirective("\t.protected\t"),
105   AbsoluteDebugSectionOffsets(false),
106   AbsoluteEHSectionOffsets(false),
107   HasLEB128(false),
108   HasDotLocAndDotFile(false),
109   SupportsDebugInformation(false),
110   SupportsExceptionHandling(false),
111   DwarfRequiresFrameSection(true),
112   GlobalEHDirective(0),
113   SupportsWeakOmittedEHFrame(true),
114   DwarfSectionOffsetDirective(0),
115   DwarfAbbrevSection(".debug_abbrev"),
116   DwarfInfoSection(".debug_info"),
117   DwarfLineSection(".debug_line"),
118   DwarfFrameSection(".debug_frame"),
119   DwarfPubNamesSection(".debug_pubnames"),
120   DwarfPubTypesSection(".debug_pubtypes"),
121   DwarfStrSection(".debug_str"),
122   DwarfLocSection(".debug_loc"),
123   DwarfARangesSection(".debug_aranges"),
124   DwarfRangesSection(".debug_ranges"),
125   DwarfMacInfoSection(".debug_macinfo"),
126   DwarfEHFrameSection(".eh_frame"),
127   DwarfExceptionSection(".gcc_except_table"),
128   AsmTransCBE(0) {
129   TextSection_ = getUnnamedSection(TextSection);
130   DataSection_ = getUnnamedSection(DataSection);
131 }
132
133 TargetAsmInfo::~TargetAsmInfo() {
134 }
135
136 /// Measure the specified inline asm to determine an approximation of its
137 /// length.
138 /// Comments (which run till the next SeparatorChar or newline) do not
139 /// count as an instruction.
140 /// Any other non-whitespace text is considered an instruction, with
141 /// multiple instructions separated by SeparatorChar or newlines.
142 /// Variable-length instructions are not handled here; this function
143 /// may be overloaded in the target code to do that.
144 unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const {
145   // Count the number of instructions in the asm.
146   bool atInsnStart = true;
147   unsigned Length = 0;
148   for (; *Str; ++Str) {
149     if (*Str == '\n' || *Str == SeparatorChar)
150       atInsnStart = true;
151     if (atInsnStart && !isspace(*Str)) {
152       Length += MaxInstLength;
153       atInsnStart = false;
154     }
155     if (atInsnStart && strncmp(Str, CommentString, strlen(CommentString))==0)
156       atInsnStart = false;
157   }
158
159   return Length;
160 }
161
162 unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
163                                               bool Global) const {
164   return dwarf::DW_EH_PE_absptr;
165 }
166
167 static bool isSuitableForBSS(const GlobalVariable *GV) {
168   if (!GV->hasInitializer())
169     return true;
170
171   // Leave constant zeros in readonly constant sections, so they can be shared
172   Constant *C = GV->getInitializer();
173   return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
174 }
175
176 SectionKind::Kind
177 TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
178   // Early exit - functions should be always in text sections.
179   if (isa<Function>(GV))
180     return SectionKind::Text;
181
182   const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
183   bool isThreadLocal = GVar->isThreadLocal();
184   assert(GVar && "Invalid global value for section selection");
185
186   if (isSuitableForBSS(GVar)) {
187     // Variable can be easily put to BSS section.
188     return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS);
189   } else if (GVar->isConstant() && !isThreadLocal) {
190     // Now we know, that varible has initializer and it is constant. We need to
191     // check its initializer to decide, which section to output it into. Also
192     // note, there is no thread-local r/o section.
193     Constant *C = GVar->getInitializer();
194     if (C->ContainsRelocations())
195       return SectionKind::ROData;
196     else {
197       const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
198       // Check, if initializer is a null-terminated string
199       if (CVA && CVA->isCString())
200         return SectionKind::RODataMergeStr;
201       else
202         return SectionKind::RODataMergeConst;
203     }
204   }
205
206   // Variable is not constant or thread-local - emit to generic data section.
207   return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data);
208 }
209
210 unsigned
211 TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
212                                      const char* Name) const {
213   unsigned Flags = SectionFlags::None;
214
215   // Decode flags from global itself.
216   if (GV) {
217     SectionKind::Kind Kind = SectionKindForGlobal(GV);
218     switch (Kind) {
219      case SectionKind::Text:
220       Flags |= SectionFlags::Code;
221       break;
222      case SectionKind::ThreadData:
223      case SectionKind::ThreadBSS:
224       Flags |= SectionFlags::TLS;
225       // FALLS THROUGH
226      case SectionKind::Data:
227      case SectionKind::BSS:
228       Flags |= SectionFlags::Writeable;
229       break;
230      case SectionKind::ROData:
231      case SectionKind::RODataMergeStr:
232      case SectionKind::RODataMergeConst:
233       // No additional flags here
234       break;
235      case SectionKind::SmallData:
236      case SectionKind::SmallBSS:
237       Flags |= SectionFlags::Writeable;
238       // FALLS THROUGH
239      case SectionKind::SmallROData:
240       Flags |= SectionFlags::Small;
241       break;
242      default:
243       assert(0 && "Unexpected section kind!");
244     }
245
246     if (GV->isWeakForLinker())
247       Flags |= SectionFlags::Linkonce;
248   }
249
250   // Add flags from sections, if any.
251   if (Name && *Name) {
252     Flags |= SectionFlags::Named;
253
254     // Some lame default implementation based on some magic section names.
255     if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
256         strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
257         strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
258         strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
259       Flags |= SectionFlags::BSS;
260     else if (strcmp(Name, ".tdata") == 0 ||
261              strncmp(Name, ".tdata.", 7) == 0 ||
262              strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
263              strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
264       Flags |= SectionFlags::TLS;
265     else if (strcmp(Name, ".tbss") == 0 ||
266              strncmp(Name, ".tbss.", 6) == 0 ||
267              strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
268              strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
269       Flags |= SectionFlags::BSS | SectionFlags::TLS;
270   }
271
272   return Flags;
273 }
274
275 const Section*
276 TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
277   const Section* S;
278   // Select section name
279   if (GV->hasSection()) {
280     // Honour section already set, if any
281     unsigned Flags = SectionFlagsForGlobal(GV,
282                                            GV->getSection().c_str());
283     S = getNamedSection(GV->getSection().c_str(), Flags);
284   } else {
285     // Use default section depending on the 'type' of global
286     S = SelectSectionForGlobal(GV);
287   }
288
289   return S;
290 }
291
292 // Lame default implementation. Calculate the section name for global.
293 const Section*
294 TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
295   SectionKind::Kind Kind = SectionKindForGlobal(GV);
296
297   if (GV->isWeakForLinker()) {
298     std::string Name = UniqueSectionForGlobal(GV, Kind);
299     unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
300     return getNamedSection(Name.c_str(), Flags);
301   } else {
302     if (Kind == SectionKind::Text)
303       return getTextSection_();
304     else if (isBSS(Kind) && getBSSSection_())
305       return getBSSSection_();
306     else if (getReadOnlySection_() && SectionKind::isReadOnly(Kind))
307       return getReadOnlySection_();
308   }
309
310   return getDataSection_();
311 }
312
313 // Lame default implementation. Calculate the section name for machine const.
314 const Section*
315 TargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const {
316   // FIXME: Support data.rel stuff someday
317   return getDataSection_();
318 }
319
320 std::string
321 TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
322                                       SectionKind::Kind Kind) const {
323   switch (Kind) {
324    case SectionKind::Text:
325     return ".gnu.linkonce.t." + GV->getName();
326    case SectionKind::Data:
327     return ".gnu.linkonce.d." + GV->getName();
328    case SectionKind::SmallData:
329     return ".gnu.linkonce.s." + GV->getName();
330    case SectionKind::BSS:
331     return ".gnu.linkonce.b." + GV->getName();
332    case SectionKind::SmallBSS:
333     return ".gnu.linkonce.sb." + GV->getName();
334    case SectionKind::ROData:
335    case SectionKind::RODataMergeConst:
336    case SectionKind::RODataMergeStr:
337     return ".gnu.linkonce.r." + GV->getName();
338    case SectionKind::SmallROData:
339     return ".gnu.linkonce.s2." + GV->getName();
340    case SectionKind::ThreadData:
341     return ".gnu.linkonce.td." + GV->getName();
342    case SectionKind::ThreadBSS:
343     return ".gnu.linkonce.tb." + GV->getName();
344    default:
345     assert(0 && "Unknown section kind");
346   }
347 }
348
349 const Section*
350 TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
351                                bool Override) const {
352   Section& S = Sections[Name];
353
354   // This is newly-created section, set it up properly.
355   if (S.Flags == SectionFlags::Invalid || Override) {
356     S.Flags = Flags | SectionFlags::Named;
357     S.Name = Name;
358   }
359
360   return &S;
361 }
362
363 const Section*
364 TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags,
365                                  bool Override) const {
366   Section& S = Sections[Directive];
367
368   // This is newly-created section, set it up properly.
369   if (S.Flags == SectionFlags::Invalid || Override) {
370     S.Flags = Flags & ~SectionFlags::Named;
371     S.Name = Directive;
372   }
373
374   return &S;
375 }
376
377 const std::string&
378 TargetAsmInfo::getSectionFlags(unsigned Flags) const {
379   SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags);
380
381   // We didn't print these flags yet, print and save them to map. This reduces
382   // amount of heap trashing due to std::string construction / concatenation.
383   if (I == FlagsStrings.end())
384     I = FlagsStrings.insert(std::make_pair(Flags,
385                                            printSectionFlags(Flags))).first;
386
387   return I->second;
388 }
389
390 unsigned TargetAsmInfo::getULEB128Size(unsigned Value) {
391   unsigned Size = 0;
392   do {
393     Value >>= 7;
394     Size += sizeof(int8_t);
395   } while (Value);
396   return Size;
397 }
398
399 unsigned TargetAsmInfo::getSLEB128Size(int Value) {
400   unsigned Size = 0;
401   int Sign = Value >> (8 * sizeof(Value) - 1);
402   bool IsMore;
403
404   do {
405     unsigned Byte = Value & 0x7f;
406     Value >>= 7;
407     IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
408     Size += sizeof(int8_t);
409   } while (IsMore);
410   return Size;
411 }