]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===// |
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 the AsmPrinter class. | |
11 | // | |
12 | //===----------------------------------------------------------------------===// | |
13 | ||
223e47cc LB |
14 | #include "llvm/CodeGen/AsmPrinter.h" |
15 | #include "DwarfDebug.h" | |
16 | #include "DwarfException.h" | |
1a4d82fc JJ |
17 | #include "Win64Exception.h" |
18 | #include "WinCodeViewLineTables.h" | |
970d7e83 LB |
19 | #include "llvm/ADT/SmallString.h" |
20 | #include "llvm/ADT/Statistic.h" | |
21 | #include "llvm/Analysis/ConstantFolding.h" | |
1a4d82fc JJ |
22 | #include "llvm/Analysis/JumpInstrTableInfo.h" |
23 | #include "llvm/CodeGen/Analysis.h" | |
223e47cc LB |
24 | #include "llvm/CodeGen/GCMetadataPrinter.h" |
25 | #include "llvm/CodeGen/MachineConstantPool.h" | |
26 | #include "llvm/CodeGen/MachineFrameInfo.h" | |
27 | #include "llvm/CodeGen/MachineFunction.h" | |
1a4d82fc | 28 | #include "llvm/CodeGen/MachineInstrBundle.h" |
223e47cc LB |
29 | #include "llvm/CodeGen/MachineJumpTableInfo.h" |
30 | #include "llvm/CodeGen/MachineLoopInfo.h" | |
31 | #include "llvm/CodeGen/MachineModuleInfo.h" | |
970d7e83 | 32 | #include "llvm/IR/DataLayout.h" |
1a4d82fc JJ |
33 | #include "llvm/IR/DebugInfo.h" |
34 | #include "llvm/IR/Mangler.h" | |
970d7e83 LB |
35 | #include "llvm/IR/Module.h" |
36 | #include "llvm/IR/Operator.h" | |
223e47cc LB |
37 | #include "llvm/MC/MCAsmInfo.h" |
38 | #include "llvm/MC/MCContext.h" | |
39 | #include "llvm/MC/MCExpr.h" | |
40 | #include "llvm/MC/MCInst.h" | |
41 | #include "llvm/MC/MCSection.h" | |
42 | #include "llvm/MC/MCStreamer.h" | |
43 | #include "llvm/MC/MCSymbol.h" | |
970d7e83 LB |
44 | #include "llvm/Support/ErrorHandling.h" |
45 | #include "llvm/Support/Format.h" | |
46 | #include "llvm/Support/MathExtras.h" | |
47 | #include "llvm/Support/Timer.h" | |
1a4d82fc | 48 | #include "llvm/Target/TargetFrameLowering.h" |
223e47cc LB |
49 | #include "llvm/Target/TargetInstrInfo.h" |
50 | #include "llvm/Target/TargetLowering.h" | |
51 | #include "llvm/Target/TargetLoweringObjectFile.h" | |
223e47cc | 52 | #include "llvm/Target/TargetRegisterInfo.h" |
1a4d82fc | 53 | #include "llvm/Target/TargetSubtargetInfo.h" |
223e47cc LB |
54 | using namespace llvm; |
55 | ||
1a4d82fc JJ |
56 | #define DEBUG_TYPE "asm-printer" |
57 | ||
58 | static const char *const DWARFGroupName = "DWARF Emission"; | |
59 | static const char *const DbgTimerName = "Debug Info Emission"; | |
60 | static const char *const EHTimerName = "DWARF Exception Writer"; | |
61 | static const char *const CodeViewLineTablesGroupName = "CodeView Line Tables"; | |
223e47cc LB |
62 | |
63 | STATISTIC(EmittedInsts, "Number of machine instrs printed"); | |
64 | ||
65 | char AsmPrinter::ID = 0; | |
66 | ||
1a4d82fc | 67 | typedef DenseMap<GCStrategy*, std::unique_ptr<GCMetadataPrinter>> gcp_map_type; |
223e47cc | 68 | static gcp_map_type &getGCMap(void *&P) { |
1a4d82fc | 69 | if (!P) |
223e47cc LB |
70 | P = new gcp_map_type(); |
71 | return *(gcp_map_type*)P; | |
72 | } | |
73 | ||
74 | ||
75 | /// getGVAlignmentLog2 - Return the alignment to use for the specified global | |
76 | /// value in log2 form. This rounds up to the preferred alignment if possible | |
77 | /// and legal. | |
970d7e83 | 78 | static unsigned getGVAlignmentLog2(const GlobalValue *GV, const DataLayout &TD, |
223e47cc LB |
79 | unsigned InBits = 0) { |
80 | unsigned NumBits = 0; | |
81 | if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) | |
82 | NumBits = TD.getPreferredAlignmentLog(GVar); | |
83 | ||
84 | // If InBits is specified, round it to it. | |
85 | if (InBits > NumBits) | |
86 | NumBits = InBits; | |
87 | ||
88 | // If the GV has a specified alignment, take it into account. | |
89 | if (GV->getAlignment() == 0) | |
90 | return NumBits; | |
91 | ||
92 | unsigned GVAlign = Log2_32(GV->getAlignment()); | |
93 | ||
94 | // If the GVAlign is larger than NumBits, or if we are required to obey | |
95 | // NumBits because the GV has an assigned section, obey it. | |
96 | if (GVAlign > NumBits || GV->hasSection()) | |
97 | NumBits = GVAlign; | |
98 | return NumBits; | |
99 | } | |
100 | ||
223e47cc | 101 | AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer) |
1a4d82fc JJ |
102 | : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()), |
103 | MII(tm.getSubtargetImpl()->getInstrInfo()), | |
104 | OutContext(Streamer.getContext()), OutStreamer(Streamer), LastMI(nullptr), | |
105 | LastFn(0), Counter(~0U), SetCounter(0) { | |
106 | DD = nullptr; MMI = nullptr; LI = nullptr; MF = nullptr; | |
107 | CurrentFnSym = CurrentFnSymForSize = nullptr; | |
108 | GCMetadataPrinters = nullptr; | |
223e47cc LB |
109 | VerboseAsm = Streamer.isVerboseAsm(); |
110 | } | |
111 | ||
112 | AsmPrinter::~AsmPrinter() { | |
1a4d82fc | 113 | assert(!DD && Handlers.empty() && "Debug/EH info didn't get finalized"); |
223e47cc | 114 | |
1a4d82fc | 115 | if (GCMetadataPrinters) { |
223e47cc LB |
116 | gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); |
117 | ||
223e47cc | 118 | delete &GCMap; |
1a4d82fc | 119 | GCMetadataPrinters = nullptr; |
223e47cc LB |
120 | } |
121 | ||
122 | delete &OutStreamer; | |
123 | } | |
124 | ||
125 | /// getFunctionNumber - Return a unique ID for the current function. | |
126 | /// | |
127 | unsigned AsmPrinter::getFunctionNumber() const { | |
128 | return MF->getFunctionNumber(); | |
129 | } | |
130 | ||
131 | const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { | |
1a4d82fc | 132 | return TM.getSubtargetImpl()->getTargetLowering()->getObjFileLowering(); |
223e47cc LB |
133 | } |
134 | ||
970d7e83 LB |
135 | /// getDataLayout - Return information about data layout. |
136 | const DataLayout &AsmPrinter::getDataLayout() const { | |
1a4d82fc JJ |
137 | return *TM.getSubtargetImpl()->getDataLayout(); |
138 | } | |
139 | ||
140 | const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const { | |
141 | return TM.getSubtarget<MCSubtargetInfo>(); | |
142 | } | |
143 | ||
144 | void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { | |
145 | S.EmitInstruction(Inst, getSubtargetInfo()); | |
146 | } | |
147 | ||
148 | StringRef AsmPrinter::getTargetTriple() const { | |
149 | return TM.getTargetTriple(); | |
223e47cc LB |
150 | } |
151 | ||
152 | /// getCurrentSection() - Return the current section we are emitting to. | |
153 | const MCSection *AsmPrinter::getCurrentSection() const { | |
1a4d82fc | 154 | return OutStreamer.getCurrentSection().first; |
223e47cc LB |
155 | } |
156 | ||
157 | ||
158 | ||
159 | void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { | |
160 | AU.setPreservesAll(); | |
161 | MachineFunctionPass::getAnalysisUsage(AU); | |
162 | AU.addRequired<MachineModuleInfo>(); | |
163 | AU.addRequired<GCModuleInfo>(); | |
164 | if (isVerbose()) | |
165 | AU.addRequired<MachineLoopInfo>(); | |
166 | } | |
167 | ||
168 | bool AsmPrinter::doInitialization(Module &M) { | |
169 | MMI = getAnalysisIfAvailable<MachineModuleInfo>(); | |
170 | MMI->AnalyzeModule(M); | |
171 | ||
172 | // Initialize TargetLoweringObjectFile. | |
173 | const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) | |
174 | .Initialize(OutContext, TM); | |
175 | ||
85aaf69f | 176 | OutStreamer.InitSections(false); |
1a4d82fc JJ |
177 | |
178 | Mang = new Mangler(TM.getSubtargetImpl()->getDataLayout()); | |
179 | ||
180 | // Emit the version-min deplyment target directive if needed. | |
181 | // | |
182 | // FIXME: If we end up with a collection of these sorts of Darwin-specific | |
183 | // or ELF-specific things, it may make sense to have a platform helper class | |
184 | // that will work with the target helper class. For now keep it here, as the | |
185 | // alternative is duplicated code in each of the target asm printers that | |
186 | // use the directive, where it would need the same conditionalization | |
187 | // anyway. | |
188 | Triple TT(getTargetTriple()); | |
189 | if (TT.isOSDarwin()) { | |
190 | unsigned Major, Minor, Update; | |
191 | TT.getOSVersion(Major, Minor, Update); | |
192 | // If there is a version specified, Major will be non-zero. | |
193 | if (Major) | |
194 | OutStreamer.EmitVersionMin((TT.isMacOSX() ? | |
195 | MCVM_OSXVersionMin : MCVM_IOSVersionMin), | |
196 | Major, Minor, Update); | |
197 | } | |
223e47cc LB |
198 | |
199 | // Allow the target to emit any magic that it wants at the start of the file. | |
200 | EmitStartOfAsmFile(M); | |
201 | ||
202 | // Very minimal debug info. It is ignored if we emit actual debug info. If we | |
203 | // don't, this at least helps the user find where a global came from. | |
204 | if (MAI->hasSingleParameterDotFile()) { | |
205 | // .file "foo.c" | |
206 | OutStreamer.EmitFileDirective(M.getModuleIdentifier()); | |
207 | } | |
208 | ||
209 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); | |
210 | assert(MI && "AsmPrinter didn't require GCModuleInfo?"); | |
1a4d82fc | 211 | for (auto &I : *MI) |
223e47cc | 212 | if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) |
85aaf69f | 213 | MP->beginAssembly(M, *MI, *this); |
223e47cc LB |
214 | |
215 | // Emit module-level inline asm if it exists. | |
216 | if (!M.getModuleInlineAsm().empty()) { | |
217 | OutStreamer.AddComment("Start of file scope inline assembly"); | |
218 | OutStreamer.AddBlankLine(); | |
219 | EmitInlineAsm(M.getModuleInlineAsm()+"\n"); | |
220 | OutStreamer.AddComment("End of file scope inline assembly"); | |
221 | OutStreamer.AddBlankLine(); | |
222 | } | |
223 | ||
1a4d82fc | 224 | if (MAI->doesSupportDebugInformation()) { |
85aaf69f | 225 | bool skip_dwarf = false; |
1a4d82fc JJ |
226 | if (Triple(TM.getTargetTriple()).isKnownWindowsMSVCEnvironment()) { |
227 | Handlers.push_back(HandlerInfo(new WinCodeViewLineTables(this), | |
228 | DbgTimerName, | |
229 | CodeViewLineTablesGroupName)); | |
85aaf69f SL |
230 | // FIXME: Don't emit DWARF debug info if there's at least one function |
231 | // with AddressSanitizer instrumentation. | |
232 | // This is a band-aid fix for PR22032. | |
233 | for (auto &F : M.functions()) { | |
234 | if (F.hasFnAttribute(Attribute::SanitizeAddress)) { | |
235 | skip_dwarf = true; | |
236 | break; | |
237 | } | |
238 | } | |
239 | } | |
240 | if (!skip_dwarf) { | |
1a4d82fc JJ |
241 | DD = new DwarfDebug(this, &M); |
242 | Handlers.push_back(HandlerInfo(DD, DbgTimerName, DWARFGroupName)); | |
243 | } | |
244 | } | |
223e47cc | 245 | |
1a4d82fc | 246 | EHStreamer *ES = nullptr; |
223e47cc LB |
247 | switch (MAI->getExceptionHandlingType()) { |
248 | case ExceptionHandling::None: | |
1a4d82fc | 249 | break; |
223e47cc LB |
250 | case ExceptionHandling::SjLj: |
251 | case ExceptionHandling::DwarfCFI: | |
1a4d82fc JJ |
252 | ES = new DwarfCFIException(this); |
253 | break; | |
223e47cc | 254 | case ExceptionHandling::ARM: |
1a4d82fc JJ |
255 | ES = new ARMException(this); |
256 | break; | |
85aaf69f SL |
257 | case ExceptionHandling::ItaniumWinEH: |
258 | case ExceptionHandling::MSVC: | |
1a4d82fc JJ |
259 | switch (MAI->getWinEHEncodingType()) { |
260 | default: llvm_unreachable("unsupported unwinding information encoding"); | |
261 | case WinEH::EncodingType::Itanium: | |
262 | ES = new Win64Exception(this); | |
263 | break; | |
264 | } | |
265 | break; | |
223e47cc | 266 | } |
1a4d82fc JJ |
267 | if (ES) |
268 | Handlers.push_back(HandlerInfo(ES, EHTimerName, DWARFGroupName)); | |
269 | return false; | |
270 | } | |
271 | ||
272 | static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI) { | |
273 | if (!MAI.hasWeakDefCanBeHiddenDirective()) | |
274 | return false; | |
223e47cc | 275 | |
1a4d82fc | 276 | return canBeOmittedFromSymbolTable(GV); |
223e47cc LB |
277 | } |
278 | ||
1a4d82fc JJ |
279 | void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { |
280 | GlobalValue::LinkageTypes Linkage = GV->getLinkage(); | |
281 | switch (Linkage) { | |
223e47cc LB |
282 | case GlobalValue::CommonLinkage: |
283 | case GlobalValue::LinkOnceAnyLinkage: | |
284 | case GlobalValue::LinkOnceODRLinkage: | |
223e47cc LB |
285 | case GlobalValue::WeakAnyLinkage: |
286 | case GlobalValue::WeakODRLinkage: | |
1a4d82fc | 287 | if (MAI->hasWeakDefDirective()) { |
223e47cc LB |
288 | // .globl _foo |
289 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); | |
290 | ||
1a4d82fc | 291 | if (!canBeHidden(GV, *MAI)) |
223e47cc LB |
292 | // .weak_definition _foo |
293 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); | |
294 | else | |
295 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate); | |
1a4d82fc | 296 | } else if (MAI->hasLinkOnceDirective()) { |
223e47cc LB |
297 | // .globl _foo |
298 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); | |
299 | //NOTE: linkonce is handled by the section the symbol was assigned to. | |
300 | } else { | |
301 | // .weak _foo | |
302 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); | |
303 | } | |
1a4d82fc | 304 | return; |
223e47cc LB |
305 | case GlobalValue::AppendingLinkage: |
306 | // FIXME: appending linkage variables should go into a section of | |
307 | // their name or something. For now, just emit them as external. | |
308 | case GlobalValue::ExternalLinkage: | |
309 | // If external or appending, declare as a global symbol. | |
310 | // .globl _foo | |
311 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); | |
1a4d82fc | 312 | return; |
223e47cc LB |
313 | case GlobalValue::PrivateLinkage: |
314 | case GlobalValue::InternalLinkage: | |
1a4d82fc JJ |
315 | return; |
316 | case GlobalValue::AvailableExternallyLinkage: | |
317 | llvm_unreachable("Should never emit this"); | |
318 | case GlobalValue::ExternalWeakLinkage: | |
319 | llvm_unreachable("Don't know how to emit these"); | |
223e47cc | 320 | } |
1a4d82fc | 321 | llvm_unreachable("Unknown linkage type!"); |
223e47cc LB |
322 | } |
323 | ||
1a4d82fc JJ |
324 | void AsmPrinter::getNameWithPrefix(SmallVectorImpl<char> &Name, |
325 | const GlobalValue *GV) const { | |
326 | TM.getNameWithPrefix(Name, GV, *Mang); | |
327 | } | |
328 | ||
329 | MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const { | |
330 | return TM.getSymbol(GV, *Mang); | |
331 | } | |
223e47cc LB |
332 | |
333 | /// EmitGlobalVariable - Emit the specified global variable to the .s file. | |
334 | void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { | |
335 | if (GV->hasInitializer()) { | |
336 | // Check to see if this is a special global used by LLVM, if so, emit it. | |
337 | if (EmitSpecialLLVMGlobal(GV)) | |
338 | return; | |
339 | ||
340 | if (isVerbose()) { | |
1a4d82fc | 341 | GV->printAsOperand(OutStreamer.GetCommentOS(), |
223e47cc LB |
342 | /*PrintType=*/false, GV->getParent()); |
343 | OutStreamer.GetCommentOS() << '\n'; | |
344 | } | |
345 | } | |
346 | ||
1a4d82fc | 347 | MCSymbol *GVSym = getSymbol(GV); |
223e47cc LB |
348 | EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration()); |
349 | ||
350 | if (!GV->hasInitializer()) // External globals require no extra code. | |
351 | return; | |
352 | ||
85aaf69f SL |
353 | GVSym->redefineIfPossible(); |
354 | if (GVSym->isDefined() || GVSym->isVariable()) | |
355 | report_fatal_error("symbol '" + Twine(GVSym->getName()) + | |
356 | "' is already defined"); | |
357 | ||
223e47cc LB |
358 | if (MAI->hasDotTypeDotSizeDirective()) |
359 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); | |
360 | ||
361 | SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); | |
362 | ||
1a4d82fc JJ |
363 | const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); |
364 | uint64_t Size = DL->getTypeAllocSize(GV->getType()->getElementType()); | |
223e47cc LB |
365 | |
366 | // If the alignment is specified, we *must* obey it. Overaligning a global | |
367 | // with a specified alignment is a prompt way to break globals emitted to | |
368 | // sections and expected to be contiguous (e.g. ObjC metadata). | |
1a4d82fc JJ |
369 | unsigned AlignLog = getGVAlignmentLog2(GV, *DL); |
370 | ||
371 | for (const HandlerInfo &HI : Handlers) { | |
372 | NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled); | |
373 | HI.Handler->setSymbolSize(GVSym, Size); | |
374 | } | |
223e47cc LB |
375 | |
376 | // Handle common and BSS local symbols (.lcomm). | |
377 | if (GVKind.isCommon() || GVKind.isBSSLocal()) { | |
378 | if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. | |
379 | unsigned Align = 1 << AlignLog; | |
380 | ||
381 | // Handle common symbols. | |
382 | if (GVKind.isCommon()) { | |
383 | if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) | |
384 | Align = 0; | |
385 | ||
386 | // .comm _foo, 42, 4 | |
387 | OutStreamer.EmitCommonSymbol(GVSym, Size, Align); | |
388 | return; | |
389 | } | |
390 | ||
391 | // Handle local BSS symbols. | |
392 | if (MAI->hasMachoZeroFillDirective()) { | |
393 | const MCSection *TheSection = | |
1a4d82fc | 394 | getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM); |
223e47cc LB |
395 | // .zerofill __DATA, __bss, _foo, 400, 5 |
396 | OutStreamer.EmitZerofill(TheSection, GVSym, Size, Align); | |
397 | return; | |
398 | } | |
399 | ||
970d7e83 LB |
400 | // Use .lcomm only if it supports user-specified alignment. |
401 | // Otherwise, while it would still be correct to use .lcomm in some | |
402 | // cases (e.g. when Align == 1), the external assembler might enfore | |
403 | // some -unknown- default alignment behavior, which could cause | |
404 | // spurious differences between external and integrated assembler. | |
405 | // Prefer to simply fall back to .local / .comm in this case. | |
406 | if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) { | |
223e47cc LB |
407 | // .lcomm _foo, 42 |
408 | OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align); | |
409 | return; | |
410 | } | |
411 | ||
412 | if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) | |
413 | Align = 0; | |
414 | ||
415 | // .local _foo | |
416 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local); | |
417 | // .comm _foo, 42, 4 | |
418 | OutStreamer.EmitCommonSymbol(GVSym, Size, Align); | |
419 | return; | |
420 | } | |
421 | ||
422 | const MCSection *TheSection = | |
1a4d82fc | 423 | getObjFileLowering().SectionForGlobal(GV, GVKind, *Mang, TM); |
223e47cc LB |
424 | |
425 | // Handle the zerofill directive on darwin, which is a special form of BSS | |
426 | // emission. | |
427 | if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) { | |
428 | if (Size == 0) Size = 1; // zerofill of 0 bytes is undefined. | |
429 | ||
430 | // .globl _foo | |
431 | OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); | |
432 | // .zerofill __DATA, __common, _foo, 400, 5 | |
433 | OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); | |
434 | return; | |
435 | } | |
436 | ||
437 | // Handle thread local data for mach-o which requires us to output an | |
438 | // additional structure of data and mangle the original symbol so that we | |
439 | // can reference it later. | |
440 | // | |
441 | // TODO: This should become an "emit thread local global" method on TLOF. | |
442 | // All of this macho specific stuff should be sunk down into TLOFMachO and | |
443 | // stuff like "TLSExtraDataSection" should no longer be part of the parent | |
444 | // TLOF class. This will also make it more obvious that stuff like | |
445 | // MCStreamer::EmitTBSSSymbol is macho specific and only called from macho | |
446 | // specific code. | |
447 | if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { | |
448 | // Emit the .tbss symbol | |
449 | MCSymbol *MangSym = | |
450 | OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init")); | |
451 | ||
1a4d82fc JJ |
452 | if (GVKind.isThreadBSS()) { |
453 | TheSection = getObjFileLowering().getTLSBSSSection(); | |
223e47cc | 454 | OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog); |
1a4d82fc | 455 | } else if (GVKind.isThreadData()) { |
223e47cc LB |
456 | OutStreamer.SwitchSection(TheSection); |
457 | ||
458 | EmitAlignment(AlignLog, GV); | |
459 | OutStreamer.EmitLabel(MangSym); | |
460 | ||
461 | EmitGlobalConstant(GV->getInitializer()); | |
462 | } | |
463 | ||
464 | OutStreamer.AddBlankLine(); | |
465 | ||
466 | // Emit the variable struct for the runtime. | |
467 | const MCSection *TLVSect | |
468 | = getObjFileLowering().getTLSExtraDataSection(); | |
469 | ||
470 | OutStreamer.SwitchSection(TLVSect); | |
471 | // Emit the linkage here. | |
1a4d82fc | 472 | EmitLinkage(GV, GVSym); |
223e47cc LB |
473 | OutStreamer.EmitLabel(GVSym); |
474 | ||
475 | // Three pointers in size: | |
476 | // - __tlv_bootstrap - used to make sure support exists | |
477 | // - spare pointer, used when mapped by the runtime | |
478 | // - pointer to mangled symbol above with initializer | |
1a4d82fc | 479 | unsigned PtrSize = DL->getPointerTypeSize(GV->getType()); |
223e47cc | 480 | OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"), |
1a4d82fc | 481 | PtrSize); |
970d7e83 LB |
482 | OutStreamer.EmitIntValue(0, PtrSize); |
483 | OutStreamer.EmitSymbolValue(MangSym, PtrSize); | |
223e47cc LB |
484 | |
485 | OutStreamer.AddBlankLine(); | |
486 | return; | |
487 | } | |
488 | ||
489 | OutStreamer.SwitchSection(TheSection); | |
490 | ||
1a4d82fc | 491 | EmitLinkage(GV, GVSym); |
223e47cc LB |
492 | EmitAlignment(AlignLog, GV); |
493 | ||
494 | OutStreamer.EmitLabel(GVSym); | |
495 | ||
496 | EmitGlobalConstant(GV->getInitializer()); | |
497 | ||
498 | if (MAI->hasDotTypeDotSizeDirective()) | |
499 | // .size foo, 42 | |
500 | OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); | |
501 | ||
502 | OutStreamer.AddBlankLine(); | |
503 | } | |
504 | ||
505 | /// EmitFunctionHeader - This method emits the header for the current | |
506 | /// function. | |
507 | void AsmPrinter::EmitFunctionHeader() { | |
508 | // Print out constants referenced by the function | |
509 | EmitConstantPool(); | |
510 | ||
511 | // Print the 'header' of function. | |
512 | const Function *F = MF->getFunction(); | |
513 | ||
1a4d82fc JJ |
514 | OutStreamer.SwitchSection( |
515 | getObjFileLowering().SectionForGlobal(F, *Mang, TM)); | |
223e47cc LB |
516 | EmitVisibility(CurrentFnSym, F->getVisibility()); |
517 | ||
1a4d82fc | 518 | EmitLinkage(F, CurrentFnSym); |
223e47cc LB |
519 | EmitAlignment(MF->getAlignment(), F); |
520 | ||
521 | if (MAI->hasDotTypeDotSizeDirective()) | |
522 | OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); | |
523 | ||
524 | if (isVerbose()) { | |
1a4d82fc | 525 | F->printAsOperand(OutStreamer.GetCommentOS(), |
223e47cc LB |
526 | /*PrintType=*/false, F->getParent()); |
527 | OutStreamer.GetCommentOS() << '\n'; | |
528 | } | |
529 | ||
85aaf69f SL |
530 | // Emit the prefix data. |
531 | if (F->hasPrefixData()) | |
532 | EmitGlobalConstant(F->getPrefixData()); | |
533 | ||
223e47cc LB |
534 | // Emit the CurrentFnSym. This is a virtual function to allow targets to |
535 | // do their wild and crazy things as required. | |
536 | EmitFunctionEntryLabel(); | |
537 | ||
538 | // If the function had address-taken blocks that got deleted, then we have | |
539 | // references to the dangling symbols. Emit them at the start of the function | |
540 | // so that we don't get references to undefined symbols. | |
541 | std::vector<MCSymbol*> DeadBlockSyms; | |
542 | MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms); | |
543 | for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { | |
544 | OutStreamer.AddComment("Address taken block that was later removed"); | |
545 | OutStreamer.EmitLabel(DeadBlockSyms[i]); | |
546 | } | |
547 | ||
223e47cc | 548 | // Emit pre-function debug and/or EH information. |
1a4d82fc JJ |
549 | for (const HandlerInfo &HI : Handlers) { |
550 | NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled); | |
551 | HI.Handler->beginFunction(MF); | |
223e47cc | 552 | } |
1a4d82fc | 553 | |
85aaf69f SL |
554 | // Emit the prologue data. |
555 | if (F->hasPrologueData()) | |
556 | EmitGlobalConstant(F->getPrologueData()); | |
223e47cc LB |
557 | } |
558 | ||
559 | /// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the | |
560 | /// function. This can be overridden by targets as required to do custom stuff. | |
561 | void AsmPrinter::EmitFunctionEntryLabel() { | |
85aaf69f SL |
562 | CurrentFnSym->redefineIfPossible(); |
563 | ||
223e47cc LB |
564 | // The function label could have already been emitted if two symbols end up |
565 | // conflicting due to asm renaming. Detect this and emit an error. | |
85aaf69f SL |
566 | if (CurrentFnSym->isVariable()) |
567 | report_fatal_error("'" + Twine(CurrentFnSym->getName()) + | |
568 | "' is a protected alias"); | |
569 | if (CurrentFnSym->isDefined()) | |
570 | report_fatal_error("'" + Twine(CurrentFnSym->getName()) + | |
571 | "' label emitted multiple times to assembly file"); | |
223e47cc | 572 | |
85aaf69f | 573 | return OutStreamer.EmitLabel(CurrentFnSym); |
223e47cc LB |
574 | } |
575 | ||
576 | /// emitComments - Pretty-print comments for instructions. | |
577 | static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS) { | |
578 | const MachineFunction *MF = MI.getParent()->getParent(); | |
579 | const TargetMachine &TM = MF->getTarget(); | |
580 | ||
581 | // Check for spills and reloads | |
582 | int FI; | |
583 | ||
584 | const MachineFrameInfo *FrameInfo = MF->getFrameInfo(); | |
585 | ||
586 | // We assume a single instruction only has a spill or reload, not | |
587 | // both. | |
588 | const MachineMemOperand *MMO; | |
1a4d82fc JJ |
589 | if (TM.getSubtargetImpl()->getInstrInfo()->isLoadFromStackSlotPostFE(&MI, |
590 | FI)) { | |
223e47cc LB |
591 | if (FrameInfo->isSpillSlotObjectIndex(FI)) { |
592 | MMO = *MI.memoperands_begin(); | |
593 | CommentOS << MMO->getSize() << "-byte Reload\n"; | |
594 | } | |
1a4d82fc JJ |
595 | } else if (TM.getSubtargetImpl()->getInstrInfo()->hasLoadFromStackSlot( |
596 | &MI, MMO, FI)) { | |
223e47cc LB |
597 | if (FrameInfo->isSpillSlotObjectIndex(FI)) |
598 | CommentOS << MMO->getSize() << "-byte Folded Reload\n"; | |
1a4d82fc JJ |
599 | } else if (TM.getSubtargetImpl()->getInstrInfo()->isStoreToStackSlotPostFE( |
600 | &MI, FI)) { | |
223e47cc LB |
601 | if (FrameInfo->isSpillSlotObjectIndex(FI)) { |
602 | MMO = *MI.memoperands_begin(); | |
603 | CommentOS << MMO->getSize() << "-byte Spill\n"; | |
604 | } | |
1a4d82fc JJ |
605 | } else if (TM.getSubtargetImpl()->getInstrInfo()->hasStoreToStackSlot( |
606 | &MI, MMO, FI)) { | |
223e47cc LB |
607 | if (FrameInfo->isSpillSlotObjectIndex(FI)) |
608 | CommentOS << MMO->getSize() << "-byte Folded Spill\n"; | |
609 | } | |
610 | ||
611 | // Check for spill-induced copies | |
612 | if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse)) | |
613 | CommentOS << " Reload Reuse\n"; | |
614 | } | |
615 | ||
616 | /// emitImplicitDef - This method emits the specified machine instruction | |
617 | /// that is an implicit def. | |
1a4d82fc | 618 | void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const { |
223e47cc | 619 | unsigned RegNo = MI->getOperand(0).getReg(); |
1a4d82fc JJ |
620 | OutStreamer.AddComment( |
621 | Twine("implicit-def: ") + | |
622 | TM.getSubtargetImpl()->getRegisterInfo()->getName(RegNo)); | |
623 | OutStreamer.AddBlankLine(); | |
223e47cc LB |
624 | } |
625 | ||
626 | static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { | |
627 | std::string Str = "kill:"; | |
628 | for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { | |
629 | const MachineOperand &Op = MI->getOperand(i); | |
630 | assert(Op.isReg() && "KILL instruction must have only register operands"); | |
631 | Str += ' '; | |
1a4d82fc | 632 | Str += AP.TM.getSubtargetImpl()->getRegisterInfo()->getName(Op.getReg()); |
223e47cc LB |
633 | Str += (Op.isDef() ? "<def>" : "<kill>"); |
634 | } | |
635 | AP.OutStreamer.AddComment(Str); | |
636 | AP.OutStreamer.AddBlankLine(); | |
637 | } | |
638 | ||
639 | /// emitDebugValueComment - This method handles the target-independent form | |
640 | /// of DBG_VALUE, returning true if it was able to do so. A false return | |
641 | /// means the target will need to handle MI in EmitInstruction. | |
642 | static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { | |
85aaf69f SL |
643 | // This code handles only the 4-operand target-independent form. |
644 | if (MI->getNumOperands() != 4) | |
223e47cc LB |
645 | return false; |
646 | ||
647 | SmallString<128> Str; | |
648 | raw_svector_ostream OS(Str); | |
1a4d82fc JJ |
649 | OS << "DEBUG_VALUE: "; |
650 | ||
651 | DIVariable V = MI->getDebugVariable(); | |
652 | if (V.getContext().isSubprogram()) { | |
653 | StringRef Name = DISubprogram(V.getContext()).getDisplayName(); | |
654 | if (!Name.empty()) | |
655 | OS << Name << ":"; | |
656 | } | |
657 | OS << V.getName(); | |
85aaf69f SL |
658 | |
659 | DIExpression Expr = MI->getDebugExpression(); | |
660 | if (Expr.isVariablePiece()) | |
661 | OS << " [piece offset=" << Expr.getPieceOffset() | |
662 | << " size=" << Expr.getPieceSize() << "]"; | |
1a4d82fc | 663 | OS << " <- "; |
223e47cc | 664 | |
1a4d82fc JJ |
665 | // The second operand is only an offset if it's an immediate. |
666 | bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm(); | |
667 | int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0; | |
223e47cc LB |
668 | |
669 | // Register or immediate value. Register 0 means undef. | |
670 | if (MI->getOperand(0).isFPImm()) { | |
671 | APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF()); | |
672 | if (MI->getOperand(0).getFPImm()->getType()->isFloatTy()) { | |
673 | OS << (double)APF.convertToFloat(); | |
674 | } else if (MI->getOperand(0).getFPImm()->getType()->isDoubleTy()) { | |
675 | OS << APF.convertToDouble(); | |
676 | } else { | |
677 | // There is no good way to print long double. Convert a copy to | |
678 | // double. Ah well, it's only a comment. | |
679 | bool ignored; | |
680 | APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, | |
681 | &ignored); | |
682 | OS << "(long double) " << APF.convertToDouble(); | |
683 | } | |
684 | } else if (MI->getOperand(0).isImm()) { | |
685 | OS << MI->getOperand(0).getImm(); | |
686 | } else if (MI->getOperand(0).isCImm()) { | |
687 | MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/); | |
688 | } else { | |
1a4d82fc JJ |
689 | unsigned Reg; |
690 | if (MI->getOperand(0).isReg()) { | |
691 | Reg = MI->getOperand(0).getReg(); | |
692 | } else { | |
693 | assert(MI->getOperand(0).isFI() && "Unknown operand type"); | |
694 | const TargetFrameLowering *TFI = | |
695 | AP.TM.getSubtargetImpl()->getFrameLowering(); | |
696 | Offset += TFI->getFrameIndexReference(*AP.MF, | |
697 | MI->getOperand(0).getIndex(), Reg); | |
698 | Deref = true; | |
699 | } | |
700 | if (Reg == 0) { | |
223e47cc LB |
701 | // Suppress offset, it is not meaningful here. |
702 | OS << "undef"; | |
703 | // NOTE: Want this comment at start of line, don't emit with AddComment. | |
1a4d82fc | 704 | AP.OutStreamer.emitRawComment(OS.str()); |
223e47cc LB |
705 | return true; |
706 | } | |
1a4d82fc JJ |
707 | if (Deref) |
708 | OS << '['; | |
709 | OS << AP.TM.getSubtargetImpl()->getRegisterInfo()->getName(Reg); | |
223e47cc LB |
710 | } |
711 | ||
1a4d82fc JJ |
712 | if (Deref) |
713 | OS << '+' << Offset << ']'; | |
714 | ||
223e47cc | 715 | // NOTE: Want this comment at start of line, don't emit with AddComment. |
1a4d82fc | 716 | AP.OutStreamer.emitRawComment(OS.str()); |
223e47cc LB |
717 | return true; |
718 | } | |
719 | ||
223e47cc LB |
720 | AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() { |
721 | if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && | |
722 | MF->getFunction()->needsUnwindTableEntry()) | |
723 | return CFI_M_EH; | |
724 | ||
725 | if (MMI->hasDebugInfo()) | |
726 | return CFI_M_Debug; | |
727 | ||
728 | return CFI_M_None; | |
729 | } | |
730 | ||
731 | bool AsmPrinter::needsSEHMoves() { | |
85aaf69f | 732 | return MAI->usesWindowsCFI() && MF->getFunction()->needsUnwindTableEntry(); |
223e47cc LB |
733 | } |
734 | ||
1a4d82fc JJ |
735 | void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) { |
736 | ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType(); | |
737 | if (ExceptionHandlingType != ExceptionHandling::DwarfCFI && | |
738 | ExceptionHandlingType != ExceptionHandling::ARM) | |
223e47cc LB |
739 | return; |
740 | ||
741 | if (needsCFIMoves() == CFI_M_None) | |
742 | return; | |
743 | ||
1a4d82fc JJ |
744 | const MachineModuleInfo &MMI = MF->getMMI(); |
745 | const std::vector<MCCFIInstruction> &Instrs = MMI.getFrameInstructions(); | |
746 | unsigned CFIIndex = MI.getOperand(0).getCFIIndex(); | |
747 | const MCCFIInstruction &CFI = Instrs[CFIIndex]; | |
748 | emitCFIInstruction(CFI); | |
223e47cc LB |
749 | } |
750 | ||
85aaf69f SL |
751 | void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) { |
752 | // The operands are the MCSymbol and the frame offset of the allocation. | |
753 | MCSymbol *FrameAllocSym = MI.getOperand(0).getMCSymbol(); | |
754 | int FrameOffset = MI.getOperand(1).getImm(); | |
755 | ||
756 | // Emit a symbol assignment. | |
757 | OutStreamer.EmitAssignment(FrameAllocSym, | |
758 | MCConstantExpr::Create(FrameOffset, OutContext)); | |
759 | } | |
760 | ||
223e47cc LB |
761 | /// EmitFunctionBody - This method emits the body and trailer for a |
762 | /// function. | |
763 | void AsmPrinter::EmitFunctionBody() { | |
764 | // Emit target-specific gunk before the function body. | |
765 | EmitFunctionBodyStart(); | |
766 | ||
1a4d82fc | 767 | bool ShouldPrintDebugScopes = MMI->hasDebugInfo(); |
223e47cc LB |
768 | |
769 | // Print out code for the function. | |
770 | bool HasAnyRealCode = false; | |
1a4d82fc | 771 | for (auto &MBB : *MF) { |
223e47cc | 772 | // Print a label for the basic block. |
1a4d82fc JJ |
773 | EmitBasicBlockStart(MBB); |
774 | for (auto &MI : MBB) { | |
223e47cc LB |
775 | |
776 | // Print the assembly for the instruction. | |
1a4d82fc JJ |
777 | if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() && |
778 | !MI.isDebugValue()) { | |
223e47cc LB |
779 | HasAnyRealCode = true; |
780 | ++EmittedInsts; | |
781 | } | |
782 | ||
783 | if (ShouldPrintDebugScopes) { | |
1a4d82fc JJ |
784 | for (const HandlerInfo &HI : Handlers) { |
785 | NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, | |
786 | TimePassesIsEnabled); | |
787 | HI.Handler->beginInstruction(&MI); | |
788 | } | |
223e47cc LB |
789 | } |
790 | ||
791 | if (isVerbose()) | |
1a4d82fc | 792 | emitComments(MI, OutStreamer.GetCommentOS()); |
223e47cc | 793 | |
1a4d82fc JJ |
794 | switch (MI.getOpcode()) { |
795 | case TargetOpcode::CFI_INSTRUCTION: | |
796 | emitCFIInstruction(MI); | |
223e47cc LB |
797 | break; |
798 | ||
85aaf69f SL |
799 | case TargetOpcode::FRAME_ALLOC: |
800 | emitFrameAlloc(MI); | |
801 | break; | |
802 | ||
223e47cc LB |
803 | case TargetOpcode::EH_LABEL: |
804 | case TargetOpcode::GC_LABEL: | |
1a4d82fc | 805 | OutStreamer.EmitLabel(MI.getOperand(0).getMCSymbol()); |
223e47cc LB |
806 | break; |
807 | case TargetOpcode::INLINEASM: | |
1a4d82fc | 808 | EmitInlineAsm(&MI); |
223e47cc LB |
809 | break; |
810 | case TargetOpcode::DBG_VALUE: | |
811 | if (isVerbose()) { | |
1a4d82fc JJ |
812 | if (!emitDebugValueComment(&MI, *this)) |
813 | EmitInstruction(&MI); | |
223e47cc LB |
814 | } |
815 | break; | |
816 | case TargetOpcode::IMPLICIT_DEF: | |
1a4d82fc | 817 | if (isVerbose()) emitImplicitDef(&MI); |
223e47cc LB |
818 | break; |
819 | case TargetOpcode::KILL: | |
1a4d82fc | 820 | if (isVerbose()) emitKill(&MI, *this); |
223e47cc | 821 | break; |
223e47cc | 822 | default: |
1a4d82fc | 823 | EmitInstruction(&MI); |
223e47cc LB |
824 | break; |
825 | } | |
826 | ||
827 | if (ShouldPrintDebugScopes) { | |
1a4d82fc JJ |
828 | for (const HandlerInfo &HI : Handlers) { |
829 | NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, | |
830 | TimePassesIsEnabled); | |
831 | HI.Handler->endInstruction(); | |
832 | } | |
223e47cc LB |
833 | } |
834 | } | |
223e47cc | 835 | |
1a4d82fc JJ |
836 | EmitBasicBlockEnd(MBB); |
837 | } | |
223e47cc LB |
838 | |
839 | // If the function is empty and the object file uses .subsections_via_symbols, | |
840 | // then we need to emit *something* to the function body to prevent the | |
841 | // labels from collapsing together. Just emit a noop. | |
1a4d82fc | 842 | if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)) { |
223e47cc | 843 | MCInst Noop; |
1a4d82fc JJ |
844 | TM.getSubtargetImpl()->getInstrInfo()->getNoopForMachoTarget(Noop); |
845 | OutStreamer.AddComment("avoids zero-length function"); | |
846 | ||
847 | // Targets can opt-out of emitting the noop here by leaving the opcode | |
848 | // unspecified. | |
849 | if (Noop.getOpcode()) | |
850 | OutStreamer.EmitInstruction(Noop, getSubtargetInfo()); | |
223e47cc LB |
851 | } |
852 | ||
853 | const Function *F = MF->getFunction(); | |
1a4d82fc JJ |
854 | for (const auto &BB : *F) { |
855 | if (!BB.hasAddressTaken()) | |
223e47cc | 856 | continue; |
1a4d82fc | 857 | MCSymbol *Sym = GetBlockAddressSymbol(&BB); |
223e47cc LB |
858 | if (Sym->isDefined()) |
859 | continue; | |
860 | OutStreamer.AddComment("Address of block that was removed by CodeGen"); | |
861 | OutStreamer.EmitLabel(Sym); | |
862 | } | |
863 | ||
864 | // Emit target-specific gunk after the function body. | |
865 | EmitFunctionBodyEnd(); | |
866 | ||
867 | // If the target wants a .size directive for the size of the function, emit | |
868 | // it. | |
869 | if (MAI->hasDotTypeDotSizeDirective()) { | |
870 | // Create a symbol for the end of function, so we can get the size as | |
871 | // difference between the function label and the temp label. | |
872 | MCSymbol *FnEndLabel = OutContext.CreateTempSymbol(); | |
873 | OutStreamer.EmitLabel(FnEndLabel); | |
874 | ||
875 | const MCExpr *SizeExp = | |
876 | MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext), | |
877 | MCSymbolRefExpr::Create(CurrentFnSymForSize, | |
878 | OutContext), | |
879 | OutContext); | |
880 | OutStreamer.EmitELFSize(CurrentFnSym, SizeExp); | |
881 | } | |
882 | ||
1a4d82fc JJ |
883 | // Emit post-function debug and/or EH information. |
884 | for (const HandlerInfo &HI : Handlers) { | |
885 | NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled); | |
886 | HI.Handler->endFunction(MF); | |
223e47cc LB |
887 | } |
888 | MMI->EndFunction(); | |
889 | ||
890 | // Print out jump tables referenced by the function. | |
891 | EmitJumpTableInfo(); | |
892 | ||
893 | OutStreamer.AddBlankLine(); | |
894 | } | |
895 | ||
223e47cc LB |
896 | bool AsmPrinter::doFinalization(Module &M) { |
897 | // Emit global variables. | |
1a4d82fc JJ |
898 | for (const auto &G : M.globals()) |
899 | EmitGlobalVariable(&G); | |
223e47cc LB |
900 | |
901 | // Emit visibility info for declarations | |
1a4d82fc | 902 | for (const Function &F : M) { |
223e47cc LB |
903 | if (!F.isDeclaration()) |
904 | continue; | |
905 | GlobalValue::VisibilityTypes V = F.getVisibility(); | |
906 | if (V == GlobalValue::DefaultVisibility) | |
907 | continue; | |
908 | ||
1a4d82fc | 909 | MCSymbol *Name = getSymbol(&F); |
223e47cc LB |
910 | EmitVisibility(Name, V, false); |
911 | } | |
912 | ||
1a4d82fc JJ |
913 | // Get information about jump-instruction tables to print. |
914 | JumpInstrTableInfo *JITI = getAnalysisIfAvailable<JumpInstrTableInfo>(); | |
915 | ||
916 | if (JITI && !JITI->getTables().empty()) { | |
917 | unsigned Arch = Triple(getTargetTriple()).getArch(); | |
918 | bool IsThumb = (Arch == Triple::thumb || Arch == Triple::thumbeb); | |
919 | MCInst TrapInst; | |
920 | TM.getSubtargetImpl()->getInstrInfo()->getTrap(TrapInst); | |
85aaf69f SL |
921 | unsigned LogAlignment = llvm::Log2_64(JITI->entryByteAlignment()); |
922 | ||
923 | // Emit the right section for these functions. | |
924 | OutStreamer.SwitchSection(OutContext.getObjectFileInfo()->getTextSection()); | |
1a4d82fc JJ |
925 | for (const auto &KV : JITI->getTables()) { |
926 | uint64_t Count = 0; | |
927 | for (const auto &FunPair : KV.second) { | |
928 | // Emit the function labels to make this be a function entry point. | |
929 | MCSymbol *FunSym = | |
930 | OutContext.GetOrCreateSymbol(FunPair.second->getName()); | |
85aaf69f | 931 | EmitAlignment(LogAlignment); |
1a4d82fc JJ |
932 | if (IsThumb) |
933 | OutStreamer.EmitThumbFunc(FunSym); | |
934 | if (MAI->hasDotTypeDotSizeDirective()) | |
935 | OutStreamer.EmitSymbolAttribute(FunSym, MCSA_ELF_TypeFunction); | |
936 | OutStreamer.EmitLabel(FunSym); | |
937 | ||
938 | // Emit the jump instruction to transfer control to the original | |
939 | // function. | |
940 | MCInst JumpToFun; | |
941 | MCSymbol *TargetSymbol = | |
942 | OutContext.GetOrCreateSymbol(FunPair.first->getName()); | |
943 | const MCSymbolRefExpr *TargetSymRef = | |
944 | MCSymbolRefExpr::Create(TargetSymbol, MCSymbolRefExpr::VK_PLT, | |
945 | OutContext); | |
946 | TM.getSubtargetImpl()->getInstrInfo()->getUnconditionalBranch( | |
947 | JumpToFun, TargetSymRef); | |
948 | OutStreamer.EmitInstruction(JumpToFun, getSubtargetInfo()); | |
949 | ++Count; | |
950 | } | |
951 | ||
952 | // Emit enough padding instructions to fill up to the next power of two. | |
1a4d82fc JJ |
953 | uint64_t Remaining = NextPowerOf2(Count) - Count; |
954 | for (uint64_t C = 0; C < Remaining; ++C) { | |
85aaf69f | 955 | EmitAlignment(LogAlignment); |
1a4d82fc JJ |
956 | OutStreamer.EmitInstruction(TrapInst, getSubtargetInfo()); |
957 | } | |
958 | ||
959 | } | |
960 | } | |
961 | ||
223e47cc LB |
962 | // Emit module flags. |
963 | SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; | |
964 | M.getModuleFlagsMetadata(ModuleFlags); | |
965 | if (!ModuleFlags.empty()) | |
1a4d82fc JJ |
966 | getObjFileLowering().emitModuleFlags(OutStreamer, ModuleFlags, *Mang, TM); |
967 | ||
968 | // Make sure we wrote out everything we need. | |
969 | OutStreamer.Flush(); | |
223e47cc LB |
970 | |
971 | // Finalize debug and EH information. | |
1a4d82fc JJ |
972 | for (const HandlerInfo &HI : Handlers) { |
973 | NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, | |
974 | TimePassesIsEnabled); | |
975 | HI.Handler->endModule(); | |
976 | delete HI.Handler; | |
223e47cc | 977 | } |
1a4d82fc JJ |
978 | Handlers.clear(); |
979 | DD = nullptr; | |
223e47cc LB |
980 | |
981 | // If the target wants to know about weak references, print them all. | |
982 | if (MAI->getWeakRefDirective()) { | |
983 | // FIXME: This is not lazy, it would be nice to only print weak references | |
984 | // to stuff that is actually used. Note that doing so would require targets | |
985 | // to notice uses in operands (due to constant exprs etc). This should | |
986 | // happen with the MC stuff eventually. | |
987 | ||
988 | // Print out module-level global variables here. | |
1a4d82fc JJ |
989 | for (const auto &G : M.globals()) { |
990 | if (!G.hasExternalWeakLinkage()) | |
991 | continue; | |
992 | OutStreamer.EmitSymbolAttribute(getSymbol(&G), MCSA_WeakReference); | |
223e47cc LB |
993 | } |
994 | ||
1a4d82fc JJ |
995 | for (const auto &F : M) { |
996 | if (!F.hasExternalWeakLinkage()) | |
997 | continue; | |
998 | OutStreamer.EmitSymbolAttribute(getSymbol(&F), MCSA_WeakReference); | |
223e47cc LB |
999 | } |
1000 | } | |
1001 | ||
85aaf69f SL |
1002 | OutStreamer.AddBlankLine(); |
1003 | for (const auto &Alias : M.aliases()) { | |
1004 | MCSymbol *Name = getSymbol(&Alias); | |
223e47cc | 1005 | |
85aaf69f SL |
1006 | if (Alias.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
1007 | OutStreamer.EmitSymbolAttribute(Name, MCSA_Global); | |
1008 | else if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage()) | |
1009 | OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference); | |
1010 | else | |
1011 | assert(Alias.hasLocalLinkage() && "Invalid alias linkage"); | |
223e47cc | 1012 | |
85aaf69f | 1013 | EmitVisibility(Name, Alias.getVisibility()); |
223e47cc | 1014 | |
85aaf69f SL |
1015 | // Emit the directives as assignments aka .set: |
1016 | OutStreamer.EmitAssignment(Name, lowerConstant(Alias.getAliasee())); | |
223e47cc LB |
1017 | } |
1018 | ||
1019 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); | |
1020 | assert(MI && "AsmPrinter didn't require GCModuleInfo?"); | |
1021 | for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) | |
1a4d82fc | 1022 | if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(**--I)) |
85aaf69f | 1023 | MP->finishAssembly(M, *MI, *this); |
223e47cc | 1024 | |
1a4d82fc JJ |
1025 | // Emit llvm.ident metadata in an '.ident' directive. |
1026 | EmitModuleIdents(M); | |
1027 | ||
85aaf69f SL |
1028 | // Emit __morestack address if needed for indirect calls. |
1029 | if (MMI->usesMorestackAddr()) { | |
1030 | const MCSection *ReadOnlySection = | |
1031 | getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly(), | |
1032 | /*C=*/nullptr); | |
1033 | OutStreamer.SwitchSection(ReadOnlySection); | |
1034 | ||
1035 | MCSymbol *AddrSymbol = | |
1036 | OutContext.GetOrCreateSymbol(StringRef("__morestack_addr")); | |
1037 | OutStreamer.EmitLabel(AddrSymbol); | |
1038 | ||
1039 | const DataLayout &DL = *TM.getSubtargetImpl()->getDataLayout(); | |
1040 | unsigned PtrSize = DL.getPointerSize(0); | |
1041 | OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("__morestack"), | |
1042 | PtrSize); | |
1043 | } | |
1044 | ||
223e47cc LB |
1045 | // If we don't have any trampolines, then we don't require stack memory |
1046 | // to be executable. Some targets have a directive to declare this. | |
1047 | Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); | |
1048 | if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) | |
1049 | if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext)) | |
1050 | OutStreamer.SwitchSection(S); | |
1051 | ||
1052 | // Allow the target to emit any magic that it wants at the end of the file, | |
1053 | // after everything else has gone out. | |
1054 | EmitEndOfAsmFile(M); | |
1055 | ||
1a4d82fc JJ |
1056 | delete Mang; Mang = nullptr; |
1057 | MMI = nullptr; | |
223e47cc LB |
1058 | |
1059 | OutStreamer.Finish(); | |
970d7e83 LB |
1060 | OutStreamer.reset(); |
1061 | ||
223e47cc LB |
1062 | return false; |
1063 | } | |
1064 | ||
1065 | void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { | |
1066 | this->MF = &MF; | |
1067 | // Get the function symbol. | |
1a4d82fc | 1068 | CurrentFnSym = getSymbol(MF.getFunction()); |
223e47cc LB |
1069 | CurrentFnSymForSize = CurrentFnSym; |
1070 | ||
1071 | if (isVerbose()) | |
1072 | LI = &getAnalysis<MachineLoopInfo>(); | |
1073 | } | |
1074 | ||
1075 | namespace { | |
1076 | // SectionCPs - Keep track the alignment, constpool entries per Section. | |
1077 | struct SectionCPs { | |
1078 | const MCSection *S; | |
1079 | unsigned Alignment; | |
1080 | SmallVector<unsigned, 4> CPEs; | |
1081 | SectionCPs(const MCSection *s, unsigned a) : S(s), Alignment(a) {} | |
1082 | }; | |
1083 | } | |
1084 | ||
1085 | /// EmitConstantPool - Print to the current output stream assembly | |
1086 | /// representations of the constants in the constant pool MCP. This is | |
1087 | /// used to print out constants which have been "spilled to memory" by | |
1088 | /// the code generator. | |
1089 | /// | |
1090 | void AsmPrinter::EmitConstantPool() { | |
1091 | const MachineConstantPool *MCP = MF->getConstantPool(); | |
1092 | const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); | |
1093 | if (CP.empty()) return; | |
1094 | ||
1095 | // Calculate sections for constant pool entries. We collect entries to go into | |
1096 | // the same section together to reduce amount of section switch statements. | |
1097 | SmallVector<SectionCPs, 4> CPSections; | |
1098 | for (unsigned i = 0, e = CP.size(); i != e; ++i) { | |
1099 | const MachineConstantPoolEntry &CPE = CP[i]; | |
1100 | unsigned Align = CPE.getAlignment(); | |
1101 | ||
1a4d82fc JJ |
1102 | SectionKind Kind = |
1103 | CPE.getSectionKind(TM.getSubtargetImpl()->getDataLayout()); | |
223e47cc | 1104 | |
1a4d82fc JJ |
1105 | const Constant *C = nullptr; |
1106 | if (!CPE.isMachineConstantPoolEntry()) | |
1107 | C = CPE.Val.ConstVal; | |
1108 | ||
1109 | const MCSection *S = getObjFileLowering().getSectionForConstant(Kind, C); | |
223e47cc LB |
1110 | |
1111 | // The number of sections are small, just do a linear search from the | |
1112 | // last section to the first. | |
1113 | bool Found = false; | |
1114 | unsigned SecIdx = CPSections.size(); | |
1115 | while (SecIdx != 0) { | |
1116 | if (CPSections[--SecIdx].S == S) { | |
1117 | Found = true; | |
1118 | break; | |
1119 | } | |
1120 | } | |
1121 | if (!Found) { | |
1122 | SecIdx = CPSections.size(); | |
1123 | CPSections.push_back(SectionCPs(S, Align)); | |
1124 | } | |
1125 | ||
1126 | if (Align > CPSections[SecIdx].Alignment) | |
1127 | CPSections[SecIdx].Alignment = Align; | |
1128 | CPSections[SecIdx].CPEs.push_back(i); | |
1129 | } | |
1130 | ||
1131 | // Now print stuff into the calculated sections. | |
1a4d82fc JJ |
1132 | const MCSection *CurSection = nullptr; |
1133 | unsigned Offset = 0; | |
223e47cc | 1134 | for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { |
223e47cc LB |
1135 | for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { |
1136 | unsigned CPI = CPSections[i].CPEs[j]; | |
1a4d82fc JJ |
1137 | MCSymbol *Sym = GetCPISymbol(CPI); |
1138 | if (!Sym->isUndefined()) | |
1139 | continue; | |
1140 | ||
1141 | if (CurSection != CPSections[i].S) { | |
1142 | OutStreamer.SwitchSection(CPSections[i].S); | |
1143 | EmitAlignment(Log2_32(CPSections[i].Alignment)); | |
1144 | CurSection = CPSections[i].S; | |
1145 | Offset = 0; | |
1146 | } | |
1147 | ||
223e47cc LB |
1148 | MachineConstantPoolEntry CPE = CP[CPI]; |
1149 | ||
1150 | // Emit inter-object padding for alignment. | |
1151 | unsigned AlignMask = CPE.getAlignment() - 1; | |
1152 | unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; | |
970d7e83 | 1153 | OutStreamer.EmitZeros(NewOffset - Offset); |
223e47cc LB |
1154 | |
1155 | Type *Ty = CPE.getType(); | |
1a4d82fc JJ |
1156 | Offset = NewOffset + |
1157 | TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(Ty); | |
223e47cc | 1158 | |
1a4d82fc | 1159 | OutStreamer.EmitLabel(Sym); |
223e47cc LB |
1160 | if (CPE.isMachineConstantPoolEntry()) |
1161 | EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); | |
1162 | else | |
1163 | EmitGlobalConstant(CPE.Val.ConstVal); | |
1164 | } | |
1165 | } | |
1166 | } | |
1167 | ||
1168 | /// EmitJumpTableInfo - Print assembly representations of the jump tables used | |
1169 | /// by the current function to the current output stream. | |
1170 | /// | |
1171 | void AsmPrinter::EmitJumpTableInfo() { | |
1a4d82fc | 1172 | const DataLayout *DL = MF->getSubtarget().getDataLayout(); |
223e47cc | 1173 | const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); |
1a4d82fc | 1174 | if (!MJTI) return; |
223e47cc LB |
1175 | if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; |
1176 | const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); | |
1177 | if (JT.empty()) return; | |
1178 | ||
1179 | // Pick the directive to use to print the jump table entries, and switch to | |
1180 | // the appropriate section. | |
1181 | const Function *F = MF->getFunction(); | |
1182 | bool JTInDiffSection = false; | |
1183 | if (// In PIC mode, we need to emit the jump table to the same section as the | |
1184 | // function body itself, otherwise the label differences won't make sense. | |
1185 | // FIXME: Need a better predicate for this: what about custom entries? | |
1186 | MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || | |
1187 | // We should also do if the section name is NULL or function is declared | |
1188 | // in discardable section | |
1189 | // FIXME: this isn't the right predicate, should be based on the MCSection | |
1190 | // for the function. | |
1191 | F->isWeakForLinker()) { | |
1a4d82fc JJ |
1192 | OutStreamer.SwitchSection( |
1193 | getObjFileLowering().SectionForGlobal(F, *Mang, TM)); | |
223e47cc LB |
1194 | } else { |
1195 | // Otherwise, drop it in the readonly section. | |
1196 | const MCSection *ReadOnlySection = | |
1a4d82fc JJ |
1197 | getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly(), |
1198 | /*C=*/nullptr); | |
223e47cc LB |
1199 | OutStreamer.SwitchSection(ReadOnlySection); |
1200 | JTInDiffSection = true; | |
1201 | } | |
1202 | ||
1a4d82fc JJ |
1203 | EmitAlignment(Log2_32( |
1204 | MJTI->getEntryAlignment(*TM.getSubtargetImpl()->getDataLayout()))); | |
223e47cc LB |
1205 | |
1206 | // Jump tables in code sections are marked with a data_region directive | |
1207 | // where that's supported. | |
1208 | if (!JTInDiffSection) | |
1209 | OutStreamer.EmitDataRegion(MCDR_DataRegionJT32); | |
1210 | ||
1211 | for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { | |
1212 | const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; | |
1213 | ||
1214 | // If this jump table was deleted, ignore it. | |
1215 | if (JTBBs.empty()) continue; | |
1216 | ||
85aaf69f SL |
1217 | // For the EK_LabelDifference32 entry, if using .set avoids a relocation, |
1218 | /// emit a .set directive for each unique entry. | |
223e47cc | 1219 | if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && |
85aaf69f | 1220 | MAI->doesSetDirectiveSuppressesReloc()) { |
223e47cc | 1221 | SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets; |
1a4d82fc | 1222 | const TargetLowering *TLI = TM.getSubtargetImpl()->getTargetLowering(); |
223e47cc LB |
1223 | const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext); |
1224 | for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { | |
1225 | const MachineBasicBlock *MBB = JTBBs[ii]; | |
85aaf69f SL |
1226 | if (!EmittedSets.insert(MBB).second) |
1227 | continue; | |
223e47cc LB |
1228 | |
1229 | // .set LJTSet, LBB32-base | |
1230 | const MCExpr *LHS = | |
1231 | MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); | |
1232 | OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), | |
1233 | MCBinaryExpr::CreateSub(LHS, Base, OutContext)); | |
1234 | } | |
1235 | } | |
1236 | ||
1237 | // On some targets (e.g. Darwin) we want to emit two consecutive labels | |
1238 | // before each jump table. The first label is never referenced, but tells | |
1239 | // the assembler and linker the extents of the jump table object. The | |
1240 | // second label is actually referenced by the code. | |
1a4d82fc | 1241 | if (JTInDiffSection && DL->hasLinkerPrivateGlobalPrefix()) |
223e47cc LB |
1242 | // FIXME: This doesn't have to have any specific name, just any randomly |
1243 | // named and numbered 'l' label would work. Simplify GetJTISymbol. | |
1244 | OutStreamer.EmitLabel(GetJTISymbol(JTI, true)); | |
1245 | ||
1246 | OutStreamer.EmitLabel(GetJTISymbol(JTI)); | |
1247 | ||
1248 | for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) | |
1249 | EmitJumpTableEntry(MJTI, JTBBs[ii], JTI); | |
1250 | } | |
1251 | if (!JTInDiffSection) | |
1252 | OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); | |
1253 | } | |
1254 | ||
1255 | /// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the | |
1256 | /// current stream. | |
1257 | void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, | |
1258 | const MachineBasicBlock *MBB, | |
1259 | unsigned UID) const { | |
1260 | assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block"); | |
1a4d82fc | 1261 | const MCExpr *Value = nullptr; |
223e47cc LB |
1262 | switch (MJTI->getEntryKind()) { |
1263 | case MachineJumpTableInfo::EK_Inline: | |
1264 | llvm_unreachable("Cannot emit EK_Inline jump table entry"); | |
1265 | case MachineJumpTableInfo::EK_Custom32: | |
1a4d82fc JJ |
1266 | Value = |
1267 | TM.getSubtargetImpl()->getTargetLowering()->LowerCustomJumpTableEntry( | |
1268 | MJTI, MBB, UID, OutContext); | |
223e47cc LB |
1269 | break; |
1270 | case MachineJumpTableInfo::EK_BlockAddress: | |
1271 | // EK_BlockAddress - Each entry is a plain address of block, e.g.: | |
1272 | // .word LBB123 | |
1273 | Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); | |
1274 | break; | |
1275 | case MachineJumpTableInfo::EK_GPRel32BlockAddress: { | |
1276 | // EK_GPRel32BlockAddress - Each entry is an address of block, encoded | |
1277 | // with a relocation as gp-relative, e.g.: | |
1278 | // .gprel32 LBB123 | |
1279 | MCSymbol *MBBSym = MBB->getSymbol(); | |
1280 | OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); | |
1281 | return; | |
1282 | } | |
1283 | ||
1284 | case MachineJumpTableInfo::EK_GPRel64BlockAddress: { | |
1285 | // EK_GPRel64BlockAddress - Each entry is an address of block, encoded | |
1286 | // with a relocation as gp-relative, e.g.: | |
1287 | // .gpdword LBB123 | |
1288 | MCSymbol *MBBSym = MBB->getSymbol(); | |
1289 | OutStreamer.EmitGPRel64Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); | |
1290 | return; | |
1291 | } | |
1292 | ||
1293 | case MachineJumpTableInfo::EK_LabelDifference32: { | |
85aaf69f SL |
1294 | // Each entry is the address of the block minus the address of the jump |
1295 | // table. This is used for PIC jump tables where gprel32 is not supported. | |
1296 | // e.g.: | |
223e47cc | 1297 | // .word LBB123 - LJTI1_2 |
85aaf69f | 1298 | // If the .set directive avoids relocations, this is emitted as: |
223e47cc LB |
1299 | // .set L4_5_set_123, LBB123 - LJTI1_2 |
1300 | // .word L4_5_set_123 | |
85aaf69f | 1301 | if (MAI->doesSetDirectiveSuppressesReloc()) { |
223e47cc LB |
1302 | Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()), |
1303 | OutContext); | |
1304 | break; | |
1305 | } | |
223e47cc | 1306 | Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); |
85aaf69f SL |
1307 | const TargetLowering *TLI = TM.getSubtargetImpl()->getTargetLowering(); |
1308 | const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF, UID, OutContext); | |
1309 | Value = MCBinaryExpr::CreateSub(Value, Base, OutContext); | |
223e47cc LB |
1310 | break; |
1311 | } | |
1312 | } | |
1313 | ||
1314 | assert(Value && "Unknown entry kind!"); | |
1315 | ||
1a4d82fc JJ |
1316 | unsigned EntrySize = |
1317 | MJTI->getEntrySize(*TM.getSubtargetImpl()->getDataLayout()); | |
970d7e83 | 1318 | OutStreamer.EmitValue(Value, EntrySize); |
223e47cc LB |
1319 | } |
1320 | ||
1321 | ||
1322 | /// EmitSpecialLLVMGlobal - Check to see if the specified global is a | |
1323 | /// special global used by LLVM. If so, emit it and return true, otherwise | |
1324 | /// do nothing and return false. | |
1325 | bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { | |
1326 | if (GV->getName() == "llvm.used") { | |
1327 | if (MAI->hasNoDeadStrip()) // No need to emit this at all. | |
1a4d82fc | 1328 | EmitLLVMUsedList(cast<ConstantArray>(GV->getInitializer())); |
223e47cc LB |
1329 | return true; |
1330 | } | |
1331 | ||
1332 | // Ignore debug and non-emitted data. This handles llvm.compiler.used. | |
1a4d82fc | 1333 | if (StringRef(GV->getSection()) == "llvm.metadata" || |
223e47cc LB |
1334 | GV->hasAvailableExternallyLinkage()) |
1335 | return true; | |
1336 | ||
1337 | if (!GV->hasAppendingLinkage()) return false; | |
1338 | ||
1339 | assert(GV->hasInitializer() && "Not a special LLVM global!"); | |
1340 | ||
1341 | if (GV->getName() == "llvm.global_ctors") { | |
1342 | EmitXXStructorList(GV->getInitializer(), /* isCtor */ true); | |
1343 | ||
1344 | if (TM.getRelocationModel() == Reloc::Static && | |
1345 | MAI->hasStaticCtorDtorReferenceInStaticMode()) { | |
1346 | StringRef Sym(".constructors_used"); | |
1347 | OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), | |
1348 | MCSA_Reference); | |
1349 | } | |
1350 | return true; | |
1351 | } | |
1352 | ||
1353 | if (GV->getName() == "llvm.global_dtors") { | |
1354 | EmitXXStructorList(GV->getInitializer(), /* isCtor */ false); | |
1355 | ||
1356 | if (TM.getRelocationModel() == Reloc::Static && | |
1357 | MAI->hasStaticCtorDtorReferenceInStaticMode()) { | |
1358 | StringRef Sym(".destructors_used"); | |
1359 | OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), | |
1360 | MCSA_Reference); | |
1361 | } | |
1362 | return true; | |
1363 | } | |
1364 | ||
1365 | return false; | |
1366 | } | |
1367 | ||
1368 | /// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each | |
1369 | /// global in the specified llvm.used list for which emitUsedDirectiveFor | |
1370 | /// is true, as being used with this directive. | |
1a4d82fc | 1371 | void AsmPrinter::EmitLLVMUsedList(const ConstantArray *InitList) { |
223e47cc | 1372 | // Should be an array of 'i8*'. |
223e47cc LB |
1373 | for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { |
1374 | const GlobalValue *GV = | |
1375 | dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); | |
1a4d82fc JJ |
1376 | if (GV) |
1377 | OutStreamer.EmitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip); | |
223e47cc LB |
1378 | } |
1379 | } | |
1380 | ||
1a4d82fc JJ |
1381 | namespace { |
1382 | struct Structor { | |
1383 | Structor() : Priority(0), Func(nullptr), ComdatKey(nullptr) {} | |
1384 | int Priority; | |
1385 | llvm::Constant *Func; | |
1386 | llvm::GlobalValue *ComdatKey; | |
1387 | }; | |
1388 | } // end namespace | |
223e47cc LB |
1389 | |
1390 | /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init | |
1391 | /// priority. | |
1392 | void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) { | |
1393 | // Should be an array of '{ int, void ()* }' structs. The first value is the | |
1394 | // init priority. | |
1395 | if (!isa<ConstantArray>(List)) return; | |
1396 | ||
1397 | // Sanity check the structors list. | |
1398 | const ConstantArray *InitList = dyn_cast<ConstantArray>(List); | |
1399 | if (!InitList) return; // Not an array! | |
1400 | StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType()); | |
1a4d82fc JJ |
1401 | // FIXME: Only allow the 3-field form in LLVM 4.0. |
1402 | if (!ETy || ETy->getNumElements() < 2 || ETy->getNumElements() > 3) | |
1403 | return; // Not an array of two or three elements! | |
223e47cc LB |
1404 | if (!isa<IntegerType>(ETy->getTypeAtIndex(0U)) || |
1405 | !isa<PointerType>(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr). | |
1a4d82fc JJ |
1406 | if (ETy->getNumElements() == 3 && !isa<PointerType>(ETy->getTypeAtIndex(2U))) |
1407 | return; // Not (int, ptr, ptr). | |
223e47cc LB |
1408 | |
1409 | // Gather the structors in a form that's convenient for sorting by priority. | |
1410 | SmallVector<Structor, 8> Structors; | |
1a4d82fc JJ |
1411 | for (Value *O : InitList->operands()) { |
1412 | ConstantStruct *CS = dyn_cast<ConstantStruct>(O); | |
223e47cc LB |
1413 | if (!CS) continue; // Malformed. |
1414 | if (CS->getOperand(1)->isNullValue()) | |
1415 | break; // Found a null terminator, skip the rest. | |
1416 | ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0)); | |
1417 | if (!Priority) continue; // Malformed. | |
1a4d82fc JJ |
1418 | Structors.push_back(Structor()); |
1419 | Structor &S = Structors.back(); | |
1420 | S.Priority = Priority->getLimitedValue(65535); | |
1421 | S.Func = CS->getOperand(1); | |
1422 | if (ETy->getNumElements() == 3 && !CS->getOperand(2)->isNullValue()) | |
1423 | S.ComdatKey = dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts()); | |
223e47cc LB |
1424 | } |
1425 | ||
1426 | // Emit the function pointers in the target-specific order | |
1a4d82fc JJ |
1427 | const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); |
1428 | unsigned Align = Log2_32(DL->getPointerPrefAlignment()); | |
1429 | std::stable_sort(Structors.begin(), Structors.end(), | |
1430 | [](const Structor &L, | |
1431 | const Structor &R) { return L.Priority < R.Priority; }); | |
1432 | for (Structor &S : Structors) { | |
1433 | const TargetLoweringObjectFile &Obj = getObjFileLowering(); | |
1434 | const MCSymbol *KeySym = nullptr; | |
1435 | if (GlobalValue *GV = S.ComdatKey) { | |
1436 | if (GV->hasAvailableExternallyLinkage()) | |
1437 | // If the associated variable is available_externally, some other TU | |
1438 | // will provide its dynamic initializer. | |
1439 | continue; | |
1440 | ||
1441 | KeySym = getSymbol(GV); | |
1442 | } | |
223e47cc | 1443 | const MCSection *OutputSection = |
1a4d82fc JJ |
1444 | (isCtor ? Obj.getStaticCtorSection(S.Priority, KeySym) |
1445 | : Obj.getStaticDtorSection(S.Priority, KeySym)); | |
223e47cc LB |
1446 | OutStreamer.SwitchSection(OutputSection); |
1447 | if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection()) | |
1448 | EmitAlignment(Align); | |
1a4d82fc JJ |
1449 | EmitXXStructor(S.Func); |
1450 | } | |
1451 | } | |
1452 | ||
1453 | void AsmPrinter::EmitModuleIdents(Module &M) { | |
1454 | if (!MAI->hasIdentDirective()) | |
1455 | return; | |
1456 | ||
1457 | if (const NamedMDNode *NMD = M.getNamedMetadata("llvm.ident")) { | |
1458 | for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { | |
1459 | const MDNode *N = NMD->getOperand(i); | |
1460 | assert(N->getNumOperands() == 1 && | |
1461 | "llvm.ident metadata entry can have only one operand"); | |
1462 | const MDString *S = cast<MDString>(N->getOperand(0)); | |
1463 | OutStreamer.EmitIdent(S->getString()); | |
1464 | } | |
223e47cc LB |
1465 | } |
1466 | } | |
1467 | ||
1468 | //===--------------------------------------------------------------------===// | |
1469 | // Emission and print routines | |
1470 | // | |
1471 | ||
1472 | /// EmitInt8 - Emit a byte directive and value. | |
1473 | /// | |
1474 | void AsmPrinter::EmitInt8(int Value) const { | |
970d7e83 | 1475 | OutStreamer.EmitIntValue(Value, 1); |
223e47cc LB |
1476 | } |
1477 | ||
1478 | /// EmitInt16 - Emit a short directive and value. | |
1479 | /// | |
1480 | void AsmPrinter::EmitInt16(int Value) const { | |
970d7e83 | 1481 | OutStreamer.EmitIntValue(Value, 2); |
223e47cc LB |
1482 | } |
1483 | ||
1484 | /// EmitInt32 - Emit a long directive and value. | |
1485 | /// | |
1486 | void AsmPrinter::EmitInt32(int Value) const { | |
970d7e83 | 1487 | OutStreamer.EmitIntValue(Value, 4); |
223e47cc LB |
1488 | } |
1489 | ||
85aaf69f SL |
1490 | /// Emit something like ".long Hi-Lo" where the size in bytes of the directive |
1491 | /// is specified by Size and Hi/Lo specify the labels. This implicitly uses | |
1492 | /// .set if it avoids relocations. | |
223e47cc LB |
1493 | void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, |
1494 | unsigned Size) const { | |
1495 | // Get the Hi-Lo expression. | |
1496 | const MCExpr *Diff = | |
1497 | MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), | |
1498 | MCSymbolRefExpr::Create(Lo, OutContext), | |
1499 | OutContext); | |
1500 | ||
85aaf69f | 1501 | if (!MAI->doesSetDirectiveSuppressesReloc()) { |
970d7e83 | 1502 | OutStreamer.EmitValue(Diff, Size); |
223e47cc LB |
1503 | return; |
1504 | } | |
1505 | ||
1506 | // Otherwise, emit with .set (aka assignment). | |
1507 | MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++); | |
1508 | OutStreamer.EmitAssignment(SetLabel, Diff); | |
970d7e83 | 1509 | OutStreamer.EmitSymbolValue(SetLabel, Size); |
223e47cc LB |
1510 | } |
1511 | ||
223e47cc LB |
1512 | /// EmitLabelPlusOffset - Emit something like ".long Label+Offset" |
1513 | /// where the size in bytes of the directive is specified by Size and Label | |
1514 | /// specifies the label. This implicitly uses .set if it is available. | |
1515 | void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, | |
1a4d82fc JJ |
1516 | unsigned Size, |
1517 | bool IsSectionRelative) const { | |
1518 | if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) { | |
1519 | OutStreamer.EmitCOFFSecRel32(Label); | |
1520 | return; | |
1521 | } | |
223e47cc LB |
1522 | |
1523 | // Emit Label+Offset (or just Label if Offset is zero) | |
1524 | const MCExpr *Expr = MCSymbolRefExpr::Create(Label, OutContext); | |
1525 | if (Offset) | |
1a4d82fc JJ |
1526 | Expr = MCBinaryExpr::CreateAdd( |
1527 | Expr, MCConstantExpr::Create(Offset, OutContext), OutContext); | |
223e47cc | 1528 | |
970d7e83 | 1529 | OutStreamer.EmitValue(Expr, Size); |
223e47cc LB |
1530 | } |
1531 | ||
223e47cc LB |
1532 | //===----------------------------------------------------------------------===// |
1533 | ||
1534 | // EmitAlignment - Emit an alignment directive to the specified power of | |
1535 | // two boundary. For example, if you pass in 3 here, you will get an 8 | |
1536 | // byte alignment. If a global value is specified, and if that global has | |
1537 | // an explicit alignment requested, it will override the alignment request | |
1538 | // if required for correctness. | |
1539 | // | |
1a4d82fc JJ |
1540 | void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalObject *GV) const { |
1541 | if (GV) | |
1542 | NumBits = getGVAlignmentLog2(GV, *TM.getSubtargetImpl()->getDataLayout(), | |
1543 | NumBits); | |
223e47cc LB |
1544 | |
1545 | if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment. | |
1546 | ||
85aaf69f SL |
1547 | assert(NumBits < |
1548 | static_cast<unsigned>(std::numeric_limits<unsigned>::digits) && | |
1549 | "undefined behavior"); | |
223e47cc | 1550 | if (getCurrentSection()->getKind().isText()) |
85aaf69f | 1551 | OutStreamer.EmitCodeAlignment(1u << NumBits); |
223e47cc | 1552 | else |
85aaf69f | 1553 | OutStreamer.EmitValueToAlignment(1u << NumBits); |
223e47cc LB |
1554 | } |
1555 | ||
1556 | //===----------------------------------------------------------------------===// | |
1557 | // Constant emission. | |
1558 | //===----------------------------------------------------------------------===// | |
1559 | ||
85aaf69f SL |
1560 | const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { |
1561 | MCContext &Ctx = OutContext; | |
223e47cc LB |
1562 | |
1563 | if (CV->isNullValue() || isa<UndefValue>(CV)) | |
1564 | return MCConstantExpr::Create(0, Ctx); | |
1565 | ||
1566 | if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) | |
1567 | return MCConstantExpr::Create(CI->getZExtValue(), Ctx); | |
1568 | ||
1569 | if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) | |
85aaf69f | 1570 | return MCSymbolRefExpr::Create(getSymbol(GV), Ctx); |
223e47cc LB |
1571 | |
1572 | if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) | |
85aaf69f | 1573 | return MCSymbolRefExpr::Create(GetBlockAddressSymbol(BA), Ctx); |
223e47cc LB |
1574 | |
1575 | const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); | |
1a4d82fc | 1576 | if (!CE) { |
223e47cc LB |
1577 | llvm_unreachable("Unknown constant value to lower!"); |
1578 | } | |
1579 | ||
85aaf69f SL |
1580 | if (const MCExpr *RelocExpr |
1581 | = getObjFileLowering().getExecutableRelativeSymbol(CE, *Mang, TM)) | |
1a4d82fc JJ |
1582 | return RelocExpr; |
1583 | ||
223e47cc LB |
1584 | switch (CE->getOpcode()) { |
1585 | default: | |
1586 | // If the code isn't optimized, there may be outstanding folding | |
970d7e83 | 1587 | // opportunities. Attempt to fold the expression using DataLayout as a |
223e47cc | 1588 | // last resort before giving up. |
1a4d82fc | 1589 | if (Constant *C = ConstantFoldConstantExpression( |
85aaf69f | 1590 | CE, TM.getSubtargetImpl()->getDataLayout())) |
223e47cc | 1591 | if (C != CE) |
85aaf69f | 1592 | return lowerConstant(C); |
223e47cc LB |
1593 | |
1594 | // Otherwise report the problem to the user. | |
1595 | { | |
1596 | std::string S; | |
1597 | raw_string_ostream OS(S); | |
1598 | OS << "Unsupported expression in static initializer: "; | |
1a4d82fc | 1599 | CE->printAsOperand(OS, /*PrintType=*/false, |
85aaf69f | 1600 | !MF ? nullptr : MF->getFunction()->getParent()); |
223e47cc LB |
1601 | report_fatal_error(OS.str()); |
1602 | } | |
1603 | case Instruction::GetElementPtr: { | |
85aaf69f | 1604 | const DataLayout &DL = *TM.getSubtargetImpl()->getDataLayout(); |
223e47cc | 1605 | // Generate a symbolic expression for the byte address |
1a4d82fc JJ |
1606 | APInt OffsetAI(DL.getPointerTypeSizeInBits(CE->getType()), 0); |
1607 | cast<GEPOperator>(CE)->accumulateConstantOffset(DL, OffsetAI); | |
223e47cc | 1608 | |
85aaf69f | 1609 | const MCExpr *Base = lowerConstant(CE->getOperand(0)); |
970d7e83 | 1610 | if (!OffsetAI) |
223e47cc LB |
1611 | return Base; |
1612 | ||
970d7e83 | 1613 | int64_t Offset = OffsetAI.getSExtValue(); |
223e47cc LB |
1614 | return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), |
1615 | Ctx); | |
1616 | } | |
1617 | ||
1618 | case Instruction::Trunc: | |
1619 | // We emit the value and depend on the assembler to truncate the generated | |
1620 | // expression properly. This is important for differences between | |
1621 | // blockaddress labels. Since the two labels are in the same function, it | |
1622 | // is reasonable to treat their delta as a 32-bit value. | |
1623 | // FALL THROUGH. | |
1624 | case Instruction::BitCast: | |
85aaf69f | 1625 | return lowerConstant(CE->getOperand(0)); |
223e47cc LB |
1626 | |
1627 | case Instruction::IntToPtr: { | |
85aaf69f | 1628 | const DataLayout &DL = *TM.getSubtargetImpl()->getDataLayout(); |
223e47cc LB |
1629 | // Handle casts to pointers by changing them into casts to the appropriate |
1630 | // integer type. This promotes constant folding and simplifies this code. | |
1631 | Constant *Op = CE->getOperand(0); | |
1a4d82fc | 1632 | Op = ConstantExpr::getIntegerCast(Op, DL.getIntPtrType(CV->getType()), |
223e47cc | 1633 | false/*ZExt*/); |
85aaf69f | 1634 | return lowerConstant(Op); |
223e47cc LB |
1635 | } |
1636 | ||
1637 | case Instruction::PtrToInt: { | |
85aaf69f | 1638 | const DataLayout &DL = *TM.getSubtargetImpl()->getDataLayout(); |
223e47cc LB |
1639 | // Support only foldable casts to/from pointers that can be eliminated by |
1640 | // changing the pointer to the appropriately sized integer type. | |
1641 | Constant *Op = CE->getOperand(0); | |
1642 | Type *Ty = CE->getType(); | |
1643 | ||
85aaf69f | 1644 | const MCExpr *OpExpr = lowerConstant(Op); |
223e47cc LB |
1645 | |
1646 | // We can emit the pointer value into this slot if the slot is an | |
1647 | // integer slot equal to the size of the pointer. | |
1a4d82fc | 1648 | if (DL.getTypeAllocSize(Ty) == DL.getTypeAllocSize(Op->getType())) |
223e47cc LB |
1649 | return OpExpr; |
1650 | ||
1651 | // Otherwise the pointer is smaller than the resultant integer, mask off | |
1652 | // the high bits so we are sure to get a proper truncation if the input is | |
1653 | // a constant expr. | |
1a4d82fc | 1654 | unsigned InBits = DL.getTypeAllocSizeInBits(Op->getType()); |
223e47cc LB |
1655 | const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); |
1656 | return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); | |
1657 | } | |
1658 | ||
1659 | // The MC library also has a right-shift operator, but it isn't consistently | |
1660 | // signed or unsigned between different targets. | |
1661 | case Instruction::Add: | |
1662 | case Instruction::Sub: | |
1663 | case Instruction::Mul: | |
1664 | case Instruction::SDiv: | |
1665 | case Instruction::SRem: | |
1666 | case Instruction::Shl: | |
1667 | case Instruction::And: | |
1668 | case Instruction::Or: | |
1669 | case Instruction::Xor: { | |
85aaf69f SL |
1670 | const MCExpr *LHS = lowerConstant(CE->getOperand(0)); |
1671 | const MCExpr *RHS = lowerConstant(CE->getOperand(1)); | |
223e47cc LB |
1672 | switch (CE->getOpcode()) { |
1673 | default: llvm_unreachable("Unknown binary operator constant cast expr"); | |
1674 | case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); | |
1675 | case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); | |
1676 | case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx); | |
1677 | case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx); | |
1678 | case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx); | |
1679 | case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx); | |
1680 | case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); | |
1681 | case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); | |
1682 | case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); | |
1683 | } | |
1684 | } | |
1685 | } | |
1686 | } | |
1687 | ||
1a4d82fc | 1688 | static void emitGlobalConstantImpl(const Constant *C, AsmPrinter &AP); |
223e47cc LB |
1689 | |
1690 | /// isRepeatedByteSequence - Determine whether the given value is | |
1691 | /// composed of a repeated sequence of identical bytes and return the | |
1692 | /// byte value. If it is not a repeated sequence, return -1. | |
1693 | static int isRepeatedByteSequence(const ConstantDataSequential *V) { | |
1694 | StringRef Data = V->getRawDataValues(); | |
1695 | assert(!Data.empty() && "Empty aggregates should be CAZ node"); | |
1696 | char C = Data[0]; | |
1697 | for (unsigned i = 1, e = Data.size(); i != e; ++i) | |
1698 | if (Data[i] != C) return -1; | |
1699 | return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1. | |
1700 | } | |
1701 | ||
1702 | ||
1703 | /// isRepeatedByteSequence - Determine whether the given value is | |
1704 | /// composed of a repeated sequence of identical bytes and return the | |
1705 | /// byte value. If it is not a repeated sequence, return -1. | |
1706 | static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { | |
1707 | ||
1708 | if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) { | |
1709 | if (CI->getBitWidth() > 64) return -1; | |
1710 | ||
1a4d82fc JJ |
1711 | uint64_t Size = |
1712 | TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(V->getType()); | |
223e47cc LB |
1713 | uint64_t Value = CI->getZExtValue(); |
1714 | ||
1715 | // Make sure the constant is at least 8 bits long and has a power | |
1716 | // of 2 bit width. This guarantees the constant bit width is | |
1717 | // always a multiple of 8 bits, avoiding issues with padding out | |
1718 | // to Size and other such corner cases. | |
1719 | if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1; | |
1720 | ||
1721 | uint8_t Byte = static_cast<uint8_t>(Value); | |
1722 | ||
1723 | for (unsigned i = 1; i < Size; ++i) { | |
1724 | Value >>= 8; | |
1725 | if (static_cast<uint8_t>(Value) != Byte) return -1; | |
1726 | } | |
1727 | return Byte; | |
1728 | } | |
1729 | if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) { | |
1730 | // Make sure all array elements are sequences of the same repeated | |
1731 | // byte. | |
1732 | assert(CA->getNumOperands() != 0 && "Should be a CAZ"); | |
1733 | int Byte = isRepeatedByteSequence(CA->getOperand(0), TM); | |
1734 | if (Byte == -1) return -1; | |
1735 | ||
1736 | for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { | |
1737 | int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM); | |
1738 | if (ThisByte == -1) return -1; | |
1739 | if (Byte != ThisByte) return -1; | |
1740 | } | |
1741 | return Byte; | |
1742 | } | |
970d7e83 | 1743 | |
223e47cc LB |
1744 | if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V)) |
1745 | return isRepeatedByteSequence(CDS); | |
1746 | ||
1747 | return -1; | |
1748 | } | |
1749 | ||
1750 | static void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS, | |
1a4d82fc | 1751 | AsmPrinter &AP){ |
970d7e83 | 1752 | |
223e47cc LB |
1753 | // See if we can aggregate this into a .fill, if so, emit it as such. |
1754 | int Value = isRepeatedByteSequence(CDS, AP.TM); | |
1755 | if (Value != -1) { | |
1a4d82fc JJ |
1756 | uint64_t Bytes = |
1757 | AP.TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize( | |
1758 | CDS->getType()); | |
223e47cc LB |
1759 | // Don't emit a 1-byte object as a .fill. |
1760 | if (Bytes > 1) | |
1a4d82fc | 1761 | return AP.OutStreamer.EmitFill(Bytes, Value); |
223e47cc | 1762 | } |
970d7e83 | 1763 | |
223e47cc LB |
1764 | // If this can be emitted with .ascii/.asciz, emit it as such. |
1765 | if (CDS->isString()) | |
1a4d82fc | 1766 | return AP.OutStreamer.EmitBytes(CDS->getAsString()); |
223e47cc LB |
1767 | |
1768 | // Otherwise, emit the values in successive locations. | |
1769 | unsigned ElementByteSize = CDS->getElementByteSize(); | |
1770 | if (isa<IntegerType>(CDS->getElementType())) { | |
1771 | for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { | |
1772 | if (AP.isVerbose()) | |
1773 | AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n", | |
1774 | CDS->getElementAsInteger(i)); | |
1775 | AP.OutStreamer.EmitIntValue(CDS->getElementAsInteger(i), | |
1a4d82fc | 1776 | ElementByteSize); |
223e47cc LB |
1777 | } |
1778 | } else if (ElementByteSize == 4) { | |
1779 | // FP Constants are printed as integer constants to avoid losing | |
1780 | // precision. | |
1781 | assert(CDS->getElementType()->isFloatTy()); | |
1782 | for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { | |
1783 | union { | |
1784 | float F; | |
1785 | uint32_t I; | |
1786 | }; | |
970d7e83 | 1787 | |
223e47cc LB |
1788 | F = CDS->getElementAsFloat(i); |
1789 | if (AP.isVerbose()) | |
1790 | AP.OutStreamer.GetCommentOS() << "float " << F << '\n'; | |
1a4d82fc | 1791 | AP.OutStreamer.EmitIntValue(I, 4); |
223e47cc LB |
1792 | } |
1793 | } else { | |
1794 | assert(CDS->getElementType()->isDoubleTy()); | |
1795 | for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { | |
1796 | union { | |
1797 | double F; | |
1798 | uint64_t I; | |
1799 | }; | |
970d7e83 | 1800 | |
223e47cc LB |
1801 | F = CDS->getElementAsDouble(i); |
1802 | if (AP.isVerbose()) | |
1803 | AP.OutStreamer.GetCommentOS() << "double " << F << '\n'; | |
1a4d82fc | 1804 | AP.OutStreamer.EmitIntValue(I, 8); |
223e47cc LB |
1805 | } |
1806 | } | |
1807 | ||
1a4d82fc JJ |
1808 | const DataLayout &DL = *AP.TM.getSubtargetImpl()->getDataLayout(); |
1809 | unsigned Size = DL.getTypeAllocSize(CDS->getType()); | |
1810 | unsigned EmittedSize = DL.getTypeAllocSize(CDS->getType()->getElementType()) * | |
223e47cc LB |
1811 | CDS->getNumElements(); |
1812 | if (unsigned Padding = Size - EmittedSize) | |
1a4d82fc | 1813 | AP.OutStreamer.EmitZeros(Padding); |
223e47cc LB |
1814 | |
1815 | } | |
1816 | ||
1a4d82fc | 1817 | static void emitGlobalConstantArray(const ConstantArray *CA, AsmPrinter &AP) { |
223e47cc LB |
1818 | // See if we can aggregate some values. Make sure it can be |
1819 | // represented as a series of bytes of the constant value. | |
1820 | int Value = isRepeatedByteSequence(CA, AP.TM); | |
1821 | ||
1822 | if (Value != -1) { | |
1a4d82fc JJ |
1823 | uint64_t Bytes = |
1824 | AP.TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize( | |
1825 | CA->getType()); | |
1826 | AP.OutStreamer.EmitFill(Bytes, Value); | |
223e47cc LB |
1827 | } |
1828 | else { | |
1829 | for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) | |
1a4d82fc | 1830 | emitGlobalConstantImpl(CA->getOperand(i), AP); |
223e47cc LB |
1831 | } |
1832 | } | |
1833 | ||
1a4d82fc | 1834 | static void emitGlobalConstantVector(const ConstantVector *CV, AsmPrinter &AP) { |
223e47cc | 1835 | for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) |
1a4d82fc | 1836 | emitGlobalConstantImpl(CV->getOperand(i), AP); |
223e47cc | 1837 | |
1a4d82fc JJ |
1838 | const DataLayout &DL = *AP.TM.getSubtargetImpl()->getDataLayout(); |
1839 | unsigned Size = DL.getTypeAllocSize(CV->getType()); | |
1840 | unsigned EmittedSize = DL.getTypeAllocSize(CV->getType()->getElementType()) * | |
223e47cc LB |
1841 | CV->getType()->getNumElements(); |
1842 | if (unsigned Padding = Size - EmittedSize) | |
1a4d82fc | 1843 | AP.OutStreamer.EmitZeros(Padding); |
223e47cc LB |
1844 | } |
1845 | ||
1a4d82fc | 1846 | static void emitGlobalConstantStruct(const ConstantStruct *CS, AsmPrinter &AP) { |
223e47cc | 1847 | // Print the fields in successive locations. Pad to align if needed! |
1a4d82fc JJ |
1848 | const DataLayout *DL = AP.TM.getSubtargetImpl()->getDataLayout(); |
1849 | unsigned Size = DL->getTypeAllocSize(CS->getType()); | |
1850 | const StructLayout *Layout = DL->getStructLayout(CS->getType()); | |
223e47cc LB |
1851 | uint64_t SizeSoFar = 0; |
1852 | for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { | |
1853 | const Constant *Field = CS->getOperand(i); | |
1854 | ||
1855 | // Check if padding is needed and insert one or more 0s. | |
1a4d82fc | 1856 | uint64_t FieldSize = DL->getTypeAllocSize(Field->getType()); |
223e47cc LB |
1857 | uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1)) |
1858 | - Layout->getElementOffset(i)) - FieldSize; | |
1859 | SizeSoFar += FieldSize + PadSize; | |
1860 | ||
1861 | // Now print the actual field value. | |
1a4d82fc | 1862 | emitGlobalConstantImpl(Field, AP); |
223e47cc LB |
1863 | |
1864 | // Insert padding - this may include padding to increase the size of the | |
1865 | // current field up to the ABI size (if the struct is not packed) as well | |
1866 | // as padding to ensure that the next field starts at the right offset. | |
1a4d82fc | 1867 | AP.OutStreamer.EmitZeros(PadSize); |
223e47cc LB |
1868 | } |
1869 | assert(SizeSoFar == Layout->getSizeInBytes() && | |
1870 | "Layout of constant struct may be incorrect!"); | |
1871 | } | |
1872 | ||
1a4d82fc | 1873 | static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) { |
970d7e83 | 1874 | APInt API = CFP->getValueAPF().bitcastToAPInt(); |
223e47cc | 1875 | |
970d7e83 LB |
1876 | // First print a comment with what we think the original floating-point value |
1877 | // should have been. | |
1878 | if (AP.isVerbose()) { | |
1879 | SmallString<8> StrVal; | |
1880 | CFP->getValueAPF().toString(StrVal); | |
223e47cc | 1881 | |
1a4d82fc JJ |
1882 | if (CFP->getType()) |
1883 | CFP->getType()->print(AP.OutStreamer.GetCommentOS()); | |
1884 | else | |
1885 | AP.OutStreamer.GetCommentOS() << "Printing <null> Type"; | |
970d7e83 | 1886 | AP.OutStreamer.GetCommentOS() << ' ' << StrVal << '\n'; |
223e47cc LB |
1887 | } |
1888 | ||
970d7e83 LB |
1889 | // Now iterate through the APInt chunks, emitting them in endian-correct |
1890 | // order, possibly with a smaller chunk at beginning/end (e.g. for x87 80-bit | |
1891 | // floats). | |
1892 | unsigned NumBytes = API.getBitWidth() / 8; | |
1893 | unsigned TrailingBytes = NumBytes % sizeof(uint64_t); | |
1894 | const uint64_t *p = API.getRawData(); | |
223e47cc | 1895 | |
970d7e83 LB |
1896 | // PPC's long double has odd notions of endianness compared to how LLVM |
1897 | // handles it: p[0] goes first for *big* endian on PPC. | |
1a4d82fc JJ |
1898 | if (AP.TM.getSubtargetImpl()->getDataLayout()->isBigEndian() && |
1899 | !CFP->getType()->isPPC_FP128Ty()) { | |
970d7e83 | 1900 | int Chunk = API.getNumWords() - 1; |
223e47cc | 1901 | |
970d7e83 | 1902 | if (TrailingBytes) |
1a4d82fc | 1903 | AP.OutStreamer.EmitIntValue(p[Chunk--], TrailingBytes); |
223e47cc | 1904 | |
970d7e83 | 1905 | for (; Chunk >= 0; --Chunk) |
1a4d82fc | 1906 | AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t)); |
223e47cc | 1907 | } else { |
970d7e83 LB |
1908 | unsigned Chunk; |
1909 | for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk) | |
1a4d82fc | 1910 | AP.OutStreamer.EmitIntValue(p[Chunk], sizeof(uint64_t)); |
970d7e83 LB |
1911 | |
1912 | if (TrailingBytes) | |
1a4d82fc | 1913 | AP.OutStreamer.EmitIntValue(p[Chunk], TrailingBytes); |
223e47cc | 1914 | } |
970d7e83 LB |
1915 | |
1916 | // Emit the tail padding for the long double. | |
1a4d82fc JJ |
1917 | const DataLayout &DL = *AP.TM.getSubtargetImpl()->getDataLayout(); |
1918 | AP.OutStreamer.EmitZeros(DL.getTypeAllocSize(CFP->getType()) - | |
1919 | DL.getTypeStoreSize(CFP->getType())); | |
223e47cc LB |
1920 | } |
1921 | ||
1a4d82fc JJ |
1922 | static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) { |
1923 | const DataLayout *DL = AP.TM.getSubtargetImpl()->getDataLayout(); | |
223e47cc | 1924 | unsigned BitWidth = CI->getBitWidth(); |
1a4d82fc JJ |
1925 | |
1926 | // Copy the value as we may massage the layout for constants whose bit width | |
1927 | // is not a multiple of 64-bits. | |
1928 | APInt Realigned(CI->getValue()); | |
1929 | uint64_t ExtraBits = 0; | |
1930 | unsigned ExtraBitsSize = BitWidth & 63; | |
1931 | ||
1932 | if (ExtraBitsSize) { | |
1933 | // The bit width of the data is not a multiple of 64-bits. | |
1934 | // The extra bits are expected to be at the end of the chunk of the memory. | |
1935 | // Little endian: | |
1936 | // * Nothing to be done, just record the extra bits to emit. | |
1937 | // Big endian: | |
1938 | // * Record the extra bits to emit. | |
1939 | // * Realign the raw data to emit the chunks of 64-bits. | |
1940 | if (DL->isBigEndian()) { | |
1941 | // Basically the structure of the raw data is a chunk of 64-bits cells: | |
1942 | // 0 1 BitWidth / 64 | |
1943 | // [chunk1][chunk2] ... [chunkN]. | |
1944 | // The most significant chunk is chunkN and it should be emitted first. | |
1945 | // However, due to the alignment issue chunkN contains useless bits. | |
1946 | // Realign the chunks so that they contain only useless information: | |
1947 | // ExtraBits 0 1 (BitWidth / 64) - 1 | |
1948 | // chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN] | |
1949 | ExtraBits = Realigned.getRawData()[0] & | |
1950 | (((uint64_t)-1) >> (64 - ExtraBitsSize)); | |
1951 | Realigned = Realigned.lshr(ExtraBitsSize); | |
1952 | } else | |
1953 | ExtraBits = Realigned.getRawData()[BitWidth / 64]; | |
1954 | } | |
223e47cc LB |
1955 | |
1956 | // We don't expect assemblers to support integer data directives | |
1957 | // for more than 64 bits, so we emit the data in at most 64-bit | |
1958 | // quantities at a time. | |
1a4d82fc | 1959 | const uint64_t *RawData = Realigned.getRawData(); |
223e47cc | 1960 | for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { |
1a4d82fc JJ |
1961 | uint64_t Val = DL->isBigEndian() ? RawData[e - i - 1] : RawData[i]; |
1962 | AP.OutStreamer.EmitIntValue(Val, 8); | |
1963 | } | |
1964 | ||
1965 | if (ExtraBitsSize) { | |
1966 | // Emit the extra bits after the 64-bits chunks. | |
1967 | ||
1968 | // Emit a directive that fills the expected size. | |
1969 | uint64_t Size = AP.TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize( | |
1970 | CI->getType()); | |
1971 | Size -= (BitWidth / 64) * 8; | |
1972 | assert(Size && Size * 8 >= ExtraBitsSize && | |
1973 | (ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize))) | |
1974 | == ExtraBits && "Directive too small for extra bits."); | |
1975 | AP.OutStreamer.EmitIntValue(ExtraBits, Size); | |
223e47cc LB |
1976 | } |
1977 | } | |
1978 | ||
1a4d82fc JJ |
1979 | static void emitGlobalConstantImpl(const Constant *CV, AsmPrinter &AP) { |
1980 | const DataLayout *DL = AP.TM.getSubtargetImpl()->getDataLayout(); | |
1981 | uint64_t Size = DL->getTypeAllocSize(CV->getType()); | |
223e47cc | 1982 | if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) |
1a4d82fc | 1983 | return AP.OutStreamer.EmitZeros(Size); |
223e47cc LB |
1984 | |
1985 | if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { | |
1986 | switch (Size) { | |
1987 | case 1: | |
1988 | case 2: | |
1989 | case 4: | |
1990 | case 8: | |
1991 | if (AP.isVerbose()) | |
1992 | AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n", | |
1993 | CI->getZExtValue()); | |
1a4d82fc | 1994 | AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size); |
223e47cc LB |
1995 | return; |
1996 | default: | |
1a4d82fc | 1997 | emitGlobalConstantLargeInt(CI, AP); |
223e47cc LB |
1998 | return; |
1999 | } | |
2000 | } | |
2001 | ||
2002 | if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) | |
1a4d82fc | 2003 | return emitGlobalConstantFP(CFP, AP); |
223e47cc LB |
2004 | |
2005 | if (isa<ConstantPointerNull>(CV)) { | |
1a4d82fc | 2006 | AP.OutStreamer.EmitIntValue(0, Size); |
223e47cc LB |
2007 | return; |
2008 | } | |
2009 | ||
2010 | if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV)) | |
1a4d82fc | 2011 | return emitGlobalConstantDataSequential(CDS, AP); |
970d7e83 | 2012 | |
223e47cc | 2013 | if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) |
1a4d82fc | 2014 | return emitGlobalConstantArray(CVA, AP); |
223e47cc LB |
2015 | |
2016 | if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) | |
1a4d82fc | 2017 | return emitGlobalConstantStruct(CVS, AP); |
223e47cc LB |
2018 | |
2019 | if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { | |
2020 | // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of | |
2021 | // vectors). | |
2022 | if (CE->getOpcode() == Instruction::BitCast) | |
1a4d82fc | 2023 | return emitGlobalConstantImpl(CE->getOperand(0), AP); |
223e47cc LB |
2024 | |
2025 | if (Size > 8) { | |
2026 | // If the constant expression's size is greater than 64-bits, then we have | |
2027 | // to emit the value in chunks. Try to constant fold the value and emit it | |
2028 | // that way. | |
1a4d82fc | 2029 | Constant *New = ConstantFoldConstantExpression(CE, DL); |
223e47cc | 2030 | if (New && New != CE) |
1a4d82fc | 2031 | return emitGlobalConstantImpl(New, AP); |
223e47cc LB |
2032 | } |
2033 | } | |
970d7e83 | 2034 | |
223e47cc | 2035 | if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) |
1a4d82fc | 2036 | return emitGlobalConstantVector(V, AP); |
970d7e83 | 2037 | |
223e47cc LB |
2038 | // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it |
2039 | // thread the streamer with EmitValue. | |
85aaf69f | 2040 | AP.OutStreamer.EmitValue(AP.lowerConstant(CV), Size); |
223e47cc LB |
2041 | } |
2042 | ||
2043 | /// EmitGlobalConstant - Print a general LLVM constant to the .s file. | |
1a4d82fc JJ |
2044 | void AsmPrinter::EmitGlobalConstant(const Constant *CV) { |
2045 | uint64_t Size = | |
2046 | TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(CV->getType()); | |
223e47cc | 2047 | if (Size) |
1a4d82fc | 2048 | emitGlobalConstantImpl(CV, *this); |
223e47cc LB |
2049 | else if (MAI->hasSubsectionsViaSymbols()) { |
2050 | // If the global has zero size, emit a single byte so that two labels don't | |
2051 | // look like they are at the same location. | |
1a4d82fc | 2052 | OutStreamer.EmitIntValue(0, 1); |
223e47cc LB |
2053 | } |
2054 | } | |
2055 | ||
2056 | void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { | |
2057 | // Target doesn't support this yet! | |
2058 | llvm_unreachable("Target does not support EmitMachineConstantPoolValue"); | |
2059 | } | |
2060 | ||
2061 | void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { | |
2062 | if (Offset > 0) | |
2063 | OS << '+' << Offset; | |
2064 | else if (Offset < 0) | |
2065 | OS << Offset; | |
2066 | } | |
2067 | ||
2068 | //===----------------------------------------------------------------------===// | |
2069 | // Symbol Lowering Routines. | |
2070 | //===----------------------------------------------------------------------===// | |
2071 | ||
2072 | /// GetTempSymbol - Return the MCSymbol corresponding to the assembler | |
2073 | /// temporary label with the specified stem and unique ID. | |
1a4d82fc JJ |
2074 | MCSymbol *AsmPrinter::GetTempSymbol(Twine Name, unsigned ID) const { |
2075 | const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); | |
2076 | return OutContext.GetOrCreateSymbol(Twine(DL->getPrivateGlobalPrefix()) + | |
223e47cc LB |
2077 | Name + Twine(ID)); |
2078 | } | |
2079 | ||
2080 | /// GetTempSymbol - Return an assembler temporary label with the specified | |
2081 | /// stem. | |
1a4d82fc JJ |
2082 | MCSymbol *AsmPrinter::GetTempSymbol(Twine Name) const { |
2083 | const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); | |
2084 | return OutContext.GetOrCreateSymbol(Twine(DL->getPrivateGlobalPrefix())+ | |
223e47cc LB |
2085 | Name); |
2086 | } | |
2087 | ||
2088 | ||
2089 | MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { | |
2090 | return MMI->getAddrLabelSymbol(BA->getBasicBlock()); | |
2091 | } | |
2092 | ||
2093 | MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { | |
2094 | return MMI->getAddrLabelSymbol(BB); | |
2095 | } | |
2096 | ||
2097 | /// GetCPISymbol - Return the symbol for the specified constant pool entry. | |
2098 | MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { | |
1a4d82fc | 2099 | const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); |
223e47cc | 2100 | return OutContext.GetOrCreateSymbol |
1a4d82fc | 2101 | (Twine(DL->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber()) |
223e47cc LB |
2102 | + "_" + Twine(CPID)); |
2103 | } | |
2104 | ||
2105 | /// GetJTISymbol - Return the symbol for the specified jump table entry. | |
2106 | MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { | |
2107 | return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate); | |
2108 | } | |
2109 | ||
2110 | /// GetJTSetSymbol - Return the symbol for the specified jump table .set | |
2111 | /// FIXME: privatize to AsmPrinter. | |
2112 | MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { | |
1a4d82fc | 2113 | const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout(); |
223e47cc | 2114 | return OutContext.GetOrCreateSymbol |
1a4d82fc | 2115 | (Twine(DL->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" + |
223e47cc LB |
2116 | Twine(UID) + "_set_" + Twine(MBBID)); |
2117 | } | |
2118 | ||
1a4d82fc JJ |
2119 | MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV, |
2120 | StringRef Suffix) const { | |
2121 | return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, *Mang, | |
2122 | TM); | |
223e47cc LB |
2123 | } |
2124 | ||
2125 | /// GetExternalSymbolSymbol - Return the MCSymbol for the specified | |
2126 | /// ExternalSymbol. | |
2127 | MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { | |
2128 | SmallString<60> NameStr; | |
2129 | Mang->getNameWithPrefix(NameStr, Sym); | |
2130 | return OutContext.GetOrCreateSymbol(NameStr.str()); | |
2131 | } | |
2132 | ||
2133 | ||
2134 | ||
2135 | /// PrintParentLoopComment - Print comments about parent loops of this one. | |
2136 | static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, | |
2137 | unsigned FunctionNumber) { | |
1a4d82fc | 2138 | if (!Loop) return; |
223e47cc LB |
2139 | PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber); |
2140 | OS.indent(Loop->getLoopDepth()*2) | |
2141 | << "Parent Loop BB" << FunctionNumber << "_" | |
2142 | << Loop->getHeader()->getNumber() | |
2143 | << " Depth=" << Loop->getLoopDepth() << '\n'; | |
2144 | } | |
2145 | ||
2146 | ||
2147 | /// PrintChildLoopComment - Print comments about child loops within | |
2148 | /// the loop for this basic block, with nesting. | |
2149 | static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, | |
2150 | unsigned FunctionNumber) { | |
2151 | // Add child loop information | |
1a4d82fc JJ |
2152 | for (const MachineLoop *CL : *Loop) { |
2153 | OS.indent(CL->getLoopDepth()*2) | |
223e47cc | 2154 | << "Child Loop BB" << FunctionNumber << "_" |
1a4d82fc | 2155 | << CL->getHeader()->getNumber() << " Depth " << CL->getLoopDepth() |
223e47cc | 2156 | << '\n'; |
1a4d82fc | 2157 | PrintChildLoopComment(OS, CL, FunctionNumber); |
223e47cc LB |
2158 | } |
2159 | } | |
2160 | ||
2161 | /// emitBasicBlockLoopComments - Pretty-print comments for basic blocks. | |
2162 | static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB, | |
2163 | const MachineLoopInfo *LI, | |
2164 | const AsmPrinter &AP) { | |
2165 | // Add loop depth information | |
2166 | const MachineLoop *Loop = LI->getLoopFor(&MBB); | |
1a4d82fc | 2167 | if (!Loop) return; |
223e47cc LB |
2168 | |
2169 | MachineBasicBlock *Header = Loop->getHeader(); | |
2170 | assert(Header && "No header for loop"); | |
2171 | ||
2172 | // If this block is not a loop header, just print out what is the loop header | |
2173 | // and return. | |
2174 | if (Header != &MBB) { | |
2175 | AP.OutStreamer.AddComment(" in Loop: Header=BB" + | |
2176 | Twine(AP.getFunctionNumber())+"_" + | |
2177 | Twine(Loop->getHeader()->getNumber())+ | |
2178 | " Depth="+Twine(Loop->getLoopDepth())); | |
2179 | return; | |
2180 | } | |
2181 | ||
2182 | // Otherwise, it is a loop header. Print out information about child and | |
2183 | // parent loops. | |
2184 | raw_ostream &OS = AP.OutStreamer.GetCommentOS(); | |
2185 | ||
2186 | PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); | |
2187 | ||
2188 | OS << "=>"; | |
2189 | OS.indent(Loop->getLoopDepth()*2-2); | |
2190 | ||
2191 | OS << "This "; | |
2192 | if (Loop->empty()) | |
2193 | OS << "Inner "; | |
2194 | OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; | |
2195 | ||
2196 | PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); | |
2197 | } | |
2198 | ||
2199 | ||
2200 | /// EmitBasicBlockStart - This method prints the label for the specified | |
2201 | /// MachineBasicBlock, an alignment (if present) and a comment describing | |
2202 | /// it if appropriate. | |
1a4d82fc | 2203 | void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const { |
223e47cc | 2204 | // Emit an alignment directive for this block, if needed. |
1a4d82fc | 2205 | if (unsigned Align = MBB.getAlignment()) |
223e47cc LB |
2206 | EmitAlignment(Align); |
2207 | ||
2208 | // If the block has its address taken, emit any labels that were used to | |
2209 | // reference the block. It is possible that there is more than one label | |
2210 | // here, because multiple LLVM BB's may have been RAUW'd to this block after | |
2211 | // the references were generated. | |
1a4d82fc JJ |
2212 | if (MBB.hasAddressTaken()) { |
2213 | const BasicBlock *BB = MBB.getBasicBlock(); | |
223e47cc LB |
2214 | if (isVerbose()) |
2215 | OutStreamer.AddComment("Block address taken"); | |
2216 | ||
1a4d82fc JJ |
2217 | std::vector<MCSymbol*> Symbols = MMI->getAddrLabelSymbolToEmit(BB); |
2218 | for (auto *Sym : Symbols) | |
2219 | OutStreamer.EmitLabel(Sym); | |
223e47cc LB |
2220 | } |
2221 | ||
2222 | // Print some verbose block comments. | |
2223 | if (isVerbose()) { | |
1a4d82fc | 2224 | if (const BasicBlock *BB = MBB.getBasicBlock()) |
223e47cc LB |
2225 | if (BB->hasName()) |
2226 | OutStreamer.AddComment("%" + BB->getName()); | |
1a4d82fc | 2227 | emitBasicBlockLoopComments(MBB, LI, *this); |
223e47cc LB |
2228 | } |
2229 | ||
2230 | // Print the main label for the block. | |
1a4d82fc JJ |
2231 | if (MBB.pred_empty() || isBlockOnlyReachableByFallthrough(&MBB)) { |
2232 | if (isVerbose()) { | |
223e47cc | 2233 | // NOTE: Want this comment at start of line, don't emit with AddComment. |
1a4d82fc | 2234 | OutStreamer.emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false); |
223e47cc LB |
2235 | } |
2236 | } else { | |
1a4d82fc | 2237 | OutStreamer.EmitLabel(MBB.getSymbol()); |
223e47cc LB |
2238 | } |
2239 | } | |
2240 | ||
2241 | void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility, | |
2242 | bool IsDefinition) const { | |
2243 | MCSymbolAttr Attr = MCSA_Invalid; | |
2244 | ||
2245 | switch (Visibility) { | |
2246 | default: break; | |
2247 | case GlobalValue::HiddenVisibility: | |
2248 | if (IsDefinition) | |
2249 | Attr = MAI->getHiddenVisibilityAttr(); | |
2250 | else | |
2251 | Attr = MAI->getHiddenDeclarationVisibilityAttr(); | |
2252 | break; | |
2253 | case GlobalValue::ProtectedVisibility: | |
2254 | Attr = MAI->getProtectedVisibilityAttr(); | |
2255 | break; | |
2256 | } | |
2257 | ||
2258 | if (Attr != MCSA_Invalid) | |
2259 | OutStreamer.EmitSymbolAttribute(Sym, Attr); | |
2260 | } | |
2261 | ||
2262 | /// isBlockOnlyReachableByFallthough - Return true if the basic block has | |
2263 | /// exactly one predecessor and the control transfer mechanism between | |
2264 | /// the predecessor and this block is a fall-through. | |
2265 | bool AsmPrinter:: | |
2266 | isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { | |
2267 | // If this is a landing pad, it isn't a fall through. If it has no preds, | |
2268 | // then nothing falls through to it. | |
2269 | if (MBB->isLandingPad() || MBB->pred_empty()) | |
2270 | return false; | |
2271 | ||
2272 | // If there isn't exactly one predecessor, it can't be a fall through. | |
1a4d82fc | 2273 | if (MBB->pred_size() > 1) |
223e47cc LB |
2274 | return false; |
2275 | ||
2276 | // The predecessor has to be immediately before this block. | |
1a4d82fc | 2277 | MachineBasicBlock *Pred = *MBB->pred_begin(); |
223e47cc LB |
2278 | if (!Pred->isLayoutSuccessor(MBB)) |
2279 | return false; | |
2280 | ||
2281 | // If the block is completely empty, then it definitely does fall through. | |
2282 | if (Pred->empty()) | |
2283 | return true; | |
2284 | ||
2285 | // Check the terminators in the previous blocks | |
1a4d82fc | 2286 | for (const auto &MI : Pred->terminators()) { |
223e47cc LB |
2287 | // If it is not a simple branch, we are in a table somewhere. |
2288 | if (!MI.isBranch() || MI.isIndirectBranch()) | |
2289 | return false; | |
2290 | ||
1a4d82fc JJ |
2291 | // If we are the operands of one of the branches, this is not a fall |
2292 | // through. Note that targets with delay slots will usually bundle | |
2293 | // terminators with the delay slot instruction. | |
2294 | for (ConstMIBundleOperands OP(&MI); OP.isValid(); ++OP) { | |
2295 | if (OP->isJTI()) | |
223e47cc | 2296 | return false; |
1a4d82fc | 2297 | if (OP->isMBB() && OP->getMBB() == MBB) |
223e47cc LB |
2298 | return false; |
2299 | } | |
2300 | } | |
2301 | ||
2302 | return true; | |
2303 | } | |
2304 | ||
2305 | ||
2306 | ||
1a4d82fc JJ |
2307 | GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy &S) { |
2308 | if (!S.usesMetadata()) | |
2309 | return nullptr; | |
223e47cc | 2310 | |
85aaf69f SL |
2311 | assert(!S.useStatepoints() && "statepoints do not currently support custom" |
2312 | " stackmap formats, please see the documentation for a description of" | |
2313 | " the default format. If you really need a custom serialized format," | |
2314 | " please file a bug"); | |
2315 | ||
223e47cc | 2316 | gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); |
1a4d82fc | 2317 | gcp_map_type::iterator GCPI = GCMap.find(&S); |
223e47cc | 2318 | if (GCPI != GCMap.end()) |
1a4d82fc | 2319 | return GCPI->second.get(); |
223e47cc | 2320 | |
1a4d82fc | 2321 | const char *Name = S.getName().c_str(); |
223e47cc LB |
2322 | |
2323 | for (GCMetadataPrinterRegistry::iterator | |
2324 | I = GCMetadataPrinterRegistry::begin(), | |
2325 | E = GCMetadataPrinterRegistry::end(); I != E; ++I) | |
2326 | if (strcmp(Name, I->getName()) == 0) { | |
1a4d82fc JJ |
2327 | std::unique_ptr<GCMetadataPrinter> GMP = I->instantiate(); |
2328 | GMP->S = &S; | |
2329 | auto IterBool = GCMap.insert(std::make_pair(&S, std::move(GMP))); | |
2330 | return IterBool.first->second.get(); | |
223e47cc LB |
2331 | } |
2332 | ||
2333 | report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); | |
2334 | } | |
1a4d82fc JJ |
2335 | |
2336 | /// Pin vtable to this file. | |
2337 | AsmPrinterHandler::~AsmPrinterHandler() {} |