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