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