1 | //===- AsmPrinter.cpp - Common AsmPrinter code ----------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements the AsmPrinter class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/CodeGen/AsmPrinter.h" |
14 | #include "CodeViewDebug.h" |
15 | #include "DwarfDebug.h" |
16 | #include "DwarfException.h" |
17 | #include "PseudoProbePrinter.h" |
18 | #include "WasmException.h" |
19 | #include "WinCFGuard.h" |
20 | #include "WinException.h" |
21 | #include "llvm/ADT/APFloat.h" |
22 | #include "llvm/ADT/APInt.h" |
23 | #include "llvm/ADT/DenseMap.h" |
24 | #include "llvm/ADT/STLExtras.h" |
25 | #include "llvm/ADT/SmallPtrSet.h" |
26 | #include "llvm/ADT/SmallString.h" |
27 | #include "llvm/ADT/SmallVector.h" |
28 | #include "llvm/ADT/Statistic.h" |
29 | #include "llvm/ADT/StringExtras.h" |
30 | #include "llvm/ADT/StringRef.h" |
31 | #include "llvm/ADT/TinyPtrVector.h" |
32 | #include "llvm/ADT/Twine.h" |
33 | #include "llvm/Analysis/ConstantFolding.h" |
34 | #include "llvm/Analysis/MemoryLocation.h" |
35 | #include "llvm/Analysis/OptimizationRemarkEmitter.h" |
36 | #include "llvm/BinaryFormat/COFF.h" |
37 | #include "llvm/BinaryFormat/Dwarf.h" |
38 | #include "llvm/BinaryFormat/ELF.h" |
39 | #include "llvm/CodeGen/GCMetadata.h" |
40 | #include "llvm/CodeGen/GCMetadataPrinter.h" |
41 | #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h" |
42 | #include "llvm/CodeGen/MachineBasicBlock.h" |
43 | #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" |
44 | #include "llvm/CodeGen/MachineConstantPool.h" |
45 | #include "llvm/CodeGen/MachineDominators.h" |
46 | #include "llvm/CodeGen/MachineFrameInfo.h" |
47 | #include "llvm/CodeGen/MachineFunction.h" |
48 | #include "llvm/CodeGen/MachineFunctionPass.h" |
49 | #include "llvm/CodeGen/MachineInstr.h" |
50 | #include "llvm/CodeGen/MachineInstrBundle.h" |
51 | #include "llvm/CodeGen/MachineJumpTableInfo.h" |
52 | #include "llvm/CodeGen/MachineLoopInfo.h" |
53 | #include "llvm/CodeGen/MachineModuleInfo.h" |
54 | #include "llvm/CodeGen/MachineModuleInfoImpls.h" |
55 | #include "llvm/CodeGen/MachineOperand.h" |
56 | #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" |
57 | #include "llvm/CodeGen/StackMaps.h" |
58 | #include "llvm/CodeGen/TargetFrameLowering.h" |
59 | #include "llvm/CodeGen/TargetInstrInfo.h" |
60 | #include "llvm/CodeGen/TargetLowering.h" |
61 | #include "llvm/CodeGen/TargetOpcodes.h" |
62 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
63 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
64 | #include "llvm/Config/config.h" |
65 | #include "llvm/IR/BasicBlock.h" |
66 | #include "llvm/IR/Comdat.h" |
67 | #include "llvm/IR/Constant.h" |
68 | #include "llvm/IR/Constants.h" |
69 | #include "llvm/IR/DataLayout.h" |
70 | #include "llvm/IR/DebugInfoMetadata.h" |
71 | #include "llvm/IR/DerivedTypes.h" |
72 | #include "llvm/IR/EHPersonalities.h" |
73 | #include "llvm/IR/Function.h" |
74 | #include "llvm/IR/GCStrategy.h" |
75 | #include "llvm/IR/GlobalAlias.h" |
76 | #include "llvm/IR/GlobalIFunc.h" |
77 | #include "llvm/IR/GlobalObject.h" |
78 | #include "llvm/IR/GlobalValue.h" |
79 | #include "llvm/IR/GlobalVariable.h" |
80 | #include "llvm/IR/Instruction.h" |
81 | #include "llvm/IR/Mangler.h" |
82 | #include "llvm/IR/Metadata.h" |
83 | #include "llvm/IR/Module.h" |
84 | #include "llvm/IR/Operator.h" |
85 | #include "llvm/IR/PseudoProbe.h" |
86 | #include "llvm/IR/Type.h" |
87 | #include "llvm/IR/Value.h" |
88 | #include "llvm/IR/ValueHandle.h" |
89 | #include "llvm/MC/MCAsmInfo.h" |
90 | #include "llvm/MC/MCContext.h" |
91 | #include "llvm/MC/MCDirectives.h" |
92 | #include "llvm/MC/MCExpr.h" |
93 | #include "llvm/MC/MCInst.h" |
94 | #include "llvm/MC/MCSection.h" |
95 | #include "llvm/MC/MCSectionCOFF.h" |
96 | #include "llvm/MC/MCSectionELF.h" |
97 | #include "llvm/MC/MCSectionMachO.h" |
98 | #include "llvm/MC/MCSectionXCOFF.h" |
99 | #include "llvm/MC/MCStreamer.h" |
100 | #include "llvm/MC/MCSubtargetInfo.h" |
101 | #include "llvm/MC/MCSymbol.h" |
102 | #include "llvm/MC/MCSymbolELF.h" |
103 | #include "llvm/MC/MCTargetOptions.h" |
104 | #include "llvm/MC/MCValue.h" |
105 | #include "llvm/MC/SectionKind.h" |
106 | #include "llvm/Object/ELFTypes.h" |
107 | #include "llvm/Pass.h" |
108 | #include "llvm/Remarks/RemarkStreamer.h" |
109 | #include "llvm/Support/Casting.h" |
110 | #include "llvm/Support/Compiler.h" |
111 | #include "llvm/Support/ErrorHandling.h" |
112 | #include "llvm/Support/FileSystem.h" |
113 | #include "llvm/Support/Format.h" |
114 | #include "llvm/Support/MathExtras.h" |
115 | #include "llvm/Support/Path.h" |
116 | #include "llvm/Support/VCSRevision.h" |
117 | #include "llvm/Support/raw_ostream.h" |
118 | #include "llvm/Target/TargetLoweringObjectFile.h" |
119 | #include "llvm/Target/TargetMachine.h" |
120 | #include "llvm/Target/TargetOptions.h" |
121 | #include "llvm/TargetParser/Triple.h" |
122 | #include <algorithm> |
123 | #include <cassert> |
124 | #include <cinttypes> |
125 | #include <cstdint> |
126 | #include <iterator> |
127 | #include <memory> |
128 | #include <optional> |
129 | #include <string> |
130 | #include <utility> |
131 | #include <vector> |
132 | |
133 | using namespace llvm; |
134 | |
135 | #define DEBUG_TYPE "asm-printer" |
136 | |
137 | // This is a replication of fields of object::PGOAnalysisMap::Features. It |
138 | // should match the order of the fields so that |
139 | // `object::PGOAnalysisMap::Features::decode(PgoAnalysisMapFeatures.getBits())` |
140 | // succeeds. |
141 | enum class PGOMapFeaturesEnum { |
142 | FuncEntryCount, |
143 | BBFreq, |
144 | BrProb, |
145 | }; |
146 | static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures( |
147 | "pgo-analysis-map" , cl::Hidden, cl::CommaSeparated, |
148 | cl::values(clEnumValN(PGOMapFeaturesEnum::FuncEntryCount, |
149 | "func-entry-count" , "Function Entry Count" ), |
150 | clEnumValN(PGOMapFeaturesEnum::BBFreq, "bb-freq" , |
151 | "Basic Block Frequency" ), |
152 | clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob" , |
153 | "Branch Probability" )), |
154 | cl::desc( |
155 | "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is " |
156 | "extracted from PGO related analysis." )); |
157 | |
158 | STATISTIC(EmittedInsts, "Number of machine instrs printed" ); |
159 | |
160 | char AsmPrinter::ID = 0; |
161 | |
162 | namespace { |
163 | class AddrLabelMapCallbackPtr final : CallbackVH { |
164 | AddrLabelMap *Map = nullptr; |
165 | |
166 | public: |
167 | AddrLabelMapCallbackPtr() = default; |
168 | AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {} |
169 | |
170 | void setPtr(BasicBlock *BB) { |
171 | ValueHandleBase::operator=(RHS: BB); |
172 | } |
173 | |
174 | void setMap(AddrLabelMap *map) { Map = map; } |
175 | |
176 | void deleted() override; |
177 | void allUsesReplacedWith(Value *V2) override; |
178 | }; |
179 | } // namespace |
180 | |
181 | class llvm::AddrLabelMap { |
182 | MCContext &Context; |
183 | struct AddrLabelSymEntry { |
184 | /// The symbols for the label. |
185 | TinyPtrVector<MCSymbol *> Symbols; |
186 | |
187 | Function *Fn; // The containing function of the BasicBlock. |
188 | unsigned Index; // The index in BBCallbacks for the BasicBlock. |
189 | }; |
190 | |
191 | DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols; |
192 | |
193 | /// Callbacks for the BasicBlock's that we have entries for. We use this so |
194 | /// we get notified if a block is deleted or RAUWd. |
195 | std::vector<AddrLabelMapCallbackPtr> BBCallbacks; |
196 | |
197 | /// This is a per-function list of symbols whose corresponding BasicBlock got |
198 | /// deleted. These symbols need to be emitted at some point in the file, so |
199 | /// AsmPrinter emits them after the function body. |
200 | DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>> |
201 | DeletedAddrLabelsNeedingEmission; |
202 | |
203 | public: |
204 | AddrLabelMap(MCContext &context) : Context(context) {} |
205 | |
206 | ~AddrLabelMap() { |
207 | assert(DeletedAddrLabelsNeedingEmission.empty() && |
208 | "Some labels for deleted blocks never got emitted" ); |
209 | } |
210 | |
211 | ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB); |
212 | |
213 | void takeDeletedSymbolsForFunction(Function *F, |
214 | std::vector<MCSymbol *> &Result); |
215 | |
216 | void UpdateForDeletedBlock(BasicBlock *BB); |
217 | void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New); |
218 | }; |
219 | |
220 | ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) { |
221 | assert(BB->hasAddressTaken() && |
222 | "Shouldn't get label for block without address taken" ); |
223 | AddrLabelSymEntry &Entry = AddrLabelSymbols[BB]; |
224 | |
225 | // If we already had an entry for this block, just return it. |
226 | if (!Entry.Symbols.empty()) { |
227 | assert(BB->getParent() == Entry.Fn && "Parent changed" ); |
228 | return Entry.Symbols; |
229 | } |
230 | |
231 | // Otherwise, this is a new entry, create a new symbol for it and add an |
232 | // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd. |
233 | BBCallbacks.emplace_back(args&: BB); |
234 | BBCallbacks.back().setMap(this); |
235 | Entry.Index = BBCallbacks.size() - 1; |
236 | Entry.Fn = BB->getParent(); |
237 | MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol() |
238 | : Context.createTempSymbol(); |
239 | Entry.Symbols.push_back(NewVal: Sym); |
240 | return Entry.Symbols; |
241 | } |
242 | |
243 | /// If we have any deleted symbols for F, return them. |
244 | void AddrLabelMap::takeDeletedSymbolsForFunction( |
245 | Function *F, std::vector<MCSymbol *> &Result) { |
246 | DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I = |
247 | DeletedAddrLabelsNeedingEmission.find(Val: F); |
248 | |
249 | // If there are no entries for the function, just return. |
250 | if (I == DeletedAddrLabelsNeedingEmission.end()) |
251 | return; |
252 | |
253 | // Otherwise, take the list. |
254 | std::swap(x&: Result, y&: I->second); |
255 | DeletedAddrLabelsNeedingEmission.erase(I); |
256 | } |
257 | |
258 | //===- Address of Block Management ----------------------------------------===// |
259 | |
260 | ArrayRef<MCSymbol *> |
261 | AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) { |
262 | // Lazily create AddrLabelSymbols. |
263 | if (!AddrLabelSymbols) |
264 | AddrLabelSymbols = std::make_unique<AddrLabelMap>(args&: OutContext); |
265 | return AddrLabelSymbols->getAddrLabelSymbolToEmit( |
266 | BB: const_cast<BasicBlock *>(BB)); |
267 | } |
268 | |
269 | void AsmPrinter::takeDeletedSymbolsForFunction( |
270 | const Function *F, std::vector<MCSymbol *> &Result) { |
271 | // If no blocks have had their addresses taken, we're done. |
272 | if (!AddrLabelSymbols) |
273 | return; |
274 | return AddrLabelSymbols->takeDeletedSymbolsForFunction( |
275 | F: const_cast<Function *>(F), Result); |
276 | } |
277 | |
278 | void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) { |
279 | // If the block got deleted, there is no need for the symbol. If the symbol |
280 | // was already emitted, we can just forget about it, otherwise we need to |
281 | // queue it up for later emission when the function is output. |
282 | AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]); |
283 | AddrLabelSymbols.erase(Val: BB); |
284 | assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?" ); |
285 | BBCallbacks[Entry.Index] = nullptr; // Clear the callback. |
286 | |
287 | #if !LLVM_MEMORY_SANITIZER_BUILD |
288 | // BasicBlock is destroyed already, so this access is UB detectable by msan. |
289 | assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) && |
290 | "Block/parent mismatch" ); |
291 | #endif |
292 | |
293 | for (MCSymbol *Sym : Entry.Symbols) { |
294 | if (Sym->isDefined()) |
295 | return; |
296 | |
297 | // If the block is not yet defined, we need to emit it at the end of the |
298 | // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list |
299 | // for the containing Function. Since the block is being deleted, its |
300 | // parent may already be removed, we have to get the function from 'Entry'. |
301 | DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(x: Sym); |
302 | } |
303 | } |
304 | |
305 | void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) { |
306 | // Get the entry for the RAUW'd block and remove it from our map. |
307 | AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]); |
308 | AddrLabelSymbols.erase(Val: Old); |
309 | assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?" ); |
310 | |
311 | AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New]; |
312 | |
313 | // If New is not address taken, just move our symbol over to it. |
314 | if (NewEntry.Symbols.empty()) { |
315 | BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback. |
316 | NewEntry = std::move(OldEntry); // Set New's entry. |
317 | return; |
318 | } |
319 | |
320 | BBCallbacks[OldEntry.Index] = nullptr; // Update the callback. |
321 | |
322 | // Otherwise, we need to add the old symbols to the new block's set. |
323 | llvm::append_range(C&: NewEntry.Symbols, R&: OldEntry.Symbols); |
324 | } |
325 | |
326 | void AddrLabelMapCallbackPtr::deleted() { |
327 | Map->UpdateForDeletedBlock(BB: cast<BasicBlock>(Val: getValPtr())); |
328 | } |
329 | |
330 | void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { |
331 | Map->UpdateForRAUWBlock(Old: cast<BasicBlock>(Val: getValPtr()), New: cast<BasicBlock>(Val: V2)); |
332 | } |
333 | |
334 | /// getGVAlignment - Return the alignment to use for the specified global |
335 | /// value. This rounds up to the preferred alignment if possible and legal. |
336 | Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL, |
337 | Align InAlign) { |
338 | Align Alignment; |
339 | if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(Val: GV)) |
340 | Alignment = DL.getPreferredAlign(GV: GVar); |
341 | |
342 | // If InAlign is specified, round it to it. |
343 | if (InAlign > Alignment) |
344 | Alignment = InAlign; |
345 | |
346 | // If the GV has a specified alignment, take it into account. |
347 | const MaybeAlign GVAlign(GV->getAlign()); |
348 | if (!GVAlign) |
349 | return Alignment; |
350 | |
351 | assert(GVAlign && "GVAlign must be set" ); |
352 | |
353 | // If the GVAlign is larger than NumBits, or if we are required to obey |
354 | // NumBits because the GV has an assigned section, obey it. |
355 | if (*GVAlign > Alignment || GV->hasSection()) |
356 | Alignment = *GVAlign; |
357 | return Alignment; |
358 | } |
359 | |
360 | AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer) |
361 | : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()), |
362 | OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)), |
363 | SM(*this) { |
364 | VerboseAsm = OutStreamer->isVerboseAsm(); |
365 | DwarfUsesRelocationsAcrossSections = |
366 | MAI->doesDwarfUseRelocationsAcrossSections(); |
367 | } |
368 | |
369 | AsmPrinter::~AsmPrinter() { |
370 | assert(!DD && Handlers.size() == NumUserHandlers && |
371 | "Debug/EH info didn't get finalized" ); |
372 | } |
373 | |
374 | bool AsmPrinter::isPositionIndependent() const { |
375 | return TM.isPositionIndependent(); |
376 | } |
377 | |
378 | /// getFunctionNumber - Return a unique ID for the current function. |
379 | unsigned AsmPrinter::getFunctionNumber() const { |
380 | return MF->getFunctionNumber(); |
381 | } |
382 | |
383 | const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const { |
384 | return *TM.getObjFileLowering(); |
385 | } |
386 | |
387 | const DataLayout &AsmPrinter::getDataLayout() const { |
388 | assert(MMI && "MMI could not be nullptr!" ); |
389 | return MMI->getModule()->getDataLayout(); |
390 | } |
391 | |
392 | // Do not use the cached DataLayout because some client use it without a Module |
393 | // (dsymutil, llvm-dwarfdump). |
394 | unsigned AsmPrinter::getPointerSize() const { |
395 | return TM.getPointerSize(AS: 0); // FIXME: Default address space |
396 | } |
397 | |
398 | const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const { |
399 | assert(MF && "getSubtargetInfo requires a valid MachineFunction!" ); |
400 | return MF->getSubtarget<MCSubtargetInfo>(); |
401 | } |
402 | |
403 | void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) { |
404 | S.emitInstruction(Inst, STI: getSubtargetInfo()); |
405 | } |
406 | |
407 | void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) { |
408 | if (DD) { |
409 | assert(OutStreamer->hasRawTextSupport() && |
410 | "Expected assembly output mode." ); |
411 | // This is NVPTX specific and it's unclear why. |
412 | // PR51079: If we have code without debug information we need to give up. |
413 | DISubprogram *MFSP = MF.getFunction().getSubprogram(); |
414 | if (!MFSP) |
415 | return; |
416 | (void)DD->emitInitialLocDirective(MF, /*CUID=*/0); |
417 | } |
418 | } |
419 | |
420 | /// getCurrentSection() - Return the current section we are emitting to. |
421 | const MCSection *AsmPrinter::getCurrentSection() const { |
422 | return OutStreamer->getCurrentSectionOnly(); |
423 | } |
424 | |
425 | void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { |
426 | AU.setPreservesAll(); |
427 | MachineFunctionPass::getAnalysisUsage(AU); |
428 | AU.addRequired<MachineOptimizationRemarkEmitterPass>(); |
429 | AU.addRequired<GCModuleInfo>(); |
430 | AU.addRequired<LazyMachineBlockFrequencyInfoPass>(); |
431 | AU.addRequired<MachineBranchProbabilityInfoWrapperPass>(); |
432 | } |
433 | |
434 | bool AsmPrinter::doInitialization(Module &M) { |
435 | auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>(); |
436 | MMI = MMIWP ? &MMIWP->getMMI() : nullptr; |
437 | HasSplitStack = false; |
438 | HasNoSplitStack = false; |
439 | |
440 | AddrLabelSymbols = nullptr; |
441 | |
442 | // Initialize TargetLoweringObjectFile. |
443 | const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) |
444 | .Initialize(ctx&: OutContext, TM); |
445 | |
446 | const_cast<TargetLoweringObjectFile &>(getObjFileLowering()) |
447 | .getModuleMetadata(M); |
448 | |
449 | // On AIX, we delay emitting any section information until |
450 | // after emitting the .file pseudo-op. This allows additional |
451 | // information (such as the embedded command line) to be associated |
452 | // with all sections in the object file rather than a single section. |
453 | if (!TM.getTargetTriple().isOSBinFormatXCOFF()) |
454 | OutStreamer->initSections(NoExecStack: false, STI: *TM.getMCSubtargetInfo()); |
455 | |
456 | // Emit the version-min deployment target directive if needed. |
457 | // |
458 | // FIXME: If we end up with a collection of these sorts of Darwin-specific |
459 | // or ELF-specific things, it may make sense to have a platform helper class |
460 | // that will work with the target helper class. For now keep it here, as the |
461 | // alternative is duplicated code in each of the target asm printers that |
462 | // use the directive, where it would need the same conditionalization |
463 | // anyway. |
464 | const Triple &Target = TM.getTargetTriple(); |
465 | if (Target.isOSBinFormatMachO() && Target.isOSDarwin()) { |
466 | Triple TVT(M.getDarwinTargetVariantTriple()); |
467 | OutStreamer->emitVersionForTarget( |
468 | Target, SDKVersion: M.getSDKVersion(), |
469 | DarwinTargetVariantTriple: M.getDarwinTargetVariantTriple().empty() ? nullptr : &TVT, |
470 | DarwinTargetVariantSDKVersion: M.getDarwinTargetVariantSDKVersion()); |
471 | } |
472 | |
473 | // Allow the target to emit any magic that it wants at the start of the file. |
474 | emitStartOfAsmFile(M); |
475 | |
476 | // Very minimal debug info. It is ignored if we emit actual debug info. If we |
477 | // don't, this at least helps the user find where a global came from. |
478 | if (MAI->hasSingleParameterDotFile()) { |
479 | // .file "foo.c" |
480 | |
481 | SmallString<128> FileName; |
482 | if (MAI->hasBasenameOnlyForFileDirective()) |
483 | FileName = llvm::sys::path::filename(path: M.getSourceFileName()); |
484 | else |
485 | FileName = M.getSourceFileName(); |
486 | if (MAI->hasFourStringsDotFile()) { |
487 | const char VerStr[] = |
488 | #ifdef PACKAGE_VENDOR |
489 | PACKAGE_VENDOR " " |
490 | #endif |
491 | PACKAGE_NAME " version " PACKAGE_VERSION |
492 | #ifdef LLVM_REVISION |
493 | " (" LLVM_REVISION ")" |
494 | #endif |
495 | ; |
496 | // TODO: Add timestamp and description. |
497 | OutStreamer->emitFileDirective(Filename: FileName, CompilerVersion: VerStr, TimeStamp: "" , Description: "" ); |
498 | } else { |
499 | OutStreamer->emitFileDirective(Filename: FileName); |
500 | } |
501 | } |
502 | |
503 | // On AIX, emit bytes for llvm.commandline metadata after .file so that the |
504 | // C_INFO symbol is preserved if any csect is kept by the linker. |
505 | if (TM.getTargetTriple().isOSBinFormatXCOFF()) { |
506 | emitModuleCommandLines(M); |
507 | // Now we can generate section information. |
508 | OutStreamer->initSections(NoExecStack: false, STI: *TM.getMCSubtargetInfo()); |
509 | |
510 | // To work around an AIX assembler and/or linker bug, generate |
511 | // a rename for the default text-section symbol name. This call has |
512 | // no effect when generating object code directly. |
513 | MCSection *TextSection = |
514 | OutStreamer->getContext().getObjectFileInfo()->getTextSection(); |
515 | MCSymbolXCOFF *XSym = |
516 | static_cast<MCSectionXCOFF *>(TextSection)->getQualNameSymbol(); |
517 | if (XSym->hasRename()) |
518 | OutStreamer->emitXCOFFRenameDirective(Name: XSym, Rename: XSym->getSymbolTableName()); |
519 | } |
520 | |
521 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); |
522 | assert(MI && "AsmPrinter didn't require GCModuleInfo?" ); |
523 | for (const auto &I : *MI) |
524 | if (GCMetadataPrinter *MP = getOrCreateGCPrinter(S&: *I)) |
525 | MP->beginAssembly(M, Info&: *MI, AP&: *this); |
526 | |
527 | // Emit module-level inline asm if it exists. |
528 | if (!M.getModuleInlineAsm().empty()) { |
529 | OutStreamer->AddComment(T: "Start of file scope inline assembly" ); |
530 | OutStreamer->addBlankLine(); |
531 | emitInlineAsm( |
532 | Str: M.getModuleInlineAsm() + "\n" , STI: *TM.getMCSubtargetInfo(), |
533 | MCOptions: TM.Options.MCOptions, LocMDNode: nullptr, |
534 | AsmDialect: InlineAsm::AsmDialect(TM.getMCAsmInfo()->getAssemblerDialect())); |
535 | OutStreamer->AddComment(T: "End of file scope inline assembly" ); |
536 | OutStreamer->addBlankLine(); |
537 | } |
538 | |
539 | if (MAI->doesSupportDebugInformation()) { |
540 | bool EmitCodeView = M.getCodeViewFlag(); |
541 | if (EmitCodeView && TM.getTargetTriple().isOSWindows()) |
542 | DebugHandlers.push_back(Elt: std::make_unique<CodeViewDebug>(args: this)); |
543 | if (!EmitCodeView || M.getDwarfVersion()) { |
544 | assert(MMI && "MMI could not be nullptr here!" ); |
545 | if (MMI->hasDebugInfo()) { |
546 | DD = new DwarfDebug(this); |
547 | DebugHandlers.push_back(Elt: std::unique_ptr<DwarfDebug>(DD)); |
548 | } |
549 | } |
550 | } |
551 | |
552 | if (M.getNamedMetadata(Name: PseudoProbeDescMetadataName)) |
553 | PP = std::make_unique<PseudoProbeHandler>(args: this); |
554 | |
555 | switch (MAI->getExceptionHandlingType()) { |
556 | case ExceptionHandling::None: |
557 | // We may want to emit CFI for debug. |
558 | [[fallthrough]]; |
559 | case ExceptionHandling::SjLj: |
560 | case ExceptionHandling::DwarfCFI: |
561 | case ExceptionHandling::ARM: |
562 | for (auto &F : M.getFunctionList()) { |
563 | if (getFunctionCFISectionType(F) != CFISection::None) |
564 | ModuleCFISection = getFunctionCFISectionType(F); |
565 | // If any function needsUnwindTableEntry(), it needs .eh_frame and hence |
566 | // the module needs .eh_frame. If we have found that case, we are done. |
567 | if (ModuleCFISection == CFISection::EH) |
568 | break; |
569 | } |
570 | assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI || |
571 | usesCFIWithoutEH() || ModuleCFISection != CFISection::EH); |
572 | break; |
573 | default: |
574 | break; |
575 | } |
576 | |
577 | EHStreamer *ES = nullptr; |
578 | switch (MAI->getExceptionHandlingType()) { |
579 | case ExceptionHandling::None: |
580 | if (!usesCFIWithoutEH()) |
581 | break; |
582 | [[fallthrough]]; |
583 | case ExceptionHandling::SjLj: |
584 | case ExceptionHandling::DwarfCFI: |
585 | case ExceptionHandling::ZOS: |
586 | ES = new DwarfCFIException(this); |
587 | break; |
588 | case ExceptionHandling::ARM: |
589 | ES = new ARMException(this); |
590 | break; |
591 | case ExceptionHandling::WinEH: |
592 | switch (MAI->getWinEHEncodingType()) { |
593 | default: llvm_unreachable("unsupported unwinding information encoding" ); |
594 | case WinEH::EncodingType::Invalid: |
595 | break; |
596 | case WinEH::EncodingType::X86: |
597 | case WinEH::EncodingType::Itanium: |
598 | ES = new WinException(this); |
599 | break; |
600 | } |
601 | break; |
602 | case ExceptionHandling::Wasm: |
603 | ES = new WasmException(this); |
604 | break; |
605 | case ExceptionHandling::AIX: |
606 | ES = new AIXException(this); |
607 | break; |
608 | } |
609 | if (ES) |
610 | Handlers.push_back(Elt: std::unique_ptr<EHStreamer>(ES)); |
611 | |
612 | // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2). |
613 | if (mdconst::extract_or_null<ConstantInt>(MD: M.getModuleFlag(Key: "cfguard" ))) |
614 | Handlers.push_back(Elt: std::make_unique<WinCFGuard>(args: this)); |
615 | |
616 | for (auto &Handler : DebugHandlers) |
617 | Handler->beginModule(M: &M); |
618 | for (auto &Handler : Handlers) |
619 | Handler->beginModule(M: &M); |
620 | |
621 | return false; |
622 | } |
623 | |
624 | static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI) { |
625 | if (!MAI.hasWeakDefCanBeHiddenDirective()) |
626 | return false; |
627 | |
628 | return GV->canBeOmittedFromSymbolTable(); |
629 | } |
630 | |
631 | void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { |
632 | GlobalValue::LinkageTypes Linkage = GV->getLinkage(); |
633 | switch (Linkage) { |
634 | case GlobalValue::CommonLinkage: |
635 | case GlobalValue::LinkOnceAnyLinkage: |
636 | case GlobalValue::LinkOnceODRLinkage: |
637 | case GlobalValue::WeakAnyLinkage: |
638 | case GlobalValue::WeakODRLinkage: |
639 | if (MAI->hasWeakDefDirective()) { |
640 | // .globl _foo |
641 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_Global); |
642 | |
643 | if (!canBeHidden(GV, MAI: *MAI)) |
644 | // .weak_definition _foo |
645 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_WeakDefinition); |
646 | else |
647 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_WeakDefAutoPrivate); |
648 | } else if (MAI->avoidWeakIfComdat() && GV->hasComdat()) { |
649 | // .globl _foo |
650 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_Global); |
651 | //NOTE: linkonce is handled by the section the symbol was assigned to. |
652 | } else { |
653 | // .weak _foo |
654 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_Weak); |
655 | } |
656 | return; |
657 | case GlobalValue::ExternalLinkage: |
658 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_Global); |
659 | return; |
660 | case GlobalValue::PrivateLinkage: |
661 | case GlobalValue::InternalLinkage: |
662 | return; |
663 | case GlobalValue::ExternalWeakLinkage: |
664 | case GlobalValue::AvailableExternallyLinkage: |
665 | case GlobalValue::AppendingLinkage: |
666 | llvm_unreachable("Should never emit this" ); |
667 | } |
668 | llvm_unreachable("Unknown linkage type!" ); |
669 | } |
670 | |
671 | void AsmPrinter::getNameWithPrefix(SmallVectorImpl<char> &Name, |
672 | const GlobalValue *GV) const { |
673 | TM.getNameWithPrefix(Name, GV, Mang&: getObjFileLowering().getMangler()); |
674 | } |
675 | |
676 | MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const { |
677 | return TM.getSymbol(GV); |
678 | } |
679 | |
680 | MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const { |
681 | // On ELF, use .Lfoo$local if GV is a non-interposable GlobalObject with an |
682 | // exact definion (intersection of GlobalValue::hasExactDefinition() and |
683 | // !isInterposable()). These linkages include: external, appending, internal, |
684 | // private. It may be profitable to use a local alias for external. The |
685 | // assembler would otherwise be conservative and assume a global default |
686 | // visibility symbol can be interposable, even if the code generator already |
687 | // assumed it. |
688 | if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) { |
689 | const Module &M = *GV.getParent(); |
690 | if (TM.getRelocationModel() != Reloc::Static && |
691 | M.getPIELevel() == PIELevel::Default && GV.isDSOLocal()) |
692 | return getSymbolWithGlobalValueBase(GV: &GV, Suffix: "$local" ); |
693 | } |
694 | return TM.getSymbol(GV: &GV); |
695 | } |
696 | |
697 | /// EmitGlobalVariable - Emit the specified global variable to the .s file. |
698 | void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { |
699 | bool IsEmuTLSVar = TM.useEmulatedTLS() && GV->isThreadLocal(); |
700 | assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) && |
701 | "No emulated TLS variables in the common section" ); |
702 | |
703 | // Never emit TLS variable xyz in emulated TLS model. |
704 | // The initialization value is in __emutls_t.xyz instead of xyz. |
705 | if (IsEmuTLSVar) |
706 | return; |
707 | |
708 | if (GV->hasInitializer()) { |
709 | // Check to see if this is a special global used by LLVM, if so, emit it. |
710 | if (emitSpecialLLVMGlobal(GV)) |
711 | return; |
712 | |
713 | // Skip the emission of global equivalents. The symbol can be emitted later |
714 | // on by emitGlobalGOTEquivs in case it turns out to be needed. |
715 | if (GlobalGOTEquivs.count(Key: getSymbol(GV))) |
716 | return; |
717 | |
718 | if (isVerbose()) { |
719 | // When printing the control variable __emutls_v.*, |
720 | // we don't need to print the original TLS variable name. |
721 | GV->printAsOperand(O&: OutStreamer->getCommentOS(), |
722 | /*PrintType=*/false, M: GV->getParent()); |
723 | OutStreamer->getCommentOS() << '\n'; |
724 | } |
725 | } |
726 | |
727 | MCSymbol *GVSym = getSymbol(GV); |
728 | MCSymbol *EmittedSym = GVSym; |
729 | |
730 | // getOrCreateEmuTLSControlSym only creates the symbol with name and default |
731 | // attributes. |
732 | // GV's or GVSym's attributes will be used for the EmittedSym. |
733 | emitVisibility(Sym: EmittedSym, Visibility: GV->getVisibility(), IsDefinition: !GV->isDeclaration()); |
734 | |
735 | if (GV->isTagged()) { |
736 | Triple T = TM.getTargetTriple(); |
737 | |
738 | if (T.getArch() != Triple::aarch64 || !T.isAndroid()) |
739 | OutContext.reportError(L: SMLoc(), |
740 | Msg: "tagged symbols (-fsanitize=memtag-globals) are " |
741 | "only supported on AArch64 Android" ); |
742 | OutStreamer->emitSymbolAttribute(Symbol: EmittedSym, Attribute: MAI->getMemtagAttr()); |
743 | } |
744 | |
745 | if (!GV->hasInitializer()) // External globals require no extra code. |
746 | return; |
747 | |
748 | GVSym->redefineIfPossible(); |
749 | if (GVSym->isDefined() || GVSym->isVariable()) |
750 | OutContext.reportError(L: SMLoc(), Msg: "symbol '" + Twine(GVSym->getName()) + |
751 | "' is already defined" ); |
752 | |
753 | if (MAI->hasDotTypeDotSizeDirective()) |
754 | OutStreamer->emitSymbolAttribute(Symbol: EmittedSym, Attribute: MCSA_ELF_TypeObject); |
755 | |
756 | SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GO: GV, TM); |
757 | |
758 | const DataLayout &DL = GV->getDataLayout(); |
759 | uint64_t Size = DL.getTypeAllocSize(Ty: GV->getValueType()); |
760 | |
761 | // If the alignment is specified, we *must* obey it. Overaligning a global |
762 | // with a specified alignment is a prompt way to break globals emitted to |
763 | // sections and expected to be contiguous (e.g. ObjC metadata). |
764 | const Align Alignment = getGVAlignment(GV, DL); |
765 | |
766 | for (auto &Handler : DebugHandlers) |
767 | Handler->setSymbolSize(Sym: GVSym, Size); |
768 | |
769 | // Handle common symbols |
770 | if (GVKind.isCommon()) { |
771 | if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. |
772 | // .comm _foo, 42, 4 |
773 | OutStreamer->emitCommonSymbol(Symbol: GVSym, Size, ByteAlignment: Alignment); |
774 | return; |
775 | } |
776 | |
777 | // Determine to which section this global should be emitted. |
778 | MCSection *TheSection = getObjFileLowering().SectionForGlobal(GO: GV, Kind: GVKind, TM); |
779 | |
780 | // If we have a bss global going to a section that supports the |
781 | // zerofill directive, do so here. |
782 | if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective() && |
783 | TheSection->isVirtualSection()) { |
784 | if (Size == 0) |
785 | Size = 1; // zerofill of 0 bytes is undefined. |
786 | emitLinkage(GV, GVSym); |
787 | // .zerofill __DATA, __bss, _foo, 400, 5 |
788 | OutStreamer->emitZerofill(Section: TheSection, Symbol: GVSym, Size, ByteAlignment: Alignment); |
789 | return; |
790 | } |
791 | |
792 | // If this is a BSS local symbol and we are emitting in the BSS |
793 | // section use .lcomm/.comm directive. |
794 | if (GVKind.isBSSLocal() && |
795 | getObjFileLowering().getBSSSection() == TheSection) { |
796 | if (Size == 0) |
797 | Size = 1; // .comm Foo, 0 is undefined, avoid it. |
798 | |
799 | // Use .lcomm only if it supports user-specified alignment. |
800 | // Otherwise, while it would still be correct to use .lcomm in some |
801 | // cases (e.g. when Align == 1), the external assembler might enfore |
802 | // some -unknown- default alignment behavior, which could cause |
803 | // spurious differences between external and integrated assembler. |
804 | // Prefer to simply fall back to .local / .comm in this case. |
805 | if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) { |
806 | // .lcomm _foo, 42 |
807 | OutStreamer->emitLocalCommonSymbol(Symbol: GVSym, Size, ByteAlignment: Alignment); |
808 | return; |
809 | } |
810 | |
811 | // .local _foo |
812 | OutStreamer->emitSymbolAttribute(Symbol: GVSym, Attribute: MCSA_Local); |
813 | // .comm _foo, 42, 4 |
814 | OutStreamer->emitCommonSymbol(Symbol: GVSym, Size, ByteAlignment: Alignment); |
815 | return; |
816 | } |
817 | |
818 | // Handle thread local data for mach-o which requires us to output an |
819 | // additional structure of data and mangle the original symbol so that we |
820 | // can reference it later. |
821 | // |
822 | // TODO: This should become an "emit thread local global" method on TLOF. |
823 | // All of this macho specific stuff should be sunk down into TLOFMachO and |
824 | // stuff like "TLSExtraDataSection" should no longer be part of the parent |
825 | // TLOF class. This will also make it more obvious that stuff like |
826 | // MCStreamer::EmitTBSSSymbol is macho specific and only called from macho |
827 | // specific code. |
828 | if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) { |
829 | // Emit the .tbss symbol |
830 | MCSymbol *MangSym = |
831 | OutContext.getOrCreateSymbol(Name: GVSym->getName() + Twine("$tlv$init" )); |
832 | |
833 | if (GVKind.isThreadBSS()) { |
834 | TheSection = getObjFileLowering().getTLSBSSSection(); |
835 | OutStreamer->emitTBSSSymbol(Section: TheSection, Symbol: MangSym, Size, ByteAlignment: Alignment); |
836 | } else if (GVKind.isThreadData()) { |
837 | OutStreamer->switchSection(Section: TheSection); |
838 | |
839 | emitAlignment(Alignment, GV); |
840 | OutStreamer->emitLabel(Symbol: MangSym); |
841 | |
842 | emitGlobalConstant(DL: GV->getDataLayout(), |
843 | CV: GV->getInitializer()); |
844 | } |
845 | |
846 | OutStreamer->addBlankLine(); |
847 | |
848 | // Emit the variable struct for the runtime. |
849 | MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection(); |
850 | |
851 | OutStreamer->switchSection(Section: TLVSect); |
852 | // Emit the linkage here. |
853 | emitLinkage(GV, GVSym); |
854 | OutStreamer->emitLabel(Symbol: GVSym); |
855 | |
856 | // Three pointers in size: |
857 | // - __tlv_bootstrap - used to make sure support exists |
858 | // - spare pointer, used when mapped by the runtime |
859 | // - pointer to mangled symbol above with initializer |
860 | unsigned PtrSize = DL.getPointerTypeSize(Ty: GV->getType()); |
861 | OutStreamer->emitSymbolValue(Sym: GetExternalSymbolSymbol(Sym: "_tlv_bootstrap" ), |
862 | Size: PtrSize); |
863 | OutStreamer->emitIntValue(Value: 0, Size: PtrSize); |
864 | OutStreamer->emitSymbolValue(Sym: MangSym, Size: PtrSize); |
865 | |
866 | OutStreamer->addBlankLine(); |
867 | return; |
868 | } |
869 | |
870 | MCSymbol *EmittedInitSym = GVSym; |
871 | |
872 | OutStreamer->switchSection(Section: TheSection); |
873 | |
874 | emitLinkage(GV, GVSym: EmittedInitSym); |
875 | emitAlignment(Alignment, GV); |
876 | |
877 | OutStreamer->emitLabel(Symbol: EmittedInitSym); |
878 | MCSymbol *LocalAlias = getSymbolPreferLocal(GV: *GV); |
879 | if (LocalAlias != EmittedInitSym) |
880 | OutStreamer->emitLabel(Symbol: LocalAlias); |
881 | |
882 | emitGlobalConstant(DL: GV->getDataLayout(), CV: GV->getInitializer()); |
883 | |
884 | if (MAI->hasDotTypeDotSizeDirective()) |
885 | // .size foo, 42 |
886 | OutStreamer->emitELFSize(Symbol: EmittedInitSym, |
887 | Value: MCConstantExpr::create(Value: Size, Ctx&: OutContext)); |
888 | |
889 | OutStreamer->addBlankLine(); |
890 | } |
891 | |
892 | /// Emit the directive and value for debug thread local expression |
893 | /// |
894 | /// \p Value - The value to emit. |
895 | /// \p Size - The size of the integer (in bytes) to emit. |
896 | void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const { |
897 | OutStreamer->emitValue(Value, Size); |
898 | } |
899 | |
900 | void AsmPrinter::() {} |
901 | |
902 | void AsmPrinter::emitFunctionPrefix(ArrayRef<const Constant *> Prefix) { |
903 | const Function &F = MF->getFunction(); |
904 | if (!MAI->hasSubsectionsViaSymbols()) { |
905 | for (auto &C : Prefix) |
906 | emitGlobalConstant(DL: F.getDataLayout(), CV: C); |
907 | return; |
908 | } |
909 | // Preserving prefix-like data on platforms which use subsections-via-symbols |
910 | // is a bit tricky. Here we introduce a symbol for the prefix-like data |
911 | // and use the .alt_entry attribute to mark the function's real entry point |
912 | // as an alternative entry point to the symbol that precedes the function.. |
913 | OutStreamer->emitLabel(Symbol: OutContext.createLinkerPrivateTempSymbol()); |
914 | |
915 | for (auto &C : Prefix) { |
916 | emitGlobalConstant(DL: F.getDataLayout(), CV: C); |
917 | } |
918 | |
919 | // Emit an .alt_entry directive for the actual function symbol. |
920 | OutStreamer->emitSymbolAttribute(Symbol: CurrentFnSym, Attribute: MCSA_AltEntry); |
921 | } |
922 | |
923 | /// EmitFunctionHeader - This method emits the header for the current |
924 | /// function. |
925 | void AsmPrinter::() { |
926 | const Function &F = MF->getFunction(); |
927 | |
928 | if (isVerbose()) |
929 | OutStreamer->getCommentOS() |
930 | << "-- Begin function " |
931 | << GlobalValue::dropLLVMManglingEscape(Name: F.getName()) << '\n'; |
932 | |
933 | // Print out constants referenced by the function |
934 | emitConstantPool(); |
935 | |
936 | // Print the 'header' of function. |
937 | // If basic block sections are desired, explicitly request a unique section |
938 | // for this function's entry block. |
939 | if (MF->front().isBeginSection()) |
940 | MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM)); |
941 | else |
942 | MF->setSection(getObjFileLowering().SectionForGlobal(GO: &F, TM)); |
943 | OutStreamer->switchSection(Section: MF->getSection()); |
944 | |
945 | if (!MAI->hasVisibilityOnlyWithLinkage()) |
946 | emitVisibility(Sym: CurrentFnSym, Visibility: F.getVisibility()); |
947 | |
948 | if (MAI->needsFunctionDescriptors()) |
949 | emitLinkage(GV: &F, GVSym: CurrentFnDescSym); |
950 | |
951 | emitLinkage(GV: &F, GVSym: CurrentFnSym); |
952 | if (MAI->hasFunctionAlignment()) |
953 | emitAlignment(Alignment: MF->getAlignment(), GV: &F); |
954 | |
955 | if (MAI->hasDotTypeDotSizeDirective()) |
956 | OutStreamer->emitSymbolAttribute(Symbol: CurrentFnSym, Attribute: MCSA_ELF_TypeFunction); |
957 | |
958 | if (F.hasFnAttribute(Kind: Attribute::Cold)) |
959 | OutStreamer->emitSymbolAttribute(Symbol: CurrentFnSym, Attribute: MCSA_Cold); |
960 | |
961 | // Emit the prefix data. |
962 | if (F.hasPrefixData()) |
963 | emitFunctionPrefix(Prefix: {F.getPrefixData()}); |
964 | |
965 | // Emit KCFI type information before patchable-function-prefix nops. |
966 | emitKCFITypeId(MF: *MF); |
967 | |
968 | // Emit M NOPs for -fpatchable-function-entry=N,M where M>0. We arbitrarily |
969 | // place prefix data before NOPs. |
970 | unsigned PatchableFunctionPrefix = 0; |
971 | unsigned PatchableFunctionEntry = 0; |
972 | (void)F.getFnAttribute(Kind: "patchable-function-prefix" ) |
973 | .getValueAsString() |
974 | .getAsInteger(Radix: 10, Result&: PatchableFunctionPrefix); |
975 | (void)F.getFnAttribute(Kind: "patchable-function-entry" ) |
976 | .getValueAsString() |
977 | .getAsInteger(Radix: 10, Result&: PatchableFunctionEntry); |
978 | if (PatchableFunctionPrefix) { |
979 | CurrentPatchableFunctionEntrySym = |
980 | OutContext.createLinkerPrivateTempSymbol(); |
981 | OutStreamer->emitLabel(Symbol: CurrentPatchableFunctionEntrySym); |
982 | emitNops(N: PatchableFunctionPrefix); |
983 | } else if (PatchableFunctionEntry) { |
984 | // May be reassigned when emitting the body, to reference the label after |
985 | // the initial BTI (AArch64) or endbr32/endbr64 (x86). |
986 | CurrentPatchableFunctionEntrySym = CurrentFnBegin; |
987 | } |
988 | |
989 | // Emit the function prologue data for the indirect call sanitizer. |
990 | if (const MDNode *MD = F.getMetadata(KindID: LLVMContext::MD_func_sanitize)) { |
991 | assert(MD->getNumOperands() == 2); |
992 | |
993 | auto *PrologueSig = mdconst::extract<Constant>(MD: MD->getOperand(I: 0)); |
994 | auto *TypeHash = mdconst::extract<Constant>(MD: MD->getOperand(I: 1)); |
995 | emitFunctionPrefix(Prefix: {PrologueSig, TypeHash}); |
996 | } |
997 | |
998 | if (isVerbose()) { |
999 | F.printAsOperand(O&: OutStreamer->getCommentOS(), |
1000 | /*PrintType=*/false, M: F.getParent()); |
1001 | emitFunctionHeaderComment(); |
1002 | OutStreamer->getCommentOS() << '\n'; |
1003 | } |
1004 | |
1005 | // Emit the function descriptor. This is a virtual function to allow targets |
1006 | // to emit their specific function descriptor. Right now it is only used by |
1007 | // the AIX target. The PowerPC 64-bit V1 ELF target also uses function |
1008 | // descriptors and should be converted to use this hook as well. |
1009 | if (MAI->needsFunctionDescriptors()) |
1010 | emitFunctionDescriptor(); |
1011 | |
1012 | // Emit the CurrentFnSym. This is a virtual function to allow targets to do |
1013 | // their wild and crazy things as required. |
1014 | emitFunctionEntryLabel(); |
1015 | |
1016 | // If the function had address-taken blocks that got deleted, then we have |
1017 | // references to the dangling symbols. Emit them at the start of the function |
1018 | // so that we don't get references to undefined symbols. |
1019 | std::vector<MCSymbol*> DeadBlockSyms; |
1020 | takeDeletedSymbolsForFunction(F: &F, Result&: DeadBlockSyms); |
1021 | for (MCSymbol *DeadBlockSym : DeadBlockSyms) { |
1022 | OutStreamer->AddComment(T: "Address taken block that was later removed" ); |
1023 | OutStreamer->emitLabel(Symbol: DeadBlockSym); |
1024 | } |
1025 | |
1026 | if (CurrentFnBegin) { |
1027 | if (MAI->useAssignmentForEHBegin()) { |
1028 | MCSymbol *CurPos = OutContext.createTempSymbol(); |
1029 | OutStreamer->emitLabel(Symbol: CurPos); |
1030 | OutStreamer->emitAssignment(Symbol: CurrentFnBegin, |
1031 | Value: MCSymbolRefExpr::create(Symbol: CurPos, Ctx&: OutContext)); |
1032 | } else { |
1033 | OutStreamer->emitLabel(Symbol: CurrentFnBegin); |
1034 | } |
1035 | } |
1036 | |
1037 | // Emit pre-function debug and/or EH information. |
1038 | for (auto &Handler : DebugHandlers) { |
1039 | Handler->beginFunction(MF); |
1040 | Handler->beginBasicBlockSection(MBB: MF->front()); |
1041 | } |
1042 | for (auto &Handler : Handlers) |
1043 | Handler->beginFunction(MF); |
1044 | for (auto &Handler : Handlers) |
1045 | Handler->beginBasicBlockSection(MBB: MF->front()); |
1046 | |
1047 | // Emit the prologue data. |
1048 | if (F.hasPrologueData()) |
1049 | emitGlobalConstant(DL: F.getDataLayout(), CV: F.getPrologueData()); |
1050 | } |
1051 | |
1052 | /// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the |
1053 | /// function. This can be overridden by targets as required to do custom stuff. |
1054 | void AsmPrinter::emitFunctionEntryLabel() { |
1055 | CurrentFnSym->redefineIfPossible(); |
1056 | |
1057 | // The function label could have already been emitted if two symbols end up |
1058 | // conflicting due to asm renaming. Detect this and emit an error. |
1059 | if (CurrentFnSym->isVariable()) |
1060 | report_fatal_error(reason: "'" + Twine(CurrentFnSym->getName()) + |
1061 | "' is a protected alias" ); |
1062 | |
1063 | OutStreamer->emitLabel(Symbol: CurrentFnSym); |
1064 | |
1065 | if (TM.getTargetTriple().isOSBinFormatELF()) { |
1066 | MCSymbol *Sym = getSymbolPreferLocal(GV: MF->getFunction()); |
1067 | if (Sym != CurrentFnSym) { |
1068 | cast<MCSymbolELF>(Val: Sym)->setType(ELF::STT_FUNC); |
1069 | CurrentFnBeginLocal = Sym; |
1070 | OutStreamer->emitLabel(Symbol: Sym); |
1071 | if (MAI->hasDotTypeDotSizeDirective()) |
1072 | OutStreamer->emitSymbolAttribute(Symbol: Sym, Attribute: MCSA_ELF_TypeFunction); |
1073 | } |
1074 | } |
1075 | } |
1076 | |
1077 | /// emitComments - Pretty-print comments for instructions. |
1078 | static void (const MachineInstr &MI, raw_ostream &) { |
1079 | const MachineFunction *MF = MI.getMF(); |
1080 | const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); |
1081 | |
1082 | // Check for spills and reloads |
1083 | |
1084 | // We assume a single instruction only has a spill or reload, not |
1085 | // both. |
1086 | std::optional<LocationSize> Size; |
1087 | if ((Size = MI.getRestoreSize(TII))) { |
1088 | CommentOS << Size->getValue() << "-byte Reload\n" ; |
1089 | } else if ((Size = MI.getFoldedRestoreSize(TII))) { |
1090 | if (!Size->hasValue()) |
1091 | CommentOS << "Unknown-size Folded Reload\n" ; |
1092 | else if (Size->getValue()) |
1093 | CommentOS << Size->getValue() << "-byte Folded Reload\n" ; |
1094 | } else if ((Size = MI.getSpillSize(TII))) { |
1095 | CommentOS << Size->getValue() << "-byte Spill\n" ; |
1096 | } else if ((Size = MI.getFoldedSpillSize(TII))) { |
1097 | if (!Size->hasValue()) |
1098 | CommentOS << "Unknown-size Folded Spill\n" ; |
1099 | else if (Size->getValue()) |
1100 | CommentOS << Size->getValue() << "-byte Folded Spill\n" ; |
1101 | } |
1102 | |
1103 | // Check for spill-induced copies |
1104 | if (MI.getAsmPrinterFlag(Flag: MachineInstr::ReloadReuse)) |
1105 | CommentOS << " Reload Reuse\n" ; |
1106 | } |
1107 | |
1108 | /// emitImplicitDef - This method emits the specified machine instruction |
1109 | /// that is an implicit def. |
1110 | void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const { |
1111 | Register RegNo = MI->getOperand(i: 0).getReg(); |
1112 | |
1113 | SmallString<128> Str; |
1114 | raw_svector_ostream OS(Str); |
1115 | OS << "implicit-def: " |
1116 | << printReg(Reg: RegNo, TRI: MF->getSubtarget().getRegisterInfo()); |
1117 | |
1118 | OutStreamer->AddComment(T: OS.str()); |
1119 | OutStreamer->addBlankLine(); |
1120 | } |
1121 | |
1122 | static void emitKill(const MachineInstr *MI, AsmPrinter &AP) { |
1123 | std::string Str; |
1124 | raw_string_ostream OS(Str); |
1125 | OS << "kill:" ; |
1126 | for (const MachineOperand &Op : MI->operands()) { |
1127 | assert(Op.isReg() && "KILL instruction must have only register operands" ); |
1128 | OS << ' ' << (Op.isDef() ? "def " : "killed " ) |
1129 | << printReg(Reg: Op.getReg(), TRI: AP.MF->getSubtarget().getRegisterInfo()); |
1130 | } |
1131 | AP.OutStreamer->AddComment(T: Str); |
1132 | AP.OutStreamer->addBlankLine(); |
1133 | } |
1134 | |
1135 | /// emitDebugValueComment - This method handles the target-independent form |
1136 | /// of DBG_VALUE, returning true if it was able to do so. A false return |
1137 | /// means the target will need to handle MI in EmitInstruction. |
1138 | static bool (const MachineInstr *MI, AsmPrinter &AP) { |
1139 | // This code handles only the 4-operand target-independent form. |
1140 | if (MI->isNonListDebugValue() && MI->getNumOperands() != 4) |
1141 | return false; |
1142 | |
1143 | SmallString<128> Str; |
1144 | raw_svector_ostream OS(Str); |
1145 | OS << "DEBUG_VALUE: " ; |
1146 | |
1147 | const DILocalVariable *V = MI->getDebugVariable(); |
1148 | if (auto *SP = dyn_cast<DISubprogram>(Val: V->getScope())) { |
1149 | StringRef Name = SP->getName(); |
1150 | if (!Name.empty()) |
1151 | OS << Name << ":" ; |
1152 | } |
1153 | OS << V->getName(); |
1154 | OS << " <- " ; |
1155 | |
1156 | const DIExpression *Expr = MI->getDebugExpression(); |
1157 | // First convert this to a non-variadic expression if possible, to simplify |
1158 | // the output. |
1159 | if (auto NonVariadicExpr = DIExpression::convertToNonVariadicExpression(Expr)) |
1160 | Expr = *NonVariadicExpr; |
1161 | // Then, output the possibly-simplified expression. |
1162 | if (Expr->getNumElements()) { |
1163 | OS << '['; |
1164 | ListSeparator LS; |
1165 | for (auto &Op : Expr->expr_ops()) { |
1166 | OS << LS << dwarf::OperationEncodingString(Encoding: Op.getOp()); |
1167 | for (unsigned I = 0; I < Op.getNumArgs(); ++I) |
1168 | OS << ' ' << Op.getArg(I); |
1169 | } |
1170 | OS << "] " ; |
1171 | } |
1172 | |
1173 | // Register or immediate value. Register 0 means undef. |
1174 | for (const MachineOperand &Op : MI->debug_operands()) { |
1175 | if (&Op != MI->debug_operands().begin()) |
1176 | OS << ", " ; |
1177 | switch (Op.getType()) { |
1178 | case MachineOperand::MO_FPImmediate: { |
1179 | APFloat APF = APFloat(Op.getFPImm()->getValueAPF()); |
1180 | Type *ImmTy = Op.getFPImm()->getType(); |
1181 | if (ImmTy->isBFloatTy() || ImmTy->isHalfTy() || ImmTy->isFloatTy() || |
1182 | ImmTy->isDoubleTy()) { |
1183 | OS << APF.convertToDouble(); |
1184 | } else { |
1185 | // There is no good way to print long double. Convert a copy to |
1186 | // double. Ah well, it's only a comment. |
1187 | bool ignored; |
1188 | APF.convert(ToSemantics: APFloat::IEEEdouble(), RM: APFloat::rmNearestTiesToEven, |
1189 | losesInfo: &ignored); |
1190 | OS << "(long double) " << APF.convertToDouble(); |
1191 | } |
1192 | break; |
1193 | } |
1194 | case MachineOperand::MO_Immediate: { |
1195 | OS << Op.getImm(); |
1196 | break; |
1197 | } |
1198 | case MachineOperand::MO_CImmediate: { |
1199 | Op.getCImm()->getValue().print(OS, isSigned: false /*isSigned*/); |
1200 | break; |
1201 | } |
1202 | case MachineOperand::MO_TargetIndex: { |
1203 | OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")" ; |
1204 | break; |
1205 | } |
1206 | case MachineOperand::MO_Register: |
1207 | case MachineOperand::MO_FrameIndex: { |
1208 | Register Reg; |
1209 | std::optional<StackOffset> Offset; |
1210 | if (Op.isReg()) { |
1211 | Reg = Op.getReg(); |
1212 | } else { |
1213 | const TargetFrameLowering *TFI = |
1214 | AP.MF->getSubtarget().getFrameLowering(); |
1215 | Offset = TFI->getFrameIndexReference(MF: *AP.MF, FI: Op.getIndex(), FrameReg&: Reg); |
1216 | } |
1217 | if (!Reg) { |
1218 | // Suppress offset, it is not meaningful here. |
1219 | OS << "undef" ; |
1220 | break; |
1221 | } |
1222 | // The second operand is only an offset if it's an immediate. |
1223 | if (MI->isIndirectDebugValue()) |
1224 | Offset = StackOffset::getFixed(Fixed: MI->getDebugOffset().getImm()); |
1225 | if (Offset) |
1226 | OS << '['; |
1227 | OS << printReg(Reg, TRI: AP.MF->getSubtarget().getRegisterInfo()); |
1228 | if (Offset) |
1229 | OS << '+' << Offset->getFixed() << ']'; |
1230 | break; |
1231 | } |
1232 | default: |
1233 | llvm_unreachable("Unknown operand type" ); |
1234 | } |
1235 | } |
1236 | |
1237 | // NOTE: Want this comment at start of line, don't emit with AddComment. |
1238 | AP.OutStreamer->emitRawComment(T: Str); |
1239 | return true; |
1240 | } |
1241 | |
1242 | /// This method handles the target-independent form of DBG_LABEL, returning |
1243 | /// true if it was able to do so. A false return means the target will need |
1244 | /// to handle MI in EmitInstruction. |
1245 | static bool (const MachineInstr *MI, AsmPrinter &AP) { |
1246 | if (MI->getNumOperands() != 1) |
1247 | return false; |
1248 | |
1249 | SmallString<128> Str; |
1250 | raw_svector_ostream OS(Str); |
1251 | OS << "DEBUG_LABEL: " ; |
1252 | |
1253 | const DILabel *V = MI->getDebugLabel(); |
1254 | if (auto *SP = dyn_cast<DISubprogram>( |
1255 | Val: V->getScope()->getNonLexicalBlockFileScope())) { |
1256 | StringRef Name = SP->getName(); |
1257 | if (!Name.empty()) |
1258 | OS << Name << ":" ; |
1259 | } |
1260 | OS << V->getName(); |
1261 | |
1262 | // NOTE: Want this comment at start of line, don't emit with AddComment. |
1263 | AP.OutStreamer->emitRawComment(T: OS.str()); |
1264 | return true; |
1265 | } |
1266 | |
1267 | AsmPrinter::CFISection |
1268 | AsmPrinter::getFunctionCFISectionType(const Function &F) const { |
1269 | // Ignore functions that won't get emitted. |
1270 | if (F.isDeclarationForLinker()) |
1271 | return CFISection::None; |
1272 | |
1273 | if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && |
1274 | F.needsUnwindTableEntry()) |
1275 | return CFISection::EH; |
1276 | |
1277 | if (MAI->usesCFIWithoutEH() && F.hasUWTable()) |
1278 | return CFISection::EH; |
1279 | |
1280 | assert(MMI != nullptr && "Invalid machine module info" ); |
1281 | if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection) |
1282 | return CFISection::Debug; |
1283 | |
1284 | return CFISection::None; |
1285 | } |
1286 | |
1287 | AsmPrinter::CFISection |
1288 | AsmPrinter::getFunctionCFISectionType(const MachineFunction &MF) const { |
1289 | return getFunctionCFISectionType(F: MF.getFunction()); |
1290 | } |
1291 | |
1292 | bool AsmPrinter::needsSEHMoves() { |
1293 | return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry(); |
1294 | } |
1295 | |
1296 | bool AsmPrinter::usesCFIWithoutEH() const { |
1297 | return MAI->usesCFIWithoutEH() && ModuleCFISection != CFISection::None; |
1298 | } |
1299 | |
1300 | void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) { |
1301 | ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType(); |
1302 | if (!usesCFIWithoutEH() && |
1303 | ExceptionHandlingType != ExceptionHandling::DwarfCFI && |
1304 | ExceptionHandlingType != ExceptionHandling::ARM) |
1305 | return; |
1306 | |
1307 | if (getFunctionCFISectionType(MF: *MF) == CFISection::None) |
1308 | return; |
1309 | |
1310 | // If there is no "real" instruction following this CFI instruction, skip |
1311 | // emitting it; it would be beyond the end of the function's FDE range. |
1312 | auto *MBB = MI.getParent(); |
1313 | auto I = std::next(x: MI.getIterator()); |
1314 | while (I != MBB->end() && I->isTransient()) |
1315 | ++I; |
1316 | if (I == MBB->instr_end() && |
1317 | MBB->getReverseIterator() == MBB->getParent()->rbegin()) |
1318 | return; |
1319 | |
1320 | const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions(); |
1321 | unsigned CFIIndex = MI.getOperand(i: 0).getCFIIndex(); |
1322 | const MCCFIInstruction &CFI = Instrs[CFIIndex]; |
1323 | emitCFIInstruction(Inst: CFI); |
1324 | } |
1325 | |
1326 | void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) { |
1327 | // The operands are the MCSymbol and the frame offset of the allocation. |
1328 | MCSymbol *FrameAllocSym = MI.getOperand(i: 0).getMCSymbol(); |
1329 | int FrameOffset = MI.getOperand(i: 1).getImm(); |
1330 | |
1331 | // Emit a symbol assignment. |
1332 | OutStreamer->emitAssignment(Symbol: FrameAllocSym, |
1333 | Value: MCConstantExpr::create(Value: FrameOffset, Ctx&: OutContext)); |
1334 | } |
1335 | |
1336 | /// Returns the BB metadata to be emitted in the SHT_LLVM_BB_ADDR_MAP section |
1337 | /// for a given basic block. This can be used to capture more precise profile |
1338 | /// information. |
1339 | static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) { |
1340 | const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); |
1341 | return object::BBAddrMap::BBEntry::Metadata{ |
1342 | .HasReturn: MBB.isReturnBlock(), .HasTailCall: !MBB.empty() && TII->isTailCall(Inst: MBB.back()), |
1343 | .IsEHPad: MBB.isEHPad(), .CanFallThrough: const_cast<MachineBasicBlock &>(MBB).canFallThrough(), |
1344 | .HasIndirectBranch: !MBB.empty() && MBB.rbegin()->isIndirectBranch()} |
1345 | .encode(); |
1346 | } |
1347 | |
1348 | static llvm::object::BBAddrMap::Features |
1349 | getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) { |
1350 | return {.FuncEntryCount: PgoAnalysisMapFeatures.isSet(V: PGOMapFeaturesEnum::FuncEntryCount), |
1351 | .BBFreq: PgoAnalysisMapFeatures.isSet(V: PGOMapFeaturesEnum::BBFreq), |
1352 | .BrProb: PgoAnalysisMapFeatures.isSet(V: PGOMapFeaturesEnum::BrProb), |
1353 | .MultiBBRange: MF.hasBBSections() && NumMBBSectionRanges > 1}; |
1354 | } |
1355 | |
1356 | void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) { |
1357 | MCSection *BBAddrMapSection = |
1358 | getObjFileLowering().getBBAddrMapSection(TextSec: *MF.getSection()); |
1359 | assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized." ); |
1360 | |
1361 | const MCSymbol *FunctionSymbol = getFunctionBegin(); |
1362 | |
1363 | OutStreamer->pushSection(); |
1364 | OutStreamer->switchSection(Section: BBAddrMapSection); |
1365 | OutStreamer->AddComment(T: "version" ); |
1366 | uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion(); |
1367 | OutStreamer->emitInt8(Value: BBAddrMapVersion); |
1368 | OutStreamer->AddComment(T: "feature" ); |
1369 | auto Features = getBBAddrMapFeature(MF, NumMBBSectionRanges: MBBSectionRanges.size()); |
1370 | OutStreamer->emitInt8(Value: Features.encode()); |
1371 | // Emit BB Information for each basic block in the function. |
1372 | if (Features.MultiBBRange) { |
1373 | OutStreamer->AddComment(T: "number of basic block ranges" ); |
1374 | OutStreamer->emitULEB128IntValue(Value: MBBSectionRanges.size()); |
1375 | } |
1376 | // Number of blocks in each MBB section. |
1377 | MapVector<MBBSectionID, unsigned> MBBSectionNumBlocks; |
1378 | const MCSymbol *PrevMBBEndSymbol = nullptr; |
1379 | if (!Features.MultiBBRange) { |
1380 | OutStreamer->AddComment(T: "function address" ); |
1381 | OutStreamer->emitSymbolValue(Sym: FunctionSymbol, Size: getPointerSize()); |
1382 | OutStreamer->AddComment(T: "number of basic blocks" ); |
1383 | OutStreamer->emitULEB128IntValue(Value: MF.size()); |
1384 | PrevMBBEndSymbol = FunctionSymbol; |
1385 | } else { |
1386 | unsigned BBCount = 0; |
1387 | for (const MachineBasicBlock &MBB : MF) { |
1388 | BBCount++; |
1389 | if (MBB.isEndSection()) { |
1390 | // Store each section's basic block count when it ends. |
1391 | MBBSectionNumBlocks[MBB.getSectionID()] = BBCount; |
1392 | // Reset the count for the next section. |
1393 | BBCount = 0; |
1394 | } |
1395 | } |
1396 | } |
1397 | // Emit the BB entry for each basic block in the function. |
1398 | for (const MachineBasicBlock &MBB : MF) { |
1399 | const MCSymbol *MBBSymbol = |
1400 | MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol(); |
1401 | bool IsBeginSection = |
1402 | Features.MultiBBRange && (MBB.isBeginSection() || MBB.isEntryBlock()); |
1403 | if (IsBeginSection) { |
1404 | OutStreamer->AddComment(T: "base address" ); |
1405 | OutStreamer->emitSymbolValue(Sym: MBBSymbol, Size: getPointerSize()); |
1406 | OutStreamer->AddComment(T: "number of basic blocks" ); |
1407 | OutStreamer->emitULEB128IntValue(Value: MBBSectionNumBlocks[MBB.getSectionID()]); |
1408 | PrevMBBEndSymbol = MBBSymbol; |
1409 | } |
1410 | // TODO: Remove this check when version 1 is deprecated. |
1411 | if (BBAddrMapVersion > 1) { |
1412 | OutStreamer->AddComment(T: "BB id" ); |
1413 | // Emit the BB ID for this basic block. |
1414 | // We only emit BaseID since CloneID is unset for |
1415 | // basic-block-sections=labels. |
1416 | // TODO: Emit the full BBID when labels and sections can be mixed |
1417 | // together. |
1418 | OutStreamer->emitULEB128IntValue(Value: MBB.getBBID()->BaseID); |
1419 | } |
1420 | // Emit the basic block offset relative to the end of the previous block. |
1421 | // This is zero unless the block is padded due to alignment. |
1422 | emitLabelDifferenceAsULEB128(Hi: MBBSymbol, Lo: PrevMBBEndSymbol); |
1423 | // Emit the basic block size. When BBs have alignments, their size cannot |
1424 | // always be computed from their offsets. |
1425 | emitLabelDifferenceAsULEB128(Hi: MBB.getEndSymbol(), Lo: MBBSymbol); |
1426 | // Emit the Metadata. |
1427 | OutStreamer->emitULEB128IntValue(Value: getBBAddrMapMetadata(MBB)); |
1428 | PrevMBBEndSymbol = MBB.getEndSymbol(); |
1429 | } |
1430 | |
1431 | if (Features.hasPGOAnalysis()) { |
1432 | assert(BBAddrMapVersion >= 2 && |
1433 | "PGOAnalysisMap only supports version 2 or later" ); |
1434 | |
1435 | if (Features.FuncEntryCount) { |
1436 | OutStreamer->AddComment(T: "function entry count" ); |
1437 | auto MaybeEntryCount = MF.getFunction().getEntryCount(); |
1438 | OutStreamer->emitULEB128IntValue( |
1439 | Value: MaybeEntryCount ? MaybeEntryCount->getCount() : 0); |
1440 | } |
1441 | const MachineBlockFrequencyInfo *MBFI = |
1442 | Features.BBFreq |
1443 | ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() |
1444 | : nullptr; |
1445 | const MachineBranchProbabilityInfo *MBPI = |
1446 | Features.BrProb |
1447 | ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI() |
1448 | : nullptr; |
1449 | |
1450 | if (Features.BBFreq || Features.BrProb) { |
1451 | for (const MachineBasicBlock &MBB : MF) { |
1452 | if (Features.BBFreq) { |
1453 | OutStreamer->AddComment(T: "basic block frequency" ); |
1454 | OutStreamer->emitULEB128IntValue( |
1455 | Value: MBFI->getBlockFreq(MBB: &MBB).getFrequency()); |
1456 | } |
1457 | if (Features.BrProb) { |
1458 | unsigned SuccCount = MBB.succ_size(); |
1459 | OutStreamer->AddComment(T: "basic block successor count" ); |
1460 | OutStreamer->emitULEB128IntValue(Value: SuccCount); |
1461 | for (const MachineBasicBlock *SuccMBB : MBB.successors()) { |
1462 | OutStreamer->AddComment(T: "successor BB ID" ); |
1463 | OutStreamer->emitULEB128IntValue(Value: SuccMBB->getBBID()->BaseID); |
1464 | OutStreamer->AddComment(T: "successor branch probability" ); |
1465 | OutStreamer->emitULEB128IntValue( |
1466 | Value: MBPI->getEdgeProbability(Src: &MBB, Dst: SuccMBB).getNumerator()); |
1467 | } |
1468 | } |
1469 | } |
1470 | } |
1471 | } |
1472 | |
1473 | OutStreamer->popSection(); |
1474 | } |
1475 | |
1476 | void AsmPrinter::emitKCFITrapEntry(const MachineFunction &MF, |
1477 | const MCSymbol *Symbol) { |
1478 | MCSection *Section = |
1479 | getObjFileLowering().getKCFITrapSection(TextSec: *MF.getSection()); |
1480 | if (!Section) |
1481 | return; |
1482 | |
1483 | OutStreamer->pushSection(); |
1484 | OutStreamer->switchSection(Section); |
1485 | |
1486 | MCSymbol *Loc = OutContext.createLinkerPrivateTempSymbol(); |
1487 | OutStreamer->emitLabel(Symbol: Loc); |
1488 | OutStreamer->emitAbsoluteSymbolDiff(Hi: Symbol, Lo: Loc, Size: 4); |
1489 | |
1490 | OutStreamer->popSection(); |
1491 | } |
1492 | |
1493 | void AsmPrinter::emitKCFITypeId(const MachineFunction &MF) { |
1494 | const Function &F = MF.getFunction(); |
1495 | if (const MDNode *MD = F.getMetadata(KindID: LLVMContext::MD_kcfi_type)) |
1496 | emitGlobalConstant(DL: F.getDataLayout(), |
1497 | CV: mdconst::extract<ConstantInt>(MD: MD->getOperand(I: 0))); |
1498 | } |
1499 | |
1500 | void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) { |
1501 | if (PP) { |
1502 | auto GUID = MI.getOperand(i: 0).getImm(); |
1503 | auto Index = MI.getOperand(i: 1).getImm(); |
1504 | auto Type = MI.getOperand(i: 2).getImm(); |
1505 | auto Attr = MI.getOperand(i: 3).getImm(); |
1506 | DILocation *DebugLoc = MI.getDebugLoc(); |
1507 | PP->emitPseudoProbe(Guid: GUID, Index, Type, Attr, DebugLoc); |
1508 | } |
1509 | } |
1510 | |
1511 | void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) { |
1512 | if (!MF.getTarget().Options.EmitStackSizeSection) |
1513 | return; |
1514 | |
1515 | MCSection *StackSizeSection = |
1516 | getObjFileLowering().getStackSizesSection(TextSec: *getCurrentSection()); |
1517 | if (!StackSizeSection) |
1518 | return; |
1519 | |
1520 | const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); |
1521 | // Don't emit functions with dynamic stack allocations. |
1522 | if (FrameInfo.hasVarSizedObjects()) |
1523 | return; |
1524 | |
1525 | OutStreamer->pushSection(); |
1526 | OutStreamer->switchSection(Section: StackSizeSection); |
1527 | |
1528 | const MCSymbol *FunctionSymbol = getFunctionBegin(); |
1529 | uint64_t StackSize = |
1530 | FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); |
1531 | OutStreamer->emitSymbolValue(Sym: FunctionSymbol, Size: TM.getProgramPointerSize()); |
1532 | OutStreamer->emitULEB128IntValue(Value: StackSize); |
1533 | |
1534 | OutStreamer->popSection(); |
1535 | } |
1536 | |
1537 | void AsmPrinter::emitStackUsage(const MachineFunction &MF) { |
1538 | const std::string &OutputFilename = MF.getTarget().Options.StackUsageOutput; |
1539 | |
1540 | // OutputFilename empty implies -fstack-usage is not passed. |
1541 | if (OutputFilename.empty()) |
1542 | return; |
1543 | |
1544 | const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); |
1545 | uint64_t StackSize = |
1546 | FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); |
1547 | |
1548 | if (StackUsageStream == nullptr) { |
1549 | std::error_code EC; |
1550 | StackUsageStream = |
1551 | std::make_unique<raw_fd_ostream>(args: OutputFilename, args&: EC, args: sys::fs::OF_Text); |
1552 | if (EC) { |
1553 | errs() << "Could not open file: " << EC.message(); |
1554 | return; |
1555 | } |
1556 | } |
1557 | |
1558 | if (const DISubprogram *DSP = MF.getFunction().getSubprogram()) |
1559 | *StackUsageStream << DSP->getFilename() << ':' << DSP->getLine(); |
1560 | else |
1561 | *StackUsageStream << MF.getFunction().getParent()->getName(); |
1562 | |
1563 | *StackUsageStream << ':' << MF.getName() << '\t' << StackSize << '\t'; |
1564 | if (FrameInfo.hasVarSizedObjects()) |
1565 | *StackUsageStream << "dynamic\n" ; |
1566 | else |
1567 | *StackUsageStream << "static\n" ; |
1568 | } |
1569 | |
1570 | void AsmPrinter::emitPCSectionsLabel(const MachineFunction &MF, |
1571 | const MDNode &MD) { |
1572 | MCSymbol *S = MF.getContext().createTempSymbol(Name: "pcsection" ); |
1573 | OutStreamer->emitLabel(Symbol: S); |
1574 | PCSectionsSymbols[&MD].emplace_back(Args&: S); |
1575 | } |
1576 | |
1577 | void AsmPrinter::emitPCSections(const MachineFunction &MF) { |
1578 | const Function &F = MF.getFunction(); |
1579 | if (PCSectionsSymbols.empty() && !F.hasMetadata(KindID: LLVMContext::MD_pcsections)) |
1580 | return; |
1581 | |
1582 | const CodeModel::Model CM = MF.getTarget().getCodeModel(); |
1583 | const unsigned RelativeRelocSize = |
1584 | (CM == CodeModel::Medium || CM == CodeModel::Large) ? getPointerSize() |
1585 | : 4; |
1586 | |
1587 | // Switch to PCSection, short-circuiting the common case where the current |
1588 | // section is still valid (assume most MD_pcsections contain just 1 section). |
1589 | auto SwitchSection = [&, Prev = StringRef()](const StringRef &Sec) mutable { |
1590 | if (Sec == Prev) |
1591 | return; |
1592 | MCSection *S = getObjFileLowering().getPCSection(Name: Sec, TextSec: MF.getSection()); |
1593 | assert(S && "PC section is not initialized" ); |
1594 | OutStreamer->switchSection(Section: S); |
1595 | Prev = Sec; |
1596 | }; |
1597 | // Emit symbols into sections and data as specified in the pcsections MDNode. |
1598 | auto EmitForMD = [&](const MDNode &MD, ArrayRef<const MCSymbol *> Syms, |
1599 | bool Deltas) { |
1600 | // Expect the first operand to be a section name. After that, a tuple of |
1601 | // constants may appear, which will simply be emitted into the current |
1602 | // section (the user of MD_pcsections decides the format of encoded data). |
1603 | assert(isa<MDString>(MD.getOperand(0)) && "first operand not a string" ); |
1604 | bool ConstULEB128 = false; |
1605 | for (const MDOperand &MDO : MD.operands()) { |
1606 | if (auto *S = dyn_cast<MDString>(Val: MDO)) { |
1607 | // Found string, start of new section! |
1608 | // Find options for this section "<section>!<opts>" - supported options: |
1609 | // C = Compress constant integers of size 2-8 bytes as ULEB128. |
1610 | const StringRef SecWithOpt = S->getString(); |
1611 | const size_t OptStart = SecWithOpt.find(C: '!'); // likely npos |
1612 | const StringRef Sec = SecWithOpt.substr(Start: 0, N: OptStart); |
1613 | const StringRef Opts = SecWithOpt.substr(Start: OptStart); // likely empty |
1614 | ConstULEB128 = Opts.contains(C: 'C'); |
1615 | #ifndef NDEBUG |
1616 | for (char O : Opts) |
1617 | assert((O == '!' || O == 'C') && "Invalid !pcsections options" ); |
1618 | #endif |
1619 | SwitchSection(Sec); |
1620 | const MCSymbol *Prev = Syms.front(); |
1621 | for (const MCSymbol *Sym : Syms) { |
1622 | if (Sym == Prev || !Deltas) { |
1623 | // Use the entry itself as the base of the relative offset. |
1624 | MCSymbol *Base = MF.getContext().createTempSymbol(Name: "pcsection_base" ); |
1625 | OutStreamer->emitLabel(Symbol: Base); |
1626 | // Emit relative relocation `addr - base`, which avoids a dynamic |
1627 | // relocation in the final binary. User will get the address with |
1628 | // `base + addr`. |
1629 | emitLabelDifference(Hi: Sym, Lo: Base, Size: RelativeRelocSize); |
1630 | } else { |
1631 | // Emit delta between symbol and previous symbol. |
1632 | if (ConstULEB128) |
1633 | emitLabelDifferenceAsULEB128(Hi: Sym, Lo: Prev); |
1634 | else |
1635 | emitLabelDifference(Hi: Sym, Lo: Prev, Size: 4); |
1636 | } |
1637 | Prev = Sym; |
1638 | } |
1639 | } else { |
1640 | // Emit auxiliary data after PC. |
1641 | assert(isa<MDNode>(MDO) && "expecting either string or tuple" ); |
1642 | const auto *AuxMDs = cast<MDNode>(Val: MDO); |
1643 | for (const MDOperand &AuxMDO : AuxMDs->operands()) { |
1644 | assert(isa<ConstantAsMetadata>(AuxMDO) && "expecting a constant" ); |
1645 | const Constant *C = cast<ConstantAsMetadata>(Val: AuxMDO)->getValue(); |
1646 | const DataLayout &DL = F.getDataLayout(); |
1647 | const uint64_t Size = DL.getTypeStoreSize(Ty: C->getType()); |
1648 | |
1649 | if (auto *CI = dyn_cast<ConstantInt>(Val: C); |
1650 | CI && ConstULEB128 && Size > 1 && Size <= 8) { |
1651 | emitULEB128(Value: CI->getZExtValue()); |
1652 | } else { |
1653 | emitGlobalConstant(DL, CV: C); |
1654 | } |
1655 | } |
1656 | } |
1657 | } |
1658 | }; |
1659 | |
1660 | OutStreamer->pushSection(); |
1661 | // Emit PCs for function start and function size. |
1662 | if (const MDNode *MD = F.getMetadata(KindID: LLVMContext::MD_pcsections)) |
1663 | EmitForMD(*MD, {getFunctionBegin(), getFunctionEnd()}, true); |
1664 | // Emit PCs for instructions collected. |
1665 | for (const auto &MS : PCSectionsSymbols) |
1666 | EmitForMD(*MS.first, MS.second, false); |
1667 | OutStreamer->popSection(); |
1668 | PCSectionsSymbols.clear(); |
1669 | } |
1670 | |
1671 | /// Returns true if function begin and end labels should be emitted. |
1672 | static bool needFuncLabels(const MachineFunction &MF, |
1673 | const MachineModuleInfo &MMI) { |
1674 | if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || |
1675 | MMI.hasDebugInfo() || |
1676 | MF.getFunction().hasMetadata(KindID: LLVMContext::MD_pcsections)) |
1677 | return true; |
1678 | |
1679 | // We might emit an EH table that uses function begin and end labels even if |
1680 | // we don't have any landingpads. |
1681 | if (!MF.getFunction().hasPersonalityFn()) |
1682 | return false; |
1683 | return !isNoOpWithoutInvoke( |
1684 | Pers: classifyEHPersonality(Pers: MF.getFunction().getPersonalityFn())); |
1685 | } |
1686 | |
1687 | /// EmitFunctionBody - This method emits the body and trailer for a |
1688 | /// function. |
1689 | void AsmPrinter::emitFunctionBody() { |
1690 | emitFunctionHeader(); |
1691 | |
1692 | // Emit target-specific gunk before the function body. |
1693 | emitFunctionBodyStart(); |
1694 | |
1695 | if (isVerbose()) { |
1696 | // Get MachineDominatorTree or compute it on the fly if it's unavailable |
1697 | auto MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>(); |
1698 | MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; |
1699 | if (!MDT) { |
1700 | OwnedMDT = std::make_unique<MachineDominatorTree>(); |
1701 | OwnedMDT->getBase().recalculate(Func&: *MF); |
1702 | MDT = OwnedMDT.get(); |
1703 | } |
1704 | |
1705 | // Get MachineLoopInfo or compute it on the fly if it's unavailable |
1706 | auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>(); |
1707 | MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr; |
1708 | if (!MLI) { |
1709 | OwnedMLI = std::make_unique<MachineLoopInfo>(); |
1710 | OwnedMLI->analyze(DomTree: MDT->getBase()); |
1711 | MLI = OwnedMLI.get(); |
1712 | } |
1713 | } |
1714 | |
1715 | // Print out code for the function. |
1716 | bool HasAnyRealCode = false; |
1717 | int NumInstsInFunction = 0; |
1718 | bool IsEHa = MMI->getModule()->getModuleFlag(Key: "eh-asynch" ); |
1719 | |
1720 | bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE); |
1721 | for (auto &MBB : *MF) { |
1722 | // Print a label for the basic block. |
1723 | emitBasicBlockStart(MBB); |
1724 | DenseMap<StringRef, unsigned> MnemonicCounts; |
1725 | for (auto &MI : MBB) { |
1726 | // Print the assembly for the instruction. |
1727 | if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() && |
1728 | !MI.isDebugInstr()) { |
1729 | HasAnyRealCode = true; |
1730 | ++NumInstsInFunction; |
1731 | } |
1732 | |
1733 | // If there is a pre-instruction symbol, emit a label for it here. |
1734 | if (MCSymbol *S = MI.getPreInstrSymbol()) |
1735 | OutStreamer->emitLabel(Symbol: S); |
1736 | |
1737 | if (MDNode *MD = MI.getPCSections()) |
1738 | emitPCSectionsLabel(MF: *MF, MD: *MD); |
1739 | |
1740 | for (auto &Handler : DebugHandlers) |
1741 | Handler->beginInstruction(MI: &MI); |
1742 | |
1743 | if (isVerbose()) |
1744 | emitComments(MI, CommentOS&: OutStreamer->getCommentOS()); |
1745 | |
1746 | switch (MI.getOpcode()) { |
1747 | case TargetOpcode::CFI_INSTRUCTION: |
1748 | emitCFIInstruction(MI); |
1749 | break; |
1750 | case TargetOpcode::LOCAL_ESCAPE: |
1751 | emitFrameAlloc(MI); |
1752 | break; |
1753 | case TargetOpcode::ANNOTATION_LABEL: |
1754 | case TargetOpcode::GC_LABEL: |
1755 | OutStreamer->emitLabel(Symbol: MI.getOperand(i: 0).getMCSymbol()); |
1756 | break; |
1757 | case TargetOpcode::EH_LABEL: |
1758 | OutStreamer->emitLabel(Symbol: MI.getOperand(i: 0).getMCSymbol()); |
1759 | // For AsynchEH, insert a Nop if followed by a trap inst |
1760 | // Or the exception won't be caught. |
1761 | // (see MCConstantExpr::create(1,..) in WinException.cpp) |
1762 | // Ignore SDiv/UDiv because a DIV with Const-0 divisor |
1763 | // must have being turned into an UndefValue. |
1764 | // Div with variable opnds won't be the first instruction in |
1765 | // an EH region as it must be led by at least a Load |
1766 | { |
1767 | auto MI2 = std::next(x: MI.getIterator()); |
1768 | if (IsEHa && MI2 != MBB.end() && |
1769 | (MI2->mayLoadOrStore() || MI2->mayRaiseFPException())) |
1770 | emitNops(N: 1); |
1771 | } |
1772 | break; |
1773 | case TargetOpcode::INLINEASM: |
1774 | case TargetOpcode::INLINEASM_BR: |
1775 | emitInlineAsm(MI: &MI); |
1776 | break; |
1777 | case TargetOpcode::DBG_VALUE: |
1778 | case TargetOpcode::DBG_VALUE_LIST: |
1779 | if (isVerbose()) { |
1780 | if (!emitDebugValueComment(MI: &MI, AP&: *this)) |
1781 | emitInstruction(&MI); |
1782 | } |
1783 | break; |
1784 | case TargetOpcode::DBG_INSTR_REF: |
1785 | // This instruction reference will have been resolved to a machine |
1786 | // location, and a nearby DBG_VALUE created. We can safely ignore |
1787 | // the instruction reference. |
1788 | break; |
1789 | case TargetOpcode::DBG_PHI: |
1790 | // This instruction is only used to label a program point, it's purely |
1791 | // meta information. |
1792 | break; |
1793 | case TargetOpcode::DBG_LABEL: |
1794 | if (isVerbose()) { |
1795 | if (!emitDebugLabelComment(MI: &MI, AP&: *this)) |
1796 | emitInstruction(&MI); |
1797 | } |
1798 | break; |
1799 | case TargetOpcode::IMPLICIT_DEF: |
1800 | if (isVerbose()) emitImplicitDef(MI: &MI); |
1801 | break; |
1802 | case TargetOpcode::KILL: |
1803 | if (isVerbose()) emitKill(MI: &MI, AP&: *this); |
1804 | break; |
1805 | case TargetOpcode::PSEUDO_PROBE: |
1806 | emitPseudoProbe(MI); |
1807 | break; |
1808 | case TargetOpcode::ARITH_FENCE: |
1809 | if (isVerbose()) |
1810 | OutStreamer->emitRawComment(T: "ARITH_FENCE" ); |
1811 | break; |
1812 | case TargetOpcode::MEMBARRIER: |
1813 | OutStreamer->emitRawComment(T: "MEMBARRIER" ); |
1814 | break; |
1815 | case TargetOpcode::JUMP_TABLE_DEBUG_INFO: |
1816 | // This instruction is only used to note jump table debug info, it's |
1817 | // purely meta information. |
1818 | break; |
1819 | default: |
1820 | emitInstruction(&MI); |
1821 | if (CanDoExtraAnalysis) { |
1822 | MCInst MCI; |
1823 | MCI.setOpcode(MI.getOpcode()); |
1824 | auto Name = OutStreamer->getMnemonic(MI&: MCI); |
1825 | auto I = MnemonicCounts.insert(KV: {Name, 0u}); |
1826 | I.first->second++; |
1827 | } |
1828 | break; |
1829 | } |
1830 | |
1831 | // If there is a post-instruction symbol, emit a label for it here. |
1832 | if (MCSymbol *S = MI.getPostInstrSymbol()) |
1833 | OutStreamer->emitLabel(Symbol: S); |
1834 | |
1835 | for (auto &Handler : DebugHandlers) |
1836 | Handler->endInstruction(); |
1837 | } |
1838 | |
1839 | // We must emit temporary symbol for the end of this basic block, if either |
1840 | // we have BBLabels enabled or if this basic blocks marks the end of a |
1841 | // section. |
1842 | if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap || |
1843 | (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection())) |
1844 | OutStreamer->emitLabel(Symbol: MBB.getEndSymbol()); |
1845 | |
1846 | if (MBB.isEndSection()) { |
1847 | // The size directive for the section containing the entry block is |
1848 | // handled separately by the function section. |
1849 | if (!MBB.sameSection(MBB: &MF->front())) { |
1850 | if (MAI->hasDotTypeDotSizeDirective()) { |
1851 | // Emit the size directive for the basic block section. |
1852 | const MCExpr *SizeExp = MCBinaryExpr::createSub( |
1853 | LHS: MCSymbolRefExpr::create(Symbol: MBB.getEndSymbol(), Ctx&: OutContext), |
1854 | RHS: MCSymbolRefExpr::create(Symbol: CurrentSectionBeginSym, Ctx&: OutContext), |
1855 | Ctx&: OutContext); |
1856 | OutStreamer->emitELFSize(Symbol: CurrentSectionBeginSym, Value: SizeExp); |
1857 | } |
1858 | assert(!MBBSectionRanges.contains(MBB.getSectionID()) && |
1859 | "Overwrite section range" ); |
1860 | MBBSectionRanges[MBB.getSectionID()] = |
1861 | MBBSectionRange{.BeginLabel: CurrentSectionBeginSym, .EndLabel: MBB.getEndSymbol()}; |
1862 | } |
1863 | } |
1864 | emitBasicBlockEnd(MBB); |
1865 | |
1866 | if (CanDoExtraAnalysis) { |
1867 | // Skip empty blocks. |
1868 | if (MBB.empty()) |
1869 | continue; |
1870 | |
1871 | MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix" , |
1872 | MBB.begin()->getDebugLoc(), &MBB); |
1873 | |
1874 | // Generate instruction mix remark. First, sort counts in descending order |
1875 | // by count and name. |
1876 | SmallVector<std::pair<StringRef, unsigned>, 128> MnemonicVec; |
1877 | for (auto &KV : MnemonicCounts) |
1878 | MnemonicVec.emplace_back(Args&: KV.first, Args&: KV.second); |
1879 | |
1880 | sort(C&: MnemonicVec, Comp: [](const std::pair<StringRef, unsigned> &A, |
1881 | const std::pair<StringRef, unsigned> &B) { |
1882 | if (A.second > B.second) |
1883 | return true; |
1884 | if (A.second == B.second) |
1885 | return StringRef(A.first) < StringRef(B.first); |
1886 | return false; |
1887 | }); |
1888 | R << "BasicBlock: " << ore::NV("BasicBlock" , MBB.getName()) << "\n" ; |
1889 | for (auto &KV : MnemonicVec) { |
1890 | auto Name = (Twine("INST_" ) + getToken(Source: KV.first.trim()).first).str(); |
1891 | R << KV.first << ": " << ore::NV(Name, KV.second) << "\n" ; |
1892 | } |
1893 | ORE->emit(OptDiag&: R); |
1894 | } |
1895 | } |
1896 | |
1897 | EmittedInsts += NumInstsInFunction; |
1898 | MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount" , |
1899 | MF->getFunction().getSubprogram(), |
1900 | &MF->front()); |
1901 | R << ore::NV("NumInstructions" , NumInstsInFunction) |
1902 | << " instructions in function" ; |
1903 | ORE->emit(OptDiag&: R); |
1904 | |
1905 | // If the function is empty and the object file uses .subsections_via_symbols, |
1906 | // then we need to emit *something* to the function body to prevent the |
1907 | // labels from collapsing together. Just emit a noop. |
1908 | // Similarly, don't emit empty functions on Windows either. It can lead to |
1909 | // duplicate entries (two functions with the same RVA) in the Guard CF Table |
1910 | // after linking, causing the kernel not to load the binary: |
1911 | // https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html |
1912 | // FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer. |
1913 | const Triple &TT = TM.getTargetTriple(); |
1914 | if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() || |
1915 | (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) { |
1916 | MCInst Noop = MF->getSubtarget().getInstrInfo()->getNop(); |
1917 | |
1918 | // Targets can opt-out of emitting the noop here by leaving the opcode |
1919 | // unspecified. |
1920 | if (Noop.getOpcode()) { |
1921 | OutStreamer->AddComment(T: "avoids zero-length function" ); |
1922 | emitNops(N: 1); |
1923 | } |
1924 | } |
1925 | |
1926 | // Switch to the original section in case basic block sections was used. |
1927 | OutStreamer->switchSection(Section: MF->getSection()); |
1928 | |
1929 | const Function &F = MF->getFunction(); |
1930 | for (const auto &BB : F) { |
1931 | if (!BB.hasAddressTaken()) |
1932 | continue; |
1933 | MCSymbol *Sym = GetBlockAddressSymbol(BB: &BB); |
1934 | if (Sym->isDefined()) |
1935 | continue; |
1936 | OutStreamer->AddComment(T: "Address of block that was removed by CodeGen" ); |
1937 | OutStreamer->emitLabel(Symbol: Sym); |
1938 | } |
1939 | |
1940 | // Emit target-specific gunk after the function body. |
1941 | emitFunctionBodyEnd(); |
1942 | |
1943 | // Even though wasm supports .type and .size in general, function symbols |
1944 | // are automatically sized. |
1945 | bool EmitFunctionSize = MAI->hasDotTypeDotSizeDirective() && !TT.isWasm(); |
1946 | |
1947 | if (needFuncLabels(MF: *MF, MMI: *MMI) || EmitFunctionSize) { |
1948 | // Create a symbol for the end of function. |
1949 | CurrentFnEnd = createTempSymbol(Name: "func_end" ); |
1950 | OutStreamer->emitLabel(Symbol: CurrentFnEnd); |
1951 | } |
1952 | |
1953 | // If the target wants a .size directive for the size of the function, emit |
1954 | // it. |
1955 | if (EmitFunctionSize) { |
1956 | // We can get the size as difference between the function label and the |
1957 | // temp label. |
1958 | const MCExpr *SizeExp = MCBinaryExpr::createSub( |
1959 | LHS: MCSymbolRefExpr::create(Symbol: CurrentFnEnd, Ctx&: OutContext), |
1960 | RHS: MCSymbolRefExpr::create(Symbol: CurrentFnSymForSize, Ctx&: OutContext), Ctx&: OutContext); |
1961 | OutStreamer->emitELFSize(Symbol: CurrentFnSym, Value: SizeExp); |
1962 | if (CurrentFnBeginLocal) |
1963 | OutStreamer->emitELFSize(Symbol: CurrentFnBeginLocal, Value: SizeExp); |
1964 | } |
1965 | |
1966 | // Call endBasicBlockSection on the last block now, if it wasn't already |
1967 | // called. |
1968 | if (!MF->back().isEndSection()) { |
1969 | for (auto &Handler : DebugHandlers) |
1970 | Handler->endBasicBlockSection(MBB: MF->back()); |
1971 | for (auto &Handler : Handlers) |
1972 | Handler->endBasicBlockSection(MBB: MF->back()); |
1973 | } |
1974 | for (auto &Handler : Handlers) |
1975 | Handler->markFunctionEnd(); |
1976 | |
1977 | assert(!MBBSectionRanges.contains(MF->front().getSectionID()) && |
1978 | "Overwrite section range" ); |
1979 | MBBSectionRanges[MF->front().getSectionID()] = |
1980 | MBBSectionRange{.BeginLabel: CurrentFnBegin, .EndLabel: CurrentFnEnd}; |
1981 | |
1982 | // Print out jump tables referenced by the function. |
1983 | emitJumpTableInfo(); |
1984 | |
1985 | // Emit post-function debug and/or EH information. |
1986 | for (auto &Handler : DebugHandlers) |
1987 | Handler->endFunction(MF); |
1988 | for (auto &Handler : Handlers) |
1989 | Handler->endFunction(MF); |
1990 | |
1991 | // Emit section containing BB address offsets and their metadata, when |
1992 | // BB labels are requested for this function. Skip empty functions. |
1993 | if (HasAnyRealCode) { |
1994 | if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap) |
1995 | emitBBAddrMapSection(MF: *MF); |
1996 | else if (PgoAnalysisMapFeatures.getBits() != 0) |
1997 | MF->getContext().reportWarning( |
1998 | L: SMLoc(), Msg: "pgo-analysis-map is enabled for function " + MF->getName() + |
1999 | " but it does not have labels" ); |
2000 | } |
2001 | |
2002 | // Emit sections containing instruction and function PCs. |
2003 | emitPCSections(MF: *MF); |
2004 | |
2005 | // Emit section containing stack size metadata. |
2006 | emitStackSizeSection(MF: *MF); |
2007 | |
2008 | // Emit .su file containing function stack size information. |
2009 | emitStackUsage(MF: *MF); |
2010 | |
2011 | emitPatchableFunctionEntries(); |
2012 | |
2013 | if (isVerbose()) |
2014 | OutStreamer->getCommentOS() << "-- End function\n" ; |
2015 | |
2016 | OutStreamer->addBlankLine(); |
2017 | } |
2018 | |
2019 | /// Compute the number of Global Variables that uses a Constant. |
2020 | static unsigned getNumGlobalVariableUses(const Constant *C) { |
2021 | if (!C) |
2022 | return 0; |
2023 | |
2024 | if (isa<GlobalVariable>(Val: C)) |
2025 | return 1; |
2026 | |
2027 | unsigned NumUses = 0; |
2028 | for (const auto *CU : C->users()) |
2029 | NumUses += getNumGlobalVariableUses(C: dyn_cast<Constant>(Val: CU)); |
2030 | |
2031 | return NumUses; |
2032 | } |
2033 | |
2034 | /// Only consider global GOT equivalents if at least one user is a |
2035 | /// cstexpr inside an initializer of another global variables. Also, don't |
2036 | /// handle cstexpr inside instructions. During global variable emission, |
2037 | /// candidates are skipped and are emitted later in case at least one cstexpr |
2038 | /// isn't replaced by a PC relative GOT entry access. |
2039 | static bool isGOTEquivalentCandidate(const GlobalVariable *GV, |
2040 | unsigned &NumGOTEquivUsers) { |
2041 | // Global GOT equivalents are unnamed private globals with a constant |
2042 | // pointer initializer to another global symbol. They must point to a |
2043 | // GlobalVariable or Function, i.e., as GlobalValue. |
2044 | if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || |
2045 | !GV->isConstant() || !GV->isDiscardableIfUnused() || |
2046 | !isa<GlobalValue>(Val: GV->getOperand(i_nocapture: 0))) |
2047 | return false; |
2048 | |
2049 | // To be a got equivalent, at least one of its users need to be a constant |
2050 | // expression used by another global variable. |
2051 | for (const auto *U : GV->users()) |
2052 | NumGOTEquivUsers += getNumGlobalVariableUses(C: dyn_cast<Constant>(Val: U)); |
2053 | |
2054 | return NumGOTEquivUsers > 0; |
2055 | } |
2056 | |
2057 | /// Unnamed constant global variables solely contaning a pointer to |
2058 | /// another globals variable is equivalent to a GOT table entry; it contains the |
2059 | /// the address of another symbol. Optimize it and replace accesses to these |
2060 | /// "GOT equivalents" by using the GOT entry for the final global instead. |
2061 | /// Compute GOT equivalent candidates among all global variables to avoid |
2062 | /// emitting them if possible later on, after it use is replaced by a GOT entry |
2063 | /// access. |
2064 | void AsmPrinter::computeGlobalGOTEquivs(Module &M) { |
2065 | if (!getObjFileLowering().supportIndirectSymViaGOTPCRel()) |
2066 | return; |
2067 | |
2068 | for (const auto &G : M.globals()) { |
2069 | unsigned NumGOTEquivUsers = 0; |
2070 | if (!isGOTEquivalentCandidate(GV: &G, NumGOTEquivUsers)) |
2071 | continue; |
2072 | |
2073 | const MCSymbol *GOTEquivSym = getSymbol(GV: &G); |
2074 | GlobalGOTEquivs[GOTEquivSym] = std::make_pair(x: &G, y&: NumGOTEquivUsers); |
2075 | } |
2076 | } |
2077 | |
2078 | /// Constant expressions using GOT equivalent globals may not be eligible |
2079 | /// for PC relative GOT entry conversion, in such cases we need to emit such |
2080 | /// globals we previously omitted in EmitGlobalVariable. |
2081 | void AsmPrinter::emitGlobalGOTEquivs() { |
2082 | if (!getObjFileLowering().supportIndirectSymViaGOTPCRel()) |
2083 | return; |
2084 | |
2085 | SmallVector<const GlobalVariable *, 8> FailedCandidates; |
2086 | for (auto &I : GlobalGOTEquivs) { |
2087 | const GlobalVariable *GV = I.second.first; |
2088 | unsigned Cnt = I.second.second; |
2089 | if (Cnt) |
2090 | FailedCandidates.push_back(Elt: GV); |
2091 | } |
2092 | GlobalGOTEquivs.clear(); |
2093 | |
2094 | for (const auto *GV : FailedCandidates) |
2095 | emitGlobalVariable(GV); |
2096 | } |
2097 | |
2098 | void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) { |
2099 | MCSymbol *Name = getSymbol(GV: &GA); |
2100 | bool IsFunction = GA.getValueType()->isFunctionTy(); |
2101 | // Treat bitcasts of functions as functions also. This is important at least |
2102 | // on WebAssembly where object and function addresses can't alias each other. |
2103 | if (!IsFunction) |
2104 | IsFunction = isa<Function>(Val: GA.getAliasee()->stripPointerCasts()); |
2105 | |
2106 | // AIX's assembly directive `.set` is not usable for aliasing purpose, |
2107 | // so AIX has to use the extra-label-at-definition strategy. At this |
2108 | // point, all the extra label is emitted, we just have to emit linkage for |
2109 | // those labels. |
2110 | if (TM.getTargetTriple().isOSBinFormatXCOFF()) { |
2111 | assert(MAI->hasVisibilityOnlyWithLinkage() && |
2112 | "Visibility should be handled with emitLinkage() on AIX." ); |
2113 | |
2114 | // Linkage for alias of global variable has been emitted. |
2115 | if (isa<GlobalVariable>(Val: GA.getAliaseeObject())) |
2116 | return; |
2117 | |
2118 | emitLinkage(GV: &GA, GVSym: Name); |
2119 | // If it's a function, also emit linkage for aliases of function entry |
2120 | // point. |
2121 | if (IsFunction) |
2122 | emitLinkage(GV: &GA, |
2123 | GVSym: getObjFileLowering().getFunctionEntryPointSymbol(Func: &GA, TM)); |
2124 | return; |
2125 | } |
2126 | |
2127 | if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
2128 | OutStreamer->emitSymbolAttribute(Symbol: Name, Attribute: MCSA_Global); |
2129 | else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage()) |
2130 | OutStreamer->emitSymbolAttribute(Symbol: Name, Attribute: MCSA_WeakReference); |
2131 | else |
2132 | assert(GA.hasLocalLinkage() && "Invalid alias linkage" ); |
2133 | |
2134 | // Set the symbol type to function if the alias has a function type. |
2135 | // This affects codegen when the aliasee is not a function. |
2136 | if (IsFunction) { |
2137 | OutStreamer->emitSymbolAttribute(Symbol: Name, Attribute: MCSA_ELF_TypeFunction); |
2138 | if (TM.getTargetTriple().isOSBinFormatCOFF()) { |
2139 | OutStreamer->beginCOFFSymbolDef(Symbol: Name); |
2140 | OutStreamer->emitCOFFSymbolStorageClass( |
2141 | StorageClass: GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC |
2142 | : COFF::IMAGE_SYM_CLASS_EXTERNAL); |
2143 | OutStreamer->emitCOFFSymbolType(Type: COFF::IMAGE_SYM_DTYPE_FUNCTION |
2144 | << COFF::SCT_COMPLEX_TYPE_SHIFT); |
2145 | OutStreamer->endCOFFSymbolDef(); |
2146 | } |
2147 | } |
2148 | |
2149 | emitVisibility(Sym: Name, Visibility: GA.getVisibility()); |
2150 | |
2151 | const MCExpr *Expr = lowerConstant(CV: GA.getAliasee()); |
2152 | |
2153 | if (MAI->hasAltEntry() && isa<MCBinaryExpr>(Val: Expr)) |
2154 | OutStreamer->emitSymbolAttribute(Symbol: Name, Attribute: MCSA_AltEntry); |
2155 | |
2156 | // Emit the directives as assignments aka .set: |
2157 | OutStreamer->emitAssignment(Symbol: Name, Value: Expr); |
2158 | MCSymbol *LocalAlias = getSymbolPreferLocal(GV: GA); |
2159 | if (LocalAlias != Name) |
2160 | OutStreamer->emitAssignment(Symbol: LocalAlias, Value: Expr); |
2161 | |
2162 | // If the aliasee does not correspond to a symbol in the output, i.e. the |
2163 | // alias is not of an object or the aliased object is private, then set the |
2164 | // size of the alias symbol from the type of the alias. We don't do this in |
2165 | // other situations as the alias and aliasee having differing types but same |
2166 | // size may be intentional. |
2167 | const GlobalObject *BaseObject = GA.getAliaseeObject(); |
2168 | if (MAI->hasDotTypeDotSizeDirective() && GA.getValueType()->isSized() && |
2169 | (!BaseObject || BaseObject->hasPrivateLinkage())) { |
2170 | const DataLayout &DL = M.getDataLayout(); |
2171 | uint64_t Size = DL.getTypeAllocSize(Ty: GA.getValueType()); |
2172 | OutStreamer->emitELFSize(Symbol: Name, Value: MCConstantExpr::create(Value: Size, Ctx&: OutContext)); |
2173 | } |
2174 | } |
2175 | |
2176 | void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) { |
2177 | assert(!TM.getTargetTriple().isOSBinFormatXCOFF() && |
2178 | "IFunc is not supported on AIX." ); |
2179 | |
2180 | auto EmitLinkage = [&](MCSymbol *Sym) { |
2181 | if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective()) |
2182 | OutStreamer->emitSymbolAttribute(Symbol: Sym, Attribute: MCSA_Global); |
2183 | else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage()) |
2184 | OutStreamer->emitSymbolAttribute(Symbol: Sym, Attribute: MCSA_WeakReference); |
2185 | else |
2186 | assert(GI.hasLocalLinkage() && "Invalid ifunc linkage" ); |
2187 | }; |
2188 | |
2189 | if (TM.getTargetTriple().isOSBinFormatELF()) { |
2190 | MCSymbol *Name = getSymbol(GV: &GI); |
2191 | EmitLinkage(Name); |
2192 | OutStreamer->emitSymbolAttribute(Symbol: Name, Attribute: MCSA_ELF_TypeIndFunction); |
2193 | emitVisibility(Sym: Name, Visibility: GI.getVisibility()); |
2194 | |
2195 | // Emit the directives as assignments aka .set: |
2196 | const MCExpr *Expr = lowerConstant(CV: GI.getResolver()); |
2197 | OutStreamer->emitAssignment(Symbol: Name, Value: Expr); |
2198 | MCSymbol *LocalAlias = getSymbolPreferLocal(GV: GI); |
2199 | if (LocalAlias != Name) |
2200 | OutStreamer->emitAssignment(Symbol: LocalAlias, Value: Expr); |
2201 | |
2202 | return; |
2203 | } |
2204 | |
2205 | if (!TM.getTargetTriple().isOSBinFormatMachO() || !getIFuncMCSubtargetInfo()) |
2206 | llvm::report_fatal_error(reason: "IFuncs are not supported on this platform" ); |
2207 | |
2208 | // On Darwin platforms, emit a manually-constructed .symbol_resolver that |
2209 | // implements the symbol resolution duties of the IFunc. |
2210 | // |
2211 | // Normally, this would be handled by linker magic, but unfortunately there |
2212 | // are a few limitations in ld64 and ld-prime's implementation of |
2213 | // .symbol_resolver that mean we can't always use them: |
2214 | // |
2215 | // * resolvers cannot be the target of an alias |
2216 | // * resolvers cannot have private linkage |
2217 | // * resolvers cannot have linkonce linkage |
2218 | // * resolvers cannot appear in executables |
2219 | // * resolvers cannot appear in bundles |
2220 | // |
2221 | // This works around that by emitting a close approximation of what the |
2222 | // linker would have done. |
2223 | |
2224 | MCSymbol *LazyPointer = |
2225 | GetExternalSymbolSymbol(Sym: GI.getName() + ".lazy_pointer" ); |
2226 | MCSymbol *StubHelper = GetExternalSymbolSymbol(Sym: GI.getName() + ".stub_helper" ); |
2227 | |
2228 | OutStreamer->switchSection(Section: OutContext.getObjectFileInfo()->getDataSection()); |
2229 | |
2230 | const DataLayout &DL = M.getDataLayout(); |
2231 | emitAlignment(Alignment: Align(DL.getPointerSize())); |
2232 | OutStreamer->emitLabel(Symbol: LazyPointer); |
2233 | emitVisibility(Sym: LazyPointer, Visibility: GI.getVisibility()); |
2234 | OutStreamer->emitValue(Value: MCSymbolRefExpr::create(Symbol: StubHelper, Ctx&: OutContext), Size: 8); |
2235 | |
2236 | OutStreamer->switchSection(Section: OutContext.getObjectFileInfo()->getTextSection()); |
2237 | |
2238 | const TargetSubtargetInfo *STI = |
2239 | TM.getSubtargetImpl(*GI.getResolverFunction()); |
2240 | const TargetLowering *TLI = STI->getTargetLowering(); |
2241 | Align TextAlign(TLI->getMinFunctionAlignment()); |
2242 | |
2243 | MCSymbol *Stub = getSymbol(GV: &GI); |
2244 | EmitLinkage(Stub); |
2245 | OutStreamer->emitCodeAlignment(Alignment: TextAlign, STI: getIFuncMCSubtargetInfo()); |
2246 | OutStreamer->emitLabel(Symbol: Stub); |
2247 | emitVisibility(Sym: Stub, Visibility: GI.getVisibility()); |
2248 | emitMachOIFuncStubBody(M, GI, LazyPointer); |
2249 | |
2250 | OutStreamer->emitCodeAlignment(Alignment: TextAlign, STI: getIFuncMCSubtargetInfo()); |
2251 | OutStreamer->emitLabel(Symbol: StubHelper); |
2252 | emitVisibility(Sym: StubHelper, Visibility: GI.getVisibility()); |
2253 | emitMachOIFuncStubHelperBody(M, GI, LazyPointer); |
2254 | } |
2255 | |
2256 | void AsmPrinter::(remarks::RemarkStreamer &RS) { |
2257 | if (!RS.needsSection()) |
2258 | return; |
2259 | |
2260 | remarks::RemarkSerializer & = RS.getSerializer(); |
2261 | |
2262 | std::optional<SmallString<128>> Filename; |
2263 | if (std::optional<StringRef> FilenameRef = RS.getFilename()) { |
2264 | Filename = *FilenameRef; |
2265 | sys::fs::make_absolute(path&: *Filename); |
2266 | assert(!Filename->empty() && "The filename can't be empty." ); |
2267 | } |
2268 | |
2269 | std::string Buf; |
2270 | raw_string_ostream OS(Buf); |
2271 | std::unique_ptr<remarks::MetaSerializer> MetaSerializer = |
2272 | Filename ? RemarkSerializer.metaSerializer(OS, ExternalFilename: Filename->str()) |
2273 | : RemarkSerializer.metaSerializer(OS); |
2274 | MetaSerializer->emit(); |
2275 | |
2276 | // Switch to the remarks section. |
2277 | MCSection * = |
2278 | OutContext.getObjectFileInfo()->getRemarksSection(); |
2279 | OutStreamer->switchSection(Section: RemarksSection); |
2280 | |
2281 | OutStreamer->emitBinaryData(Data: Buf); |
2282 | } |
2283 | |
2284 | bool AsmPrinter::doFinalization(Module &M) { |
2285 | // Set the MachineFunction to nullptr so that we can catch attempted |
2286 | // accesses to MF specific features at the module level and so that |
2287 | // we can conditionalize accesses based on whether or not it is nullptr. |
2288 | MF = nullptr; |
2289 | |
2290 | // Gather all GOT equivalent globals in the module. We really need two |
2291 | // passes over the globals: one to compute and another to avoid its emission |
2292 | // in EmitGlobalVariable, otherwise we would not be able to handle cases |
2293 | // where the got equivalent shows up before its use. |
2294 | computeGlobalGOTEquivs(M); |
2295 | |
2296 | // Emit global variables. |
2297 | for (const auto &G : M.globals()) |
2298 | emitGlobalVariable(GV: &G); |
2299 | |
2300 | // Emit remaining GOT equivalent globals. |
2301 | emitGlobalGOTEquivs(); |
2302 | |
2303 | const TargetLoweringObjectFile &TLOF = getObjFileLowering(); |
2304 | |
2305 | // Emit linkage(XCOFF) and visibility info for declarations |
2306 | for (const Function &F : M) { |
2307 | if (!F.isDeclarationForLinker()) |
2308 | continue; |
2309 | |
2310 | MCSymbol *Name = getSymbol(GV: &F); |
2311 | // Function getSymbol gives us the function descriptor symbol for XCOFF. |
2312 | |
2313 | if (!TM.getTargetTriple().isOSBinFormatXCOFF()) { |
2314 | GlobalValue::VisibilityTypes V = F.getVisibility(); |
2315 | if (V == GlobalValue::DefaultVisibility) |
2316 | continue; |
2317 | |
2318 | emitVisibility(Sym: Name, Visibility: V, IsDefinition: false); |
2319 | continue; |
2320 | } |
2321 | |
2322 | if (F.isIntrinsic()) |
2323 | continue; |
2324 | |
2325 | // Handle the XCOFF case. |
2326 | // Variable `Name` is the function descriptor symbol (see above). Get the |
2327 | // function entry point symbol. |
2328 | MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(Func: &F, TM); |
2329 | // Emit linkage for the function entry point. |
2330 | emitLinkage(GV: &F, GVSym: FnEntryPointSym); |
2331 | |
2332 | // If a function's address is taken, which means it may be called via a |
2333 | // function pointer, we need the function descriptor for it. |
2334 | if (F.hasAddressTaken()) |
2335 | emitLinkage(GV: &F, GVSym: Name); |
2336 | } |
2337 | |
2338 | // Emit the remarks section contents. |
2339 | // FIXME: Figure out when is the safest time to emit this section. It should |
2340 | // not come after debug info. |
2341 | if (remarks::RemarkStreamer *RS = M.getContext().getMainRemarkStreamer()) |
2342 | emitRemarksSection(RS&: *RS); |
2343 | |
2344 | TLOF.emitModuleMetadata(Streamer&: *OutStreamer, M); |
2345 | |
2346 | if (TM.getTargetTriple().isOSBinFormatELF()) { |
2347 | MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); |
2348 | |
2349 | // Output stubs for external and common global variables. |
2350 | MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); |
2351 | if (!Stubs.empty()) { |
2352 | OutStreamer->switchSection(Section: TLOF.getDataSection()); |
2353 | const DataLayout &DL = M.getDataLayout(); |
2354 | |
2355 | emitAlignment(Alignment: Align(DL.getPointerSize())); |
2356 | for (const auto &Stub : Stubs) { |
2357 | OutStreamer->emitLabel(Symbol: Stub.first); |
2358 | OutStreamer->emitSymbolValue(Sym: Stub.second.getPointer(), |
2359 | Size: DL.getPointerSize()); |
2360 | } |
2361 | } |
2362 | } |
2363 | |
2364 | if (TM.getTargetTriple().isOSBinFormatCOFF()) { |
2365 | MachineModuleInfoCOFF &MMICOFF = |
2366 | MMI->getObjFileInfo<MachineModuleInfoCOFF>(); |
2367 | |
2368 | // Output stubs for external and common global variables. |
2369 | MachineModuleInfoCOFF::SymbolListTy Stubs = MMICOFF.GetGVStubList(); |
2370 | if (!Stubs.empty()) { |
2371 | const DataLayout &DL = M.getDataLayout(); |
2372 | |
2373 | for (const auto &Stub : Stubs) { |
2374 | SmallString<256> SectionName = StringRef(".rdata$" ); |
2375 | SectionName += Stub.first->getName(); |
2376 | OutStreamer->switchSection(Section: OutContext.getCOFFSection( |
2377 | Section: SectionName, |
2378 | Characteristics: COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | |
2379 | COFF::IMAGE_SCN_LNK_COMDAT, |
2380 | COMDATSymName: Stub.first->getName(), Selection: COFF::IMAGE_COMDAT_SELECT_ANY)); |
2381 | emitAlignment(Alignment: Align(DL.getPointerSize())); |
2382 | OutStreamer->emitSymbolAttribute(Symbol: Stub.first, Attribute: MCSA_Global); |
2383 | OutStreamer->emitLabel(Symbol: Stub.first); |
2384 | OutStreamer->emitSymbolValue(Sym: Stub.second.getPointer(), |
2385 | Size: DL.getPointerSize()); |
2386 | } |
2387 | } |
2388 | } |
2389 | |
2390 | // This needs to happen before emitting debug information since that can end |
2391 | // arbitrary sections. |
2392 | if (auto *TS = OutStreamer->getTargetStreamer()) |
2393 | TS->emitConstantPools(); |
2394 | |
2395 | // Emit Stack maps before any debug info. Mach-O requires that no data or |
2396 | // text sections come after debug info has been emitted. This matters for |
2397 | // stack maps as they are arbitrary data, and may even have a custom format |
2398 | // through user plugins. |
2399 | emitStackMaps(); |
2400 | |
2401 | // Print aliases in topological order, that is, for each alias a = b, |
2402 | // b must be printed before a. |
2403 | // This is because on some targets (e.g. PowerPC) linker expects aliases in |
2404 | // such an order to generate correct TOC information. |
2405 | SmallVector<const GlobalAlias *, 16> AliasStack; |
2406 | SmallPtrSet<const GlobalAlias *, 16> AliasVisited; |
2407 | for (const auto &Alias : M.aliases()) { |
2408 | if (Alias.hasAvailableExternallyLinkage()) |
2409 | continue; |
2410 | for (const GlobalAlias *Cur = &Alias; Cur; |
2411 | Cur = dyn_cast<GlobalAlias>(Val: Cur->getAliasee())) { |
2412 | if (!AliasVisited.insert(Ptr: Cur).second) |
2413 | break; |
2414 | AliasStack.push_back(Elt: Cur); |
2415 | } |
2416 | for (const GlobalAlias *AncestorAlias : llvm::reverse(C&: AliasStack)) |
2417 | emitGlobalAlias(M, GA: *AncestorAlias); |
2418 | AliasStack.clear(); |
2419 | } |
2420 | |
2421 | // IFuncs must come before deubginfo in case the backend decides to emit them |
2422 | // as actual functions, since on Mach-O targets, we cannot create regular |
2423 | // sections after DWARF. |
2424 | for (const auto &IFunc : M.ifuncs()) |
2425 | emitGlobalIFunc(M, GI: IFunc); |
2426 | |
2427 | // Finalize debug and EH information. |
2428 | for (auto &Handler : DebugHandlers) |
2429 | Handler->endModule(); |
2430 | for (auto &Handler : Handlers) |
2431 | Handler->endModule(); |
2432 | |
2433 | // This deletes all the ephemeral handlers that AsmPrinter added, while |
2434 | // keeping all the user-added handlers alive until the AsmPrinter is |
2435 | // destroyed. |
2436 | Handlers.erase(CS: Handlers.begin() + NumUserHandlers, CE: Handlers.end()); |
2437 | DebugHandlers.erase(CS: DebugHandlers.begin() + NumUserDebugHandlers, |
2438 | CE: DebugHandlers.end()); |
2439 | DD = nullptr; |
2440 | |
2441 | // If the target wants to know about weak references, print them all. |
2442 | if (MAI->getWeakRefDirective()) { |
2443 | // FIXME: This is not lazy, it would be nice to only print weak references |
2444 | // to stuff that is actually used. Note that doing so would require targets |
2445 | // to notice uses in operands (due to constant exprs etc). This should |
2446 | // happen with the MC stuff eventually. |
2447 | |
2448 | // Print out module-level global objects here. |
2449 | for (const auto &GO : M.global_objects()) { |
2450 | if (!GO.hasExternalWeakLinkage()) |
2451 | continue; |
2452 | OutStreamer->emitSymbolAttribute(Symbol: getSymbol(GV: &GO), Attribute: MCSA_WeakReference); |
2453 | } |
2454 | if (shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()) { |
2455 | auto SymbolName = "swift_async_extendedFramePointerFlags" ; |
2456 | auto Global = M.getGlobalVariable(Name: SymbolName); |
2457 | if (!Global) { |
2458 | auto Int8PtrTy = PointerType::getUnqual(C&: M.getContext()); |
2459 | Global = new GlobalVariable(M, Int8PtrTy, false, |
2460 | GlobalValue::ExternalWeakLinkage, nullptr, |
2461 | SymbolName); |
2462 | OutStreamer->emitSymbolAttribute(Symbol: getSymbol(GV: Global), Attribute: MCSA_WeakReference); |
2463 | } |
2464 | } |
2465 | } |
2466 | |
2467 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); |
2468 | assert(MI && "AsmPrinter didn't require GCModuleInfo?" ); |
2469 | for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) |
2470 | if (GCMetadataPrinter *MP = getOrCreateGCPrinter(S&: **--I)) |
2471 | MP->finishAssembly(M, Info&: *MI, AP&: *this); |
2472 | |
2473 | // Emit llvm.ident metadata in an '.ident' directive. |
2474 | emitModuleIdents(M); |
2475 | |
2476 | // Emit bytes for llvm.commandline metadata. |
2477 | // The command line metadata is emitted earlier on XCOFF. |
2478 | if (!TM.getTargetTriple().isOSBinFormatXCOFF()) |
2479 | emitModuleCommandLines(M); |
2480 | |
2481 | // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if |
2482 | // split-stack is used. |
2483 | if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) { |
2484 | OutStreamer->switchSection(Section: OutContext.getELFSection(Section: ".note.GNU-split-stack" , |
2485 | Type: ELF::SHT_PROGBITS, Flags: 0)); |
2486 | if (HasNoSplitStack) |
2487 | OutStreamer->switchSection(Section: OutContext.getELFSection( |
2488 | Section: ".note.GNU-no-split-stack" , Type: ELF::SHT_PROGBITS, Flags: 0)); |
2489 | } |
2490 | |
2491 | // If we don't have any trampolines, then we don't require stack memory |
2492 | // to be executable. Some targets have a directive to declare this. |
2493 | Function *InitTrampolineIntrinsic = M.getFunction(Name: "llvm.init.trampoline" ); |
2494 | if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) |
2495 | if (MCSection *S = MAI->getNonexecutableStackSection(Ctx&: OutContext)) |
2496 | OutStreamer->switchSection(Section: S); |
2497 | |
2498 | if (TM.Options.EmitAddrsig) { |
2499 | // Emit address-significance attributes for all globals. |
2500 | OutStreamer->emitAddrsig(); |
2501 | for (const GlobalValue &GV : M.global_values()) { |
2502 | if (!GV.use_empty() && !GV.isThreadLocal() && |
2503 | !GV.hasDLLImportStorageClass() && |
2504 | !GV.getName().starts_with(Prefix: "llvm." ) && |
2505 | !GV.hasAtLeastLocalUnnamedAddr()) |
2506 | OutStreamer->emitAddrsigSym(Sym: getSymbol(GV: &GV)); |
2507 | } |
2508 | } |
2509 | |
2510 | // Emit symbol partition specifications (ELF only). |
2511 | if (TM.getTargetTriple().isOSBinFormatELF()) { |
2512 | unsigned UniqueID = 0; |
2513 | for (const GlobalValue &GV : M.global_values()) { |
2514 | if (!GV.hasPartition() || GV.isDeclarationForLinker() || |
2515 | GV.getVisibility() != GlobalValue::DefaultVisibility) |
2516 | continue; |
2517 | |
2518 | OutStreamer->switchSection( |
2519 | Section: OutContext.getELFSection(Section: ".llvm_sympart" , Type: ELF::SHT_LLVM_SYMPART, Flags: 0, EntrySize: 0, |
2520 | Group: "" , IsComdat: false, UniqueID: ++UniqueID, LinkedToSym: nullptr)); |
2521 | OutStreamer->emitBytes(Data: GV.getPartition()); |
2522 | OutStreamer->emitZeros(NumBytes: 1); |
2523 | OutStreamer->emitValue( |
2524 | Value: MCSymbolRefExpr::create(Symbol: getSymbol(GV: &GV), Ctx&: OutContext), |
2525 | Size: MAI->getCodePointerSize()); |
2526 | } |
2527 | } |
2528 | |
2529 | // Allow the target to emit any magic that it wants at the end of the file, |
2530 | // after everything else has gone out. |
2531 | emitEndOfAsmFile(M); |
2532 | |
2533 | MMI = nullptr; |
2534 | AddrLabelSymbols = nullptr; |
2535 | |
2536 | OutStreamer->finish(); |
2537 | OutStreamer->reset(); |
2538 | OwnedMLI.reset(); |
2539 | OwnedMDT.reset(); |
2540 | |
2541 | return false; |
2542 | } |
2543 | |
2544 | MCSymbol *AsmPrinter::getMBBExceptionSym(const MachineBasicBlock &MBB) { |
2545 | auto Res = MBBSectionExceptionSyms.try_emplace(Key: MBB.getSectionID()); |
2546 | if (Res.second) |
2547 | Res.first->second = createTempSymbol(Name: "exception" ); |
2548 | return Res.first->second; |
2549 | } |
2550 | |
2551 | void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { |
2552 | this->MF = &MF; |
2553 | const Function &F = MF.getFunction(); |
2554 | |
2555 | // Record that there are split-stack functions, so we will emit a special |
2556 | // section to tell the linker. |
2557 | if (MF.shouldSplitStack()) { |
2558 | HasSplitStack = true; |
2559 | |
2560 | if (!MF.getFrameInfo().needsSplitStackProlog()) |
2561 | HasNoSplitStack = true; |
2562 | } else |
2563 | HasNoSplitStack = true; |
2564 | |
2565 | // Get the function symbol. |
2566 | if (!MAI->needsFunctionDescriptors()) { |
2567 | CurrentFnSym = getSymbol(GV: &MF.getFunction()); |
2568 | } else { |
2569 | assert(TM.getTargetTriple().isOSAIX() && |
2570 | "Only AIX uses the function descriptor hooks." ); |
2571 | // AIX is unique here in that the name of the symbol emitted for the |
2572 | // function body does not have the same name as the source function's |
2573 | // C-linkage name. |
2574 | assert(CurrentFnDescSym && "The function descriptor symbol needs to be" |
2575 | " initalized first." ); |
2576 | |
2577 | // Get the function entry point symbol. |
2578 | CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(Func: &F, TM); |
2579 | } |
2580 | |
2581 | CurrentFnSymForSize = CurrentFnSym; |
2582 | CurrentFnBegin = nullptr; |
2583 | CurrentFnBeginLocal = nullptr; |
2584 | CurrentSectionBeginSym = nullptr; |
2585 | MBBSectionRanges.clear(); |
2586 | MBBSectionExceptionSyms.clear(); |
2587 | bool NeedsLocalForSize = MAI->needsLocalForSize(); |
2588 | if (F.hasFnAttribute(Kind: "patchable-function-entry" ) || |
2589 | F.hasFnAttribute(Kind: "function-instrument" ) || |
2590 | F.hasFnAttribute(Kind: "xray-instruction-threshold" ) || |
2591 | needFuncLabels(MF, MMI: *MMI) || NeedsLocalForSize || |
2592 | MF.getTarget().Options.EmitStackSizeSection || |
2593 | MF.getTarget().Options.BBAddrMap || MF.hasBBLabels()) { |
2594 | CurrentFnBegin = createTempSymbol(Name: "func_begin" ); |
2595 | if (NeedsLocalForSize) |
2596 | CurrentFnSymForSize = CurrentFnBegin; |
2597 | } |
2598 | |
2599 | ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE(); |
2600 | } |
2601 | |
2602 | namespace { |
2603 | |
2604 | // Keep track the alignment, constpool entries per Section. |
2605 | struct SectionCPs { |
2606 | MCSection *S; |
2607 | Align Alignment; |
2608 | SmallVector<unsigned, 4> CPEs; |
2609 | |
2610 | SectionCPs(MCSection *s, Align a) : S(s), Alignment(a) {} |
2611 | }; |
2612 | |
2613 | } // end anonymous namespace |
2614 | |
2615 | /// EmitConstantPool - Print to the current output stream assembly |
2616 | /// representations of the constants in the constant pool MCP. This is |
2617 | /// used to print out constants which have been "spilled to memory" by |
2618 | /// the code generator. |
2619 | void AsmPrinter::emitConstantPool() { |
2620 | const MachineConstantPool *MCP = MF->getConstantPool(); |
2621 | const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants(); |
2622 | if (CP.empty()) return; |
2623 | |
2624 | // Calculate sections for constant pool entries. We collect entries to go into |
2625 | // the same section together to reduce amount of section switch statements. |
2626 | SmallVector<SectionCPs, 4> CPSections; |
2627 | for (unsigned i = 0, e = CP.size(); i != e; ++i) { |
2628 | const MachineConstantPoolEntry &CPE = CP[i]; |
2629 | Align Alignment = CPE.getAlign(); |
2630 | |
2631 | SectionKind Kind = CPE.getSectionKind(DL: &getDataLayout()); |
2632 | |
2633 | const Constant *C = nullptr; |
2634 | if (!CPE.isMachineConstantPoolEntry()) |
2635 | C = CPE.Val.ConstVal; |
2636 | |
2637 | MCSection *S = getObjFileLowering().getSectionForConstant( |
2638 | DL: getDataLayout(), Kind, C, Alignment); |
2639 | |
2640 | // The number of sections are small, just do a linear search from the |
2641 | // last section to the first. |
2642 | bool Found = false; |
2643 | unsigned SecIdx = CPSections.size(); |
2644 | while (SecIdx != 0) { |
2645 | if (CPSections[--SecIdx].S == S) { |
2646 | Found = true; |
2647 | break; |
2648 | } |
2649 | } |
2650 | if (!Found) { |
2651 | SecIdx = CPSections.size(); |
2652 | CPSections.push_back(Elt: SectionCPs(S, Alignment)); |
2653 | } |
2654 | |
2655 | if (Alignment > CPSections[SecIdx].Alignment) |
2656 | CPSections[SecIdx].Alignment = Alignment; |
2657 | CPSections[SecIdx].CPEs.push_back(Elt: i); |
2658 | } |
2659 | |
2660 | // Now print stuff into the calculated sections. |
2661 | const MCSection *CurSection = nullptr; |
2662 | unsigned Offset = 0; |
2663 | for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { |
2664 | for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { |
2665 | unsigned CPI = CPSections[i].CPEs[j]; |
2666 | MCSymbol *Sym = GetCPISymbol(CPID: CPI); |
2667 | if (!Sym->isUndefined()) |
2668 | continue; |
2669 | |
2670 | if (CurSection != CPSections[i].S) { |
2671 | OutStreamer->switchSection(Section: CPSections[i].S); |
2672 | emitAlignment(Alignment: Align(CPSections[i].Alignment)); |
2673 | CurSection = CPSections[i].S; |
2674 | Offset = 0; |
2675 | } |
2676 | |
2677 | MachineConstantPoolEntry CPE = CP[CPI]; |
2678 | |
2679 | // Emit inter-object padding for alignment. |
2680 | unsigned NewOffset = alignTo(Size: Offset, A: CPE.getAlign()); |
2681 | OutStreamer->emitZeros(NumBytes: NewOffset - Offset); |
2682 | |
2683 | Offset = NewOffset + CPE.getSizeInBytes(DL: getDataLayout()); |
2684 | |
2685 | OutStreamer->emitLabel(Symbol: Sym); |
2686 | if (CPE.isMachineConstantPoolEntry()) |
2687 | emitMachineConstantPoolValue(MCPV: CPE.Val.MachineCPVal); |
2688 | else |
2689 | emitGlobalConstant(DL: getDataLayout(), CV: CPE.Val.ConstVal); |
2690 | } |
2691 | } |
2692 | } |
2693 | |
2694 | // Print assembly representations of the jump tables used by the current |
2695 | // function. |
2696 | void AsmPrinter::emitJumpTableInfo() { |
2697 | const DataLayout &DL = MF->getDataLayout(); |
2698 | const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); |
2699 | if (!MJTI) return; |
2700 | if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; |
2701 | const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); |
2702 | if (JT.empty()) return; |
2703 | |
2704 | // Pick the directive to use to print the jump table entries, and switch to |
2705 | // the appropriate section. |
2706 | const Function &F = MF->getFunction(); |
2707 | const TargetLoweringObjectFile &TLOF = getObjFileLowering(); |
2708 | bool JTInDiffSection = !TLOF.shouldPutJumpTableInFunctionSection( |
2709 | UsesLabelDifference: MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 || |
2710 | MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference64, |
2711 | F); |
2712 | if (JTInDiffSection) { |
2713 | // Drop it in the readonly section. |
2714 | MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM); |
2715 | OutStreamer->switchSection(Section: ReadOnlySection); |
2716 | } |
2717 | |
2718 | emitAlignment(Alignment: Align(MJTI->getEntryAlignment(TD: DL))); |
2719 | |
2720 | // Jump tables in code sections are marked with a data_region directive |
2721 | // where that's supported. |
2722 | if (!JTInDiffSection) |
2723 | OutStreamer->emitDataRegion(Kind: MCDR_DataRegionJT32); |
2724 | |
2725 | for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { |
2726 | const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; |
2727 | |
2728 | // If this jump table was deleted, ignore it. |
2729 | if (JTBBs.empty()) continue; |
2730 | |
2731 | // For the EK_LabelDifference32 entry, if using .set avoids a relocation, |
2732 | /// emit a .set directive for each unique entry. |
2733 | if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && |
2734 | MAI->doesSetDirectiveSuppressReloc()) { |
2735 | SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets; |
2736 | const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); |
2737 | const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,Ctx&: OutContext); |
2738 | for (const MachineBasicBlock *MBB : JTBBs) { |
2739 | if (!EmittedSets.insert(Ptr: MBB).second) |
2740 | continue; |
2741 | |
2742 | // .set LJTSet, LBB32-base |
2743 | const MCExpr *LHS = |
2744 | MCSymbolRefExpr::create(Symbol: MBB->getSymbol(), Ctx&: OutContext); |
2745 | OutStreamer->emitAssignment(Symbol: GetJTSetSymbol(UID: JTI, MBBID: MBB->getNumber()), |
2746 | Value: MCBinaryExpr::createSub(LHS, RHS: Base, |
2747 | Ctx&: OutContext)); |
2748 | } |
2749 | } |
2750 | |
2751 | // On some targets (e.g. Darwin) we want to emit two consecutive labels |
2752 | // before each jump table. The first label is never referenced, but tells |
2753 | // the assembler and linker the extents of the jump table object. The |
2754 | // second label is actually referenced by the code. |
2755 | if (JTInDiffSection && DL.hasLinkerPrivateGlobalPrefix()) |
2756 | // FIXME: This doesn't have to have any specific name, just any randomly |
2757 | // named and numbered local label started with 'l' would work. Simplify |
2758 | // GetJTISymbol. |
2759 | OutStreamer->emitLabel(Symbol: GetJTISymbol(JTID: JTI, isLinkerPrivate: true)); |
2760 | |
2761 | MCSymbol* JTISymbol = GetJTISymbol(JTID: JTI); |
2762 | OutStreamer->emitLabel(Symbol: JTISymbol); |
2763 | |
2764 | // Defer MCAssembler based constant folding due to a performance issue. The |
2765 | // label differences will be evaluated at write time. |
2766 | for (const MachineBasicBlock *MBB : JTBBs) |
2767 | emitJumpTableEntry(MJTI, MBB, uid: JTI); |
2768 | } |
2769 | if (!JTInDiffSection) |
2770 | OutStreamer->emitDataRegion(Kind: MCDR_DataRegionEnd); |
2771 | } |
2772 | |
2773 | /// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the |
2774 | /// current stream. |
2775 | void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI, |
2776 | const MachineBasicBlock *MBB, |
2777 | unsigned UID) const { |
2778 | assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block" ); |
2779 | const MCExpr *Value = nullptr; |
2780 | switch (MJTI->getEntryKind()) { |
2781 | case MachineJumpTableInfo::EK_Inline: |
2782 | llvm_unreachable("Cannot emit EK_Inline jump table entry" ); |
2783 | case MachineJumpTableInfo::EK_Custom32: |
2784 | Value = MF->getSubtarget().getTargetLowering()->LowerCustomJumpTableEntry( |
2785 | MJTI, MBB, UID, OutContext); |
2786 | break; |
2787 | case MachineJumpTableInfo::EK_BlockAddress: |
2788 | // EK_BlockAddress - Each entry is a plain address of block, e.g.: |
2789 | // .word LBB123 |
2790 | Value = MCSymbolRefExpr::create(Symbol: MBB->getSymbol(), Ctx&: OutContext); |
2791 | break; |
2792 | case MachineJumpTableInfo::EK_GPRel32BlockAddress: { |
2793 | // EK_GPRel32BlockAddress - Each entry is an address of block, encoded |
2794 | // with a relocation as gp-relative, e.g.: |
2795 | // .gprel32 LBB123 |
2796 | MCSymbol *MBBSym = MBB->getSymbol(); |
2797 | OutStreamer->emitGPRel32Value(Value: MCSymbolRefExpr::create(Symbol: MBBSym, Ctx&: OutContext)); |
2798 | return; |
2799 | } |
2800 | |
2801 | case MachineJumpTableInfo::EK_GPRel64BlockAddress: { |
2802 | // EK_GPRel64BlockAddress - Each entry is an address of block, encoded |
2803 | // with a relocation as gp-relative, e.g.: |
2804 | // .gpdword LBB123 |
2805 | MCSymbol *MBBSym = MBB->getSymbol(); |
2806 | OutStreamer->emitGPRel64Value(Value: MCSymbolRefExpr::create(Symbol: MBBSym, Ctx&: OutContext)); |
2807 | return; |
2808 | } |
2809 | |
2810 | case MachineJumpTableInfo::EK_LabelDifference32: |
2811 | case MachineJumpTableInfo::EK_LabelDifference64: { |
2812 | // Each entry is the address of the block minus the address of the jump |
2813 | // table. This is used for PIC jump tables where gprel32 is not supported. |
2814 | // e.g.: |
2815 | // .word LBB123 - LJTI1_2 |
2816 | // If the .set directive avoids relocations, this is emitted as: |
2817 | // .set L4_5_set_123, LBB123 - LJTI1_2 |
2818 | // .word L4_5_set_123 |
2819 | if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 && |
2820 | MAI->doesSetDirectiveSuppressReloc()) { |
2821 | Value = MCSymbolRefExpr::create(Symbol: GetJTSetSymbol(UID, MBBID: MBB->getNumber()), |
2822 | Ctx&: OutContext); |
2823 | break; |
2824 | } |
2825 | Value = MCSymbolRefExpr::create(Symbol: MBB->getSymbol(), Ctx&: OutContext); |
2826 | const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); |
2827 | const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF, JTI: UID, Ctx&: OutContext); |
2828 | Value = MCBinaryExpr::createSub(LHS: Value, RHS: Base, Ctx&: OutContext); |
2829 | break; |
2830 | } |
2831 | } |
2832 | |
2833 | assert(Value && "Unknown entry kind!" ); |
2834 | |
2835 | unsigned EntrySize = MJTI->getEntrySize(TD: getDataLayout()); |
2836 | OutStreamer->emitValue(Value, Size: EntrySize); |
2837 | } |
2838 | |
2839 | /// EmitSpecialLLVMGlobal - Check to see if the specified global is a |
2840 | /// special global used by LLVM. If so, emit it and return true, otherwise |
2841 | /// do nothing and return false. |
2842 | bool AsmPrinter::emitSpecialLLVMGlobal(const GlobalVariable *GV) { |
2843 | if (GV->getName() == "llvm.used" ) { |
2844 | if (MAI->hasNoDeadStrip()) // No need to emit this at all. |
2845 | emitLLVMUsedList(InitList: cast<ConstantArray>(Val: GV->getInitializer())); |
2846 | return true; |
2847 | } |
2848 | |
2849 | // Ignore debug and non-emitted data. This handles llvm.compiler.used. |
2850 | if (GV->getSection() == "llvm.metadata" || |
2851 | GV->hasAvailableExternallyLinkage()) |
2852 | return true; |
2853 | |
2854 | if (GV->getName() == "llvm.arm64ec.symbolmap" ) { |
2855 | // For ARM64EC, print the table that maps between symbols and the |
2856 | // corresponding thunks to translate between x64 and AArch64 code. |
2857 | // This table is generated by AArch64Arm64ECCallLowering. |
2858 | OutStreamer->switchSection( |
2859 | Section: OutContext.getCOFFSection(Section: ".hybmp$x" , Characteristics: COFF::IMAGE_SCN_LNK_INFO)); |
2860 | auto *Arr = cast<ConstantArray>(Val: GV->getInitializer()); |
2861 | for (auto &U : Arr->operands()) { |
2862 | auto *C = cast<Constant>(Val: U); |
2863 | auto *Src = cast<GlobalValue>(Val: C->getOperand(i: 0)->stripPointerCasts()); |
2864 | auto *Dst = cast<GlobalValue>(Val: C->getOperand(i: 1)->stripPointerCasts()); |
2865 | int Kind = cast<ConstantInt>(Val: C->getOperand(i: 2))->getZExtValue(); |
2866 | |
2867 | if (Src->hasDLLImportStorageClass()) { |
2868 | // For now, we assume dllimport functions aren't directly called. |
2869 | // (We might change this later to match MSVC.) |
2870 | OutStreamer->emitCOFFSymbolIndex( |
2871 | Symbol: OutContext.getOrCreateSymbol(Name: "__imp_" + Src->getName())); |
2872 | OutStreamer->emitCOFFSymbolIndex(Symbol: getSymbol(GV: Dst)); |
2873 | OutStreamer->emitInt32(Value: Kind); |
2874 | } else { |
2875 | // FIXME: For non-dllimport functions, MSVC emits the same entry |
2876 | // twice, for reasons I don't understand. I have to assume the linker |
2877 | // ignores the redundant entry; there aren't any reasonable semantics |
2878 | // to attach to it. |
2879 | OutStreamer->emitCOFFSymbolIndex(Symbol: getSymbol(GV: Src)); |
2880 | OutStreamer->emitCOFFSymbolIndex(Symbol: getSymbol(GV: Dst)); |
2881 | OutStreamer->emitInt32(Value: Kind); |
2882 | } |
2883 | } |
2884 | return true; |
2885 | } |
2886 | |
2887 | if (!GV->hasAppendingLinkage()) return false; |
2888 | |
2889 | assert(GV->hasInitializer() && "Not a special LLVM global!" ); |
2890 | |
2891 | if (GV->getName() == "llvm.global_ctors" ) { |
2892 | emitXXStructorList(DL: GV->getDataLayout(), List: GV->getInitializer(), |
2893 | /* isCtor */ IsCtor: true); |
2894 | |
2895 | return true; |
2896 | } |
2897 | |
2898 | if (GV->getName() == "llvm.global_dtors" ) { |
2899 | emitXXStructorList(DL: GV->getDataLayout(), List: GV->getInitializer(), |
2900 | /* isCtor */ IsCtor: false); |
2901 | |
2902 | return true; |
2903 | } |
2904 | |
2905 | report_fatal_error(reason: "unknown special variable with appending linkage" ); |
2906 | } |
2907 | |
2908 | /// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each |
2909 | /// global in the specified llvm.used list. |
2910 | void AsmPrinter::emitLLVMUsedList(const ConstantArray *InitList) { |
2911 | // Should be an array of 'i8*'. |
2912 | for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { |
2913 | const GlobalValue *GV = |
2914 | dyn_cast<GlobalValue>(Val: InitList->getOperand(i_nocapture: i)->stripPointerCasts()); |
2915 | if (GV) |
2916 | OutStreamer->emitSymbolAttribute(Symbol: getSymbol(GV), Attribute: MCSA_NoDeadStrip); |
2917 | } |
2918 | } |
2919 | |
2920 | void AsmPrinter::preprocessXXStructorList(const DataLayout &DL, |
2921 | const Constant *List, |
2922 | SmallVector<Structor, 8> &Structors) { |
2923 | // Should be an array of '{ i32, void ()*, i8* }' structs. The first value is |
2924 | // the init priority. |
2925 | if (!isa<ConstantArray>(Val: List)) |
2926 | return; |
2927 | |
2928 | // Gather the structors in a form that's convenient for sorting by priority. |
2929 | for (Value *O : cast<ConstantArray>(Val: List)->operands()) { |
2930 | auto *CS = cast<ConstantStruct>(Val: O); |
2931 | if (CS->getOperand(i_nocapture: 1)->isNullValue()) |
2932 | break; // Found a null terminator, skip the rest. |
2933 | ConstantInt *Priority = dyn_cast<ConstantInt>(Val: CS->getOperand(i_nocapture: 0)); |
2934 | if (!Priority) |
2935 | continue; // Malformed. |
2936 | Structors.push_back(Elt: Structor()); |
2937 | Structor &S = Structors.back(); |
2938 | S.Priority = Priority->getLimitedValue(Limit: 65535); |
2939 | S.Func = CS->getOperand(i_nocapture: 1); |
2940 | if (!CS->getOperand(i_nocapture: 2)->isNullValue()) { |
2941 | if (TM.getTargetTriple().isOSAIX()) |
2942 | llvm::report_fatal_error( |
2943 | reason: "associated data of XXStructor list is not yet supported on AIX" ); |
2944 | S.ComdatKey = |
2945 | dyn_cast<GlobalValue>(Val: CS->getOperand(i_nocapture: 2)->stripPointerCasts()); |
2946 | } |
2947 | } |
2948 | |
2949 | // Emit the function pointers in the target-specific order |
2950 | llvm::stable_sort(Range&: Structors, C: [](const Structor &L, const Structor &R) { |
2951 | return L.Priority < R.Priority; |
2952 | }); |
2953 | } |
2954 | |
2955 | /// EmitXXStructorList - Emit the ctor or dtor list taking into account the init |
2956 | /// priority. |
2957 | void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List, |
2958 | bool IsCtor) { |
2959 | SmallVector<Structor, 8> Structors; |
2960 | preprocessXXStructorList(DL, List, Structors); |
2961 | if (Structors.empty()) |
2962 | return; |
2963 | |
2964 | // Emit the structors in reverse order if we are using the .ctor/.dtor |
2965 | // initialization scheme. |
2966 | if (!TM.Options.UseInitArray) |
2967 | std::reverse(first: Structors.begin(), last: Structors.end()); |
2968 | |
2969 | const Align Align = DL.getPointerPrefAlignment(); |
2970 | for (Structor &S : Structors) { |
2971 | const TargetLoweringObjectFile &Obj = getObjFileLowering(); |
2972 | const MCSymbol *KeySym = nullptr; |
2973 | if (GlobalValue *GV = S.ComdatKey) { |
2974 | if (GV->isDeclarationForLinker()) |
2975 | // If the associated variable is not defined in this module |
2976 | // (it might be available_externally, or have been an |
2977 | // available_externally definition that was dropped by the |
2978 | // EliminateAvailableExternally pass), some other TU |
2979 | // will provide its dynamic initializer. |
2980 | continue; |
2981 | |
2982 | KeySym = getSymbol(GV); |
2983 | } |
2984 | |
2985 | MCSection *OutputSection = |
2986 | (IsCtor ? Obj.getStaticCtorSection(Priority: S.Priority, KeySym) |
2987 | : Obj.getStaticDtorSection(Priority: S.Priority, KeySym)); |
2988 | OutStreamer->switchSection(Section: OutputSection); |
2989 | if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection()) |
2990 | emitAlignment(Alignment: Align); |
2991 | emitXXStructor(DL, CV: S.Func); |
2992 | } |
2993 | } |
2994 | |
2995 | void AsmPrinter::emitModuleIdents(Module &M) { |
2996 | if (!MAI->hasIdentDirective()) |
2997 | return; |
2998 | |
2999 | if (const NamedMDNode *NMD = M.getNamedMetadata(Name: "llvm.ident" )) { |
3000 | for (const MDNode *N : NMD->operands()) { |
3001 | assert(N->getNumOperands() == 1 && |
3002 | "llvm.ident metadata entry can have only one operand" ); |
3003 | const MDString *S = cast<MDString>(Val: N->getOperand(I: 0)); |
3004 | OutStreamer->emitIdent(IdentString: S->getString()); |
3005 | } |
3006 | } |
3007 | } |
3008 | |
3009 | void AsmPrinter::emitModuleCommandLines(Module &M) { |
3010 | MCSection *CommandLine = getObjFileLowering().getSectionForCommandLines(); |
3011 | if (!CommandLine) |
3012 | return; |
3013 | |
3014 | const NamedMDNode *NMD = M.getNamedMetadata(Name: "llvm.commandline" ); |
3015 | if (!NMD || !NMD->getNumOperands()) |
3016 | return; |
3017 | |
3018 | OutStreamer->pushSection(); |
3019 | OutStreamer->switchSection(Section: CommandLine); |
3020 | OutStreamer->emitZeros(NumBytes: 1); |
3021 | for (const MDNode *N : NMD->operands()) { |
3022 | assert(N->getNumOperands() == 1 && |
3023 | "llvm.commandline metadata entry can have only one operand" ); |
3024 | const MDString *S = cast<MDString>(Val: N->getOperand(I: 0)); |
3025 | OutStreamer->emitBytes(Data: S->getString()); |
3026 | OutStreamer->emitZeros(NumBytes: 1); |
3027 | } |
3028 | OutStreamer->popSection(); |
3029 | } |
3030 | |
3031 | //===--------------------------------------------------------------------===// |
3032 | // Emission and print routines |
3033 | // |
3034 | |
3035 | /// Emit a byte directive and value. |
3036 | /// |
3037 | void AsmPrinter::emitInt8(int Value) const { OutStreamer->emitInt8(Value); } |
3038 | |
3039 | /// Emit a short directive and value. |
3040 | void AsmPrinter::emitInt16(int Value) const { OutStreamer->emitInt16(Value); } |
3041 | |
3042 | /// Emit a long directive and value. |
3043 | void AsmPrinter::emitInt32(int Value) const { OutStreamer->emitInt32(Value); } |
3044 | |
3045 | /// EmitSLEB128 - emit the specified signed leb128 value. |
3046 | void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const { |
3047 | if (isVerbose() && Desc) |
3048 | OutStreamer->AddComment(T: Desc); |
3049 | |
3050 | OutStreamer->emitSLEB128IntValue(Value); |
3051 | } |
3052 | |
3053 | void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc, |
3054 | unsigned PadTo) const { |
3055 | if (isVerbose() && Desc) |
3056 | OutStreamer->AddComment(T: Desc); |
3057 | |
3058 | OutStreamer->emitULEB128IntValue(Value, PadTo); |
3059 | } |
3060 | |
3061 | /// Emit a long long directive and value. |
3062 | void AsmPrinter::emitInt64(uint64_t Value) const { |
3063 | OutStreamer->emitInt64(Value); |
3064 | } |
3065 | |
3066 | /// Emit something like ".long Hi-Lo" where the size in bytes of the directive |
3067 | /// is specified by Size and Hi/Lo specify the labels. This implicitly uses |
3068 | /// .set if it avoids relocations. |
3069 | void AsmPrinter::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, |
3070 | unsigned Size) const { |
3071 | OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size); |
3072 | } |
3073 | |
3074 | /// Emit something like ".uleb128 Hi-Lo". |
3075 | void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi, |
3076 | const MCSymbol *Lo) const { |
3077 | OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); |
3078 | } |
3079 | |
3080 | /// EmitLabelPlusOffset - Emit something like ".long Label+Offset" |
3081 | /// where the size in bytes of the directive is specified by Size and Label |
3082 | /// specifies the label. This implicitly uses .set if it is available. |
3083 | void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, |
3084 | unsigned Size, |
3085 | bool IsSectionRelative) const { |
3086 | if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) { |
3087 | OutStreamer->emitCOFFSecRel32(Symbol: Label, Offset); |
3088 | if (Size > 4) |
3089 | OutStreamer->emitZeros(NumBytes: Size - 4); |
3090 | return; |
3091 | } |
3092 | |
3093 | // Emit Label+Offset (or just Label if Offset is zero) |
3094 | const MCExpr *Expr = MCSymbolRefExpr::create(Symbol: Label, Ctx&: OutContext); |
3095 | if (Offset) |
3096 | Expr = MCBinaryExpr::createAdd( |
3097 | LHS: Expr, RHS: MCConstantExpr::create(Value: Offset, Ctx&: OutContext), Ctx&: OutContext); |
3098 | |
3099 | OutStreamer->emitValue(Value: Expr, Size); |
3100 | } |
3101 | |
3102 | //===----------------------------------------------------------------------===// |
3103 | |
3104 | // EmitAlignment - Emit an alignment directive to the specified power of |
3105 | // two boundary. If a global value is specified, and if that global has |
3106 | // an explicit alignment requested, it will override the alignment request |
3107 | // if required for correctness. |
3108 | void AsmPrinter::emitAlignment(Align Alignment, const GlobalObject *GV, |
3109 | unsigned MaxBytesToEmit) const { |
3110 | if (GV) |
3111 | Alignment = getGVAlignment(GV, DL: GV->getDataLayout(), InAlign: Alignment); |
3112 | |
3113 | if (Alignment == Align(1)) |
3114 | return; // 1-byte aligned: no need to emit alignment. |
3115 | |
3116 | if (getCurrentSection()->isText()) { |
3117 | const MCSubtargetInfo *STI = nullptr; |
3118 | if (this->MF) |
3119 | STI = &getSubtargetInfo(); |
3120 | else |
3121 | STI = TM.getMCSubtargetInfo(); |
3122 | OutStreamer->emitCodeAlignment(Alignment, STI, MaxBytesToEmit); |
3123 | } else |
3124 | OutStreamer->emitValueToAlignment(Alignment, Value: 0, ValueSize: 1, MaxBytesToEmit); |
3125 | } |
3126 | |
3127 | //===----------------------------------------------------------------------===// |
3128 | // Constant emission. |
3129 | //===----------------------------------------------------------------------===// |
3130 | |
3131 | const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) { |
3132 | MCContext &Ctx = OutContext; |
3133 | |
3134 | if (CV->isNullValue() || isa<UndefValue>(Val: CV)) |
3135 | return MCConstantExpr::create(Value: 0, Ctx); |
3136 | |
3137 | if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val: CV)) |
3138 | return MCConstantExpr::create(Value: CI->getZExtValue(), Ctx); |
3139 | |
3140 | if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(Val: CV)) |
3141 | return lowerConstantPtrAuth(CPA: *CPA); |
3142 | |
3143 | if (const GlobalValue *GV = dyn_cast<GlobalValue>(Val: CV)) |
3144 | return MCSymbolRefExpr::create(Symbol: getSymbol(GV), Ctx); |
3145 | |
3146 | if (const BlockAddress *BA = dyn_cast<BlockAddress>(Val: CV)) |
3147 | return lowerBlockAddressConstant(BA: *BA); |
3148 | |
3149 | if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(Val: CV)) |
3150 | return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM); |
3151 | |
3152 | if (const NoCFIValue *NC = dyn_cast<NoCFIValue>(Val: CV)) |
3153 | return MCSymbolRefExpr::create(Symbol: getSymbol(GV: NC->getGlobalValue()), Ctx); |
3154 | |
3155 | const ConstantExpr *CE = dyn_cast<ConstantExpr>(Val: CV); |
3156 | if (!CE) { |
3157 | llvm_unreachable("Unknown constant value to lower!" ); |
3158 | } |
3159 | |
3160 | // The constant expression opcodes are limited to those that are necessary |
3161 | // to represent relocations on supported targets. Expressions involving only |
3162 | // constant addresses are constant folded instead. |
3163 | switch (CE->getOpcode()) { |
3164 | default: |
3165 | break; // Error |
3166 | case Instruction::AddrSpaceCast: { |
3167 | const Constant *Op = CE->getOperand(i_nocapture: 0); |
3168 | unsigned DstAS = CE->getType()->getPointerAddressSpace(); |
3169 | unsigned SrcAS = Op->getType()->getPointerAddressSpace(); |
3170 | if (TM.isNoopAddrSpaceCast(SrcAS, DestAS: DstAS)) |
3171 | return lowerConstant(CV: Op); |
3172 | |
3173 | break; // Error |
3174 | } |
3175 | case Instruction::GetElementPtr: { |
3176 | // Generate a symbolic expression for the byte address |
3177 | APInt OffsetAI(getDataLayout().getPointerTypeSizeInBits(CE->getType()), 0); |
3178 | cast<GEPOperator>(Val: CE)->accumulateConstantOffset(DL: getDataLayout(), Offset&: OffsetAI); |
3179 | |
3180 | const MCExpr *Base = lowerConstant(CV: CE->getOperand(i_nocapture: 0)); |
3181 | if (!OffsetAI) |
3182 | return Base; |
3183 | |
3184 | int64_t Offset = OffsetAI.getSExtValue(); |
3185 | return MCBinaryExpr::createAdd(LHS: Base, RHS: MCConstantExpr::create(Value: Offset, Ctx), |
3186 | Ctx); |
3187 | } |
3188 | |
3189 | case Instruction::Trunc: |
3190 | // We emit the value and depend on the assembler to truncate the generated |
3191 | // expression properly. This is important for differences between |
3192 | // blockaddress labels. Since the two labels are in the same function, it |
3193 | // is reasonable to treat their delta as a 32-bit value. |
3194 | [[fallthrough]]; |
3195 | case Instruction::BitCast: |
3196 | return lowerConstant(CV: CE->getOperand(i_nocapture: 0)); |
3197 | |
3198 | case Instruction::IntToPtr: { |
3199 | const DataLayout &DL = getDataLayout(); |
3200 | |
3201 | // Handle casts to pointers by changing them into casts to the appropriate |
3202 | // integer type. This promotes constant folding and simplifies this code. |
3203 | Constant *Op = CE->getOperand(i_nocapture: 0); |
3204 | Op = ConstantFoldIntegerCast(C: Op, DestTy: DL.getIntPtrType(CV->getType()), |
3205 | /*IsSigned*/ false, DL); |
3206 | if (Op) |
3207 | return lowerConstant(CV: Op); |
3208 | |
3209 | break; // Error |
3210 | } |
3211 | |
3212 | case Instruction::PtrToInt: { |
3213 | const DataLayout &DL = getDataLayout(); |
3214 | |
3215 | // Support only foldable casts to/from pointers that can be eliminated by |
3216 | // changing the pointer to the appropriately sized integer type. |
3217 | Constant *Op = CE->getOperand(i_nocapture: 0); |
3218 | Type *Ty = CE->getType(); |
3219 | |
3220 | const MCExpr *OpExpr = lowerConstant(CV: Op); |
3221 | |
3222 | // We can emit the pointer value into this slot if the slot is an |
3223 | // integer slot equal to the size of the pointer. |
3224 | // |
3225 | // If the pointer is larger than the resultant integer, then |
3226 | // as with Trunc just depend on the assembler to truncate it. |
3227 | if (DL.getTypeAllocSize(Ty).getFixedValue() <= |
3228 | DL.getTypeAllocSize(Ty: Op->getType()).getFixedValue()) |
3229 | return OpExpr; |
3230 | |
3231 | break; // Error |
3232 | } |
3233 | |
3234 | case Instruction::Sub: { |
3235 | GlobalValue *LHSGV; |
3236 | APInt LHSOffset; |
3237 | DSOLocalEquivalent *DSOEquiv; |
3238 | if (IsConstantOffsetFromGlobal(C: CE->getOperand(i_nocapture: 0), GV&: LHSGV, Offset&: LHSOffset, |
3239 | DL: getDataLayout(), DSOEquiv: &DSOEquiv)) { |
3240 | GlobalValue *RHSGV; |
3241 | APInt RHSOffset; |
3242 | if (IsConstantOffsetFromGlobal(C: CE->getOperand(i_nocapture: 1), GV&: RHSGV, Offset&: RHSOffset, |
3243 | DL: getDataLayout())) { |
3244 | const MCExpr *RelocExpr = |
3245 | getObjFileLowering().lowerRelativeReference(LHS: LHSGV, RHS: RHSGV, TM); |
3246 | if (!RelocExpr) { |
3247 | const MCExpr *LHSExpr = |
3248 | MCSymbolRefExpr::create(Symbol: getSymbol(GV: LHSGV), Ctx); |
3249 | if (DSOEquiv && |
3250 | getObjFileLowering().supportDSOLocalEquivalentLowering()) |
3251 | LHSExpr = |
3252 | getObjFileLowering().lowerDSOLocalEquivalent(Equiv: DSOEquiv, TM); |
3253 | RelocExpr = MCBinaryExpr::createSub( |
3254 | LHS: LHSExpr, RHS: MCSymbolRefExpr::create(Symbol: getSymbol(GV: RHSGV), Ctx), Ctx); |
3255 | } |
3256 | int64_t Addend = (LHSOffset - RHSOffset).getSExtValue(); |
3257 | if (Addend != 0) |
3258 | RelocExpr = MCBinaryExpr::createAdd( |
3259 | LHS: RelocExpr, RHS: MCConstantExpr::create(Value: Addend, Ctx), Ctx); |
3260 | return RelocExpr; |
3261 | } |
3262 | } |
3263 | |
3264 | const MCExpr *LHS = lowerConstant(CV: CE->getOperand(i_nocapture: 0)); |
3265 | const MCExpr *RHS = lowerConstant(CV: CE->getOperand(i_nocapture: 1)); |
3266 | return MCBinaryExpr::createSub(LHS, RHS, Ctx); |
3267 | break; |
3268 | } |
3269 | |
3270 | case Instruction::Add: { |
3271 | const MCExpr *LHS = lowerConstant(CV: CE->getOperand(i_nocapture: 0)); |
3272 | const MCExpr *RHS = lowerConstant(CV: CE->getOperand(i_nocapture: 1)); |
3273 | return MCBinaryExpr::createAdd(LHS, RHS, Ctx); |
3274 | } |
3275 | } |
3276 | |
3277 | // If the code isn't optimized, there may be outstanding folding |
3278 | // opportunities. Attempt to fold the expression using DataLayout as a |
3279 | // last resort before giving up. |
3280 | Constant *C = ConstantFoldConstant(C: CE, DL: getDataLayout()); |
3281 | if (C != CE) |
3282 | return lowerConstant(CV: C); |
3283 | |
3284 | // Otherwise report the problem to the user. |
3285 | std::string S; |
3286 | raw_string_ostream OS(S); |
3287 | OS << "Unsupported expression in static initializer: " ; |
3288 | CE->printAsOperand(O&: OS, /*PrintType=*/false, |
3289 | M: !MF ? nullptr : MF->getFunction().getParent()); |
3290 | report_fatal_error(reason: Twine(S)); |
3291 | } |
3292 | |
3293 | static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *C, |
3294 | AsmPrinter &AP, |
3295 | const Constant *BaseCV = nullptr, |
3296 | uint64_t Offset = 0, |
3297 | AsmPrinter::AliasMapTy *AliasList = nullptr); |
3298 | |
3299 | static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP); |
3300 | static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP); |
3301 | |
3302 | /// isRepeatedByteSequence - Determine whether the given value is |
3303 | /// composed of a repeated sequence of identical bytes and return the |
3304 | /// byte value. If it is not a repeated sequence, return -1. |
3305 | static int isRepeatedByteSequence(const ConstantDataSequential *V) { |
3306 | StringRef Data = V->getRawDataValues(); |
3307 | assert(!Data.empty() && "Empty aggregates should be CAZ node" ); |
3308 | char C = Data[0]; |
3309 | for (unsigned i = 1, e = Data.size(); i != e; ++i) |
3310 | if (Data[i] != C) return -1; |
3311 | return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1. |
3312 | } |
3313 | |
3314 | /// isRepeatedByteSequence - Determine whether the given value is |
3315 | /// composed of a repeated sequence of identical bytes and return the |
3316 | /// byte value. If it is not a repeated sequence, return -1. |
3317 | static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) { |
3318 | if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val: V)) { |
3319 | uint64_t Size = DL.getTypeAllocSizeInBits(Ty: V->getType()); |
3320 | assert(Size % 8 == 0); |
3321 | |
3322 | // Extend the element to take zero padding into account. |
3323 | APInt Value = CI->getValue().zext(width: Size); |
3324 | if (!Value.isSplat(SplatSizeInBits: 8)) |
3325 | return -1; |
3326 | |
3327 | return Value.zextOrTrunc(width: 8).getZExtValue(); |
3328 | } |
3329 | if (const ConstantArray *CA = dyn_cast<ConstantArray>(Val: V)) { |
3330 | // Make sure all array elements are sequences of the same repeated |
3331 | // byte. |
3332 | assert(CA->getNumOperands() != 0 && "Should be a CAZ" ); |
3333 | Constant *Op0 = CA->getOperand(i_nocapture: 0); |
3334 | int Byte = isRepeatedByteSequence(V: Op0, DL); |
3335 | if (Byte == -1) |
3336 | return -1; |
3337 | |
3338 | // All array elements must be equal. |
3339 | for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) |
3340 | if (CA->getOperand(i_nocapture: i) != Op0) |
3341 | return -1; |
3342 | return Byte; |
3343 | } |
3344 | |
3345 | if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(Val: V)) |
3346 | return isRepeatedByteSequence(V: CDS); |
3347 | |
3348 | return -1; |
3349 | } |
3350 | |
3351 | static void emitGlobalAliasInline(AsmPrinter &AP, uint64_t Offset, |
3352 | AsmPrinter::AliasMapTy *AliasList) { |
3353 | if (AliasList) { |
3354 | auto AliasIt = AliasList->find(Val: Offset); |
3355 | if (AliasIt != AliasList->end()) { |
3356 | for (const GlobalAlias *GA : AliasIt->second) |
3357 | AP.OutStreamer->emitLabel(Symbol: AP.getSymbol(GV: GA)); |
3358 | AliasList->erase(Val: Offset); |
3359 | } |
3360 | } |
3361 | } |
3362 | |
3363 | static void emitGlobalConstantDataSequential( |
3364 | const DataLayout &DL, const ConstantDataSequential *CDS, AsmPrinter &AP, |
3365 | AsmPrinter::AliasMapTy *AliasList) { |
3366 | // See if we can aggregate this into a .fill, if so, emit it as such. |
3367 | int Value = isRepeatedByteSequence(V: CDS, DL); |
3368 | if (Value != -1) { |
3369 | uint64_t Bytes = DL.getTypeAllocSize(Ty: CDS->getType()); |
3370 | // Don't emit a 1-byte object as a .fill. |
3371 | if (Bytes > 1) |
3372 | return AP.OutStreamer->emitFill(NumBytes: Bytes, FillValue: Value); |
3373 | } |
3374 | |
3375 | // If this can be emitted with .ascii/.asciz, emit it as such. |
3376 | if (CDS->isString()) |
3377 | return AP.OutStreamer->emitBytes(Data: CDS->getAsString()); |
3378 | |
3379 | // Otherwise, emit the values in successive locations. |
3380 | unsigned ElementByteSize = CDS->getElementByteSize(); |
3381 | if (isa<IntegerType>(Val: CDS->getElementType())) { |
3382 | for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { |
3383 | emitGlobalAliasInline(AP, Offset: ElementByteSize * I, AliasList); |
3384 | if (AP.isVerbose()) |
3385 | AP.OutStreamer->getCommentOS() |
3386 | << format(Fmt: "0x%" PRIx64 "\n" , Vals: CDS->getElementAsInteger(i: I)); |
3387 | AP.OutStreamer->emitIntValue(Value: CDS->getElementAsInteger(i: I), |
3388 | Size: ElementByteSize); |
3389 | } |
3390 | } else { |
3391 | Type *ET = CDS->getElementType(); |
3392 | for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { |
3393 | emitGlobalAliasInline(AP, Offset: ElementByteSize * I, AliasList); |
3394 | emitGlobalConstantFP(APF: CDS->getElementAsAPFloat(i: I), ET, AP); |
3395 | } |
3396 | } |
3397 | |
3398 | unsigned Size = DL.getTypeAllocSize(Ty: CDS->getType()); |
3399 | unsigned EmittedSize = |
3400 | DL.getTypeAllocSize(Ty: CDS->getElementType()) * CDS->getNumElements(); |
3401 | assert(EmittedSize <= Size && "Size cannot be less than EmittedSize!" ); |
3402 | if (unsigned Padding = Size - EmittedSize) |
3403 | AP.OutStreamer->emitZeros(NumBytes: Padding); |
3404 | } |
3405 | |
3406 | static void emitGlobalConstantArray(const DataLayout &DL, |
3407 | const ConstantArray *CA, AsmPrinter &AP, |
3408 | const Constant *BaseCV, uint64_t Offset, |
3409 | AsmPrinter::AliasMapTy *AliasList) { |
3410 | // See if we can aggregate some values. Make sure it can be |
3411 | // represented as a series of bytes of the constant value. |
3412 | int Value = isRepeatedByteSequence(V: CA, DL); |
3413 | |
3414 | if (Value != -1) { |
3415 | uint64_t Bytes = DL.getTypeAllocSize(Ty: CA->getType()); |
3416 | AP.OutStreamer->emitFill(NumBytes: Bytes, FillValue: Value); |
3417 | } else { |
3418 | for (unsigned I = 0, E = CA->getNumOperands(); I != E; ++I) { |
3419 | emitGlobalConstantImpl(DL, C: CA->getOperand(i_nocapture: I), AP, BaseCV, Offset, |
3420 | AliasList); |
3421 | Offset += DL.getTypeAllocSize(Ty: CA->getOperand(i_nocapture: I)->getType()); |
3422 | } |
3423 | } |
3424 | } |
3425 | |
3426 | static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP); |
3427 | |
3428 | static void emitGlobalConstantVector(const DataLayout &DL, |
3429 | const ConstantVector *CV, AsmPrinter &AP, |
3430 | AsmPrinter::AliasMapTy *AliasList) { |
3431 | Type *ElementType = CV->getType()->getElementType(); |
3432 | uint64_t ElementSizeInBits = DL.getTypeSizeInBits(Ty: ElementType); |
3433 | uint64_t ElementAllocSizeInBits = DL.getTypeAllocSizeInBits(Ty: ElementType); |
3434 | uint64_t EmittedSize; |
3435 | if (ElementSizeInBits != ElementAllocSizeInBits) { |
3436 | // If the allocation size of an element is different from the size in bits, |
3437 | // printing each element separately will insert incorrect padding. |
3438 | // |
3439 | // The general algorithm here is complicated; instead of writing it out |
3440 | // here, just use the existing code in ConstantFolding. |
3441 | Type *IntT = |
3442 | IntegerType::get(C&: CV->getContext(), NumBits: DL.getTypeSizeInBits(Ty: CV->getType())); |
3443 | ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Val: ConstantFoldConstant( |
3444 | C: ConstantExpr::getBitCast(C: const_cast<ConstantVector *>(CV), Ty: IntT), DL)); |
3445 | if (!CI) { |
3446 | report_fatal_error( |
3447 | reason: "Cannot lower vector global with unusual element type" ); |
3448 | } |
3449 | emitGlobalAliasInline(AP, Offset: 0, AliasList); |
3450 | emitGlobalConstantLargeInt(CI, AP); |
3451 | EmittedSize = DL.getTypeStoreSize(Ty: CV->getType()); |
3452 | } else { |
3453 | for (unsigned I = 0, E = CV->getType()->getNumElements(); I != E; ++I) { |
3454 | emitGlobalAliasInline(AP, Offset: DL.getTypeAllocSize(Ty: CV->getType()) * I, AliasList); |
3455 | emitGlobalConstantImpl(DL, C: CV->getOperand(i_nocapture: I), AP); |
3456 | } |
3457 | EmittedSize = |
3458 | DL.getTypeAllocSize(Ty: ElementType) * CV->getType()->getNumElements(); |
3459 | } |
3460 | |
3461 | unsigned Size = DL.getTypeAllocSize(Ty: CV->getType()); |
3462 | if (unsigned Padding = Size - EmittedSize) |
3463 | AP.OutStreamer->emitZeros(NumBytes: Padding); |
3464 | } |
3465 | |
3466 | static void emitGlobalConstantStruct(const DataLayout &DL, |
3467 | const ConstantStruct *CS, AsmPrinter &AP, |
3468 | const Constant *BaseCV, uint64_t Offset, |
3469 | AsmPrinter::AliasMapTy *AliasList) { |
3470 | // Print the fields in successive locations. Pad to align if needed! |
3471 | uint64_t Size = DL.getTypeAllocSize(Ty: CS->getType()); |
3472 | const StructLayout *Layout = DL.getStructLayout(Ty: CS->getType()); |
3473 | uint64_t SizeSoFar = 0; |
3474 | for (unsigned I = 0, E = CS->getNumOperands(); I != E; ++I) { |
3475 | const Constant *Field = CS->getOperand(i_nocapture: I); |
3476 | |
3477 | // Print the actual field value. |
3478 | emitGlobalConstantImpl(DL, C: Field, AP, BaseCV, Offset: Offset + SizeSoFar, |
3479 | AliasList); |
3480 | |
3481 | // Check if padding is needed and insert one or more 0s. |
3482 | uint64_t FieldSize = DL.getTypeAllocSize(Ty: Field->getType()); |
3483 | uint64_t PadSize = ((I == E - 1 ? Size : Layout->getElementOffset(Idx: I + 1)) - |
3484 | Layout->getElementOffset(Idx: I)) - |
3485 | FieldSize; |
3486 | SizeSoFar += FieldSize + PadSize; |
3487 | |
3488 | // Insert padding - this may include padding to increase the size of the |
3489 | // current field up to the ABI size (if the struct is not packed) as well |
3490 | // as padding to ensure that the next field starts at the right offset. |
3491 | AP.OutStreamer->emitZeros(NumBytes: PadSize); |
3492 | } |
3493 | assert(SizeSoFar == Layout->getSizeInBytes() && |
3494 | "Layout of constant struct may be incorrect!" ); |
3495 | } |
3496 | |
3497 | static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) { |
3498 | assert(ET && "Unknown float type" ); |
3499 | APInt API = APF.bitcastToAPInt(); |
3500 | |
3501 | // First print a comment with what we think the original floating-point value |
3502 | // should have been. |
3503 | if (AP.isVerbose()) { |
3504 | SmallString<8> StrVal; |
3505 | APF.toString(Str&: StrVal); |
3506 | ET->print(O&: AP.OutStreamer->getCommentOS()); |
3507 | AP.OutStreamer->getCommentOS() << ' ' << StrVal << '\n'; |
3508 | } |
3509 | |
3510 | // Now iterate through the APInt chunks, emitting them in endian-correct |
3511 | // order, possibly with a smaller chunk at beginning/end (e.g. for x87 80-bit |
3512 | // floats). |
3513 | unsigned NumBytes = API.getBitWidth() / 8; |
3514 | unsigned TrailingBytes = NumBytes % sizeof(uint64_t); |
3515 | const uint64_t *p = API.getRawData(); |
3516 | |
3517 | // PPC's long double has odd notions of endianness compared to how LLVM |
3518 | // handles it: p[0] goes first for *big* endian on PPC. |
3519 | if (AP.getDataLayout().isBigEndian() && !ET->isPPC_FP128Ty()) { |
3520 | int Chunk = API.getNumWords() - 1; |
3521 | |
3522 | if (TrailingBytes) |
3523 | AP.OutStreamer->emitIntValueInHexWithPadding(Value: p[Chunk--], Size: TrailingBytes); |
3524 | |
3525 | for (; Chunk >= 0; --Chunk) |
3526 | AP.OutStreamer->emitIntValueInHexWithPadding(Value: p[Chunk], Size: sizeof(uint64_t)); |
3527 | } else { |
3528 | unsigned Chunk; |
3529 | for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk) |
3530 | AP.OutStreamer->emitIntValueInHexWithPadding(Value: p[Chunk], Size: sizeof(uint64_t)); |
3531 | |
3532 | if (TrailingBytes) |
3533 | AP.OutStreamer->emitIntValueInHexWithPadding(Value: p[Chunk], Size: TrailingBytes); |
3534 | } |
3535 | |
3536 | // Emit the tail padding for the long double. |
3537 | const DataLayout &DL = AP.getDataLayout(); |
3538 | AP.OutStreamer->emitZeros(NumBytes: DL.getTypeAllocSize(Ty: ET) - DL.getTypeStoreSize(Ty: ET)); |
3539 | } |
3540 | |
3541 | static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) { |
3542 | emitGlobalConstantFP(APF: CFP->getValueAPF(), ET: CFP->getType(), AP); |
3543 | } |
3544 | |
3545 | static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) { |
3546 | const DataLayout &DL = AP.getDataLayout(); |
3547 | unsigned BitWidth = CI->getBitWidth(); |
3548 | |
3549 | // Copy the value as we may massage the layout for constants whose bit width |
3550 | // is not a multiple of 64-bits. |
3551 | APInt Realigned(CI->getValue()); |
3552 | uint64_t = 0; |
3553 | unsigned = BitWidth & 63; |
3554 | |
3555 | if (ExtraBitsSize) { |
3556 | // The bit width of the data is not a multiple of 64-bits. |
3557 | // The extra bits are expected to be at the end of the chunk of the memory. |
3558 | // Little endian: |
3559 | // * Nothing to be done, just record the extra bits to emit. |
3560 | // Big endian: |
3561 | // * Record the extra bits to emit. |
3562 | // * Realign the raw data to emit the chunks of 64-bits. |
3563 | if (DL.isBigEndian()) { |
3564 | // Basically the structure of the raw data is a chunk of 64-bits cells: |
3565 | // 0 1 BitWidth / 64 |
3566 | // [chunk1][chunk2] ... [chunkN]. |
3567 | // The most significant chunk is chunkN and it should be emitted first. |
3568 | // However, due to the alignment issue chunkN contains useless bits. |
3569 | // Realign the chunks so that they contain only useful information: |
3570 | // ExtraBits 0 1 (BitWidth / 64) - 1 |
3571 | // chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN] |
3572 | ExtraBitsSize = alignTo(Value: ExtraBitsSize, Align: 8); |
3573 | ExtraBits = Realigned.getRawData()[0] & |
3574 | (((uint64_t)-1) >> (64 - ExtraBitsSize)); |
3575 | if (BitWidth >= 64) |
3576 | Realigned.lshrInPlace(ShiftAmt: ExtraBitsSize); |
3577 | } else |
3578 | ExtraBits = Realigned.getRawData()[BitWidth / 64]; |
3579 | } |
3580 | |
3581 | // We don't expect assemblers to support integer data directives |
3582 | // for more than 64 bits, so we emit the data in at most 64-bit |
3583 | // quantities at a time. |
3584 | const uint64_t *RawData = Realigned.getRawData(); |
3585 | for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { |
3586 | uint64_t Val = DL.isBigEndian() ? RawData[e - i - 1] : RawData[i]; |
3587 | AP.OutStreamer->emitIntValue(Value: Val, Size: 8); |
3588 | } |
3589 | |
3590 | if (ExtraBitsSize) { |
3591 | // Emit the extra bits after the 64-bits chunks. |
3592 | |
3593 | // Emit a directive that fills the expected size. |
3594 | uint64_t Size = AP.getDataLayout().getTypeStoreSize(Ty: CI->getType()); |
3595 | Size -= (BitWidth / 64) * 8; |
3596 | assert(Size && Size * 8 >= ExtraBitsSize && |
3597 | (ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize))) |
3598 | == ExtraBits && "Directive too small for extra bits." ); |
3599 | AP.OutStreamer->emitIntValue(Value: ExtraBits, Size); |
3600 | } |
3601 | } |
3602 | |
3603 | /// Transform a not absolute MCExpr containing a reference to a GOT |
3604 | /// equivalent global, by a target specific GOT pc relative access to the |
3605 | /// final symbol. |
3606 | static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, |
3607 | const Constant *BaseCst, |
3608 | uint64_t Offset) { |
3609 | // The global @foo below illustrates a global that uses a got equivalent. |
3610 | // |
3611 | // @bar = global i32 42 |
3612 | // @gotequiv = private unnamed_addr constant i32* @bar |
3613 | // @foo = i32 trunc (i64 sub (i64 ptrtoint (i32** @gotequiv to i64), |
3614 | // i64 ptrtoint (i32* @foo to i64)) |
3615 | // to i32) |
3616 | // |
3617 | // The cstexpr in @foo is converted into the MCExpr `ME`, where we actually |
3618 | // check whether @foo is suitable to use a GOTPCREL. `ME` is usually in the |
3619 | // form: |
3620 | // |
3621 | // foo = cstexpr, where |
3622 | // cstexpr := <gotequiv> - "." + <cst> |
3623 | // cstexpr := <gotequiv> - (<foo> - <offset from @foo base>) + <cst> |
3624 | // |
3625 | // After canonicalization by evaluateAsRelocatable `ME` turns into: |
3626 | // |
3627 | // cstexpr := <gotequiv> - <foo> + gotpcrelcst, where |
3628 | // gotpcrelcst := <offset from @foo base> + <cst> |
3629 | MCValue MV; |
3630 | if (!(*ME)->evaluateAsRelocatable(Res&: MV, Asm: nullptr, Fixup: nullptr) || MV.isAbsolute()) |
3631 | return; |
3632 | const MCSymbolRefExpr *SymA = MV.getSymA(); |
3633 | if (!SymA) |
3634 | return; |
3635 | |
3636 | // Check that GOT equivalent symbol is cached. |
3637 | const MCSymbol *GOTEquivSym = &SymA->getSymbol(); |
3638 | if (!AP.GlobalGOTEquivs.count(Key: GOTEquivSym)) |
3639 | return; |
3640 | |
3641 | const GlobalValue *BaseGV = dyn_cast_or_null<GlobalValue>(Val: BaseCst); |
3642 | if (!BaseGV) |
3643 | return; |
3644 | |
3645 | // Check for a valid base symbol |
3646 | const MCSymbol *BaseSym = AP.getSymbol(GV: BaseGV); |
3647 | const MCSymbolRefExpr *SymB = MV.getSymB(); |
3648 | |
3649 | if (!SymB || BaseSym != &SymB->getSymbol()) |
3650 | return; |
3651 | |
3652 | // Make sure to match: |
3653 | // |
3654 | // gotpcrelcst := <offset from @foo base> + <cst> |
3655 | // |
3656 | int64_t GOTPCRelCst = Offset + MV.getConstant(); |
3657 | if (!AP.getObjFileLowering().supportGOTPCRelWithOffset() && GOTPCRelCst != 0) |
3658 | return; |
3659 | |
3660 | // Emit the GOT PC relative to replace the got equivalent global, i.e.: |
3661 | // |
3662 | // bar: |
3663 | // .long 42 |
3664 | // gotequiv: |
3665 | // .quad bar |
3666 | // foo: |
3667 | // .long gotequiv - "." + <cst> |
3668 | // |
3669 | // is replaced by the target specific equivalent to: |
3670 | // |
3671 | // bar: |
3672 | // .long 42 |
3673 | // foo: |
3674 | // .long bar@GOTPCREL+<gotpcrelcst> |
3675 | AsmPrinter::GOTEquivUsePair Result = AP.GlobalGOTEquivs[GOTEquivSym]; |
3676 | const GlobalVariable *GV = Result.first; |
3677 | int NumUses = (int)Result.second; |
3678 | const GlobalValue *FinalGV = dyn_cast<GlobalValue>(Val: GV->getOperand(i_nocapture: 0)); |
3679 | const MCSymbol *FinalSym = AP.getSymbol(GV: FinalGV); |
3680 | *ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel( |
3681 | GV: FinalGV, Sym: FinalSym, MV, Offset, MMI: AP.MMI, Streamer&: *AP.OutStreamer); |
3682 | |
3683 | // Update GOT equivalent usage information |
3684 | --NumUses; |
3685 | if (NumUses >= 0) |
3686 | AP.GlobalGOTEquivs[GOTEquivSym] = std::make_pair(x&: GV, y&: NumUses); |
3687 | } |
3688 | |
3689 | static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV, |
3690 | AsmPrinter &AP, const Constant *BaseCV, |
3691 | uint64_t Offset, |
3692 | AsmPrinter::AliasMapTy *AliasList) { |
3693 | emitGlobalAliasInline(AP, Offset, AliasList); |
3694 | uint64_t Size = DL.getTypeAllocSize(Ty: CV->getType()); |
3695 | |
3696 | // Globals with sub-elements such as combinations of arrays and structs |
3697 | // are handled recursively by emitGlobalConstantImpl. Keep track of the |
3698 | // constant symbol base and the current position with BaseCV and Offset. |
3699 | if (!BaseCV && CV->hasOneUse()) |
3700 | BaseCV = dyn_cast<Constant>(Val: CV->user_back()); |
3701 | |
3702 | if (isa<ConstantAggregateZero>(Val: CV) || isa<UndefValue>(Val: CV)) |
3703 | return AP.OutStreamer->emitZeros(NumBytes: Size); |
3704 | |
3705 | if (const ConstantInt *CI = dyn_cast<ConstantInt>(Val: CV)) { |
3706 | const uint64_t StoreSize = DL.getTypeStoreSize(Ty: CV->getType()); |
3707 | |
3708 | if (StoreSize <= 8) { |
3709 | if (AP.isVerbose()) |
3710 | AP.OutStreamer->getCommentOS() |
3711 | << format(Fmt: "0x%" PRIx64 "\n" , Vals: CI->getZExtValue()); |
3712 | AP.OutStreamer->emitIntValue(Value: CI->getZExtValue(), Size: StoreSize); |
3713 | } else { |
3714 | emitGlobalConstantLargeInt(CI, AP); |
3715 | } |
3716 | |
3717 | // Emit tail padding if needed |
3718 | if (Size != StoreSize) |
3719 | AP.OutStreamer->emitZeros(NumBytes: Size - StoreSize); |
3720 | |
3721 | return; |
3722 | } |
3723 | |
3724 | if (const ConstantFP *CFP = dyn_cast<ConstantFP>(Val: CV)) |
3725 | return emitGlobalConstantFP(CFP, AP); |
3726 | |
3727 | if (isa<ConstantPointerNull>(Val: CV)) { |
3728 | AP.OutStreamer->emitIntValue(Value: 0, Size); |
3729 | return; |
3730 | } |
3731 | |
3732 | if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(Val: CV)) |
3733 | return emitGlobalConstantDataSequential(DL, CDS, AP, AliasList); |
3734 | |
3735 | if (const ConstantArray *CVA = dyn_cast<ConstantArray>(Val: CV)) |
3736 | return emitGlobalConstantArray(DL, CA: CVA, AP, BaseCV, Offset, AliasList); |
3737 | |
3738 | if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(Val: CV)) |
3739 | return emitGlobalConstantStruct(DL, CS: CVS, AP, BaseCV, Offset, AliasList); |
3740 | |
3741 | if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Val: CV)) { |
3742 | // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of |
3743 | // vectors). |
3744 | if (CE->getOpcode() == Instruction::BitCast) |
3745 | return emitGlobalConstantImpl(DL, CV: CE->getOperand(i_nocapture: 0), AP); |
3746 | |
3747 | if (Size > 8) { |
3748 | // If the constant expression's size is greater than 64-bits, then we have |
3749 | // to emit the value in chunks. Try to constant fold the value and emit it |
3750 | // that way. |
3751 | Constant *New = ConstantFoldConstant(C: CE, DL); |
3752 | if (New != CE) |
3753 | return emitGlobalConstantImpl(DL, CV: New, AP); |
3754 | } |
3755 | } |
3756 | |
3757 | if (const ConstantVector *V = dyn_cast<ConstantVector>(Val: CV)) |
3758 | return emitGlobalConstantVector(DL, CV: V, AP, AliasList); |
3759 | |
3760 | // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it |
3761 | // thread the streamer with EmitValue. |
3762 | const MCExpr *ME = AP.lowerConstant(CV); |
3763 | |
3764 | // Since lowerConstant already folded and got rid of all IR pointer and |
3765 | // integer casts, detect GOT equivalent accesses by looking into the MCExpr |
3766 | // directly. |
3767 | if (AP.getObjFileLowering().supportIndirectSymViaGOTPCRel()) |
3768 | handleIndirectSymViaGOTPCRel(AP, ME: &ME, BaseCst: BaseCV, Offset); |
3769 | |
3770 | AP.OutStreamer->emitValue(Value: ME, Size); |
3771 | } |
3772 | |
3773 | /// EmitGlobalConstant - Print a general LLVM constant to the .s file. |
3774 | void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV, |
3775 | AliasMapTy *AliasList) { |
3776 | uint64_t Size = DL.getTypeAllocSize(Ty: CV->getType()); |
3777 | if (Size) |
3778 | emitGlobalConstantImpl(DL, CV, AP&: *this, BaseCV: nullptr, Offset: 0, AliasList); |
3779 | else if (MAI->hasSubsectionsViaSymbols()) { |
3780 | // If the global has zero size, emit a single byte so that two labels don't |
3781 | // look like they are at the same location. |
3782 | OutStreamer->emitIntValue(Value: 0, Size: 1); |
3783 | } |
3784 | if (!AliasList) |
3785 | return; |
3786 | // TODO: These remaining aliases are not emitted in the correct location. Need |
3787 | // to handle the case where the alias offset doesn't refer to any sub-element. |
3788 | for (auto &AliasPair : *AliasList) { |
3789 | for (const GlobalAlias *GA : AliasPair.second) |
3790 | OutStreamer->emitLabel(Symbol: getSymbol(GV: GA)); |
3791 | } |
3792 | } |
3793 | |
3794 | void AsmPrinter::emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { |
3795 | // Target doesn't support this yet! |
3796 | llvm_unreachable("Target does not support EmitMachineConstantPoolValue" ); |
3797 | } |
3798 | |
3799 | void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { |
3800 | if (Offset > 0) |
3801 | OS << '+' << Offset; |
3802 | else if (Offset < 0) |
3803 | OS << Offset; |
3804 | } |
3805 | |
3806 | void AsmPrinter::emitNops(unsigned N) { |
3807 | MCInst Nop = MF->getSubtarget().getInstrInfo()->getNop(); |
3808 | for (; N; --N) |
3809 | EmitToStreamer(S&: *OutStreamer, Inst: Nop); |
3810 | } |
3811 | |
3812 | //===----------------------------------------------------------------------===// |
3813 | // Symbol Lowering Routines. |
3814 | //===----------------------------------------------------------------------===// |
3815 | |
3816 | MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const { |
3817 | return OutContext.createTempSymbol(Name, AlwaysAddSuffix: true); |
3818 | } |
3819 | |
3820 | MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { |
3821 | return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol( |
3822 | BB: BA->getBasicBlock()); |
3823 | } |
3824 | |
3825 | MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { |
3826 | return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB); |
3827 | } |
3828 | |
3829 | const MCExpr *AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) { |
3830 | return MCSymbolRefExpr::create(Symbol: GetBlockAddressSymbol(BA: &BA), Ctx&: OutContext); |
3831 | } |
3832 | |
3833 | /// GetCPISymbol - Return the symbol for the specified constant pool entry. |
3834 | MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { |
3835 | if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment()) { |
3836 | const MachineConstantPoolEntry &CPE = |
3837 | MF->getConstantPool()->getConstants()[CPID]; |
3838 | if (!CPE.isMachineConstantPoolEntry()) { |
3839 | const DataLayout &DL = MF->getDataLayout(); |
3840 | SectionKind Kind = CPE.getSectionKind(DL: &DL); |
3841 | const Constant *C = CPE.Val.ConstVal; |
3842 | Align Alignment = CPE.Alignment; |
3843 | if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>( |
3844 | Val: getObjFileLowering().getSectionForConstant(DL, Kind, C, |
3845 | Alignment))) { |
3846 | if (MCSymbol *Sym = S->getCOMDATSymbol()) { |
3847 | if (Sym->isUndefined()) |
3848 | OutStreamer->emitSymbolAttribute(Symbol: Sym, Attribute: MCSA_Global); |
3849 | return Sym; |
3850 | } |
3851 | } |
3852 | } |
3853 | } |
3854 | |
3855 | const DataLayout &DL = getDataLayout(); |
3856 | return OutContext.getOrCreateSymbol(Name: Twine(DL.getPrivateGlobalPrefix()) + |
3857 | "CPI" + Twine(getFunctionNumber()) + "_" + |
3858 | Twine(CPID)); |
3859 | } |
3860 | |
3861 | /// GetJTISymbol - Return the symbol for the specified jump table entry. |
3862 | MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { |
3863 | return MF->getJTISymbol(JTI: JTID, Ctx&: OutContext, isLinkerPrivate); |
3864 | } |
3865 | |
3866 | /// GetJTSetSymbol - Return the symbol for the specified jump table .set |
3867 | /// FIXME: privatize to AsmPrinter. |
3868 | MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { |
3869 | const DataLayout &DL = getDataLayout(); |
3870 | return OutContext.getOrCreateSymbol(Name: Twine(DL.getPrivateGlobalPrefix()) + |
3871 | Twine(getFunctionNumber()) + "_" + |
3872 | Twine(UID) + "_set_" + Twine(MBBID)); |
3873 | } |
3874 | |
3875 | MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV, |
3876 | StringRef Suffix) const { |
3877 | return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, TM); |
3878 | } |
3879 | |
3880 | /// Return the MCSymbol for the specified ExternalSymbol. |
3881 | MCSymbol *AsmPrinter::GetExternalSymbolSymbol(Twine Sym) const { |
3882 | SmallString<60> NameStr; |
3883 | Mangler::getNameWithPrefix(OutName&: NameStr, GVName: Sym, DL: getDataLayout()); |
3884 | return OutContext.getOrCreateSymbol(Name: NameStr); |
3885 | } |
3886 | |
3887 | /// PrintParentLoopComment - Print comments about parent loops of this one. |
3888 | static void (raw_ostream &OS, const MachineLoop *Loop, |
3889 | unsigned FunctionNumber) { |
3890 | if (!Loop) return; |
3891 | PrintParentLoopComment(OS, Loop: Loop->getParentLoop(), FunctionNumber); |
3892 | OS.indent(NumSpaces: Loop->getLoopDepth()*2) |
3893 | << "Parent Loop BB" << FunctionNumber << "_" |
3894 | << Loop->getHeader()->getNumber() |
3895 | << " Depth=" << Loop->getLoopDepth() << '\n'; |
3896 | } |
3897 | |
3898 | /// PrintChildLoopComment - Print comments about child loops within |
3899 | /// the loop for this basic block, with nesting. |
3900 | static void (raw_ostream &OS, const MachineLoop *Loop, |
3901 | unsigned FunctionNumber) { |
3902 | // Add child loop information |
3903 | for (const MachineLoop *CL : *Loop) { |
3904 | OS.indent(NumSpaces: CL->getLoopDepth()*2) |
3905 | << "Child Loop BB" << FunctionNumber << "_" |
3906 | << CL->getHeader()->getNumber() << " Depth " << CL->getLoopDepth() |
3907 | << '\n'; |
3908 | PrintChildLoopComment(OS, Loop: CL, FunctionNumber); |
3909 | } |
3910 | } |
3911 | |
3912 | /// emitBasicBlockLoopComments - Pretty-print comments for basic blocks. |
3913 | static void (const MachineBasicBlock &MBB, |
3914 | const MachineLoopInfo *LI, |
3915 | const AsmPrinter &AP) { |
3916 | // Add loop depth information |
3917 | const MachineLoop *Loop = LI->getLoopFor(BB: &MBB); |
3918 | if (!Loop) return; |
3919 | |
3920 | MachineBasicBlock * = Loop->getHeader(); |
3921 | assert(Header && "No header for loop" ); |
3922 | |
3923 | // If this block is not a loop header, just print out what is the loop header |
3924 | // and return. |
3925 | if (Header != &MBB) { |
3926 | AP.OutStreamer->AddComment(T: " in Loop: Header=BB" + |
3927 | Twine(AP.getFunctionNumber())+"_" + |
3928 | Twine(Loop->getHeader()->getNumber())+ |
3929 | " Depth=" +Twine(Loop->getLoopDepth())); |
3930 | return; |
3931 | } |
3932 | |
3933 | // Otherwise, it is a loop header. Print out information about child and |
3934 | // parent loops. |
3935 | raw_ostream &OS = AP.OutStreamer->getCommentOS(); |
3936 | |
3937 | PrintParentLoopComment(OS, Loop: Loop->getParentLoop(), FunctionNumber: AP.getFunctionNumber()); |
3938 | |
3939 | OS << "=>" ; |
3940 | OS.indent(NumSpaces: Loop->getLoopDepth()*2-2); |
3941 | |
3942 | OS << "This " ; |
3943 | if (Loop->isInnermost()) |
3944 | OS << "Inner " ; |
3945 | OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; |
3946 | |
3947 | PrintChildLoopComment(OS, Loop, FunctionNumber: AP.getFunctionNumber()); |
3948 | } |
3949 | |
3950 | /// emitBasicBlockStart - This method prints the label for the specified |
3951 | /// MachineBasicBlock, an alignment (if present) and a comment describing |
3952 | /// it if appropriate. |
3953 | void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) { |
3954 | // End the previous funclet and start a new one. |
3955 | if (MBB.isEHFuncletEntry()) { |
3956 | for (auto &Handler : Handlers) { |
3957 | Handler->endFunclet(); |
3958 | Handler->beginFunclet(MBB); |
3959 | } |
3960 | } |
3961 | |
3962 | // Switch to a new section if this basic block must begin a section. The |
3963 | // entry block is always placed in the function section and is handled |
3964 | // separately. |
3965 | if (MBB.isBeginSection() && !MBB.isEntryBlock()) { |
3966 | OutStreamer->switchSection( |
3967 | Section: getObjFileLowering().getSectionForMachineBasicBlock(F: MF->getFunction(), |
3968 | MBB, TM)); |
3969 | CurrentSectionBeginSym = MBB.getSymbol(); |
3970 | } |
3971 | |
3972 | // Emit an alignment directive for this block, if needed. |
3973 | const Align Alignment = MBB.getAlignment(); |
3974 | if (Alignment != Align(1)) |
3975 | emitAlignment(Alignment, GV: nullptr, MaxBytesToEmit: MBB.getMaxBytesForAlignment()); |
3976 | |
3977 | // If the block has its address taken, emit any labels that were used to |
3978 | // reference the block. It is possible that there is more than one label |
3979 | // here, because multiple LLVM BB's may have been RAUW'd to this block after |
3980 | // the references were generated. |
3981 | if (MBB.isIRBlockAddressTaken()) { |
3982 | if (isVerbose()) |
3983 | OutStreamer->AddComment(T: "Block address taken" ); |
3984 | |
3985 | BasicBlock *BB = MBB.getAddressTakenIRBlock(); |
3986 | assert(BB && BB->hasAddressTaken() && "Missing BB" ); |
3987 | for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB)) |
3988 | OutStreamer->emitLabel(Symbol: Sym); |
3989 | } else if (isVerbose() && MBB.isMachineBlockAddressTaken()) { |
3990 | OutStreamer->AddComment(T: "Block address taken" ); |
3991 | } |
3992 | |
3993 | // Print some verbose block comments. |
3994 | if (isVerbose()) { |
3995 | if (const BasicBlock *BB = MBB.getBasicBlock()) { |
3996 | if (BB->hasName()) { |
3997 | BB->printAsOperand(O&: OutStreamer->getCommentOS(), |
3998 | /*PrintType=*/false, M: BB->getModule()); |
3999 | OutStreamer->getCommentOS() << '\n'; |
4000 | } |
4001 | } |
4002 | |
4003 | assert(MLI != nullptr && "MachineLoopInfo should has been computed" ); |
4004 | emitBasicBlockLoopComments(MBB, LI: MLI, AP: *this); |
4005 | } |
4006 | |
4007 | // Print the main label for the block. |
4008 | if (shouldEmitLabelForBasicBlock(MBB)) { |
4009 | if (isVerbose() && MBB.hasLabelMustBeEmitted()) |
4010 | OutStreamer->AddComment(T: "Label of block must be emitted" ); |
4011 | OutStreamer->emitLabel(Symbol: MBB.getSymbol()); |
4012 | } else { |
4013 | if (isVerbose()) { |
4014 | // NOTE: Want this comment at start of line, don't emit with AddComment. |
4015 | OutStreamer->emitRawComment(T: " %bb." + Twine(MBB.getNumber()) + ":" , |
4016 | TabPrefix: false); |
4017 | } |
4018 | } |
4019 | |
4020 | if (MBB.isEHCatchretTarget() && |
4021 | MAI->getExceptionHandlingType() == ExceptionHandling::WinEH) { |
4022 | OutStreamer->emitLabel(Symbol: MBB.getEHCatchretSymbol()); |
4023 | } |
4024 | |
4025 | // With BB sections, each basic block must handle CFI information on its own |
4026 | // if it begins a section (Entry block call is handled separately, next to |
4027 | // beginFunction). |
4028 | if (MBB.isBeginSection() && !MBB.isEntryBlock()) { |
4029 | for (auto &Handler : DebugHandlers) |
4030 | Handler->beginBasicBlockSection(MBB); |
4031 | for (auto &Handler : Handlers) |
4032 | Handler->beginBasicBlockSection(MBB); |
4033 | } |
4034 | } |
4035 | |
4036 | void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) { |
4037 | // Check if CFI information needs to be updated for this MBB with basic block |
4038 | // sections. |
4039 | if (MBB.isEndSection()) { |
4040 | for (auto &Handler : DebugHandlers) |
4041 | Handler->endBasicBlockSection(MBB); |
4042 | for (auto &Handler : Handlers) |
4043 | Handler->endBasicBlockSection(MBB); |
4044 | } |
4045 | } |
4046 | |
4047 | void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility, |
4048 | bool IsDefinition) const { |
4049 | MCSymbolAttr Attr = MCSA_Invalid; |
4050 | |
4051 | switch (Visibility) { |
4052 | default: break; |
4053 | case GlobalValue::HiddenVisibility: |
4054 | if (IsDefinition) |
4055 | Attr = MAI->getHiddenVisibilityAttr(); |
4056 | else |
4057 | Attr = MAI->getHiddenDeclarationVisibilityAttr(); |
4058 | break; |
4059 | case GlobalValue::ProtectedVisibility: |
4060 | Attr = MAI->getProtectedVisibilityAttr(); |
4061 | break; |
4062 | } |
4063 | |
4064 | if (Attr != MCSA_Invalid) |
4065 | OutStreamer->emitSymbolAttribute(Symbol: Sym, Attribute: Attr); |
4066 | } |
4067 | |
4068 | bool AsmPrinter::shouldEmitLabelForBasicBlock( |
4069 | const MachineBasicBlock &MBB) const { |
4070 | // With `-fbasic-block-sections=`, a label is needed for every non-entry block |
4071 | // in the labels mode (option `=labels`) and every section beginning in the |
4072 | // sections mode (`=all` and `=list=`). |
4073 | if ((MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap || |
4074 | MBB.isBeginSection()) && |
4075 | !MBB.isEntryBlock()) |
4076 | return true; |
4077 | // A label is needed for any block with at least one predecessor (when that |
4078 | // predecessor is not the fallthrough predecessor, or if it is an EH funclet |
4079 | // entry, or if a label is forced). |
4080 | return !MBB.pred_empty() && |
4081 | (!isBlockOnlyReachableByFallthrough(MBB: &MBB) || MBB.isEHFuncletEntry() || |
4082 | MBB.hasLabelMustBeEmitted()); |
4083 | } |
4084 | |
4085 | /// isBlockOnlyReachableByFallthough - Return true if the basic block has |
4086 | /// exactly one predecessor and the control transfer mechanism between |
4087 | /// the predecessor and this block is a fall-through. |
4088 | bool AsmPrinter:: |
4089 | isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const { |
4090 | // If this is a landing pad, it isn't a fall through. If it has no preds, |
4091 | // then nothing falls through to it. |
4092 | if (MBB->isEHPad() || MBB->pred_empty()) |
4093 | return false; |
4094 | |
4095 | // If there isn't exactly one predecessor, it can't be a fall through. |
4096 | if (MBB->pred_size() > 1) |
4097 | return false; |
4098 | |
4099 | // The predecessor has to be immediately before this block. |
4100 | MachineBasicBlock *Pred = *MBB->pred_begin(); |
4101 | if (!Pred->isLayoutSuccessor(MBB)) |
4102 | return false; |
4103 | |
4104 | // If the block is completely empty, then it definitely does fall through. |
4105 | if (Pred->empty()) |
4106 | return true; |
4107 | |
4108 | // Check the terminators in the previous blocks |
4109 | for (const auto &MI : Pred->terminators()) { |
4110 | // If it is not a simple branch, we are in a table somewhere. |
4111 | if (!MI.isBranch() || MI.isIndirectBranch()) |
4112 | return false; |
4113 | |
4114 | // If we are the operands of one of the branches, this is not a fall |
4115 | // through. Note that targets with delay slots will usually bundle |
4116 | // terminators with the delay slot instruction. |
4117 | for (ConstMIBundleOperands OP(MI); OP.isValid(); ++OP) { |
4118 | if (OP->isJTI()) |
4119 | return false; |
4120 | if (OP->isMBB() && OP->getMBB() == MBB) |
4121 | return false; |
4122 | } |
4123 | } |
4124 | |
4125 | return true; |
4126 | } |
4127 | |
4128 | GCMetadataPrinter *AsmPrinter::getOrCreateGCPrinter(GCStrategy &S) { |
4129 | if (!S.usesMetadata()) |
4130 | return nullptr; |
4131 | |
4132 | auto [GCPI, Inserted] = GCMetadataPrinters.insert(KV: {&S, nullptr}); |
4133 | if (!Inserted) |
4134 | return GCPI->second.get(); |
4135 | |
4136 | auto Name = S.getName(); |
4137 | |
4138 | for (const GCMetadataPrinterRegistry::entry &GCMetaPrinter : |
4139 | GCMetadataPrinterRegistry::entries()) |
4140 | if (Name == GCMetaPrinter.getName()) { |
4141 | std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate(); |
4142 | GMP->S = &S; |
4143 | GCPI->second = std::move(GMP); |
4144 | return GCPI->second.get(); |
4145 | } |
4146 | |
4147 | report_fatal_error(reason: "no GCMetadataPrinter registered for GC: " + Twine(Name)); |
4148 | } |
4149 | |
4150 | void AsmPrinter::emitStackMaps() { |
4151 | GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>(); |
4152 | assert(MI && "AsmPrinter didn't require GCModuleInfo?" ); |
4153 | bool NeedsDefault = false; |
4154 | if (MI->begin() == MI->end()) |
4155 | // No GC strategy, use the default format. |
4156 | NeedsDefault = true; |
4157 | else |
4158 | for (const auto &I : *MI) { |
4159 | if (GCMetadataPrinter *MP = getOrCreateGCPrinter(S&: *I)) |
4160 | if (MP->emitStackMaps(SM, AP&: *this)) |
4161 | continue; |
4162 | // The strategy doesn't have printer or doesn't emit custom stack maps. |
4163 | // Use the default format. |
4164 | NeedsDefault = true; |
4165 | } |
4166 | |
4167 | if (NeedsDefault) |
4168 | SM.serializeToStackMapSection(); |
4169 | } |
4170 | |
4171 | void AsmPrinter::addAsmPrinterHandler( |
4172 | std::unique_ptr<AsmPrinterHandler> Handler) { |
4173 | Handlers.insert(I: Handlers.begin(), Elt: std::move(Handler)); |
4174 | NumUserHandlers++; |
4175 | } |
4176 | |
4177 | void AsmPrinter::addDebugHandler(std::unique_ptr<DebugHandlerBase> Handler) { |
4178 | DebugHandlers.insert(I: DebugHandlers.begin(), Elt: std::move(Handler)); |
4179 | NumUserDebugHandlers++; |
4180 | } |
4181 | |
4182 | /// Pin vtable to this file. |
4183 | AsmPrinterHandler::~AsmPrinterHandler() = default; |
4184 | |
4185 | void AsmPrinterHandler::markFunctionEnd() {} |
4186 | |
4187 | // In the binary's "xray_instr_map" section, an array of these function entries |
4188 | // describes each instrumentation point. When XRay patches your code, the index |
4189 | // into this table will be given to your handler as a patch point identifier. |
4190 | void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out) const { |
4191 | auto Kind8 = static_cast<uint8_t>(Kind); |
4192 | Out->emitBinaryData(Data: StringRef(reinterpret_cast<const char *>(&Kind8), 1)); |
4193 | Out->emitBinaryData( |
4194 | Data: StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1)); |
4195 | Out->emitBinaryData(Data: StringRef(reinterpret_cast<const char *>(&Version), 1)); |
4196 | auto Padding = (4 * Bytes) - ((2 * Bytes) + 3); |
4197 | assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size" ); |
4198 | Out->emitZeros(NumBytes: Padding); |
4199 | } |
4200 | |
4201 | void AsmPrinter::emitXRayTable() { |
4202 | if (Sleds.empty()) |
4203 | return; |
4204 | |
4205 | auto PrevSection = OutStreamer->getCurrentSectionOnly(); |
4206 | const Function &F = MF->getFunction(); |
4207 | MCSection *InstMap = nullptr; |
4208 | MCSection *FnSledIndex = nullptr; |
4209 | const Triple &TT = TM.getTargetTriple(); |
4210 | // Use PC-relative addresses on all targets. |
4211 | if (TT.isOSBinFormatELF()) { |
4212 | auto LinkedToSym = cast<MCSymbolELF>(Val: CurrentFnSym); |
4213 | auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER; |
4214 | StringRef GroupName; |
4215 | if (F.hasComdat()) { |
4216 | Flags |= ELF::SHF_GROUP; |
4217 | GroupName = F.getComdat()->getName(); |
4218 | } |
4219 | InstMap = OutContext.getELFSection(Section: "xray_instr_map" , Type: ELF::SHT_PROGBITS, |
4220 | Flags, EntrySize: 0, Group: GroupName, IsComdat: F.hasComdat(), |
4221 | UniqueID: MCSection::NonUniqueID, LinkedToSym); |
4222 | |
4223 | if (TM.Options.XRayFunctionIndex) |
4224 | FnSledIndex = OutContext.getELFSection( |
4225 | Section: "xray_fn_idx" , Type: ELF::SHT_PROGBITS, Flags, EntrySize: 0, Group: GroupName, IsComdat: F.hasComdat(), |
4226 | UniqueID: MCSection::NonUniqueID, LinkedToSym); |
4227 | } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) { |
4228 | InstMap = OutContext.getMachOSection(Segment: "__DATA" , Section: "xray_instr_map" , |
4229 | TypeAndAttributes: MachO::S_ATTR_LIVE_SUPPORT, |
4230 | K: SectionKind::getReadOnlyWithRel()); |
4231 | if (TM.Options.XRayFunctionIndex) |
4232 | FnSledIndex = OutContext.getMachOSection(Segment: "__DATA" , Section: "xray_fn_idx" , |
4233 | TypeAndAttributes: MachO::S_ATTR_LIVE_SUPPORT, |
4234 | K: SectionKind::getReadOnly()); |
4235 | } else { |
4236 | llvm_unreachable("Unsupported target" ); |
4237 | } |
4238 | |
4239 | auto WordSizeBytes = MAI->getCodePointerSize(); |
4240 | |
4241 | // Now we switch to the instrumentation map section. Because this is done |
4242 | // per-function, we are able to create an index entry that will represent the |
4243 | // range of sleds associated with a function. |
4244 | auto &Ctx = OutContext; |
4245 | MCSymbol *SledsStart = |
4246 | OutContext.createLinkerPrivateSymbol(Name: "xray_sleds_start" ); |
4247 | OutStreamer->switchSection(Section: InstMap); |
4248 | OutStreamer->emitLabel(Symbol: SledsStart); |
4249 | for (const auto &Sled : Sleds) { |
4250 | MCSymbol *Dot = Ctx.createTempSymbol(); |
4251 | OutStreamer->emitLabel(Symbol: Dot); |
4252 | OutStreamer->emitValueImpl( |
4253 | Value: MCBinaryExpr::createSub(LHS: MCSymbolRefExpr::create(Symbol: Sled.Sled, Ctx), |
4254 | RHS: MCSymbolRefExpr::create(Symbol: Dot, Ctx), Ctx), |
4255 | Size: WordSizeBytes); |
4256 | OutStreamer->emitValueImpl( |
4257 | Value: MCBinaryExpr::createSub( |
4258 | LHS: MCSymbolRefExpr::create(Symbol: CurrentFnBegin, Ctx), |
4259 | RHS: MCBinaryExpr::createAdd(LHS: MCSymbolRefExpr::create(Symbol: Dot, Ctx), |
4260 | RHS: MCConstantExpr::create(Value: WordSizeBytes, Ctx), |
4261 | Ctx), |
4262 | Ctx), |
4263 | Size: WordSizeBytes); |
4264 | Sled.emit(Bytes: WordSizeBytes, Out: OutStreamer.get()); |
4265 | } |
4266 | MCSymbol *SledsEnd = OutContext.createTempSymbol(Name: "xray_sleds_end" , AlwaysAddSuffix: true); |
4267 | OutStreamer->emitLabel(Symbol: SledsEnd); |
4268 | |
4269 | // We then emit a single entry in the index per function. We use the symbols |
4270 | // that bound the instrumentation map as the range for a specific function. |
4271 | // Each entry here will be 2 * word size aligned, as we're writing down two |
4272 | // pointers. This should work for both 32-bit and 64-bit platforms. |
4273 | if (FnSledIndex) { |
4274 | OutStreamer->switchSection(Section: FnSledIndex); |
4275 | OutStreamer->emitCodeAlignment(Alignment: Align(2 * WordSizeBytes), |
4276 | STI: &getSubtargetInfo()); |
4277 | // For Mach-O, use an "l" symbol as the atom of this subsection. The label |
4278 | // difference uses a SUBTRACTOR external relocation which references the |
4279 | // symbol. |
4280 | MCSymbol *Dot = Ctx.createLinkerPrivateSymbol(Name: "xray_fn_idx" ); |
4281 | OutStreamer->emitLabel(Symbol: Dot); |
4282 | OutStreamer->emitValueImpl( |
4283 | Value: MCBinaryExpr::createSub(LHS: MCSymbolRefExpr::create(Symbol: SledsStart, Ctx), |
4284 | RHS: MCSymbolRefExpr::create(Symbol: Dot, Ctx), Ctx), |
4285 | Size: WordSizeBytes); |
4286 | OutStreamer->emitValueImpl(Value: MCConstantExpr::create(Value: Sleds.size(), Ctx), |
4287 | Size: WordSizeBytes); |
4288 | OutStreamer->switchSection(Section: PrevSection); |
4289 | } |
4290 | Sleds.clear(); |
4291 | } |
4292 | |
4293 | void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, |
4294 | SledKind Kind, uint8_t Version) { |
4295 | const Function &F = MI.getMF()->getFunction(); |
4296 | auto Attr = F.getFnAttribute(Kind: "function-instrument" ); |
4297 | bool LogArgs = F.hasFnAttribute(Kind: "xray-log-args" ); |
4298 | bool AlwaysInstrument = |
4299 | Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always" ; |
4300 | if (Kind == SledKind::FUNCTION_ENTER && LogArgs) |
4301 | Kind = SledKind::LOG_ARGS_ENTER; |
4302 | Sleds.emplace_back(Args: XRayFunctionEntry{.Sled: Sled, .Function: CurrentFnSym, .Kind: Kind, |
4303 | .AlwaysInstrument: AlwaysInstrument, .Fn: &F, .Version: Version}); |
4304 | } |
4305 | |
4306 | void AsmPrinter::emitPatchableFunctionEntries() { |
4307 | const Function &F = MF->getFunction(); |
4308 | unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0; |
4309 | (void)F.getFnAttribute(Kind: "patchable-function-prefix" ) |
4310 | .getValueAsString() |
4311 | .getAsInteger(Radix: 10, Result&: PatchableFunctionPrefix); |
4312 | (void)F.getFnAttribute(Kind: "patchable-function-entry" ) |
4313 | .getValueAsString() |
4314 | .getAsInteger(Radix: 10, Result&: PatchableFunctionEntry); |
4315 | if (!PatchableFunctionPrefix && !PatchableFunctionEntry) |
4316 | return; |
4317 | const unsigned PointerSize = getPointerSize(); |
4318 | if (TM.getTargetTriple().isOSBinFormatELF()) { |
4319 | auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC; |
4320 | const MCSymbolELF *LinkedToSym = nullptr; |
4321 | StringRef GroupName; |
4322 | |
4323 | // GNU as < 2.35 did not support section flag 'o'. GNU ld < 2.36 did not |
4324 | // support mixed SHF_LINK_ORDER and non-SHF_LINK_ORDER sections. |
4325 | if (MAI->useIntegratedAssembler() || MAI->binutilsIsAtLeast(Major: 2, Minor: 36)) { |
4326 | Flags |= ELF::SHF_LINK_ORDER; |
4327 | if (F.hasComdat()) { |
4328 | Flags |= ELF::SHF_GROUP; |
4329 | GroupName = F.getComdat()->getName(); |
4330 | } |
4331 | LinkedToSym = cast<MCSymbolELF>(Val: CurrentFnSym); |
4332 | } |
4333 | OutStreamer->switchSection(Section: OutContext.getELFSection( |
4334 | Section: "__patchable_function_entries" , Type: ELF::SHT_PROGBITS, Flags, EntrySize: 0, Group: GroupName, |
4335 | IsComdat: F.hasComdat(), UniqueID: MCSection::NonUniqueID, LinkedToSym)); |
4336 | emitAlignment(Alignment: Align(PointerSize)); |
4337 | OutStreamer->emitSymbolValue(Sym: CurrentPatchableFunctionEntrySym, Size: PointerSize); |
4338 | } |
4339 | } |
4340 | |
4341 | uint16_t AsmPrinter::getDwarfVersion() const { |
4342 | return OutStreamer->getContext().getDwarfVersion(); |
4343 | } |
4344 | |
4345 | void AsmPrinter::setDwarfVersion(uint16_t Version) { |
4346 | OutStreamer->getContext().setDwarfVersion(Version); |
4347 | } |
4348 | |
4349 | bool AsmPrinter::isDwarf64() const { |
4350 | return OutStreamer->getContext().getDwarfFormat() == dwarf::DWARF64; |
4351 | } |
4352 | |
4353 | unsigned int AsmPrinter::getDwarfOffsetByteSize() const { |
4354 | return dwarf::getDwarfOffsetByteSize( |
4355 | Format: OutStreamer->getContext().getDwarfFormat()); |
4356 | } |
4357 | |
4358 | dwarf::FormParams AsmPrinter::getDwarfFormParams() const { |
4359 | return {.Version: getDwarfVersion(), .AddrSize: uint8_t(MAI->getCodePointerSize()), |
4360 | .Format: OutStreamer->getContext().getDwarfFormat(), |
4361 | .DwarfUsesRelocationsAcrossSections: doesDwarfUseRelocationsAcrossSections()}; |
4362 | } |
4363 | |
4364 | unsigned int AsmPrinter::getUnitLengthFieldByteSize() const { |
4365 | return dwarf::getUnitLengthFieldByteSize( |
4366 | Format: OutStreamer->getContext().getDwarfFormat()); |
4367 | } |
4368 | |
4369 | std::tuple<const MCSymbol *, uint64_t, const MCSymbol *, |
4370 | codeview::JumpTableEntrySize> |
4371 | AsmPrinter::getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, |
4372 | const MCSymbol *BranchLabel) const { |
4373 | const auto TLI = MF->getSubtarget().getTargetLowering(); |
4374 | const auto BaseExpr = |
4375 | TLI->getPICJumpTableRelocBaseExpr(MF, JTI, Ctx&: MMI->getContext()); |
4376 | const auto Base = &cast<MCSymbolRefExpr>(Val: BaseExpr)->getSymbol(); |
4377 | |
4378 | // By default, for the architectures that support CodeView, |
4379 | // EK_LabelDifference32 is implemented as an Int32 from the base address. |
4380 | return std::make_tuple(args: Base, args: 0, args&: BranchLabel, |
4381 | args: codeview::JumpTableEntrySize::Int32); |
4382 | } |
4383 | |