Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
35271 views
//===- AsmPrinter.cpp - Common AsmPrinter code ----------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the AsmPrinter class.9//10//===----------------------------------------------------------------------===//1112#include "llvm/CodeGen/AsmPrinter.h"13#include "CodeViewDebug.h"14#include "DwarfDebug.h"15#include "DwarfException.h"16#include "PseudoProbePrinter.h"17#include "WasmException.h"18#include "WinCFGuard.h"19#include "WinException.h"20#include "llvm/ADT/APFloat.h"21#include "llvm/ADT/APInt.h"22#include "llvm/ADT/DenseMap.h"23#include "llvm/ADT/STLExtras.h"24#include "llvm/ADT/SmallPtrSet.h"25#include "llvm/ADT/SmallString.h"26#include "llvm/ADT/SmallVector.h"27#include "llvm/ADT/Statistic.h"28#include "llvm/ADT/StringExtras.h"29#include "llvm/ADT/StringRef.h"30#include "llvm/ADT/TinyPtrVector.h"31#include "llvm/ADT/Twine.h"32#include "llvm/Analysis/ConstantFolding.h"33#include "llvm/Analysis/MemoryLocation.h"34#include "llvm/Analysis/OptimizationRemarkEmitter.h"35#include "llvm/BinaryFormat/COFF.h"36#include "llvm/BinaryFormat/Dwarf.h"37#include "llvm/BinaryFormat/ELF.h"38#include "llvm/CodeGen/GCMetadata.h"39#include "llvm/CodeGen/GCMetadataPrinter.h"40#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"41#include "llvm/CodeGen/MachineBasicBlock.h"42#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"43#include "llvm/CodeGen/MachineConstantPool.h"44#include "llvm/CodeGen/MachineDominators.h"45#include "llvm/CodeGen/MachineFrameInfo.h"46#include "llvm/CodeGen/MachineFunction.h"47#include "llvm/CodeGen/MachineFunctionPass.h"48#include "llvm/CodeGen/MachineInstr.h"49#include "llvm/CodeGen/MachineInstrBundle.h"50#include "llvm/CodeGen/MachineJumpTableInfo.h"51#include "llvm/CodeGen/MachineLoopInfo.h"52#include "llvm/CodeGen/MachineModuleInfo.h"53#include "llvm/CodeGen/MachineModuleInfoImpls.h"54#include "llvm/CodeGen/MachineOperand.h"55#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"56#include "llvm/CodeGen/StackMaps.h"57#include "llvm/CodeGen/TargetFrameLowering.h"58#include "llvm/CodeGen/TargetInstrInfo.h"59#include "llvm/CodeGen/TargetLowering.h"60#include "llvm/CodeGen/TargetOpcodes.h"61#include "llvm/CodeGen/TargetRegisterInfo.h"62#include "llvm/CodeGen/TargetSubtargetInfo.h"63#include "llvm/Config/config.h"64#include "llvm/IR/BasicBlock.h"65#include "llvm/IR/Comdat.h"66#include "llvm/IR/Constant.h"67#include "llvm/IR/Constants.h"68#include "llvm/IR/DataLayout.h"69#include "llvm/IR/DebugInfoMetadata.h"70#include "llvm/IR/DerivedTypes.h"71#include "llvm/IR/EHPersonalities.h"72#include "llvm/IR/Function.h"73#include "llvm/IR/GCStrategy.h"74#include "llvm/IR/GlobalAlias.h"75#include "llvm/IR/GlobalIFunc.h"76#include "llvm/IR/GlobalObject.h"77#include "llvm/IR/GlobalValue.h"78#include "llvm/IR/GlobalVariable.h"79#include "llvm/IR/Instruction.h"80#include "llvm/IR/Mangler.h"81#include "llvm/IR/Metadata.h"82#include "llvm/IR/Module.h"83#include "llvm/IR/Operator.h"84#include "llvm/IR/PseudoProbe.h"85#include "llvm/IR/Type.h"86#include "llvm/IR/Value.h"87#include "llvm/IR/ValueHandle.h"88#include "llvm/MC/MCAsmInfo.h"89#include "llvm/MC/MCContext.h"90#include "llvm/MC/MCDirectives.h"91#include "llvm/MC/MCExpr.h"92#include "llvm/MC/MCInst.h"93#include "llvm/MC/MCSection.h"94#include "llvm/MC/MCSectionCOFF.h"95#include "llvm/MC/MCSectionELF.h"96#include "llvm/MC/MCSectionMachO.h"97#include "llvm/MC/MCSectionXCOFF.h"98#include "llvm/MC/MCStreamer.h"99#include "llvm/MC/MCSubtargetInfo.h"100#include "llvm/MC/MCSymbol.h"101#include "llvm/MC/MCSymbolELF.h"102#include "llvm/MC/MCTargetOptions.h"103#include "llvm/MC/MCValue.h"104#include "llvm/MC/SectionKind.h"105#include "llvm/Object/ELFTypes.h"106#include "llvm/Pass.h"107#include "llvm/Remarks/RemarkStreamer.h"108#include "llvm/Support/Casting.h"109#include "llvm/Support/Compiler.h"110#include "llvm/Support/ErrorHandling.h"111#include "llvm/Support/FileSystem.h"112#include "llvm/Support/Format.h"113#include "llvm/Support/MathExtras.h"114#include "llvm/Support/Path.h"115#include "llvm/Support/VCSRevision.h"116#include "llvm/Support/raw_ostream.h"117#include "llvm/Target/TargetLoweringObjectFile.h"118#include "llvm/Target/TargetMachine.h"119#include "llvm/Target/TargetOptions.h"120#include "llvm/TargetParser/Triple.h"121#include <algorithm>122#include <cassert>123#include <cinttypes>124#include <cstdint>125#include <iterator>126#include <memory>127#include <optional>128#include <string>129#include <utility>130#include <vector>131132using namespace llvm;133134#define DEBUG_TYPE "asm-printer"135136// This is a replication of fields of object::PGOAnalysisMap::Features. It137// should match the order of the fields so that138// `object::PGOAnalysisMap::Features::decode(PgoAnalysisMapFeatures.getBits())`139// succeeds.140enum class PGOMapFeaturesEnum {141FuncEntryCount,142BBFreq,143BrProb,144};145static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(146"pgo-analysis-map", cl::Hidden, cl::CommaSeparated,147cl::values(clEnumValN(PGOMapFeaturesEnum::FuncEntryCount,148"func-entry-count", "Function Entry Count"),149clEnumValN(PGOMapFeaturesEnum::BBFreq, "bb-freq",150"Basic Block Frequency"),151clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob",152"Branch Probability")),153cl::desc(154"Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "155"extracted from PGO related analysis."));156157STATISTIC(EmittedInsts, "Number of machine instrs printed");158159char AsmPrinter::ID = 0;160161namespace {162class AddrLabelMapCallbackPtr final : CallbackVH {163AddrLabelMap *Map = nullptr;164165public:166AddrLabelMapCallbackPtr() = default;167AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {}168169void setPtr(BasicBlock *BB) {170ValueHandleBase::operator=(BB);171}172173void setMap(AddrLabelMap *map) { Map = map; }174175void deleted() override;176void allUsesReplacedWith(Value *V2) override;177};178} // namespace179180class llvm::AddrLabelMap {181MCContext &Context;182struct AddrLabelSymEntry {183/// The symbols for the label.184TinyPtrVector<MCSymbol *> Symbols;185186Function *Fn; // The containing function of the BasicBlock.187unsigned Index; // The index in BBCallbacks for the BasicBlock.188};189190DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;191192/// Callbacks for the BasicBlock's that we have entries for. We use this so193/// we get notified if a block is deleted or RAUWd.194std::vector<AddrLabelMapCallbackPtr> BBCallbacks;195196/// This is a per-function list of symbols whose corresponding BasicBlock got197/// deleted. These symbols need to be emitted at some point in the file, so198/// AsmPrinter emits them after the function body.199DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>200DeletedAddrLabelsNeedingEmission;201202public:203AddrLabelMap(MCContext &context) : Context(context) {}204205~AddrLabelMap() {206assert(DeletedAddrLabelsNeedingEmission.empty() &&207"Some labels for deleted blocks never got emitted");208}209210ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);211212void takeDeletedSymbolsForFunction(Function *F,213std::vector<MCSymbol *> &Result);214215void UpdateForDeletedBlock(BasicBlock *BB);216void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);217};218219ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {220assert(BB->hasAddressTaken() &&221"Shouldn't get label for block without address taken");222AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];223224// If we already had an entry for this block, just return it.225if (!Entry.Symbols.empty()) {226assert(BB->getParent() == Entry.Fn && "Parent changed");227return Entry.Symbols;228}229230// Otherwise, this is a new entry, create a new symbol for it and add an231// entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.232BBCallbacks.emplace_back(BB);233BBCallbacks.back().setMap(this);234Entry.Index = BBCallbacks.size() - 1;235Entry.Fn = BB->getParent();236MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol()237: Context.createTempSymbol();238Entry.Symbols.push_back(Sym);239return Entry.Symbols;240}241242/// If we have any deleted symbols for F, return them.243void AddrLabelMap::takeDeletedSymbolsForFunction(244Function *F, std::vector<MCSymbol *> &Result) {245DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I =246DeletedAddrLabelsNeedingEmission.find(F);247248// If there are no entries for the function, just return.249if (I == DeletedAddrLabelsNeedingEmission.end())250return;251252// Otherwise, take the list.253std::swap(Result, I->second);254DeletedAddrLabelsNeedingEmission.erase(I);255}256257//===- Address of Block Management ----------------------------------------===//258259ArrayRef<MCSymbol *>260AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) {261// Lazily create AddrLabelSymbols.262if (!AddrLabelSymbols)263AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext);264return AddrLabelSymbols->getAddrLabelSymbolToEmit(265const_cast<BasicBlock *>(BB));266}267268void AsmPrinter::takeDeletedSymbolsForFunction(269const Function *F, std::vector<MCSymbol *> &Result) {270// If no blocks have had their addresses taken, we're done.271if (!AddrLabelSymbols)272return;273return AddrLabelSymbols->takeDeletedSymbolsForFunction(274const_cast<Function *>(F), Result);275}276277void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {278// If the block got deleted, there is no need for the symbol. If the symbol279// was already emitted, we can just forget about it, otherwise we need to280// queue it up for later emission when the function is output.281AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);282AddrLabelSymbols.erase(BB);283assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");284BBCallbacks[Entry.Index] = nullptr; // Clear the callback.285286#if !LLVM_MEMORY_SANITIZER_BUILD287// BasicBlock is destroyed already, so this access is UB detectable by msan.288assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&289"Block/parent mismatch");290#endif291292for (MCSymbol *Sym : Entry.Symbols) {293if (Sym->isDefined())294return;295296// If the block is not yet defined, we need to emit it at the end of the297// function. Add the symbol to the DeletedAddrLabelsNeedingEmission list298// for the containing Function. Since the block is being deleted, its299// parent may already be removed, we have to get the function from 'Entry'.300DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);301}302}303304void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {305// Get the entry for the RAUW'd block and remove it from our map.306AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);307AddrLabelSymbols.erase(Old);308assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");309310AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];311312// If New is not address taken, just move our symbol over to it.313if (NewEntry.Symbols.empty()) {314BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.315NewEntry = std::move(OldEntry); // Set New's entry.316return;317}318319BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.320321// Otherwise, we need to add the old symbols to the new block's set.322llvm::append_range(NewEntry.Symbols, OldEntry.Symbols);323}324325void AddrLabelMapCallbackPtr::deleted() {326Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));327}328329void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {330Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));331}332333/// getGVAlignment - Return the alignment to use for the specified global334/// value. This rounds up to the preferred alignment if possible and legal.335Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,336Align InAlign) {337Align Alignment;338if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))339Alignment = DL.getPreferredAlign(GVar);340341// If InAlign is specified, round it to it.342if (InAlign > Alignment)343Alignment = InAlign;344345// If the GV has a specified alignment, take it into account.346const MaybeAlign GVAlign(GV->getAlign());347if (!GVAlign)348return Alignment;349350assert(GVAlign && "GVAlign must be set");351352// If the GVAlign is larger than NumBits, or if we are required to obey353// NumBits because the GV has an assigned section, obey it.354if (*GVAlign > Alignment || GV->hasSection())355Alignment = *GVAlign;356return Alignment;357}358359AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer)360: MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()),361OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)),362SM(*this) {363VerboseAsm = OutStreamer->isVerboseAsm();364DwarfUsesRelocationsAcrossSections =365MAI->doesDwarfUseRelocationsAcrossSections();366}367368AsmPrinter::~AsmPrinter() {369assert(!DD && Handlers.size() == NumUserHandlers &&370"Debug/EH info didn't get finalized");371}372373bool AsmPrinter::isPositionIndependent() const {374return TM.isPositionIndependent();375}376377/// getFunctionNumber - Return a unique ID for the current function.378unsigned AsmPrinter::getFunctionNumber() const {379return MF->getFunctionNumber();380}381382const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {383return *TM.getObjFileLowering();384}385386const DataLayout &AsmPrinter::getDataLayout() const {387assert(MMI && "MMI could not be nullptr!");388return MMI->getModule()->getDataLayout();389}390391// Do not use the cached DataLayout because some client use it without a Module392// (dsymutil, llvm-dwarfdump).393unsigned AsmPrinter::getPointerSize() const {394return TM.getPointerSize(0); // FIXME: Default address space395}396397const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const {398assert(MF && "getSubtargetInfo requires a valid MachineFunction!");399return MF->getSubtarget<MCSubtargetInfo>();400}401402void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {403S.emitInstruction(Inst, getSubtargetInfo());404}405406void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) {407if (DD) {408assert(OutStreamer->hasRawTextSupport() &&409"Expected assembly output mode.");410// This is NVPTX specific and it's unclear why.411// PR51079: If we have code without debug information we need to give up.412DISubprogram *MFSP = MF.getFunction().getSubprogram();413if (!MFSP)414return;415(void)DD->emitInitialLocDirective(MF, /*CUID=*/0);416}417}418419/// getCurrentSection() - Return the current section we are emitting to.420const MCSection *AsmPrinter::getCurrentSection() const {421return OutStreamer->getCurrentSectionOnly();422}423424void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {425AU.setPreservesAll();426MachineFunctionPass::getAnalysisUsage(AU);427AU.addRequired<MachineOptimizationRemarkEmitterPass>();428AU.addRequired<GCModuleInfo>();429AU.addRequired<LazyMachineBlockFrequencyInfoPass>();430AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();431}432433bool AsmPrinter::doInitialization(Module &M) {434auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();435MMI = MMIWP ? &MMIWP->getMMI() : nullptr;436HasSplitStack = false;437HasNoSplitStack = false;438439AddrLabelSymbols = nullptr;440441// Initialize TargetLoweringObjectFile.442const_cast<TargetLoweringObjectFile&>(getObjFileLowering())443.Initialize(OutContext, TM);444445const_cast<TargetLoweringObjectFile &>(getObjFileLowering())446.getModuleMetadata(M);447448// On AIX, we delay emitting any section information until449// after emitting the .file pseudo-op. This allows additional450// information (such as the embedded command line) to be associated451// with all sections in the object file rather than a single section.452if (!TM.getTargetTriple().isOSBinFormatXCOFF())453OutStreamer->initSections(false, *TM.getMCSubtargetInfo());454455// Emit the version-min deployment target directive if needed.456//457// FIXME: If we end up with a collection of these sorts of Darwin-specific458// or ELF-specific things, it may make sense to have a platform helper class459// that will work with the target helper class. For now keep it here, as the460// alternative is duplicated code in each of the target asm printers that461// use the directive, where it would need the same conditionalization462// anyway.463const Triple &Target = TM.getTargetTriple();464if (Target.isOSBinFormatMachO() && Target.isOSDarwin()) {465Triple TVT(M.getDarwinTargetVariantTriple());466OutStreamer->emitVersionForTarget(467Target, M.getSDKVersion(),468M.getDarwinTargetVariantTriple().empty() ? nullptr : &TVT,469M.getDarwinTargetVariantSDKVersion());470}471472// Allow the target to emit any magic that it wants at the start of the file.473emitStartOfAsmFile(M);474475// Very minimal debug info. It is ignored if we emit actual debug info. If we476// don't, this at least helps the user find where a global came from.477if (MAI->hasSingleParameterDotFile()) {478// .file "foo.c"479480SmallString<128> FileName;481if (MAI->hasBasenameOnlyForFileDirective())482FileName = llvm::sys::path::filename(M.getSourceFileName());483else484FileName = M.getSourceFileName();485if (MAI->hasFourStringsDotFile()) {486const char VerStr[] =487#ifdef PACKAGE_VENDOR488PACKAGE_VENDOR " "489#endif490PACKAGE_NAME " version " PACKAGE_VERSION491#ifdef LLVM_REVISION492" (" LLVM_REVISION ")"493#endif494;495// TODO: Add timestamp and description.496OutStreamer->emitFileDirective(FileName, VerStr, "", "");497} else {498OutStreamer->emitFileDirective(FileName);499}500}501502// On AIX, emit bytes for llvm.commandline metadata after .file so that the503// C_INFO symbol is preserved if any csect is kept by the linker.504if (TM.getTargetTriple().isOSBinFormatXCOFF()) {505emitModuleCommandLines(M);506// Now we can generate section information.507OutStreamer->initSections(false, *TM.getMCSubtargetInfo());508509// To work around an AIX assembler and/or linker bug, generate510// a rename for the default text-section symbol name. This call has511// no effect when generating object code directly.512MCSection *TextSection =513OutStreamer->getContext().getObjectFileInfo()->getTextSection();514MCSymbolXCOFF *XSym =515static_cast<MCSectionXCOFF *>(TextSection)->getQualNameSymbol();516if (XSym->hasRename())517OutStreamer->emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());518}519520GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();521assert(MI && "AsmPrinter didn't require GCModuleInfo?");522for (const auto &I : *MI)523if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))524MP->beginAssembly(M, *MI, *this);525526// Emit module-level inline asm if it exists.527if (!M.getModuleInlineAsm().empty()) {528OutStreamer->AddComment("Start of file scope inline assembly");529OutStreamer->addBlankLine();530emitInlineAsm(531M.getModuleInlineAsm() + "\n", *TM.getMCSubtargetInfo(),532TM.Options.MCOptions, nullptr,533InlineAsm::AsmDialect(TM.getMCAsmInfo()->getAssemblerDialect()));534OutStreamer->AddComment("End of file scope inline assembly");535OutStreamer->addBlankLine();536}537538if (MAI->doesSupportDebugInformation()) {539bool EmitCodeView = M.getCodeViewFlag();540if (EmitCodeView && TM.getTargetTriple().isOSWindows())541DebugHandlers.push_back(std::make_unique<CodeViewDebug>(this));542if (!EmitCodeView || M.getDwarfVersion()) {543assert(MMI && "MMI could not be nullptr here!");544if (MMI->hasDebugInfo()) {545DD = new DwarfDebug(this);546DebugHandlers.push_back(std::unique_ptr<DwarfDebug>(DD));547}548}549}550551if (M.getNamedMetadata(PseudoProbeDescMetadataName))552PP = std::make_unique<PseudoProbeHandler>(this);553554switch (MAI->getExceptionHandlingType()) {555case ExceptionHandling::None:556// We may want to emit CFI for debug.557[[fallthrough]];558case ExceptionHandling::SjLj:559case ExceptionHandling::DwarfCFI:560case ExceptionHandling::ARM:561for (auto &F : M.getFunctionList()) {562if (getFunctionCFISectionType(F) != CFISection::None)563ModuleCFISection = getFunctionCFISectionType(F);564// If any function needsUnwindTableEntry(), it needs .eh_frame and hence565// the module needs .eh_frame. If we have found that case, we are done.566if (ModuleCFISection == CFISection::EH)567break;568}569assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI ||570usesCFIWithoutEH() || ModuleCFISection != CFISection::EH);571break;572default:573break;574}575576EHStreamer *ES = nullptr;577switch (MAI->getExceptionHandlingType()) {578case ExceptionHandling::None:579if (!usesCFIWithoutEH())580break;581[[fallthrough]];582case ExceptionHandling::SjLj:583case ExceptionHandling::DwarfCFI:584case ExceptionHandling::ZOS:585ES = new DwarfCFIException(this);586break;587case ExceptionHandling::ARM:588ES = new ARMException(this);589break;590case ExceptionHandling::WinEH:591switch (MAI->getWinEHEncodingType()) {592default: llvm_unreachable("unsupported unwinding information encoding");593case WinEH::EncodingType::Invalid:594break;595case WinEH::EncodingType::X86:596case WinEH::EncodingType::Itanium:597ES = new WinException(this);598break;599}600break;601case ExceptionHandling::Wasm:602ES = new WasmException(this);603break;604case ExceptionHandling::AIX:605ES = new AIXException(this);606break;607}608if (ES)609Handlers.push_back(std::unique_ptr<EHStreamer>(ES));610611// Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2).612if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))613Handlers.push_back(std::make_unique<WinCFGuard>(this));614615for (auto &Handler : DebugHandlers)616Handler->beginModule(&M);617for (auto &Handler : Handlers)618Handler->beginModule(&M);619620return false;621}622623static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI) {624if (!MAI.hasWeakDefCanBeHiddenDirective())625return false;626627return GV->canBeOmittedFromSymbolTable();628}629630void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {631GlobalValue::LinkageTypes Linkage = GV->getLinkage();632switch (Linkage) {633case GlobalValue::CommonLinkage:634case GlobalValue::LinkOnceAnyLinkage:635case GlobalValue::LinkOnceODRLinkage:636case GlobalValue::WeakAnyLinkage:637case GlobalValue::WeakODRLinkage:638if (MAI->hasWeakDefDirective()) {639// .globl _foo640OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);641642if (!canBeHidden(GV, *MAI))643// .weak_definition _foo644OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefinition);645else646OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate);647} else if (MAI->avoidWeakIfComdat() && GV->hasComdat()) {648// .globl _foo649OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);650//NOTE: linkonce is handled by the section the symbol was assigned to.651} else {652// .weak _foo653OutStreamer->emitSymbolAttribute(GVSym, MCSA_Weak);654}655return;656case GlobalValue::ExternalLinkage:657OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);658return;659case GlobalValue::PrivateLinkage:660case GlobalValue::InternalLinkage:661return;662case GlobalValue::ExternalWeakLinkage:663case GlobalValue::AvailableExternallyLinkage:664case GlobalValue::AppendingLinkage:665llvm_unreachable("Should never emit this");666}667llvm_unreachable("Unknown linkage type!");668}669670void AsmPrinter::getNameWithPrefix(SmallVectorImpl<char> &Name,671const GlobalValue *GV) const {672TM.getNameWithPrefix(Name, GV, getObjFileLowering().getMangler());673}674675MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const {676return TM.getSymbol(GV);677}678679MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {680// On ELF, use .Lfoo$local if GV is a non-interposable GlobalObject with an681// exact definion (intersection of GlobalValue::hasExactDefinition() and682// !isInterposable()). These linkages include: external, appending, internal,683// private. It may be profitable to use a local alias for external. The684// assembler would otherwise be conservative and assume a global default685// visibility symbol can be interposable, even if the code generator already686// assumed it.687if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) {688const Module &M = *GV.getParent();689if (TM.getRelocationModel() != Reloc::Static &&690M.getPIELevel() == PIELevel::Default && GV.isDSOLocal())691return getSymbolWithGlobalValueBase(&GV, "$local");692}693return TM.getSymbol(&GV);694}695696/// EmitGlobalVariable - Emit the specified global variable to the .s file.697void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {698bool IsEmuTLSVar = TM.useEmulatedTLS() && GV->isThreadLocal();699assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) &&700"No emulated TLS variables in the common section");701702// Never emit TLS variable xyz in emulated TLS model.703// The initialization value is in __emutls_t.xyz instead of xyz.704if (IsEmuTLSVar)705return;706707if (GV->hasInitializer()) {708// Check to see if this is a special global used by LLVM, if so, emit it.709if (emitSpecialLLVMGlobal(GV))710return;711712// Skip the emission of global equivalents. The symbol can be emitted later713// on by emitGlobalGOTEquivs in case it turns out to be needed.714if (GlobalGOTEquivs.count(getSymbol(GV)))715return;716717if (isVerbose()) {718// When printing the control variable __emutls_v.*,719// we don't need to print the original TLS variable name.720GV->printAsOperand(OutStreamer->getCommentOS(),721/*PrintType=*/false, GV->getParent());722OutStreamer->getCommentOS() << '\n';723}724}725726MCSymbol *GVSym = getSymbol(GV);727MCSymbol *EmittedSym = GVSym;728729// getOrCreateEmuTLSControlSym only creates the symbol with name and default730// attributes.731// GV's or GVSym's attributes will be used for the EmittedSym.732emitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration());733734if (GV->isTagged()) {735Triple T = TM.getTargetTriple();736737if (T.getArch() != Triple::aarch64 || !T.isAndroid())738OutContext.reportError(SMLoc(),739"tagged symbols (-fsanitize=memtag-globals) are "740"only supported on AArch64 Android");741OutStreamer->emitSymbolAttribute(EmittedSym, MAI->getMemtagAttr());742}743744if (!GV->hasInitializer()) // External globals require no extra code.745return;746747GVSym->redefineIfPossible();748if (GVSym->isDefined() || GVSym->isVariable())749OutContext.reportError(SMLoc(), "symbol '" + Twine(GVSym->getName()) +750"' is already defined");751752if (MAI->hasDotTypeDotSizeDirective())753OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);754755SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);756757const DataLayout &DL = GV->getDataLayout();758uint64_t Size = DL.getTypeAllocSize(GV->getValueType());759760// If the alignment is specified, we *must* obey it. Overaligning a global761// with a specified alignment is a prompt way to break globals emitted to762// sections and expected to be contiguous (e.g. ObjC metadata).763const Align Alignment = getGVAlignment(GV, DL);764765for (auto &Handler : DebugHandlers)766Handler->setSymbolSize(GVSym, Size);767768// Handle common symbols769if (GVKind.isCommon()) {770if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.771// .comm _foo, 42, 4772OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);773return;774}775776// Determine to which section this global should be emitted.777MCSection *TheSection = getObjFileLowering().SectionForGlobal(GV, GVKind, TM);778779// If we have a bss global going to a section that supports the780// zerofill directive, do so here.781if (GVKind.isBSS() && MAI->hasMachoZeroFillDirective() &&782TheSection->isVirtualSection()) {783if (Size == 0)784Size = 1; // zerofill of 0 bytes is undefined.785emitLinkage(GV, GVSym);786// .zerofill __DATA, __bss, _foo, 400, 5787OutStreamer->emitZerofill(TheSection, GVSym, Size, Alignment);788return;789}790791// If this is a BSS local symbol and we are emitting in the BSS792// section use .lcomm/.comm directive.793if (GVKind.isBSSLocal() &&794getObjFileLowering().getBSSSection() == TheSection) {795if (Size == 0)796Size = 1; // .comm Foo, 0 is undefined, avoid it.797798// Use .lcomm only if it supports user-specified alignment.799// Otherwise, while it would still be correct to use .lcomm in some800// cases (e.g. when Align == 1), the external assembler might enfore801// some -unknown- default alignment behavior, which could cause802// spurious differences between external and integrated assembler.803// Prefer to simply fall back to .local / .comm in this case.804if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {805// .lcomm _foo, 42806OutStreamer->emitLocalCommonSymbol(GVSym, Size, Alignment);807return;808}809810// .local _foo811OutStreamer->emitSymbolAttribute(GVSym, MCSA_Local);812// .comm _foo, 42, 4813OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);814return;815}816817// Handle thread local data for mach-o which requires us to output an818// additional structure of data and mangle the original symbol so that we819// can reference it later.820//821// TODO: This should become an "emit thread local global" method on TLOF.822// All of this macho specific stuff should be sunk down into TLOFMachO and823// stuff like "TLSExtraDataSection" should no longer be part of the parent824// TLOF class. This will also make it more obvious that stuff like825// MCStreamer::EmitTBSSSymbol is macho specific and only called from macho826// specific code.827if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) {828// Emit the .tbss symbol829MCSymbol *MangSym =830OutContext.getOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));831832if (GVKind.isThreadBSS()) {833TheSection = getObjFileLowering().getTLSBSSSection();834OutStreamer->emitTBSSSymbol(TheSection, MangSym, Size, Alignment);835} else if (GVKind.isThreadData()) {836OutStreamer->switchSection(TheSection);837838emitAlignment(Alignment, GV);839OutStreamer->emitLabel(MangSym);840841emitGlobalConstant(GV->getDataLayout(),842GV->getInitializer());843}844845OutStreamer->addBlankLine();846847// Emit the variable struct for the runtime.848MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection();849850OutStreamer->switchSection(TLVSect);851// Emit the linkage here.852emitLinkage(GV, GVSym);853OutStreamer->emitLabel(GVSym);854855// Three pointers in size:856// - __tlv_bootstrap - used to make sure support exists857// - spare pointer, used when mapped by the runtime858// - pointer to mangled symbol above with initializer859unsigned PtrSize = DL.getPointerTypeSize(GV->getType());860OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),861PtrSize);862OutStreamer->emitIntValue(0, PtrSize);863OutStreamer->emitSymbolValue(MangSym, PtrSize);864865OutStreamer->addBlankLine();866return;867}868869MCSymbol *EmittedInitSym = GVSym;870871OutStreamer->switchSection(TheSection);872873emitLinkage(GV, EmittedInitSym);874emitAlignment(Alignment, GV);875876OutStreamer->emitLabel(EmittedInitSym);877MCSymbol *LocalAlias = getSymbolPreferLocal(*GV);878if (LocalAlias != EmittedInitSym)879OutStreamer->emitLabel(LocalAlias);880881emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());882883if (MAI->hasDotTypeDotSizeDirective())884// .size foo, 42885OutStreamer->emitELFSize(EmittedInitSym,886MCConstantExpr::create(Size, OutContext));887888OutStreamer->addBlankLine();889}890891/// Emit the directive and value for debug thread local expression892///893/// \p Value - The value to emit.894/// \p Size - The size of the integer (in bytes) to emit.895void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {896OutStreamer->emitValue(Value, Size);897}898899void AsmPrinter::emitFunctionHeaderComment() {}900901void AsmPrinter::emitFunctionPrefix(ArrayRef<const Constant *> Prefix) {902const Function &F = MF->getFunction();903if (!MAI->hasSubsectionsViaSymbols()) {904for (auto &C : Prefix)905emitGlobalConstant(F.getDataLayout(), C);906return;907}908// Preserving prefix-like data on platforms which use subsections-via-symbols909// is a bit tricky. Here we introduce a symbol for the prefix-like data910// and use the .alt_entry attribute to mark the function's real entry point911// as an alternative entry point to the symbol that precedes the function..912OutStreamer->emitLabel(OutContext.createLinkerPrivateTempSymbol());913914for (auto &C : Prefix) {915emitGlobalConstant(F.getDataLayout(), C);916}917918// Emit an .alt_entry directive for the actual function symbol.919OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);920}921922/// EmitFunctionHeader - This method emits the header for the current923/// function.924void AsmPrinter::emitFunctionHeader() {925const Function &F = MF->getFunction();926927if (isVerbose())928OutStreamer->getCommentOS()929<< "-- Begin function "930<< GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';931932// Print out constants referenced by the function933emitConstantPool();934935// Print the 'header' of function.936// If basic block sections are desired, explicitly request a unique section937// for this function's entry block.938if (MF->front().isBeginSection())939MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM));940else941MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM));942OutStreamer->switchSection(MF->getSection());943944if (!MAI->hasVisibilityOnlyWithLinkage())945emitVisibility(CurrentFnSym, F.getVisibility());946947if (MAI->needsFunctionDescriptors())948emitLinkage(&F, CurrentFnDescSym);949950emitLinkage(&F, CurrentFnSym);951if (MAI->hasFunctionAlignment())952emitAlignment(MF->getAlignment(), &F);953954if (MAI->hasDotTypeDotSizeDirective())955OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);956957if (F.hasFnAttribute(Attribute::Cold))958OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);959960// Emit the prefix data.961if (F.hasPrefixData())962emitFunctionPrefix({F.getPrefixData()});963964// Emit KCFI type information before patchable-function-prefix nops.965emitKCFITypeId(*MF);966967// Emit M NOPs for -fpatchable-function-entry=N,M where M>0. We arbitrarily968// place prefix data before NOPs.969unsigned PatchableFunctionPrefix = 0;970unsigned PatchableFunctionEntry = 0;971(void)F.getFnAttribute("patchable-function-prefix")972.getValueAsString()973.getAsInteger(10, PatchableFunctionPrefix);974(void)F.getFnAttribute("patchable-function-entry")975.getValueAsString()976.getAsInteger(10, PatchableFunctionEntry);977if (PatchableFunctionPrefix) {978CurrentPatchableFunctionEntrySym =979OutContext.createLinkerPrivateTempSymbol();980OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym);981emitNops(PatchableFunctionPrefix);982} else if (PatchableFunctionEntry) {983// May be reassigned when emitting the body, to reference the label after984// the initial BTI (AArch64) or endbr32/endbr64 (x86).985CurrentPatchableFunctionEntrySym = CurrentFnBegin;986}987988// Emit the function prologue data for the indirect call sanitizer.989if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {990assert(MD->getNumOperands() == 2);991992auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));993auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1));994emitFunctionPrefix({PrologueSig, TypeHash});995}996997if (isVerbose()) {998F.printAsOperand(OutStreamer->getCommentOS(),999/*PrintType=*/false, F.getParent());1000emitFunctionHeaderComment();1001OutStreamer->getCommentOS() << '\n';1002}10031004// Emit the function descriptor. This is a virtual function to allow targets1005// to emit their specific function descriptor. Right now it is only used by1006// the AIX target. The PowerPC 64-bit V1 ELF target also uses function1007// descriptors and should be converted to use this hook as well.1008if (MAI->needsFunctionDescriptors())1009emitFunctionDescriptor();10101011// Emit the CurrentFnSym. This is a virtual function to allow targets to do1012// their wild and crazy things as required.1013emitFunctionEntryLabel();10141015// If the function had address-taken blocks that got deleted, then we have1016// references to the dangling symbols. Emit them at the start of the function1017// so that we don't get references to undefined symbols.1018std::vector<MCSymbol*> DeadBlockSyms;1019takeDeletedSymbolsForFunction(&F, DeadBlockSyms);1020for (MCSymbol *DeadBlockSym : DeadBlockSyms) {1021OutStreamer->AddComment("Address taken block that was later removed");1022OutStreamer->emitLabel(DeadBlockSym);1023}10241025if (CurrentFnBegin) {1026if (MAI->useAssignmentForEHBegin()) {1027MCSymbol *CurPos = OutContext.createTempSymbol();1028OutStreamer->emitLabel(CurPos);1029OutStreamer->emitAssignment(CurrentFnBegin,1030MCSymbolRefExpr::create(CurPos, OutContext));1031} else {1032OutStreamer->emitLabel(CurrentFnBegin);1033}1034}10351036// Emit pre-function debug and/or EH information.1037for (auto &Handler : DebugHandlers) {1038Handler->beginFunction(MF);1039Handler->beginBasicBlockSection(MF->front());1040}1041for (auto &Handler : Handlers)1042Handler->beginFunction(MF);1043for (auto &Handler : Handlers)1044Handler->beginBasicBlockSection(MF->front());10451046// Emit the prologue data.1047if (F.hasPrologueData())1048emitGlobalConstant(F.getDataLayout(), F.getPrologueData());1049}10501051/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the1052/// function. This can be overridden by targets as required to do custom stuff.1053void AsmPrinter::emitFunctionEntryLabel() {1054CurrentFnSym->redefineIfPossible();10551056// The function label could have already been emitted if two symbols end up1057// conflicting due to asm renaming. Detect this and emit an error.1058if (CurrentFnSym->isVariable())1059report_fatal_error("'" + Twine(CurrentFnSym->getName()) +1060"' is a protected alias");10611062OutStreamer->emitLabel(CurrentFnSym);10631064if (TM.getTargetTriple().isOSBinFormatELF()) {1065MCSymbol *Sym = getSymbolPreferLocal(MF->getFunction());1066if (Sym != CurrentFnSym) {1067cast<MCSymbolELF>(Sym)->setType(ELF::STT_FUNC);1068CurrentFnBeginLocal = Sym;1069OutStreamer->emitLabel(Sym);1070if (MAI->hasDotTypeDotSizeDirective())1071OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);1072}1073}1074}10751076/// emitComments - Pretty-print comments for instructions.1077static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS) {1078const MachineFunction *MF = MI.getMF();1079const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();10801081// Check for spills and reloads10821083// We assume a single instruction only has a spill or reload, not1084// both.1085std::optional<LocationSize> Size;1086if ((Size = MI.getRestoreSize(TII))) {1087CommentOS << Size->getValue() << "-byte Reload\n";1088} else if ((Size = MI.getFoldedRestoreSize(TII))) {1089if (!Size->hasValue())1090CommentOS << "Unknown-size Folded Reload\n";1091else if (Size->getValue())1092CommentOS << Size->getValue() << "-byte Folded Reload\n";1093} else if ((Size = MI.getSpillSize(TII))) {1094CommentOS << Size->getValue() << "-byte Spill\n";1095} else if ((Size = MI.getFoldedSpillSize(TII))) {1096if (!Size->hasValue())1097CommentOS << "Unknown-size Folded Spill\n";1098else if (Size->getValue())1099CommentOS << Size->getValue() << "-byte Folded Spill\n";1100}11011102// Check for spill-induced copies1103if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse))1104CommentOS << " Reload Reuse\n";1105}11061107/// emitImplicitDef - This method emits the specified machine instruction1108/// that is an implicit def.1109void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const {1110Register RegNo = MI->getOperand(0).getReg();11111112SmallString<128> Str;1113raw_svector_ostream OS(Str);1114OS << "implicit-def: "1115<< printReg(RegNo, MF->getSubtarget().getRegisterInfo());11161117OutStreamer->AddComment(OS.str());1118OutStreamer->addBlankLine();1119}11201121static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {1122std::string Str;1123raw_string_ostream OS(Str);1124OS << "kill:";1125for (const MachineOperand &Op : MI->operands()) {1126assert(Op.isReg() && "KILL instruction must have only register operands");1127OS << ' ' << (Op.isDef() ? "def " : "killed ")1128<< printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo());1129}1130AP.OutStreamer->AddComment(Str);1131AP.OutStreamer->addBlankLine();1132}11331134/// emitDebugValueComment - This method handles the target-independent form1135/// of DBG_VALUE, returning true if it was able to do so. A false return1136/// means the target will need to handle MI in EmitInstruction.1137static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {1138// This code handles only the 4-operand target-independent form.1139if (MI->isNonListDebugValue() && MI->getNumOperands() != 4)1140return false;11411142SmallString<128> Str;1143raw_svector_ostream OS(Str);1144OS << "DEBUG_VALUE: ";11451146const DILocalVariable *V = MI->getDebugVariable();1147if (auto *SP = dyn_cast<DISubprogram>(V->getScope())) {1148StringRef Name = SP->getName();1149if (!Name.empty())1150OS << Name << ":";1151}1152OS << V->getName();1153OS << " <- ";11541155const DIExpression *Expr = MI->getDebugExpression();1156// First convert this to a non-variadic expression if possible, to simplify1157// the output.1158if (auto NonVariadicExpr = DIExpression::convertToNonVariadicExpression(Expr))1159Expr = *NonVariadicExpr;1160// Then, output the possibly-simplified expression.1161if (Expr->getNumElements()) {1162OS << '[';1163ListSeparator LS;1164for (auto &Op : Expr->expr_ops()) {1165OS << LS << dwarf::OperationEncodingString(Op.getOp());1166for (unsigned I = 0; I < Op.getNumArgs(); ++I)1167OS << ' ' << Op.getArg(I);1168}1169OS << "] ";1170}11711172// Register or immediate value. Register 0 means undef.1173for (const MachineOperand &Op : MI->debug_operands()) {1174if (&Op != MI->debug_operands().begin())1175OS << ", ";1176switch (Op.getType()) {1177case MachineOperand::MO_FPImmediate: {1178APFloat APF = APFloat(Op.getFPImm()->getValueAPF());1179Type *ImmTy = Op.getFPImm()->getType();1180if (ImmTy->isBFloatTy() || ImmTy->isHalfTy() || ImmTy->isFloatTy() ||1181ImmTy->isDoubleTy()) {1182OS << APF.convertToDouble();1183} else {1184// There is no good way to print long double. Convert a copy to1185// double. Ah well, it's only a comment.1186bool ignored;1187APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,1188&ignored);1189OS << "(long double) " << APF.convertToDouble();1190}1191break;1192}1193case MachineOperand::MO_Immediate: {1194OS << Op.getImm();1195break;1196}1197case MachineOperand::MO_CImmediate: {1198Op.getCImm()->getValue().print(OS, false /*isSigned*/);1199break;1200}1201case MachineOperand::MO_TargetIndex: {1202OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";1203break;1204}1205case MachineOperand::MO_Register:1206case MachineOperand::MO_FrameIndex: {1207Register Reg;1208std::optional<StackOffset> Offset;1209if (Op.isReg()) {1210Reg = Op.getReg();1211} else {1212const TargetFrameLowering *TFI =1213AP.MF->getSubtarget().getFrameLowering();1214Offset = TFI->getFrameIndexReference(*AP.MF, Op.getIndex(), Reg);1215}1216if (!Reg) {1217// Suppress offset, it is not meaningful here.1218OS << "undef";1219break;1220}1221// The second operand is only an offset if it's an immediate.1222if (MI->isIndirectDebugValue())1223Offset = StackOffset::getFixed(MI->getDebugOffset().getImm());1224if (Offset)1225OS << '[';1226OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());1227if (Offset)1228OS << '+' << Offset->getFixed() << ']';1229break;1230}1231default:1232llvm_unreachable("Unknown operand type");1233}1234}12351236// NOTE: Want this comment at start of line, don't emit with AddComment.1237AP.OutStreamer->emitRawComment(Str);1238return true;1239}12401241/// This method handles the target-independent form of DBG_LABEL, returning1242/// true if it was able to do so. A false return means the target will need1243/// to handle MI in EmitInstruction.1244static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP) {1245if (MI->getNumOperands() != 1)1246return false;12471248SmallString<128> Str;1249raw_svector_ostream OS(Str);1250OS << "DEBUG_LABEL: ";12511252const DILabel *V = MI->getDebugLabel();1253if (auto *SP = dyn_cast<DISubprogram>(1254V->getScope()->getNonLexicalBlockFileScope())) {1255StringRef Name = SP->getName();1256if (!Name.empty())1257OS << Name << ":";1258}1259OS << V->getName();12601261// NOTE: Want this comment at start of line, don't emit with AddComment.1262AP.OutStreamer->emitRawComment(OS.str());1263return true;1264}12651266AsmPrinter::CFISection1267AsmPrinter::getFunctionCFISectionType(const Function &F) const {1268// Ignore functions that won't get emitted.1269if (F.isDeclarationForLinker())1270return CFISection::None;12711272if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&1273F.needsUnwindTableEntry())1274return CFISection::EH;12751276if (MAI->usesCFIWithoutEH() && F.hasUWTable())1277return CFISection::EH;12781279assert(MMI != nullptr && "Invalid machine module info");1280if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection)1281return CFISection::Debug;12821283return CFISection::None;1284}12851286AsmPrinter::CFISection1287AsmPrinter::getFunctionCFISectionType(const MachineFunction &MF) const {1288return getFunctionCFISectionType(MF.getFunction());1289}12901291bool AsmPrinter::needsSEHMoves() {1292return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry();1293}12941295bool AsmPrinter::usesCFIWithoutEH() const {1296return MAI->usesCFIWithoutEH() && ModuleCFISection != CFISection::None;1297}12981299void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {1300ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();1301if (!usesCFIWithoutEH() &&1302ExceptionHandlingType != ExceptionHandling::DwarfCFI &&1303ExceptionHandlingType != ExceptionHandling::ARM)1304return;13051306if (getFunctionCFISectionType(*MF) == CFISection::None)1307return;13081309// If there is no "real" instruction following this CFI instruction, skip1310// emitting it; it would be beyond the end of the function's FDE range.1311auto *MBB = MI.getParent();1312auto I = std::next(MI.getIterator());1313while (I != MBB->end() && I->isTransient())1314++I;1315if (I == MBB->instr_end() &&1316MBB->getReverseIterator() == MBB->getParent()->rbegin())1317return;13181319const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions();1320unsigned CFIIndex = MI.getOperand(0).getCFIIndex();1321const MCCFIInstruction &CFI = Instrs[CFIIndex];1322emitCFIInstruction(CFI);1323}13241325void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {1326// The operands are the MCSymbol and the frame offset of the allocation.1327MCSymbol *FrameAllocSym = MI.getOperand(0).getMCSymbol();1328int FrameOffset = MI.getOperand(1).getImm();13291330// Emit a symbol assignment.1331OutStreamer->emitAssignment(FrameAllocSym,1332MCConstantExpr::create(FrameOffset, OutContext));1333}13341335/// Returns the BB metadata to be emitted in the SHT_LLVM_BB_ADDR_MAP section1336/// for a given basic block. This can be used to capture more precise profile1337/// information.1338static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) {1339const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();1340return object::BBAddrMap::BBEntry::Metadata{1341MBB.isReturnBlock(), !MBB.empty() && TII->isTailCall(MBB.back()),1342MBB.isEHPad(), const_cast<MachineBasicBlock &>(MBB).canFallThrough(),1343!MBB.empty() && MBB.rbegin()->isIndirectBranch()}1344.encode();1345}13461347static llvm::object::BBAddrMap::Features1348getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges) {1349return {PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::FuncEntryCount),1350PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BBFreq),1351PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb),1352MF.hasBBSections() && NumMBBSectionRanges > 1};1353}13541355void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {1356MCSection *BBAddrMapSection =1357getObjFileLowering().getBBAddrMapSection(*MF.getSection());1358assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized.");13591360const MCSymbol *FunctionSymbol = getFunctionBegin();13611362OutStreamer->pushSection();1363OutStreamer->switchSection(BBAddrMapSection);1364OutStreamer->AddComment("version");1365uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion();1366OutStreamer->emitInt8(BBAddrMapVersion);1367OutStreamer->AddComment("feature");1368auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size());1369OutStreamer->emitInt8(Features.encode());1370// Emit BB Information for each basic block in the function.1371if (Features.MultiBBRange) {1372OutStreamer->AddComment("number of basic block ranges");1373OutStreamer->emitULEB128IntValue(MBBSectionRanges.size());1374}1375// Number of blocks in each MBB section.1376MapVector<MBBSectionID, unsigned> MBBSectionNumBlocks;1377const MCSymbol *PrevMBBEndSymbol = nullptr;1378if (!Features.MultiBBRange) {1379OutStreamer->AddComment("function address");1380OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());1381OutStreamer->AddComment("number of basic blocks");1382OutStreamer->emitULEB128IntValue(MF.size());1383PrevMBBEndSymbol = FunctionSymbol;1384} else {1385unsigned BBCount = 0;1386for (const MachineBasicBlock &MBB : MF) {1387BBCount++;1388if (MBB.isEndSection()) {1389// Store each section's basic block count when it ends.1390MBBSectionNumBlocks[MBB.getSectionID()] = BBCount;1391// Reset the count for the next section.1392BBCount = 0;1393}1394}1395}1396// Emit the BB entry for each basic block in the function.1397for (const MachineBasicBlock &MBB : MF) {1398const MCSymbol *MBBSymbol =1399MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();1400bool IsBeginSection =1401Features.MultiBBRange && (MBB.isBeginSection() || MBB.isEntryBlock());1402if (IsBeginSection) {1403OutStreamer->AddComment("base address");1404OutStreamer->emitSymbolValue(MBBSymbol, getPointerSize());1405OutStreamer->AddComment("number of basic blocks");1406OutStreamer->emitULEB128IntValue(MBBSectionNumBlocks[MBB.getSectionID()]);1407PrevMBBEndSymbol = MBBSymbol;1408}1409// TODO: Remove this check when version 1 is deprecated.1410if (BBAddrMapVersion > 1) {1411OutStreamer->AddComment("BB id");1412// Emit the BB ID for this basic block.1413// We only emit BaseID since CloneID is unset for1414// basic-block-sections=labels.1415// TODO: Emit the full BBID when labels and sections can be mixed1416// together.1417OutStreamer->emitULEB128IntValue(MBB.getBBID()->BaseID);1418}1419// Emit the basic block offset relative to the end of the previous block.1420// This is zero unless the block is padded due to alignment.1421emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol);1422// Emit the basic block size. When BBs have alignments, their size cannot1423// always be computed from their offsets.1424emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), MBBSymbol);1425// Emit the Metadata.1426OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));1427PrevMBBEndSymbol = MBB.getEndSymbol();1428}14291430if (Features.hasPGOAnalysis()) {1431assert(BBAddrMapVersion >= 2 &&1432"PGOAnalysisMap only supports version 2 or later");14331434if (Features.FuncEntryCount) {1435OutStreamer->AddComment("function entry count");1436auto MaybeEntryCount = MF.getFunction().getEntryCount();1437OutStreamer->emitULEB128IntValue(1438MaybeEntryCount ? MaybeEntryCount->getCount() : 0);1439}1440const MachineBlockFrequencyInfo *MBFI =1441Features.BBFreq1442? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()1443: nullptr;1444const MachineBranchProbabilityInfo *MBPI =1445Features.BrProb1446? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()1447: nullptr;14481449if (Features.BBFreq || Features.BrProb) {1450for (const MachineBasicBlock &MBB : MF) {1451if (Features.BBFreq) {1452OutStreamer->AddComment("basic block frequency");1453OutStreamer->emitULEB128IntValue(1454MBFI->getBlockFreq(&MBB).getFrequency());1455}1456if (Features.BrProb) {1457unsigned SuccCount = MBB.succ_size();1458OutStreamer->AddComment("basic block successor count");1459OutStreamer->emitULEB128IntValue(SuccCount);1460for (const MachineBasicBlock *SuccMBB : MBB.successors()) {1461OutStreamer->AddComment("successor BB ID");1462OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);1463OutStreamer->AddComment("successor branch probability");1464OutStreamer->emitULEB128IntValue(1465MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());1466}1467}1468}1469}1470}14711472OutStreamer->popSection();1473}14741475void AsmPrinter::emitKCFITrapEntry(const MachineFunction &MF,1476const MCSymbol *Symbol) {1477MCSection *Section =1478getObjFileLowering().getKCFITrapSection(*MF.getSection());1479if (!Section)1480return;14811482OutStreamer->pushSection();1483OutStreamer->switchSection(Section);14841485MCSymbol *Loc = OutContext.createLinkerPrivateTempSymbol();1486OutStreamer->emitLabel(Loc);1487OutStreamer->emitAbsoluteSymbolDiff(Symbol, Loc, 4);14881489OutStreamer->popSection();1490}14911492void AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {1493const Function &F = MF.getFunction();1494if (const MDNode *MD = F.getMetadata(LLVMContext::MD_kcfi_type))1495emitGlobalConstant(F.getDataLayout(),1496mdconst::extract<ConstantInt>(MD->getOperand(0)));1497}14981499void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) {1500if (PP) {1501auto GUID = MI.getOperand(0).getImm();1502auto Index = MI.getOperand(1).getImm();1503auto Type = MI.getOperand(2).getImm();1504auto Attr = MI.getOperand(3).getImm();1505DILocation *DebugLoc = MI.getDebugLoc();1506PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc);1507}1508}15091510void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {1511if (!MF.getTarget().Options.EmitStackSizeSection)1512return;15131514MCSection *StackSizeSection =1515getObjFileLowering().getStackSizesSection(*getCurrentSection());1516if (!StackSizeSection)1517return;15181519const MachineFrameInfo &FrameInfo = MF.getFrameInfo();1520// Don't emit functions with dynamic stack allocations.1521if (FrameInfo.hasVarSizedObjects())1522return;15231524OutStreamer->pushSection();1525OutStreamer->switchSection(StackSizeSection);15261527const MCSymbol *FunctionSymbol = getFunctionBegin();1528uint64_t StackSize =1529FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize();1530OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());1531OutStreamer->emitULEB128IntValue(StackSize);15321533OutStreamer->popSection();1534}15351536void AsmPrinter::emitStackUsage(const MachineFunction &MF) {1537const std::string &OutputFilename = MF.getTarget().Options.StackUsageOutput;15381539// OutputFilename empty implies -fstack-usage is not passed.1540if (OutputFilename.empty())1541return;15421543const MachineFrameInfo &FrameInfo = MF.getFrameInfo();1544uint64_t StackSize =1545FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize();15461547if (StackUsageStream == nullptr) {1548std::error_code EC;1549StackUsageStream =1550std::make_unique<raw_fd_ostream>(OutputFilename, EC, sys::fs::OF_Text);1551if (EC) {1552errs() << "Could not open file: " << EC.message();1553return;1554}1555}15561557if (const DISubprogram *DSP = MF.getFunction().getSubprogram())1558*StackUsageStream << DSP->getFilename() << ':' << DSP->getLine();1559else1560*StackUsageStream << MF.getFunction().getParent()->getName();15611562*StackUsageStream << ':' << MF.getName() << '\t' << StackSize << '\t';1563if (FrameInfo.hasVarSizedObjects())1564*StackUsageStream << "dynamic\n";1565else1566*StackUsageStream << "static\n";1567}15681569void AsmPrinter::emitPCSectionsLabel(const MachineFunction &MF,1570const MDNode &MD) {1571MCSymbol *S = MF.getContext().createTempSymbol("pcsection");1572OutStreamer->emitLabel(S);1573PCSectionsSymbols[&MD].emplace_back(S);1574}15751576void AsmPrinter::emitPCSections(const MachineFunction &MF) {1577const Function &F = MF.getFunction();1578if (PCSectionsSymbols.empty() && !F.hasMetadata(LLVMContext::MD_pcsections))1579return;15801581const CodeModel::Model CM = MF.getTarget().getCodeModel();1582const unsigned RelativeRelocSize =1583(CM == CodeModel::Medium || CM == CodeModel::Large) ? getPointerSize()1584: 4;15851586// Switch to PCSection, short-circuiting the common case where the current1587// section is still valid (assume most MD_pcsections contain just 1 section).1588auto SwitchSection = [&, Prev = StringRef()](const StringRef &Sec) mutable {1589if (Sec == Prev)1590return;1591MCSection *S = getObjFileLowering().getPCSection(Sec, MF.getSection());1592assert(S && "PC section is not initialized");1593OutStreamer->switchSection(S);1594Prev = Sec;1595};1596// Emit symbols into sections and data as specified in the pcsections MDNode.1597auto EmitForMD = [&](const MDNode &MD, ArrayRef<const MCSymbol *> Syms,1598bool Deltas) {1599// Expect the first operand to be a section name. After that, a tuple of1600// constants may appear, which will simply be emitted into the current1601// section (the user of MD_pcsections decides the format of encoded data).1602assert(isa<MDString>(MD.getOperand(0)) && "first operand not a string");1603bool ConstULEB128 = false;1604for (const MDOperand &MDO : MD.operands()) {1605if (auto *S = dyn_cast<MDString>(MDO)) {1606// Found string, start of new section!1607// Find options for this section "<section>!<opts>" - supported options:1608// C = Compress constant integers of size 2-8 bytes as ULEB128.1609const StringRef SecWithOpt = S->getString();1610const size_t OptStart = SecWithOpt.find('!'); // likely npos1611const StringRef Sec = SecWithOpt.substr(0, OptStart);1612const StringRef Opts = SecWithOpt.substr(OptStart); // likely empty1613ConstULEB128 = Opts.contains('C');1614#ifndef NDEBUG1615for (char O : Opts)1616assert((O == '!' || O == 'C') && "Invalid !pcsections options");1617#endif1618SwitchSection(Sec);1619const MCSymbol *Prev = Syms.front();1620for (const MCSymbol *Sym : Syms) {1621if (Sym == Prev || !Deltas) {1622// Use the entry itself as the base of the relative offset.1623MCSymbol *Base = MF.getContext().createTempSymbol("pcsection_base");1624OutStreamer->emitLabel(Base);1625// Emit relative relocation `addr - base`, which avoids a dynamic1626// relocation in the final binary. User will get the address with1627// `base + addr`.1628emitLabelDifference(Sym, Base, RelativeRelocSize);1629} else {1630// Emit delta between symbol and previous symbol.1631if (ConstULEB128)1632emitLabelDifferenceAsULEB128(Sym, Prev);1633else1634emitLabelDifference(Sym, Prev, 4);1635}1636Prev = Sym;1637}1638} else {1639// Emit auxiliary data after PC.1640assert(isa<MDNode>(MDO) && "expecting either string or tuple");1641const auto *AuxMDs = cast<MDNode>(MDO);1642for (const MDOperand &AuxMDO : AuxMDs->operands()) {1643assert(isa<ConstantAsMetadata>(AuxMDO) && "expecting a constant");1644const Constant *C = cast<ConstantAsMetadata>(AuxMDO)->getValue();1645const DataLayout &DL = F.getDataLayout();1646const uint64_t Size = DL.getTypeStoreSize(C->getType());16471648if (auto *CI = dyn_cast<ConstantInt>(C);1649CI && ConstULEB128 && Size > 1 && Size <= 8) {1650emitULEB128(CI->getZExtValue());1651} else {1652emitGlobalConstant(DL, C);1653}1654}1655}1656}1657};16581659OutStreamer->pushSection();1660// Emit PCs for function start and function size.1661if (const MDNode *MD = F.getMetadata(LLVMContext::MD_pcsections))1662EmitForMD(*MD, {getFunctionBegin(), getFunctionEnd()}, true);1663// Emit PCs for instructions collected.1664for (const auto &MS : PCSectionsSymbols)1665EmitForMD(*MS.first, MS.second, false);1666OutStreamer->popSection();1667PCSectionsSymbols.clear();1668}16691670/// Returns true if function begin and end labels should be emitted.1671static bool needFuncLabels(const MachineFunction &MF,1672const MachineModuleInfo &MMI) {1673if (!MF.getLandingPads().empty() || MF.hasEHFunclets() ||1674MMI.hasDebugInfo() ||1675MF.getFunction().hasMetadata(LLVMContext::MD_pcsections))1676return true;16771678// We might emit an EH table that uses function begin and end labels even if1679// we don't have any landingpads.1680if (!MF.getFunction().hasPersonalityFn())1681return false;1682return !isNoOpWithoutInvoke(1683classifyEHPersonality(MF.getFunction().getPersonalityFn()));1684}16851686/// EmitFunctionBody - This method emits the body and trailer for a1687/// function.1688void AsmPrinter::emitFunctionBody() {1689emitFunctionHeader();16901691// Emit target-specific gunk before the function body.1692emitFunctionBodyStart();16931694if (isVerbose()) {1695// Get MachineDominatorTree or compute it on the fly if it's unavailable1696auto MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();1697MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;1698if (!MDT) {1699OwnedMDT = std::make_unique<MachineDominatorTree>();1700OwnedMDT->getBase().recalculate(*MF);1701MDT = OwnedMDT.get();1702}17031704// Get MachineLoopInfo or compute it on the fly if it's unavailable1705auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();1706MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;1707if (!MLI) {1708OwnedMLI = std::make_unique<MachineLoopInfo>();1709OwnedMLI->analyze(MDT->getBase());1710MLI = OwnedMLI.get();1711}1712}17131714// Print out code for the function.1715bool HasAnyRealCode = false;1716int NumInstsInFunction = 0;1717bool IsEHa = MMI->getModule()->getModuleFlag("eh-asynch");17181719bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);1720for (auto &MBB : *MF) {1721// Print a label for the basic block.1722emitBasicBlockStart(MBB);1723DenseMap<StringRef, unsigned> MnemonicCounts;1724for (auto &MI : MBB) {1725// Print the assembly for the instruction.1726if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&1727!MI.isDebugInstr()) {1728HasAnyRealCode = true;1729++NumInstsInFunction;1730}17311732// If there is a pre-instruction symbol, emit a label for it here.1733if (MCSymbol *S = MI.getPreInstrSymbol())1734OutStreamer->emitLabel(S);17351736if (MDNode *MD = MI.getPCSections())1737emitPCSectionsLabel(*MF, *MD);17381739for (auto &Handler : DebugHandlers)1740Handler->beginInstruction(&MI);17411742if (isVerbose())1743emitComments(MI, OutStreamer->getCommentOS());17441745switch (MI.getOpcode()) {1746case TargetOpcode::CFI_INSTRUCTION:1747emitCFIInstruction(MI);1748break;1749case TargetOpcode::LOCAL_ESCAPE:1750emitFrameAlloc(MI);1751break;1752case TargetOpcode::ANNOTATION_LABEL:1753case TargetOpcode::GC_LABEL:1754OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());1755break;1756case TargetOpcode::EH_LABEL:1757OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());1758// For AsynchEH, insert a Nop if followed by a trap inst1759// Or the exception won't be caught.1760// (see MCConstantExpr::create(1,..) in WinException.cpp)1761// Ignore SDiv/UDiv because a DIV with Const-0 divisor1762// must have being turned into an UndefValue.1763// Div with variable opnds won't be the first instruction in1764// an EH region as it must be led by at least a Load1765{1766auto MI2 = std::next(MI.getIterator());1767if (IsEHa && MI2 != MBB.end() &&1768(MI2->mayLoadOrStore() || MI2->mayRaiseFPException()))1769emitNops(1);1770}1771break;1772case TargetOpcode::INLINEASM:1773case TargetOpcode::INLINEASM_BR:1774emitInlineAsm(&MI);1775break;1776case TargetOpcode::DBG_VALUE:1777case TargetOpcode::DBG_VALUE_LIST:1778if (isVerbose()) {1779if (!emitDebugValueComment(&MI, *this))1780emitInstruction(&MI);1781}1782break;1783case TargetOpcode::DBG_INSTR_REF:1784// This instruction reference will have been resolved to a machine1785// location, and a nearby DBG_VALUE created. We can safely ignore1786// the instruction reference.1787break;1788case TargetOpcode::DBG_PHI:1789// This instruction is only used to label a program point, it's purely1790// meta information.1791break;1792case TargetOpcode::DBG_LABEL:1793if (isVerbose()) {1794if (!emitDebugLabelComment(&MI, *this))1795emitInstruction(&MI);1796}1797break;1798case TargetOpcode::IMPLICIT_DEF:1799if (isVerbose()) emitImplicitDef(&MI);1800break;1801case TargetOpcode::KILL:1802if (isVerbose()) emitKill(&MI, *this);1803break;1804case TargetOpcode::PSEUDO_PROBE:1805emitPseudoProbe(MI);1806break;1807case TargetOpcode::ARITH_FENCE:1808if (isVerbose())1809OutStreamer->emitRawComment("ARITH_FENCE");1810break;1811case TargetOpcode::MEMBARRIER:1812OutStreamer->emitRawComment("MEMBARRIER");1813break;1814case TargetOpcode::JUMP_TABLE_DEBUG_INFO:1815// This instruction is only used to note jump table debug info, it's1816// purely meta information.1817break;1818default:1819emitInstruction(&MI);1820if (CanDoExtraAnalysis) {1821MCInst MCI;1822MCI.setOpcode(MI.getOpcode());1823auto Name = OutStreamer->getMnemonic(MCI);1824auto I = MnemonicCounts.insert({Name, 0u});1825I.first->second++;1826}1827break;1828}18291830// If there is a post-instruction symbol, emit a label for it here.1831if (MCSymbol *S = MI.getPostInstrSymbol())1832OutStreamer->emitLabel(S);18331834for (auto &Handler : DebugHandlers)1835Handler->endInstruction();1836}18371838// We must emit temporary symbol for the end of this basic block, if either1839// we have BBLabels enabled or if this basic blocks marks the end of a1840// section.1841if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap ||1842(MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection()))1843OutStreamer->emitLabel(MBB.getEndSymbol());18441845if (MBB.isEndSection()) {1846// The size directive for the section containing the entry block is1847// handled separately by the function section.1848if (!MBB.sameSection(&MF->front())) {1849if (MAI->hasDotTypeDotSizeDirective()) {1850// Emit the size directive for the basic block section.1851const MCExpr *SizeExp = MCBinaryExpr::createSub(1852MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext),1853MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext),1854OutContext);1855OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);1856}1857assert(!MBBSectionRanges.contains(MBB.getSectionID()) &&1858"Overwrite section range");1859MBBSectionRanges[MBB.getSectionID()] =1860MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()};1861}1862}1863emitBasicBlockEnd(MBB);18641865if (CanDoExtraAnalysis) {1866// Skip empty blocks.1867if (MBB.empty())1868continue;18691870MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",1871MBB.begin()->getDebugLoc(), &MBB);18721873// Generate instruction mix remark. First, sort counts in descending order1874// by count and name.1875SmallVector<std::pair<StringRef, unsigned>, 128> MnemonicVec;1876for (auto &KV : MnemonicCounts)1877MnemonicVec.emplace_back(KV.first, KV.second);18781879sort(MnemonicVec, [](const std::pair<StringRef, unsigned> &A,1880const std::pair<StringRef, unsigned> &B) {1881if (A.second > B.second)1882return true;1883if (A.second == B.second)1884return StringRef(A.first) < StringRef(B.first);1885return false;1886});1887R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n";1888for (auto &KV : MnemonicVec) {1889auto Name = (Twine("INST_") + getToken(KV.first.trim()).first).str();1890R << KV.first << ": " << ore::NV(Name, KV.second) << "\n";1891}1892ORE->emit(R);1893}1894}18951896EmittedInsts += NumInstsInFunction;1897MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount",1898MF->getFunction().getSubprogram(),1899&MF->front());1900R << ore::NV("NumInstructions", NumInstsInFunction)1901<< " instructions in function";1902ORE->emit(R);19031904// If the function is empty and the object file uses .subsections_via_symbols,1905// then we need to emit *something* to the function body to prevent the1906// labels from collapsing together. Just emit a noop.1907// Similarly, don't emit empty functions on Windows either. It can lead to1908// duplicate entries (two functions with the same RVA) in the Guard CF Table1909// after linking, causing the kernel not to load the binary:1910// https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html1911// FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer.1912const Triple &TT = TM.getTargetTriple();1913if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() ||1914(TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {1915MCInst Noop = MF->getSubtarget().getInstrInfo()->getNop();19161917// Targets can opt-out of emitting the noop here by leaving the opcode1918// unspecified.1919if (Noop.getOpcode()) {1920OutStreamer->AddComment("avoids zero-length function");1921emitNops(1);1922}1923}19241925// Switch to the original section in case basic block sections was used.1926OutStreamer->switchSection(MF->getSection());19271928const Function &F = MF->getFunction();1929for (const auto &BB : F) {1930if (!BB.hasAddressTaken())1931continue;1932MCSymbol *Sym = GetBlockAddressSymbol(&BB);1933if (Sym->isDefined())1934continue;1935OutStreamer->AddComment("Address of block that was removed by CodeGen");1936OutStreamer->emitLabel(Sym);1937}19381939// Emit target-specific gunk after the function body.1940emitFunctionBodyEnd();19411942// Even though wasm supports .type and .size in general, function symbols1943// are automatically sized.1944bool EmitFunctionSize = MAI->hasDotTypeDotSizeDirective() && !TT.isWasm();19451946if (needFuncLabels(*MF, *MMI) || EmitFunctionSize) {1947// Create a symbol for the end of function.1948CurrentFnEnd = createTempSymbol("func_end");1949OutStreamer->emitLabel(CurrentFnEnd);1950}19511952// If the target wants a .size directive for the size of the function, emit1953// it.1954if (EmitFunctionSize) {1955// We can get the size as difference between the function label and the1956// temp label.1957const MCExpr *SizeExp = MCBinaryExpr::createSub(1958MCSymbolRefExpr::create(CurrentFnEnd, OutContext),1959MCSymbolRefExpr::create(CurrentFnSymForSize, OutContext), OutContext);1960OutStreamer->emitELFSize(CurrentFnSym, SizeExp);1961if (CurrentFnBeginLocal)1962OutStreamer->emitELFSize(CurrentFnBeginLocal, SizeExp);1963}19641965// Call endBasicBlockSection on the last block now, if it wasn't already1966// called.1967if (!MF->back().isEndSection()) {1968for (auto &Handler : DebugHandlers)1969Handler->endBasicBlockSection(MF->back());1970for (auto &Handler : Handlers)1971Handler->endBasicBlockSection(MF->back());1972}1973for (auto &Handler : Handlers)1974Handler->markFunctionEnd();19751976assert(!MBBSectionRanges.contains(MF->front().getSectionID()) &&1977"Overwrite section range");1978MBBSectionRanges[MF->front().getSectionID()] =1979MBBSectionRange{CurrentFnBegin, CurrentFnEnd};19801981// Print out jump tables referenced by the function.1982emitJumpTableInfo();19831984// Emit post-function debug and/or EH information.1985for (auto &Handler : DebugHandlers)1986Handler->endFunction(MF);1987for (auto &Handler : Handlers)1988Handler->endFunction(MF);19891990// Emit section containing BB address offsets and their metadata, when1991// BB labels are requested for this function. Skip empty functions.1992if (HasAnyRealCode) {1993if (MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap)1994emitBBAddrMapSection(*MF);1995else if (PgoAnalysisMapFeatures.getBits() != 0)1996MF->getContext().reportWarning(1997SMLoc(), "pgo-analysis-map is enabled for function " + MF->getName() +1998" but it does not have labels");1999}20002001// Emit sections containing instruction and function PCs.2002emitPCSections(*MF);20032004// Emit section containing stack size metadata.2005emitStackSizeSection(*MF);20062007// Emit .su file containing function stack size information.2008emitStackUsage(*MF);20092010emitPatchableFunctionEntries();20112012if (isVerbose())2013OutStreamer->getCommentOS() << "-- End function\n";20142015OutStreamer->addBlankLine();2016}20172018/// Compute the number of Global Variables that uses a Constant.2019static unsigned getNumGlobalVariableUses(const Constant *C) {2020if (!C)2021return 0;20222023if (isa<GlobalVariable>(C))2024return 1;20252026unsigned NumUses = 0;2027for (const auto *CU : C->users())2028NumUses += getNumGlobalVariableUses(dyn_cast<Constant>(CU));20292030return NumUses;2031}20322033/// Only consider global GOT equivalents if at least one user is a2034/// cstexpr inside an initializer of another global variables. Also, don't2035/// handle cstexpr inside instructions. During global variable emission,2036/// candidates are skipped and are emitted later in case at least one cstexpr2037/// isn't replaced by a PC relative GOT entry access.2038static bool isGOTEquivalentCandidate(const GlobalVariable *GV,2039unsigned &NumGOTEquivUsers) {2040// Global GOT equivalents are unnamed private globals with a constant2041// pointer initializer to another global symbol. They must point to a2042// GlobalVariable or Function, i.e., as GlobalValue.2043if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() ||2044!GV->isConstant() || !GV->isDiscardableIfUnused() ||2045!isa<GlobalValue>(GV->getOperand(0)))2046return false;20472048// To be a got equivalent, at least one of its users need to be a constant2049// expression used by another global variable.2050for (const auto *U : GV->users())2051NumGOTEquivUsers += getNumGlobalVariableUses(dyn_cast<Constant>(U));20522053return NumGOTEquivUsers > 0;2054}20552056/// Unnamed constant global variables solely contaning a pointer to2057/// another globals variable is equivalent to a GOT table entry; it contains the2058/// the address of another symbol. Optimize it and replace accesses to these2059/// "GOT equivalents" by using the GOT entry for the final global instead.2060/// Compute GOT equivalent candidates among all global variables to avoid2061/// emitting them if possible later on, after it use is replaced by a GOT entry2062/// access.2063void AsmPrinter::computeGlobalGOTEquivs(Module &M) {2064if (!getObjFileLowering().supportIndirectSymViaGOTPCRel())2065return;20662067for (const auto &G : M.globals()) {2068unsigned NumGOTEquivUsers = 0;2069if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers))2070continue;20712072const MCSymbol *GOTEquivSym = getSymbol(&G);2073GlobalGOTEquivs[GOTEquivSym] = std::make_pair(&G, NumGOTEquivUsers);2074}2075}20762077/// Constant expressions using GOT equivalent globals may not be eligible2078/// for PC relative GOT entry conversion, in such cases we need to emit such2079/// globals we previously omitted in EmitGlobalVariable.2080void AsmPrinter::emitGlobalGOTEquivs() {2081if (!getObjFileLowering().supportIndirectSymViaGOTPCRel())2082return;20832084SmallVector<const GlobalVariable *, 8> FailedCandidates;2085for (auto &I : GlobalGOTEquivs) {2086const GlobalVariable *GV = I.second.first;2087unsigned Cnt = I.second.second;2088if (Cnt)2089FailedCandidates.push_back(GV);2090}2091GlobalGOTEquivs.clear();20922093for (const auto *GV : FailedCandidates)2094emitGlobalVariable(GV);2095}20962097void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {2098MCSymbol *Name = getSymbol(&GA);2099bool IsFunction = GA.getValueType()->isFunctionTy();2100// Treat bitcasts of functions as functions also. This is important at least2101// on WebAssembly where object and function addresses can't alias each other.2102if (!IsFunction)2103IsFunction = isa<Function>(GA.getAliasee()->stripPointerCasts());21042105// AIX's assembly directive `.set` is not usable for aliasing purpose,2106// so AIX has to use the extra-label-at-definition strategy. At this2107// point, all the extra label is emitted, we just have to emit linkage for2108// those labels.2109if (TM.getTargetTriple().isOSBinFormatXCOFF()) {2110assert(MAI->hasVisibilityOnlyWithLinkage() &&2111"Visibility should be handled with emitLinkage() on AIX.");21122113// Linkage for alias of global variable has been emitted.2114if (isa<GlobalVariable>(GA.getAliaseeObject()))2115return;21162117emitLinkage(&GA, Name);2118// If it's a function, also emit linkage for aliases of function entry2119// point.2120if (IsFunction)2121emitLinkage(&GA,2122getObjFileLowering().getFunctionEntryPointSymbol(&GA, TM));2123return;2124}21252126if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective())2127OutStreamer->emitSymbolAttribute(Name, MCSA_Global);2128else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())2129OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);2130else2131assert(GA.hasLocalLinkage() && "Invalid alias linkage");21322133// Set the symbol type to function if the alias has a function type.2134// This affects codegen when the aliasee is not a function.2135if (IsFunction) {2136OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction);2137if (TM.getTargetTriple().isOSBinFormatCOFF()) {2138OutStreamer->beginCOFFSymbolDef(Name);2139OutStreamer->emitCOFFSymbolStorageClass(2140GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC2141: COFF::IMAGE_SYM_CLASS_EXTERNAL);2142OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION2143<< COFF::SCT_COMPLEX_TYPE_SHIFT);2144OutStreamer->endCOFFSymbolDef();2145}2146}21472148emitVisibility(Name, GA.getVisibility());21492150const MCExpr *Expr = lowerConstant(GA.getAliasee());21512152if (MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))2153OutStreamer->emitSymbolAttribute(Name, MCSA_AltEntry);21542155// Emit the directives as assignments aka .set:2156OutStreamer->emitAssignment(Name, Expr);2157MCSymbol *LocalAlias = getSymbolPreferLocal(GA);2158if (LocalAlias != Name)2159OutStreamer->emitAssignment(LocalAlias, Expr);21602161// If the aliasee does not correspond to a symbol in the output, i.e. the2162// alias is not of an object or the aliased object is private, then set the2163// size of the alias symbol from the type of the alias. We don't do this in2164// other situations as the alias and aliasee having differing types but same2165// size may be intentional.2166const GlobalObject *BaseObject = GA.getAliaseeObject();2167if (MAI->hasDotTypeDotSizeDirective() && GA.getValueType()->isSized() &&2168(!BaseObject || BaseObject->hasPrivateLinkage())) {2169const DataLayout &DL = M.getDataLayout();2170uint64_t Size = DL.getTypeAllocSize(GA.getValueType());2171OutStreamer->emitELFSize(Name, MCConstantExpr::create(Size, OutContext));2172}2173}21742175void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {2176assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&2177"IFunc is not supported on AIX.");21782179auto EmitLinkage = [&](MCSymbol *Sym) {2180if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective())2181OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);2182else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage())2183OutStreamer->emitSymbolAttribute(Sym, MCSA_WeakReference);2184else2185assert(GI.hasLocalLinkage() && "Invalid ifunc linkage");2186};21872188if (TM.getTargetTriple().isOSBinFormatELF()) {2189MCSymbol *Name = getSymbol(&GI);2190EmitLinkage(Name);2191OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction);2192emitVisibility(Name, GI.getVisibility());21932194// Emit the directives as assignments aka .set:2195const MCExpr *Expr = lowerConstant(GI.getResolver());2196OutStreamer->emitAssignment(Name, Expr);2197MCSymbol *LocalAlias = getSymbolPreferLocal(GI);2198if (LocalAlias != Name)2199OutStreamer->emitAssignment(LocalAlias, Expr);22002201return;2202}22032204if (!TM.getTargetTriple().isOSBinFormatMachO() || !getIFuncMCSubtargetInfo())2205llvm::report_fatal_error("IFuncs are not supported on this platform");22062207// On Darwin platforms, emit a manually-constructed .symbol_resolver that2208// implements the symbol resolution duties of the IFunc.2209//2210// Normally, this would be handled by linker magic, but unfortunately there2211// are a few limitations in ld64 and ld-prime's implementation of2212// .symbol_resolver that mean we can't always use them:2213//2214// * resolvers cannot be the target of an alias2215// * resolvers cannot have private linkage2216// * resolvers cannot have linkonce linkage2217// * resolvers cannot appear in executables2218// * resolvers cannot appear in bundles2219//2220// This works around that by emitting a close approximation of what the2221// linker would have done.22222223MCSymbol *LazyPointer =2224GetExternalSymbolSymbol(GI.getName() + ".lazy_pointer");2225MCSymbol *StubHelper = GetExternalSymbolSymbol(GI.getName() + ".stub_helper");22262227OutStreamer->switchSection(OutContext.getObjectFileInfo()->getDataSection());22282229const DataLayout &DL = M.getDataLayout();2230emitAlignment(Align(DL.getPointerSize()));2231OutStreamer->emitLabel(LazyPointer);2232emitVisibility(LazyPointer, GI.getVisibility());2233OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8);22342235OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection());22362237const TargetSubtargetInfo *STI =2238TM.getSubtargetImpl(*GI.getResolverFunction());2239const TargetLowering *TLI = STI->getTargetLowering();2240Align TextAlign(TLI->getMinFunctionAlignment());22412242MCSymbol *Stub = getSymbol(&GI);2243EmitLinkage(Stub);2244OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo());2245OutStreamer->emitLabel(Stub);2246emitVisibility(Stub, GI.getVisibility());2247emitMachOIFuncStubBody(M, GI, LazyPointer);22482249OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo());2250OutStreamer->emitLabel(StubHelper);2251emitVisibility(StubHelper, GI.getVisibility());2252emitMachOIFuncStubHelperBody(M, GI, LazyPointer);2253}22542255void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {2256if (!RS.needsSection())2257return;22582259remarks::RemarkSerializer &RemarkSerializer = RS.getSerializer();22602261std::optional<SmallString<128>> Filename;2262if (std::optional<StringRef> FilenameRef = RS.getFilename()) {2263Filename = *FilenameRef;2264sys::fs::make_absolute(*Filename);2265assert(!Filename->empty() && "The filename can't be empty.");2266}22672268std::string Buf;2269raw_string_ostream OS(Buf);2270std::unique_ptr<remarks::MetaSerializer> MetaSerializer =2271Filename ? RemarkSerializer.metaSerializer(OS, Filename->str())2272: RemarkSerializer.metaSerializer(OS);2273MetaSerializer->emit();22742275// Switch to the remarks section.2276MCSection *RemarksSection =2277OutContext.getObjectFileInfo()->getRemarksSection();2278OutStreamer->switchSection(RemarksSection);22792280OutStreamer->emitBinaryData(Buf);2281}22822283bool AsmPrinter::doFinalization(Module &M) {2284// Set the MachineFunction to nullptr so that we can catch attempted2285// accesses to MF specific features at the module level and so that2286// we can conditionalize accesses based on whether or not it is nullptr.2287MF = nullptr;22882289// Gather all GOT equivalent globals in the module. We really need two2290// passes over the globals: one to compute and another to avoid its emission2291// in EmitGlobalVariable, otherwise we would not be able to handle cases2292// where the got equivalent shows up before its use.2293computeGlobalGOTEquivs(M);22942295// Emit global variables.2296for (const auto &G : M.globals())2297emitGlobalVariable(&G);22982299// Emit remaining GOT equivalent globals.2300emitGlobalGOTEquivs();23012302const TargetLoweringObjectFile &TLOF = getObjFileLowering();23032304// Emit linkage(XCOFF) and visibility info for declarations2305for (const Function &F : M) {2306if (!F.isDeclarationForLinker())2307continue;23082309MCSymbol *Name = getSymbol(&F);2310// Function getSymbol gives us the function descriptor symbol for XCOFF.23112312if (!TM.getTargetTriple().isOSBinFormatXCOFF()) {2313GlobalValue::VisibilityTypes V = F.getVisibility();2314if (V == GlobalValue::DefaultVisibility)2315continue;23162317emitVisibility(Name, V, false);2318continue;2319}23202321if (F.isIntrinsic())2322continue;23232324// Handle the XCOFF case.2325// Variable `Name` is the function descriptor symbol (see above). Get the2326// function entry point symbol.2327MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM);2328// Emit linkage for the function entry point.2329emitLinkage(&F, FnEntryPointSym);23302331// If a function's address is taken, which means it may be called via a2332// function pointer, we need the function descriptor for it.2333if (F.hasAddressTaken())2334emitLinkage(&F, Name);2335}23362337// Emit the remarks section contents.2338// FIXME: Figure out when is the safest time to emit this section. It should2339// not come after debug info.2340if (remarks::RemarkStreamer *RS = M.getContext().getMainRemarkStreamer())2341emitRemarksSection(*RS);23422343TLOF.emitModuleMetadata(*OutStreamer, M);23442345if (TM.getTargetTriple().isOSBinFormatELF()) {2346MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();23472348// Output stubs for external and common global variables.2349MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();2350if (!Stubs.empty()) {2351OutStreamer->switchSection(TLOF.getDataSection());2352const DataLayout &DL = M.getDataLayout();23532354emitAlignment(Align(DL.getPointerSize()));2355for (const auto &Stub : Stubs) {2356OutStreamer->emitLabel(Stub.first);2357OutStreamer->emitSymbolValue(Stub.second.getPointer(),2358DL.getPointerSize());2359}2360}2361}23622363if (TM.getTargetTriple().isOSBinFormatCOFF()) {2364MachineModuleInfoCOFF &MMICOFF =2365MMI->getObjFileInfo<MachineModuleInfoCOFF>();23662367// Output stubs for external and common global variables.2368MachineModuleInfoCOFF::SymbolListTy Stubs = MMICOFF.GetGVStubList();2369if (!Stubs.empty()) {2370const DataLayout &DL = M.getDataLayout();23712372for (const auto &Stub : Stubs) {2373SmallString<256> SectionName = StringRef(".rdata$");2374SectionName += Stub.first->getName();2375OutStreamer->switchSection(OutContext.getCOFFSection(2376SectionName,2377COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |2378COFF::IMAGE_SCN_LNK_COMDAT,2379Stub.first->getName(), COFF::IMAGE_COMDAT_SELECT_ANY));2380emitAlignment(Align(DL.getPointerSize()));2381OutStreamer->emitSymbolAttribute(Stub.first, MCSA_Global);2382OutStreamer->emitLabel(Stub.first);2383OutStreamer->emitSymbolValue(Stub.second.getPointer(),2384DL.getPointerSize());2385}2386}2387}23882389// This needs to happen before emitting debug information since that can end2390// arbitrary sections.2391if (auto *TS = OutStreamer->getTargetStreamer())2392TS->emitConstantPools();23932394// Emit Stack maps before any debug info. Mach-O requires that no data or2395// text sections come after debug info has been emitted. This matters for2396// stack maps as they are arbitrary data, and may even have a custom format2397// through user plugins.2398emitStackMaps();23992400// Print aliases in topological order, that is, for each alias a = b,2401// b must be printed before a.2402// This is because on some targets (e.g. PowerPC) linker expects aliases in2403// such an order to generate correct TOC information.2404SmallVector<const GlobalAlias *, 16> AliasStack;2405SmallPtrSet<const GlobalAlias *, 16> AliasVisited;2406for (const auto &Alias : M.aliases()) {2407if (Alias.hasAvailableExternallyLinkage())2408continue;2409for (const GlobalAlias *Cur = &Alias; Cur;2410Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {2411if (!AliasVisited.insert(Cur).second)2412break;2413AliasStack.push_back(Cur);2414}2415for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack))2416emitGlobalAlias(M, *AncestorAlias);2417AliasStack.clear();2418}24192420// IFuncs must come before deubginfo in case the backend decides to emit them2421// as actual functions, since on Mach-O targets, we cannot create regular2422// sections after DWARF.2423for (const auto &IFunc : M.ifuncs())2424emitGlobalIFunc(M, IFunc);24252426// Finalize debug and EH information.2427for (auto &Handler : DebugHandlers)2428Handler->endModule();2429for (auto &Handler : Handlers)2430Handler->endModule();24312432// This deletes all the ephemeral handlers that AsmPrinter added, while2433// keeping all the user-added handlers alive until the AsmPrinter is2434// destroyed.2435Handlers.erase(Handlers.begin() + NumUserHandlers, Handlers.end());2436DebugHandlers.erase(DebugHandlers.begin() + NumUserDebugHandlers,2437DebugHandlers.end());2438DD = nullptr;24392440// If the target wants to know about weak references, print them all.2441if (MAI->getWeakRefDirective()) {2442// FIXME: This is not lazy, it would be nice to only print weak references2443// to stuff that is actually used. Note that doing so would require targets2444// to notice uses in operands (due to constant exprs etc). This should2445// happen with the MC stuff eventually.24462447// Print out module-level global objects here.2448for (const auto &GO : M.global_objects()) {2449if (!GO.hasExternalWeakLinkage())2450continue;2451OutStreamer->emitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference);2452}2453if (shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()) {2454auto SymbolName = "swift_async_extendedFramePointerFlags";2455auto Global = M.getGlobalVariable(SymbolName);2456if (!Global) {2457auto Int8PtrTy = PointerType::getUnqual(M.getContext());2458Global = new GlobalVariable(M, Int8PtrTy, false,2459GlobalValue::ExternalWeakLinkage, nullptr,2460SymbolName);2461OutStreamer->emitSymbolAttribute(getSymbol(Global), MCSA_WeakReference);2462}2463}2464}24652466GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();2467assert(MI && "AsmPrinter didn't require GCModuleInfo?");2468for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )2469if (GCMetadataPrinter *MP = getOrCreateGCPrinter(**--I))2470MP->finishAssembly(M, *MI, *this);24712472// Emit llvm.ident metadata in an '.ident' directive.2473emitModuleIdents(M);24742475// Emit bytes for llvm.commandline metadata.2476// The command line metadata is emitted earlier on XCOFF.2477if (!TM.getTargetTriple().isOSBinFormatXCOFF())2478emitModuleCommandLines(M);24792480// Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if2481// split-stack is used.2482if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) {2483OutStreamer->switchSection(OutContext.getELFSection(".note.GNU-split-stack",2484ELF::SHT_PROGBITS, 0));2485if (HasNoSplitStack)2486OutStreamer->switchSection(OutContext.getELFSection(2487".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));2488}24892490// If we don't have any trampolines, then we don't require stack memory2491// to be executable. Some targets have a directive to declare this.2492Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");2493if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())2494if (MCSection *S = MAI->getNonexecutableStackSection(OutContext))2495OutStreamer->switchSection(S);24962497if (TM.Options.EmitAddrsig) {2498// Emit address-significance attributes for all globals.2499OutStreamer->emitAddrsig();2500for (const GlobalValue &GV : M.global_values()) {2501if (!GV.use_empty() && !GV.isThreadLocal() &&2502!GV.hasDLLImportStorageClass() &&2503!GV.getName().starts_with("llvm.") &&2504!GV.hasAtLeastLocalUnnamedAddr())2505OutStreamer->emitAddrsigSym(getSymbol(&GV));2506}2507}25082509// Emit symbol partition specifications (ELF only).2510if (TM.getTargetTriple().isOSBinFormatELF()) {2511unsigned UniqueID = 0;2512for (const GlobalValue &GV : M.global_values()) {2513if (!GV.hasPartition() || GV.isDeclarationForLinker() ||2514GV.getVisibility() != GlobalValue::DefaultVisibility)2515continue;25162517OutStreamer->switchSection(2518OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0,2519"", false, ++UniqueID, nullptr));2520OutStreamer->emitBytes(GV.getPartition());2521OutStreamer->emitZeros(1);2522OutStreamer->emitValue(2523MCSymbolRefExpr::create(getSymbol(&GV), OutContext),2524MAI->getCodePointerSize());2525}2526}25272528// Allow the target to emit any magic that it wants at the end of the file,2529// after everything else has gone out.2530emitEndOfAsmFile(M);25312532MMI = nullptr;2533AddrLabelSymbols = nullptr;25342535OutStreamer->finish();2536OutStreamer->reset();2537OwnedMLI.reset();2538OwnedMDT.reset();25392540return false;2541}25422543MCSymbol *AsmPrinter::getMBBExceptionSym(const MachineBasicBlock &MBB) {2544auto Res = MBBSectionExceptionSyms.try_emplace(MBB.getSectionID());2545if (Res.second)2546Res.first->second = createTempSymbol("exception");2547return Res.first->second;2548}25492550void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {2551this->MF = &MF;2552const Function &F = MF.getFunction();25532554// Record that there are split-stack functions, so we will emit a special2555// section to tell the linker.2556if (MF.shouldSplitStack()) {2557HasSplitStack = true;25582559if (!MF.getFrameInfo().needsSplitStackProlog())2560HasNoSplitStack = true;2561} else2562HasNoSplitStack = true;25632564// Get the function symbol.2565if (!MAI->needsFunctionDescriptors()) {2566CurrentFnSym = getSymbol(&MF.getFunction());2567} else {2568assert(TM.getTargetTriple().isOSAIX() &&2569"Only AIX uses the function descriptor hooks.");2570// AIX is unique here in that the name of the symbol emitted for the2571// function body does not have the same name as the source function's2572// C-linkage name.2573assert(CurrentFnDescSym && "The function descriptor symbol needs to be"2574" initalized first.");25752576// Get the function entry point symbol.2577CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&F, TM);2578}25792580CurrentFnSymForSize = CurrentFnSym;2581CurrentFnBegin = nullptr;2582CurrentFnBeginLocal = nullptr;2583CurrentSectionBeginSym = nullptr;2584MBBSectionRanges.clear();2585MBBSectionExceptionSyms.clear();2586bool NeedsLocalForSize = MAI->needsLocalForSize();2587if (F.hasFnAttribute("patchable-function-entry") ||2588F.hasFnAttribute("function-instrument") ||2589F.hasFnAttribute("xray-instruction-threshold") ||2590needFuncLabels(MF, *MMI) || NeedsLocalForSize ||2591MF.getTarget().Options.EmitStackSizeSection ||2592MF.getTarget().Options.BBAddrMap || MF.hasBBLabels()) {2593CurrentFnBegin = createTempSymbol("func_begin");2594if (NeedsLocalForSize)2595CurrentFnSymForSize = CurrentFnBegin;2596}25972598ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();2599}26002601namespace {26022603// Keep track the alignment, constpool entries per Section.2604struct SectionCPs {2605MCSection *S;2606Align Alignment;2607SmallVector<unsigned, 4> CPEs;26082609SectionCPs(MCSection *s, Align a) : S(s), Alignment(a) {}2610};26112612} // end anonymous namespace26132614/// EmitConstantPool - Print to the current output stream assembly2615/// representations of the constants in the constant pool MCP. This is2616/// used to print out constants which have been "spilled to memory" by2617/// the code generator.2618void AsmPrinter::emitConstantPool() {2619const MachineConstantPool *MCP = MF->getConstantPool();2620const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();2621if (CP.empty()) return;26222623// Calculate sections for constant pool entries. We collect entries to go into2624// the same section together to reduce amount of section switch statements.2625SmallVector<SectionCPs, 4> CPSections;2626for (unsigned i = 0, e = CP.size(); i != e; ++i) {2627const MachineConstantPoolEntry &CPE = CP[i];2628Align Alignment = CPE.getAlign();26292630SectionKind Kind = CPE.getSectionKind(&getDataLayout());26312632const Constant *C = nullptr;2633if (!CPE.isMachineConstantPoolEntry())2634C = CPE.Val.ConstVal;26352636MCSection *S = getObjFileLowering().getSectionForConstant(2637getDataLayout(), Kind, C, Alignment);26382639// The number of sections are small, just do a linear search from the2640// last section to the first.2641bool Found = false;2642unsigned SecIdx = CPSections.size();2643while (SecIdx != 0) {2644if (CPSections[--SecIdx].S == S) {2645Found = true;2646break;2647}2648}2649if (!Found) {2650SecIdx = CPSections.size();2651CPSections.push_back(SectionCPs(S, Alignment));2652}26532654if (Alignment > CPSections[SecIdx].Alignment)2655CPSections[SecIdx].Alignment = Alignment;2656CPSections[SecIdx].CPEs.push_back(i);2657}26582659// Now print stuff into the calculated sections.2660const MCSection *CurSection = nullptr;2661unsigned Offset = 0;2662for (unsigned i = 0, e = CPSections.size(); i != e; ++i) {2663for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) {2664unsigned CPI = CPSections[i].CPEs[j];2665MCSymbol *Sym = GetCPISymbol(CPI);2666if (!Sym->isUndefined())2667continue;26682669if (CurSection != CPSections[i].S) {2670OutStreamer->switchSection(CPSections[i].S);2671emitAlignment(Align(CPSections[i].Alignment));2672CurSection = CPSections[i].S;2673Offset = 0;2674}26752676MachineConstantPoolEntry CPE = CP[CPI];26772678// Emit inter-object padding for alignment.2679unsigned NewOffset = alignTo(Offset, CPE.getAlign());2680OutStreamer->emitZeros(NewOffset - Offset);26812682Offset = NewOffset + CPE.getSizeInBytes(getDataLayout());26832684OutStreamer->emitLabel(Sym);2685if (CPE.isMachineConstantPoolEntry())2686emitMachineConstantPoolValue(CPE.Val.MachineCPVal);2687else2688emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);2689}2690}2691}26922693// Print assembly representations of the jump tables used by the current2694// function.2695void AsmPrinter::emitJumpTableInfo() {2696const DataLayout &DL = MF->getDataLayout();2697const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();2698if (!MJTI) return;2699if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return;2700const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();2701if (JT.empty()) return;27022703// Pick the directive to use to print the jump table entries, and switch to2704// the appropriate section.2705const Function &F = MF->getFunction();2706const TargetLoweringObjectFile &TLOF = getObjFileLowering();2707bool JTInDiffSection = !TLOF.shouldPutJumpTableInFunctionSection(2708MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||2709MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference64,2710F);2711if (JTInDiffSection) {2712// Drop it in the readonly section.2713MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM);2714OutStreamer->switchSection(ReadOnlySection);2715}27162717emitAlignment(Align(MJTI->getEntryAlignment(DL)));27182719// Jump tables in code sections are marked with a data_region directive2720// where that's supported.2721if (!JTInDiffSection)2722OutStreamer->emitDataRegion(MCDR_DataRegionJT32);27232724for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {2725const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;27262727// If this jump table was deleted, ignore it.2728if (JTBBs.empty()) continue;27292730// For the EK_LabelDifference32 entry, if using .set avoids a relocation,2731/// emit a .set directive for each unique entry.2732if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&2733MAI->doesSetDirectiveSuppressReloc()) {2734SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets;2735const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();2736const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext);2737for (const MachineBasicBlock *MBB : JTBBs) {2738if (!EmittedSets.insert(MBB).second)2739continue;27402741// .set LJTSet, LBB32-base2742const MCExpr *LHS =2743MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);2744OutStreamer->emitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),2745MCBinaryExpr::createSub(LHS, Base,2746OutContext));2747}2748}27492750// On some targets (e.g. Darwin) we want to emit two consecutive labels2751// before each jump table. The first label is never referenced, but tells2752// the assembler and linker the extents of the jump table object. The2753// second label is actually referenced by the code.2754if (JTInDiffSection && DL.hasLinkerPrivateGlobalPrefix())2755// FIXME: This doesn't have to have any specific name, just any randomly2756// named and numbered local label started with 'l' would work. Simplify2757// GetJTISymbol.2758OutStreamer->emitLabel(GetJTISymbol(JTI, true));27592760MCSymbol* JTISymbol = GetJTISymbol(JTI);2761OutStreamer->emitLabel(JTISymbol);27622763// Defer MCAssembler based constant folding due to a performance issue. The2764// label differences will be evaluated at write time.2765for (const MachineBasicBlock *MBB : JTBBs)2766emitJumpTableEntry(MJTI, MBB, JTI);2767}2768if (!JTInDiffSection)2769OutStreamer->emitDataRegion(MCDR_DataRegionEnd);2770}27712772/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the2773/// current stream.2774void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo *MJTI,2775const MachineBasicBlock *MBB,2776unsigned UID) const {2777assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block");2778const MCExpr *Value = nullptr;2779switch (MJTI->getEntryKind()) {2780case MachineJumpTableInfo::EK_Inline:2781llvm_unreachable("Cannot emit EK_Inline jump table entry");2782case MachineJumpTableInfo::EK_Custom32:2783Value = MF->getSubtarget().getTargetLowering()->LowerCustomJumpTableEntry(2784MJTI, MBB, UID, OutContext);2785break;2786case MachineJumpTableInfo::EK_BlockAddress:2787// EK_BlockAddress - Each entry is a plain address of block, e.g.:2788// .word LBB1232789Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);2790break;2791case MachineJumpTableInfo::EK_GPRel32BlockAddress: {2792// EK_GPRel32BlockAddress - Each entry is an address of block, encoded2793// with a relocation as gp-relative, e.g.:2794// .gprel32 LBB1232795MCSymbol *MBBSym = MBB->getSymbol();2796OutStreamer->emitGPRel32Value(MCSymbolRefExpr::create(MBBSym, OutContext));2797return;2798}27992800case MachineJumpTableInfo::EK_GPRel64BlockAddress: {2801// EK_GPRel64BlockAddress - Each entry is an address of block, encoded2802// with a relocation as gp-relative, e.g.:2803// .gpdword LBB1232804MCSymbol *MBBSym = MBB->getSymbol();2805OutStreamer->emitGPRel64Value(MCSymbolRefExpr::create(MBBSym, OutContext));2806return;2807}28082809case MachineJumpTableInfo::EK_LabelDifference32:2810case MachineJumpTableInfo::EK_LabelDifference64: {2811// Each entry is the address of the block minus the address of the jump2812// table. This is used for PIC jump tables where gprel32 is not supported.2813// e.g.:2814// .word LBB123 - LJTI1_22815// If the .set directive avoids relocations, this is emitted as:2816// .set L4_5_set_123, LBB123 - LJTI1_22817// .word L4_5_set_1232818if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&2819MAI->doesSetDirectiveSuppressReloc()) {2820Value = MCSymbolRefExpr::create(GetJTSetSymbol(UID, MBB->getNumber()),2821OutContext);2822break;2823}2824Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);2825const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();2826const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF, UID, OutContext);2827Value = MCBinaryExpr::createSub(Value, Base, OutContext);2828break;2829}2830}28312832assert(Value && "Unknown entry kind!");28332834unsigned EntrySize = MJTI->getEntrySize(getDataLayout());2835OutStreamer->emitValue(Value, EntrySize);2836}28372838/// EmitSpecialLLVMGlobal - Check to see if the specified global is a2839/// special global used by LLVM. If so, emit it and return true, otherwise2840/// do nothing and return false.2841bool AsmPrinter::emitSpecialLLVMGlobal(const GlobalVariable *GV) {2842if (GV->getName() == "llvm.used") {2843if (MAI->hasNoDeadStrip()) // No need to emit this at all.2844emitLLVMUsedList(cast<ConstantArray>(GV->getInitializer()));2845return true;2846}28472848// Ignore debug and non-emitted data. This handles llvm.compiler.used.2849if (GV->getSection() == "llvm.metadata" ||2850GV->hasAvailableExternallyLinkage())2851return true;28522853if (GV->getName() == "llvm.arm64ec.symbolmap") {2854// For ARM64EC, print the table that maps between symbols and the2855// corresponding thunks to translate between x64 and AArch64 code.2856// This table is generated by AArch64Arm64ECCallLowering.2857OutStreamer->switchSection(2858OutContext.getCOFFSection(".hybmp$x", COFF::IMAGE_SCN_LNK_INFO));2859auto *Arr = cast<ConstantArray>(GV->getInitializer());2860for (auto &U : Arr->operands()) {2861auto *C = cast<Constant>(U);2862auto *Src = cast<GlobalValue>(C->getOperand(0)->stripPointerCasts());2863auto *Dst = cast<GlobalValue>(C->getOperand(1)->stripPointerCasts());2864int Kind = cast<ConstantInt>(C->getOperand(2))->getZExtValue();28652866if (Src->hasDLLImportStorageClass()) {2867// For now, we assume dllimport functions aren't directly called.2868// (We might change this later to match MSVC.)2869OutStreamer->emitCOFFSymbolIndex(2870OutContext.getOrCreateSymbol("__imp_" + Src->getName()));2871OutStreamer->emitCOFFSymbolIndex(getSymbol(Dst));2872OutStreamer->emitInt32(Kind);2873} else {2874// FIXME: For non-dllimport functions, MSVC emits the same entry2875// twice, for reasons I don't understand. I have to assume the linker2876// ignores the redundant entry; there aren't any reasonable semantics2877// to attach to it.2878OutStreamer->emitCOFFSymbolIndex(getSymbol(Src));2879OutStreamer->emitCOFFSymbolIndex(getSymbol(Dst));2880OutStreamer->emitInt32(Kind);2881}2882}2883return true;2884}28852886if (!GV->hasAppendingLinkage()) return false;28872888assert(GV->hasInitializer() && "Not a special LLVM global!");28892890if (GV->getName() == "llvm.global_ctors") {2891emitXXStructorList(GV->getDataLayout(), GV->getInitializer(),2892/* isCtor */ true);28932894return true;2895}28962897if (GV->getName() == "llvm.global_dtors") {2898emitXXStructorList(GV->getDataLayout(), GV->getInitializer(),2899/* isCtor */ false);29002901return true;2902}29032904report_fatal_error("unknown special variable with appending linkage");2905}29062907/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each2908/// global in the specified llvm.used list.2909void AsmPrinter::emitLLVMUsedList(const ConstantArray *InitList) {2910// Should be an array of 'i8*'.2911for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {2912const GlobalValue *GV =2913dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());2914if (GV)2915OutStreamer->emitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip);2916}2917}29182919void AsmPrinter::preprocessXXStructorList(const DataLayout &DL,2920const Constant *List,2921SmallVector<Structor, 8> &Structors) {2922// Should be an array of '{ i32, void ()*, i8* }' structs. The first value is2923// the init priority.2924if (!isa<ConstantArray>(List))2925return;29262927// Gather the structors in a form that's convenient for sorting by priority.2928for (Value *O : cast<ConstantArray>(List)->operands()) {2929auto *CS = cast<ConstantStruct>(O);2930if (CS->getOperand(1)->isNullValue())2931break; // Found a null terminator, skip the rest.2932ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));2933if (!Priority)2934continue; // Malformed.2935Structors.push_back(Structor());2936Structor &S = Structors.back();2937S.Priority = Priority->getLimitedValue(65535);2938S.Func = CS->getOperand(1);2939if (!CS->getOperand(2)->isNullValue()) {2940if (TM.getTargetTriple().isOSAIX())2941llvm::report_fatal_error(2942"associated data of XXStructor list is not yet supported on AIX");2943S.ComdatKey =2944dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());2945}2946}29472948// Emit the function pointers in the target-specific order2949llvm::stable_sort(Structors, [](const Structor &L, const Structor &R) {2950return L.Priority < R.Priority;2951});2952}29532954/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init2955/// priority.2956void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,2957bool IsCtor) {2958SmallVector<Structor, 8> Structors;2959preprocessXXStructorList(DL, List, Structors);2960if (Structors.empty())2961return;29622963// Emit the structors in reverse order if we are using the .ctor/.dtor2964// initialization scheme.2965if (!TM.Options.UseInitArray)2966std::reverse(Structors.begin(), Structors.end());29672968const Align Align = DL.getPointerPrefAlignment();2969for (Structor &S : Structors) {2970const TargetLoweringObjectFile &Obj = getObjFileLowering();2971const MCSymbol *KeySym = nullptr;2972if (GlobalValue *GV = S.ComdatKey) {2973if (GV->isDeclarationForLinker())2974// If the associated variable is not defined in this module2975// (it might be available_externally, or have been an2976// available_externally definition that was dropped by the2977// EliminateAvailableExternally pass), some other TU2978// will provide its dynamic initializer.2979continue;29802981KeySym = getSymbol(GV);2982}29832984MCSection *OutputSection =2985(IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)2986: Obj.getStaticDtorSection(S.Priority, KeySym));2987OutStreamer->switchSection(OutputSection);2988if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())2989emitAlignment(Align);2990emitXXStructor(DL, S.Func);2991}2992}29932994void AsmPrinter::emitModuleIdents(Module &M) {2995if (!MAI->hasIdentDirective())2996return;29972998if (const NamedMDNode *NMD = M.getNamedMetadata("llvm.ident")) {2999for (const MDNode *N : NMD->operands()) {3000assert(N->getNumOperands() == 1 &&3001"llvm.ident metadata entry can have only one operand");3002const MDString *S = cast<MDString>(N->getOperand(0));3003OutStreamer->emitIdent(S->getString());3004}3005}3006}30073008void AsmPrinter::emitModuleCommandLines(Module &M) {3009MCSection *CommandLine = getObjFileLowering().getSectionForCommandLines();3010if (!CommandLine)3011return;30123013const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");3014if (!NMD || !NMD->getNumOperands())3015return;30163017OutStreamer->pushSection();3018OutStreamer->switchSection(CommandLine);3019OutStreamer->emitZeros(1);3020for (const MDNode *N : NMD->operands()) {3021assert(N->getNumOperands() == 1 &&3022"llvm.commandline metadata entry can have only one operand");3023const MDString *S = cast<MDString>(N->getOperand(0));3024OutStreamer->emitBytes(S->getString());3025OutStreamer->emitZeros(1);3026}3027OutStreamer->popSection();3028}30293030//===--------------------------------------------------------------------===//3031// Emission and print routines3032//30333034/// Emit a byte directive and value.3035///3036void AsmPrinter::emitInt8(int Value) const { OutStreamer->emitInt8(Value); }30373038/// Emit a short directive and value.3039void AsmPrinter::emitInt16(int Value) const { OutStreamer->emitInt16(Value); }30403041/// Emit a long directive and value.3042void AsmPrinter::emitInt32(int Value) const { OutStreamer->emitInt32(Value); }30433044/// EmitSLEB128 - emit the specified signed leb128 value.3045void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {3046if (isVerbose() && Desc)3047OutStreamer->AddComment(Desc);30483049OutStreamer->emitSLEB128IntValue(Value);3050}30513052void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,3053unsigned PadTo) const {3054if (isVerbose() && Desc)3055OutStreamer->AddComment(Desc);30563057OutStreamer->emitULEB128IntValue(Value, PadTo);3058}30593060/// Emit a long long directive and value.3061void AsmPrinter::emitInt64(uint64_t Value) const {3062OutStreamer->emitInt64(Value);3063}30643065/// Emit something like ".long Hi-Lo" where the size in bytes of the directive3066/// is specified by Size and Hi/Lo specify the labels. This implicitly uses3067/// .set if it avoids relocations.3068void AsmPrinter::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,3069unsigned Size) const {3070OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size);3071}30723073/// Emit something like ".uleb128 Hi-Lo".3074void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi,3075const MCSymbol *Lo) const {3076OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);3077}30783079/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"3080/// where the size in bytes of the directive is specified by Size and Label3081/// specifies the label. This implicitly uses .set if it is available.3082void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,3083unsigned Size,3084bool IsSectionRelative) const {3085if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) {3086OutStreamer->emitCOFFSecRel32(Label, Offset);3087if (Size > 4)3088OutStreamer->emitZeros(Size - 4);3089return;3090}30913092// Emit Label+Offset (or just Label if Offset is zero)3093const MCExpr *Expr = MCSymbolRefExpr::create(Label, OutContext);3094if (Offset)3095Expr = MCBinaryExpr::createAdd(3096Expr, MCConstantExpr::create(Offset, OutContext), OutContext);30973098OutStreamer->emitValue(Expr, Size);3099}31003101//===----------------------------------------------------------------------===//31023103// EmitAlignment - Emit an alignment directive to the specified power of3104// two boundary. If a global value is specified, and if that global has3105// an explicit alignment requested, it will override the alignment request3106// if required for correctness.3107void AsmPrinter::emitAlignment(Align Alignment, const GlobalObject *GV,3108unsigned MaxBytesToEmit) const {3109if (GV)3110Alignment = getGVAlignment(GV, GV->getDataLayout(), Alignment);31113112if (Alignment == Align(1))3113return; // 1-byte aligned: no need to emit alignment.31143115if (getCurrentSection()->isText()) {3116const MCSubtargetInfo *STI = nullptr;3117if (this->MF)3118STI = &getSubtargetInfo();3119else3120STI = TM.getMCSubtargetInfo();3121OutStreamer->emitCodeAlignment(Alignment, STI, MaxBytesToEmit);3122} else3123OutStreamer->emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);3124}31253126//===----------------------------------------------------------------------===//3127// Constant emission.3128//===----------------------------------------------------------------------===//31293130const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {3131MCContext &Ctx = OutContext;31323133if (CV->isNullValue() || isa<UndefValue>(CV))3134return MCConstantExpr::create(0, Ctx);31353136if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))3137return MCConstantExpr::create(CI->getZExtValue(), Ctx);31383139if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(CV))3140return lowerConstantPtrAuth(*CPA);31413142if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))3143return MCSymbolRefExpr::create(getSymbol(GV), Ctx);31443145if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))3146return lowerBlockAddressConstant(*BA);31473148if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))3149return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM);31503151if (const NoCFIValue *NC = dyn_cast<NoCFIValue>(CV))3152return MCSymbolRefExpr::create(getSymbol(NC->getGlobalValue()), Ctx);31533154const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);3155if (!CE) {3156llvm_unreachable("Unknown constant value to lower!");3157}31583159// The constant expression opcodes are limited to those that are necessary3160// to represent relocations on supported targets. Expressions involving only3161// constant addresses are constant folded instead.3162switch (CE->getOpcode()) {3163default:3164break; // Error3165case Instruction::AddrSpaceCast: {3166const Constant *Op = CE->getOperand(0);3167unsigned DstAS = CE->getType()->getPointerAddressSpace();3168unsigned SrcAS = Op->getType()->getPointerAddressSpace();3169if (TM.isNoopAddrSpaceCast(SrcAS, DstAS))3170return lowerConstant(Op);31713172break; // Error3173}3174case Instruction::GetElementPtr: {3175// Generate a symbolic expression for the byte address3176APInt OffsetAI(getDataLayout().getPointerTypeSizeInBits(CE->getType()), 0);3177cast<GEPOperator>(CE)->accumulateConstantOffset(getDataLayout(), OffsetAI);31783179const MCExpr *Base = lowerConstant(CE->getOperand(0));3180if (!OffsetAI)3181return Base;31823183int64_t Offset = OffsetAI.getSExtValue();3184return MCBinaryExpr::createAdd(Base, MCConstantExpr::create(Offset, Ctx),3185Ctx);3186}31873188case Instruction::Trunc:3189// We emit the value and depend on the assembler to truncate the generated3190// expression properly. This is important for differences between3191// blockaddress labels. Since the two labels are in the same function, it3192// is reasonable to treat their delta as a 32-bit value.3193[[fallthrough]];3194case Instruction::BitCast:3195return lowerConstant(CE->getOperand(0));31963197case Instruction::IntToPtr: {3198const DataLayout &DL = getDataLayout();31993200// Handle casts to pointers by changing them into casts to the appropriate3201// integer type. This promotes constant folding and simplifies this code.3202Constant *Op = CE->getOperand(0);3203Op = ConstantFoldIntegerCast(Op, DL.getIntPtrType(CV->getType()),3204/*IsSigned*/ false, DL);3205if (Op)3206return lowerConstant(Op);32073208break; // Error3209}32103211case Instruction::PtrToInt: {3212const DataLayout &DL = getDataLayout();32133214// Support only foldable casts to/from pointers that can be eliminated by3215// changing the pointer to the appropriately sized integer type.3216Constant *Op = CE->getOperand(0);3217Type *Ty = CE->getType();32183219const MCExpr *OpExpr = lowerConstant(Op);32203221// We can emit the pointer value into this slot if the slot is an3222// integer slot equal to the size of the pointer.3223//3224// If the pointer is larger than the resultant integer, then3225// as with Trunc just depend on the assembler to truncate it.3226if (DL.getTypeAllocSize(Ty).getFixedValue() <=3227DL.getTypeAllocSize(Op->getType()).getFixedValue())3228return OpExpr;32293230break; // Error3231}32323233case Instruction::Sub: {3234GlobalValue *LHSGV;3235APInt LHSOffset;3236DSOLocalEquivalent *DSOEquiv;3237if (IsConstantOffsetFromGlobal(CE->getOperand(0), LHSGV, LHSOffset,3238getDataLayout(), &DSOEquiv)) {3239GlobalValue *RHSGV;3240APInt RHSOffset;3241if (IsConstantOffsetFromGlobal(CE->getOperand(1), RHSGV, RHSOffset,3242getDataLayout())) {3243const MCExpr *RelocExpr =3244getObjFileLowering().lowerRelativeReference(LHSGV, RHSGV, TM);3245if (!RelocExpr) {3246const MCExpr *LHSExpr =3247MCSymbolRefExpr::create(getSymbol(LHSGV), Ctx);3248if (DSOEquiv &&3249getObjFileLowering().supportDSOLocalEquivalentLowering())3250LHSExpr =3251getObjFileLowering().lowerDSOLocalEquivalent(DSOEquiv, TM);3252RelocExpr = MCBinaryExpr::createSub(3253LHSExpr, MCSymbolRefExpr::create(getSymbol(RHSGV), Ctx), Ctx);3254}3255int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();3256if (Addend != 0)3257RelocExpr = MCBinaryExpr::createAdd(3258RelocExpr, MCConstantExpr::create(Addend, Ctx), Ctx);3259return RelocExpr;3260}3261}32623263const MCExpr *LHS = lowerConstant(CE->getOperand(0));3264const MCExpr *RHS = lowerConstant(CE->getOperand(1));3265return MCBinaryExpr::createSub(LHS, RHS, Ctx);3266break;3267}32683269case Instruction::Add: {3270const MCExpr *LHS = lowerConstant(CE->getOperand(0));3271const MCExpr *RHS = lowerConstant(CE->getOperand(1));3272return MCBinaryExpr::createAdd(LHS, RHS, Ctx);3273}3274}32753276// If the code isn't optimized, there may be outstanding folding3277// opportunities. Attempt to fold the expression using DataLayout as a3278// last resort before giving up.3279Constant *C = ConstantFoldConstant(CE, getDataLayout());3280if (C != CE)3281return lowerConstant(C);32823283// Otherwise report the problem to the user.3284std::string S;3285raw_string_ostream OS(S);3286OS << "Unsupported expression in static initializer: ";3287CE->printAsOperand(OS, /*PrintType=*/false,3288!MF ? nullptr : MF->getFunction().getParent());3289report_fatal_error(Twine(S));3290}32913292static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *C,3293AsmPrinter &AP,3294const Constant *BaseCV = nullptr,3295uint64_t Offset = 0,3296AsmPrinter::AliasMapTy *AliasList = nullptr);32973298static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP);3299static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP);33003301/// isRepeatedByteSequence - Determine whether the given value is3302/// composed of a repeated sequence of identical bytes and return the3303/// byte value. If it is not a repeated sequence, return -1.3304static int isRepeatedByteSequence(const ConstantDataSequential *V) {3305StringRef Data = V->getRawDataValues();3306assert(!Data.empty() && "Empty aggregates should be CAZ node");3307char C = Data[0];3308for (unsigned i = 1, e = Data.size(); i != e; ++i)3309if (Data[i] != C) return -1;3310return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1.3311}33123313/// isRepeatedByteSequence - Determine whether the given value is3314/// composed of a repeated sequence of identical bytes and return the3315/// byte value. If it is not a repeated sequence, return -1.3316static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) {3317if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {3318uint64_t Size = DL.getTypeAllocSizeInBits(V->getType());3319assert(Size % 8 == 0);33203321// Extend the element to take zero padding into account.3322APInt Value = CI->getValue().zext(Size);3323if (!Value.isSplat(8))3324return -1;33253326return Value.zextOrTrunc(8).getZExtValue();3327}3328if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) {3329// Make sure all array elements are sequences of the same repeated3330// byte.3331assert(CA->getNumOperands() != 0 && "Should be a CAZ");3332Constant *Op0 = CA->getOperand(0);3333int Byte = isRepeatedByteSequence(Op0, DL);3334if (Byte == -1)3335return -1;33363337// All array elements must be equal.3338for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i)3339if (CA->getOperand(i) != Op0)3340return -1;3341return Byte;3342}33433344if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V))3345return isRepeatedByteSequence(CDS);33463347return -1;3348}33493350static void emitGlobalAliasInline(AsmPrinter &AP, uint64_t Offset,3351AsmPrinter::AliasMapTy *AliasList) {3352if (AliasList) {3353auto AliasIt = AliasList->find(Offset);3354if (AliasIt != AliasList->end()) {3355for (const GlobalAlias *GA : AliasIt->second)3356AP.OutStreamer->emitLabel(AP.getSymbol(GA));3357AliasList->erase(Offset);3358}3359}3360}33613362static void emitGlobalConstantDataSequential(3363const DataLayout &DL, const ConstantDataSequential *CDS, AsmPrinter &AP,3364AsmPrinter::AliasMapTy *AliasList) {3365// See if we can aggregate this into a .fill, if so, emit it as such.3366int Value = isRepeatedByteSequence(CDS, DL);3367if (Value != -1) {3368uint64_t Bytes = DL.getTypeAllocSize(CDS->getType());3369// Don't emit a 1-byte object as a .fill.3370if (Bytes > 1)3371return AP.OutStreamer->emitFill(Bytes, Value);3372}33733374// If this can be emitted with .ascii/.asciz, emit it as such.3375if (CDS->isString())3376return AP.OutStreamer->emitBytes(CDS->getAsString());33773378// Otherwise, emit the values in successive locations.3379unsigned ElementByteSize = CDS->getElementByteSize();3380if (isa<IntegerType>(CDS->getElementType())) {3381for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {3382emitGlobalAliasInline(AP, ElementByteSize * I, AliasList);3383if (AP.isVerbose())3384AP.OutStreamer->getCommentOS()3385<< format("0x%" PRIx64 "\n", CDS->getElementAsInteger(I));3386AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(I),3387ElementByteSize);3388}3389} else {3390Type *ET = CDS->getElementType();3391for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {3392emitGlobalAliasInline(AP, ElementByteSize * I, AliasList);3393emitGlobalConstantFP(CDS->getElementAsAPFloat(I), ET, AP);3394}3395}33963397unsigned Size = DL.getTypeAllocSize(CDS->getType());3398unsigned EmittedSize =3399DL.getTypeAllocSize(CDS->getElementType()) * CDS->getNumElements();3400assert(EmittedSize <= Size && "Size cannot be less than EmittedSize!");3401if (unsigned Padding = Size - EmittedSize)3402AP.OutStreamer->emitZeros(Padding);3403}34043405static void emitGlobalConstantArray(const DataLayout &DL,3406const ConstantArray *CA, AsmPrinter &AP,3407const Constant *BaseCV, uint64_t Offset,3408AsmPrinter::AliasMapTy *AliasList) {3409// See if we can aggregate some values. Make sure it can be3410// represented as a series of bytes of the constant value.3411int Value = isRepeatedByteSequence(CA, DL);34123413if (Value != -1) {3414uint64_t Bytes = DL.getTypeAllocSize(CA->getType());3415AP.OutStreamer->emitFill(Bytes, Value);3416} else {3417for (unsigned I = 0, E = CA->getNumOperands(); I != E; ++I) {3418emitGlobalConstantImpl(DL, CA->getOperand(I), AP, BaseCV, Offset,3419AliasList);3420Offset += DL.getTypeAllocSize(CA->getOperand(I)->getType());3421}3422}3423}34243425static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP);34263427static void emitGlobalConstantVector(const DataLayout &DL,3428const ConstantVector *CV, AsmPrinter &AP,3429AsmPrinter::AliasMapTy *AliasList) {3430Type *ElementType = CV->getType()->getElementType();3431uint64_t ElementSizeInBits = DL.getTypeSizeInBits(ElementType);3432uint64_t ElementAllocSizeInBits = DL.getTypeAllocSizeInBits(ElementType);3433uint64_t EmittedSize;3434if (ElementSizeInBits != ElementAllocSizeInBits) {3435// If the allocation size of an element is different from the size in bits,3436// printing each element separately will insert incorrect padding.3437//3438// The general algorithm here is complicated; instead of writing it out3439// here, just use the existing code in ConstantFolding.3440Type *IntT =3441IntegerType::get(CV->getContext(), DL.getTypeSizeInBits(CV->getType()));3442ConstantInt *CI = dyn_cast_or_null<ConstantInt>(ConstantFoldConstant(3443ConstantExpr::getBitCast(const_cast<ConstantVector *>(CV), IntT), DL));3444if (!CI) {3445report_fatal_error(3446"Cannot lower vector global with unusual element type");3447}3448emitGlobalAliasInline(AP, 0, AliasList);3449emitGlobalConstantLargeInt(CI, AP);3450EmittedSize = DL.getTypeStoreSize(CV->getType());3451} else {3452for (unsigned I = 0, E = CV->getType()->getNumElements(); I != E; ++I) {3453emitGlobalAliasInline(AP, DL.getTypeAllocSize(CV->getType()) * I, AliasList);3454emitGlobalConstantImpl(DL, CV->getOperand(I), AP);3455}3456EmittedSize =3457DL.getTypeAllocSize(ElementType) * CV->getType()->getNumElements();3458}34593460unsigned Size = DL.getTypeAllocSize(CV->getType());3461if (unsigned Padding = Size - EmittedSize)3462AP.OutStreamer->emitZeros(Padding);3463}34643465static void emitGlobalConstantStruct(const DataLayout &DL,3466const ConstantStruct *CS, AsmPrinter &AP,3467const Constant *BaseCV, uint64_t Offset,3468AsmPrinter::AliasMapTy *AliasList) {3469// Print the fields in successive locations. Pad to align if needed!3470uint64_t Size = DL.getTypeAllocSize(CS->getType());3471const StructLayout *Layout = DL.getStructLayout(CS->getType());3472uint64_t SizeSoFar = 0;3473for (unsigned I = 0, E = CS->getNumOperands(); I != E; ++I) {3474const Constant *Field = CS->getOperand(I);34753476// Print the actual field value.3477emitGlobalConstantImpl(DL, Field, AP, BaseCV, Offset + SizeSoFar,3478AliasList);34793480// Check if padding is needed and insert one or more 0s.3481uint64_t FieldSize = DL.getTypeAllocSize(Field->getType());3482uint64_t PadSize = ((I == E - 1 ? Size : Layout->getElementOffset(I + 1)) -3483Layout->getElementOffset(I)) -3484FieldSize;3485SizeSoFar += FieldSize + PadSize;34863487// Insert padding - this may include padding to increase the size of the3488// current field up to the ABI size (if the struct is not packed) as well3489// as padding to ensure that the next field starts at the right offset.3490AP.OutStreamer->emitZeros(PadSize);3491}3492assert(SizeSoFar == Layout->getSizeInBytes() &&3493"Layout of constant struct may be incorrect!");3494}34953496static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) {3497assert(ET && "Unknown float type");3498APInt API = APF.bitcastToAPInt();34993500// First print a comment with what we think the original floating-point value3501// should have been.3502if (AP.isVerbose()) {3503SmallString<8> StrVal;3504APF.toString(StrVal);3505ET->print(AP.OutStreamer->getCommentOS());3506AP.OutStreamer->getCommentOS() << ' ' << StrVal << '\n';3507}35083509// Now iterate through the APInt chunks, emitting them in endian-correct3510// order, possibly with a smaller chunk at beginning/end (e.g. for x87 80-bit3511// floats).3512unsigned NumBytes = API.getBitWidth() / 8;3513unsigned TrailingBytes = NumBytes % sizeof(uint64_t);3514const uint64_t *p = API.getRawData();35153516// PPC's long double has odd notions of endianness compared to how LLVM3517// handles it: p[0] goes first for *big* endian on PPC.3518if (AP.getDataLayout().isBigEndian() && !ET->isPPC_FP128Ty()) {3519int Chunk = API.getNumWords() - 1;35203521if (TrailingBytes)3522AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk--], TrailingBytes);35233524for (; Chunk >= 0; --Chunk)3525AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t));3526} else {3527unsigned Chunk;3528for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk)3529AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t));35303531if (TrailingBytes)3532AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], TrailingBytes);3533}35343535// Emit the tail padding for the long double.3536const DataLayout &DL = AP.getDataLayout();3537AP.OutStreamer->emitZeros(DL.getTypeAllocSize(ET) - DL.getTypeStoreSize(ET));3538}35393540static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) {3541emitGlobalConstantFP(CFP->getValueAPF(), CFP->getType(), AP);3542}35433544static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) {3545const DataLayout &DL = AP.getDataLayout();3546unsigned BitWidth = CI->getBitWidth();35473548// Copy the value as we may massage the layout for constants whose bit width3549// is not a multiple of 64-bits.3550APInt Realigned(CI->getValue());3551uint64_t ExtraBits = 0;3552unsigned ExtraBitsSize = BitWidth & 63;35533554if (ExtraBitsSize) {3555// The bit width of the data is not a multiple of 64-bits.3556// The extra bits are expected to be at the end of the chunk of the memory.3557// Little endian:3558// * Nothing to be done, just record the extra bits to emit.3559// Big endian:3560// * Record the extra bits to emit.3561// * Realign the raw data to emit the chunks of 64-bits.3562if (DL.isBigEndian()) {3563// Basically the structure of the raw data is a chunk of 64-bits cells:3564// 0 1 BitWidth / 643565// [chunk1][chunk2] ... [chunkN].3566// The most significant chunk is chunkN and it should be emitted first.3567// However, due to the alignment issue chunkN contains useless bits.3568// Realign the chunks so that they contain only useful information:3569// ExtraBits 0 1 (BitWidth / 64) - 13570// chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN]3571ExtraBitsSize = alignTo(ExtraBitsSize, 8);3572ExtraBits = Realigned.getRawData()[0] &3573(((uint64_t)-1) >> (64 - ExtraBitsSize));3574if (BitWidth >= 64)3575Realigned.lshrInPlace(ExtraBitsSize);3576} else3577ExtraBits = Realigned.getRawData()[BitWidth / 64];3578}35793580// We don't expect assemblers to support integer data directives3581// for more than 64 bits, so we emit the data in at most 64-bit3582// quantities at a time.3583const uint64_t *RawData = Realigned.getRawData();3584for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {3585uint64_t Val = DL.isBigEndian() ? RawData[e - i - 1] : RawData[i];3586AP.OutStreamer->emitIntValue(Val, 8);3587}35883589if (ExtraBitsSize) {3590// Emit the extra bits after the 64-bits chunks.35913592// Emit a directive that fills the expected size.3593uint64_t Size = AP.getDataLayout().getTypeStoreSize(CI->getType());3594Size -= (BitWidth / 64) * 8;3595assert(Size && Size * 8 >= ExtraBitsSize &&3596(ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize)))3597== ExtraBits && "Directive too small for extra bits.");3598AP.OutStreamer->emitIntValue(ExtraBits, Size);3599}3600}36013602/// Transform a not absolute MCExpr containing a reference to a GOT3603/// equivalent global, by a target specific GOT pc relative access to the3604/// final symbol.3605static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,3606const Constant *BaseCst,3607uint64_t Offset) {3608// The global @foo below illustrates a global that uses a got equivalent.3609//3610// @bar = global i32 423611// @gotequiv = private unnamed_addr constant i32* @bar3612// @foo = i32 trunc (i64 sub (i64 ptrtoint (i32** @gotequiv to i64),3613// i64 ptrtoint (i32* @foo to i64))3614// to i32)3615//3616// The cstexpr in @foo is converted into the MCExpr `ME`, where we actually3617// check whether @foo is suitable to use a GOTPCREL. `ME` is usually in the3618// form:3619//3620// foo = cstexpr, where3621// cstexpr := <gotequiv> - "." + <cst>3622// cstexpr := <gotequiv> - (<foo> - <offset from @foo base>) + <cst>3623//3624// After canonicalization by evaluateAsRelocatable `ME` turns into:3625//3626// cstexpr := <gotequiv> - <foo> + gotpcrelcst, where3627// gotpcrelcst := <offset from @foo base> + <cst>3628MCValue MV;3629if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute())3630return;3631const MCSymbolRefExpr *SymA = MV.getSymA();3632if (!SymA)3633return;36343635// Check that GOT equivalent symbol is cached.3636const MCSymbol *GOTEquivSym = &SymA->getSymbol();3637if (!AP.GlobalGOTEquivs.count(GOTEquivSym))3638return;36393640const GlobalValue *BaseGV = dyn_cast_or_null<GlobalValue>(BaseCst);3641if (!BaseGV)3642return;36433644// Check for a valid base symbol3645const MCSymbol *BaseSym = AP.getSymbol(BaseGV);3646const MCSymbolRefExpr *SymB = MV.getSymB();36473648if (!SymB || BaseSym != &SymB->getSymbol())3649return;36503651// Make sure to match:3652//3653// gotpcrelcst := <offset from @foo base> + <cst>3654//3655int64_t GOTPCRelCst = Offset + MV.getConstant();3656if (!AP.getObjFileLowering().supportGOTPCRelWithOffset() && GOTPCRelCst != 0)3657return;36583659// Emit the GOT PC relative to replace the got equivalent global, i.e.:3660//3661// bar:3662// .long 423663// gotequiv:3664// .quad bar3665// foo:3666// .long gotequiv - "." + <cst>3667//3668// is replaced by the target specific equivalent to:3669//3670// bar:3671// .long 423672// foo:3673// .long bar@GOTPCREL+<gotpcrelcst>3674AsmPrinter::GOTEquivUsePair Result = AP.GlobalGOTEquivs[GOTEquivSym];3675const GlobalVariable *GV = Result.first;3676int NumUses = (int)Result.second;3677const GlobalValue *FinalGV = dyn_cast<GlobalValue>(GV->getOperand(0));3678const MCSymbol *FinalSym = AP.getSymbol(FinalGV);3679*ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel(3680FinalGV, FinalSym, MV, Offset, AP.MMI, *AP.OutStreamer);36813682// Update GOT equivalent usage information3683--NumUses;3684if (NumUses >= 0)3685AP.GlobalGOTEquivs[GOTEquivSym] = std::make_pair(GV, NumUses);3686}36873688static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,3689AsmPrinter &AP, const Constant *BaseCV,3690uint64_t Offset,3691AsmPrinter::AliasMapTy *AliasList) {3692emitGlobalAliasInline(AP, Offset, AliasList);3693uint64_t Size = DL.getTypeAllocSize(CV->getType());36943695// Globals with sub-elements such as combinations of arrays and structs3696// are handled recursively by emitGlobalConstantImpl. Keep track of the3697// constant symbol base and the current position with BaseCV and Offset.3698if (!BaseCV && CV->hasOneUse())3699BaseCV = dyn_cast<Constant>(CV->user_back());37003701if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))3702return AP.OutStreamer->emitZeros(Size);37033704if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {3705const uint64_t StoreSize = DL.getTypeStoreSize(CV->getType());37063707if (StoreSize <= 8) {3708if (AP.isVerbose())3709AP.OutStreamer->getCommentOS()3710<< format("0x%" PRIx64 "\n", CI->getZExtValue());3711AP.OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize);3712} else {3713emitGlobalConstantLargeInt(CI, AP);3714}37153716// Emit tail padding if needed3717if (Size != StoreSize)3718AP.OutStreamer->emitZeros(Size - StoreSize);37193720return;3721}37223723if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))3724return emitGlobalConstantFP(CFP, AP);37253726if (isa<ConstantPointerNull>(CV)) {3727AP.OutStreamer->emitIntValue(0, Size);3728return;3729}37303731if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV))3732return emitGlobalConstantDataSequential(DL, CDS, AP, AliasList);37333734if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))3735return emitGlobalConstantArray(DL, CVA, AP, BaseCV, Offset, AliasList);37363737if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))3738return emitGlobalConstantStruct(DL, CVS, AP, BaseCV, Offset, AliasList);37393740if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {3741// Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of3742// vectors).3743if (CE->getOpcode() == Instruction::BitCast)3744return emitGlobalConstantImpl(DL, CE->getOperand(0), AP);37453746if (Size > 8) {3747// If the constant expression's size is greater than 64-bits, then we have3748// to emit the value in chunks. Try to constant fold the value and emit it3749// that way.3750Constant *New = ConstantFoldConstant(CE, DL);3751if (New != CE)3752return emitGlobalConstantImpl(DL, New, AP);3753}3754}37553756if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))3757return emitGlobalConstantVector(DL, V, AP, AliasList);37583759// Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it3760// thread the streamer with EmitValue.3761const MCExpr *ME = AP.lowerConstant(CV);37623763// Since lowerConstant already folded and got rid of all IR pointer and3764// integer casts, detect GOT equivalent accesses by looking into the MCExpr3765// directly.3766if (AP.getObjFileLowering().supportIndirectSymViaGOTPCRel())3767handleIndirectSymViaGOTPCRel(AP, &ME, BaseCV, Offset);37683769AP.OutStreamer->emitValue(ME, Size);3770}37713772/// EmitGlobalConstant - Print a general LLVM constant to the .s file.3773void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV,3774AliasMapTy *AliasList) {3775uint64_t Size = DL.getTypeAllocSize(CV->getType());3776if (Size)3777emitGlobalConstantImpl(DL, CV, *this, nullptr, 0, AliasList);3778else if (MAI->hasSubsectionsViaSymbols()) {3779// If the global has zero size, emit a single byte so that two labels don't3780// look like they are at the same location.3781OutStreamer->emitIntValue(0, 1);3782}3783if (!AliasList)3784return;3785// TODO: These remaining aliases are not emitted in the correct location. Need3786// to handle the case where the alias offset doesn't refer to any sub-element.3787for (auto &AliasPair : *AliasList) {3788for (const GlobalAlias *GA : AliasPair.second)3789OutStreamer->emitLabel(getSymbol(GA));3790}3791}37923793void AsmPrinter::emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {3794// Target doesn't support this yet!3795llvm_unreachable("Target does not support EmitMachineConstantPoolValue");3796}37973798void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const {3799if (Offset > 0)3800OS << '+' << Offset;3801else if (Offset < 0)3802OS << Offset;3803}38043805void AsmPrinter::emitNops(unsigned N) {3806MCInst Nop = MF->getSubtarget().getInstrInfo()->getNop();3807for (; N; --N)3808EmitToStreamer(*OutStreamer, Nop);3809}38103811//===----------------------------------------------------------------------===//3812// Symbol Lowering Routines.3813//===----------------------------------------------------------------------===//38143815MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const {3816return OutContext.createTempSymbol(Name, true);3817}38183819MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {3820return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(3821BA->getBasicBlock());3822}38233824MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {3825return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB);3826}38273828const MCExpr *AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {3829return MCSymbolRefExpr::create(GetBlockAddressSymbol(&BA), OutContext);3830}38313832/// GetCPISymbol - Return the symbol for the specified constant pool entry.3833MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {3834if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment()) {3835const MachineConstantPoolEntry &CPE =3836MF->getConstantPool()->getConstants()[CPID];3837if (!CPE.isMachineConstantPoolEntry()) {3838const DataLayout &DL = MF->getDataLayout();3839SectionKind Kind = CPE.getSectionKind(&DL);3840const Constant *C = CPE.Val.ConstVal;3841Align Alignment = CPE.Alignment;3842if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>(3843getObjFileLowering().getSectionForConstant(DL, Kind, C,3844Alignment))) {3845if (MCSymbol *Sym = S->getCOMDATSymbol()) {3846if (Sym->isUndefined())3847OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);3848return Sym;3849}3850}3851}3852}38533854const DataLayout &DL = getDataLayout();3855return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +3856"CPI" + Twine(getFunctionNumber()) + "_" +3857Twine(CPID));3858}38593860/// GetJTISymbol - Return the symbol for the specified jump table entry.3861MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {3862return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate);3863}38643865/// GetJTSetSymbol - Return the symbol for the specified jump table .set3866/// FIXME: privatize to AsmPrinter.3867MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const {3868const DataLayout &DL = getDataLayout();3869return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +3870Twine(getFunctionNumber()) + "_" +3871Twine(UID) + "_set_" + Twine(MBBID));3872}38733874MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,3875StringRef Suffix) const {3876return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, TM);3877}38783879/// Return the MCSymbol for the specified ExternalSymbol.3880MCSymbol *AsmPrinter::GetExternalSymbolSymbol(Twine Sym) const {3881SmallString<60> NameStr;3882Mangler::getNameWithPrefix(NameStr, Sym, getDataLayout());3883return OutContext.getOrCreateSymbol(NameStr);3884}38853886/// PrintParentLoopComment - Print comments about parent loops of this one.3887static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,3888unsigned FunctionNumber) {3889if (!Loop) return;3890PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber);3891OS.indent(Loop->getLoopDepth()*2)3892<< "Parent Loop BB" << FunctionNumber << "_"3893<< Loop->getHeader()->getNumber()3894<< " Depth=" << Loop->getLoopDepth() << '\n';3895}38963897/// PrintChildLoopComment - Print comments about child loops within3898/// the loop for this basic block, with nesting.3899static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,3900unsigned FunctionNumber) {3901// Add child loop information3902for (const MachineLoop *CL : *Loop) {3903OS.indent(CL->getLoopDepth()*2)3904<< "Child Loop BB" << FunctionNumber << "_"3905<< CL->getHeader()->getNumber() << " Depth " << CL->getLoopDepth()3906<< '\n';3907PrintChildLoopComment(OS, CL, FunctionNumber);3908}3909}39103911/// emitBasicBlockLoopComments - Pretty-print comments for basic blocks.3912static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,3913const MachineLoopInfo *LI,3914const AsmPrinter &AP) {3915// Add loop depth information3916const MachineLoop *Loop = LI->getLoopFor(&MBB);3917if (!Loop) return;39183919MachineBasicBlock *Header = Loop->getHeader();3920assert(Header && "No header for loop");39213922// If this block is not a loop header, just print out what is the loop header3923// and return.3924if (Header != &MBB) {3925AP.OutStreamer->AddComment(" in Loop: Header=BB" +3926Twine(AP.getFunctionNumber())+"_" +3927Twine(Loop->getHeader()->getNumber())+3928" Depth="+Twine(Loop->getLoopDepth()));3929return;3930}39313932// Otherwise, it is a loop header. Print out information about child and3933// parent loops.3934raw_ostream &OS = AP.OutStreamer->getCommentOS();39353936PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());39373938OS << "=>";3939OS.indent(Loop->getLoopDepth()*2-2);39403941OS << "This ";3942if (Loop->isInnermost())3943OS << "Inner ";3944OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';39453946PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());3947}39483949/// emitBasicBlockStart - This method prints the label for the specified3950/// MachineBasicBlock, an alignment (if present) and a comment describing3951/// it if appropriate.3952void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {3953// End the previous funclet and start a new one.3954if (MBB.isEHFuncletEntry()) {3955for (auto &Handler : Handlers) {3956Handler->endFunclet();3957Handler->beginFunclet(MBB);3958}3959}39603961// Switch to a new section if this basic block must begin a section. The3962// entry block is always placed in the function section and is handled3963// separately.3964if (MBB.isBeginSection() && !MBB.isEntryBlock()) {3965OutStreamer->switchSection(3966getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),3967MBB, TM));3968CurrentSectionBeginSym = MBB.getSymbol();3969}39703971// Emit an alignment directive for this block, if needed.3972const Align Alignment = MBB.getAlignment();3973if (Alignment != Align(1))3974emitAlignment(Alignment, nullptr, MBB.getMaxBytesForAlignment());39753976// If the block has its address taken, emit any labels that were used to3977// reference the block. It is possible that there is more than one label3978// here, because multiple LLVM BB's may have been RAUW'd to this block after3979// the references were generated.3980if (MBB.isIRBlockAddressTaken()) {3981if (isVerbose())3982OutStreamer->AddComment("Block address taken");39833984BasicBlock *BB = MBB.getAddressTakenIRBlock();3985assert(BB && BB->hasAddressTaken() && "Missing BB");3986for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))3987OutStreamer->emitLabel(Sym);3988} else if (isVerbose() && MBB.isMachineBlockAddressTaken()) {3989OutStreamer->AddComment("Block address taken");3990}39913992// Print some verbose block comments.3993if (isVerbose()) {3994if (const BasicBlock *BB = MBB.getBasicBlock()) {3995if (BB->hasName()) {3996BB->printAsOperand(OutStreamer->getCommentOS(),3997/*PrintType=*/false, BB->getModule());3998OutStreamer->getCommentOS() << '\n';3999}4000}40014002assert(MLI != nullptr && "MachineLoopInfo should has been computed");4003emitBasicBlockLoopComments(MBB, MLI, *this);4004}40054006// Print the main label for the block.4007if (shouldEmitLabelForBasicBlock(MBB)) {4008if (isVerbose() && MBB.hasLabelMustBeEmitted())4009OutStreamer->AddComment("Label of block must be emitted");4010OutStreamer->emitLabel(MBB.getSymbol());4011} else {4012if (isVerbose()) {4013// NOTE: Want this comment at start of line, don't emit with AddComment.4014OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",4015false);4016}4017}40184019if (MBB.isEHCatchretTarget() &&4020MAI->getExceptionHandlingType() == ExceptionHandling::WinEH) {4021OutStreamer->emitLabel(MBB.getEHCatchretSymbol());4022}40234024// With BB sections, each basic block must handle CFI information on its own4025// if it begins a section (Entry block call is handled separately, next to4026// beginFunction).4027if (MBB.isBeginSection() && !MBB.isEntryBlock()) {4028for (auto &Handler : DebugHandlers)4029Handler->beginBasicBlockSection(MBB);4030for (auto &Handler : Handlers)4031Handler->beginBasicBlockSection(MBB);4032}4033}40344035void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {4036// Check if CFI information needs to be updated for this MBB with basic block4037// sections.4038if (MBB.isEndSection()) {4039for (auto &Handler : DebugHandlers)4040Handler->endBasicBlockSection(MBB);4041for (auto &Handler : Handlers)4042Handler->endBasicBlockSection(MBB);4043}4044}40454046void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility,4047bool IsDefinition) const {4048MCSymbolAttr Attr = MCSA_Invalid;40494050switch (Visibility) {4051default: break;4052case GlobalValue::HiddenVisibility:4053if (IsDefinition)4054Attr = MAI->getHiddenVisibilityAttr();4055else4056Attr = MAI->getHiddenDeclarationVisibilityAttr();4057break;4058case GlobalValue::ProtectedVisibility:4059Attr = MAI->getProtectedVisibilityAttr();4060break;4061}40624063if (Attr != MCSA_Invalid)4064OutStreamer->emitSymbolAttribute(Sym, Attr);4065}40664067bool AsmPrinter::shouldEmitLabelForBasicBlock(4068const MachineBasicBlock &MBB) const {4069// With `-fbasic-block-sections=`, a label is needed for every non-entry block4070// in the labels mode (option `=labels`) and every section beginning in the4071// sections mode (`=all` and `=list=`).4072if ((MF->hasBBLabels() || MF->getTarget().Options.BBAddrMap ||4073MBB.isBeginSection()) &&4074!MBB.isEntryBlock())4075return true;4076// A label is needed for any block with at least one predecessor (when that4077// predecessor is not the fallthrough predecessor, or if it is an EH funclet4078// entry, or if a label is forced).4079return !MBB.pred_empty() &&4080(!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() ||4081MBB.hasLabelMustBeEmitted());4082}40834084/// isBlockOnlyReachableByFallthough - Return true if the basic block has4085/// exactly one predecessor and the control transfer mechanism between4086/// the predecessor and this block is a fall-through.4087bool AsmPrinter::4088isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {4089// If this is a landing pad, it isn't a fall through. If it has no preds,4090// then nothing falls through to it.4091if (MBB->isEHPad() || MBB->pred_empty())4092return false;40934094// If there isn't exactly one predecessor, it can't be a fall through.4095if (MBB->pred_size() > 1)4096return false;40974098// The predecessor has to be immediately before this block.4099MachineBasicBlock *Pred = *MBB->pred_begin();4100if (!Pred->isLayoutSuccessor(MBB))4101return false;41024103// If the block is completely empty, then it definitely does fall through.4104if (Pred->empty())4105return true;41064107// Check the terminators in the previous blocks4108for (const auto &MI : Pred->terminators()) {4109// If it is not a simple branch, we are in a table somewhere.4110if (!MI.isBranch() || MI.isIndirectBranch())4111return false;41124113// If we are the operands of one of the branches, this is not a fall4114// through. Note that targets with delay slots will usually bundle4115// terminators with the delay slot instruction.4116for (ConstMIBundleOperands OP(MI); OP.isValid(); ++OP) {4117if (OP->isJTI())4118return false;4119if (OP->isMBB() && OP->getMBB() == MBB)4120return false;4121}4122}41234124return true;4125}41264127GCMetadataPrinter *AsmPrinter::getOrCreateGCPrinter(GCStrategy &S) {4128if (!S.usesMetadata())4129return nullptr;41304131auto [GCPI, Inserted] = GCMetadataPrinters.insert({&S, nullptr});4132if (!Inserted)4133return GCPI->second.get();41344135auto Name = S.getName();41364137for (const GCMetadataPrinterRegistry::entry &GCMetaPrinter :4138GCMetadataPrinterRegistry::entries())4139if (Name == GCMetaPrinter.getName()) {4140std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate();4141GMP->S = &S;4142GCPI->second = std::move(GMP);4143return GCPI->second.get();4144}41454146report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));4147}41484149void AsmPrinter::emitStackMaps() {4150GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();4151assert(MI && "AsmPrinter didn't require GCModuleInfo?");4152bool NeedsDefault = false;4153if (MI->begin() == MI->end())4154// No GC strategy, use the default format.4155NeedsDefault = true;4156else4157for (const auto &I : *MI) {4158if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))4159if (MP->emitStackMaps(SM, *this))4160continue;4161// The strategy doesn't have printer or doesn't emit custom stack maps.4162// Use the default format.4163NeedsDefault = true;4164}41654166if (NeedsDefault)4167SM.serializeToStackMapSection();4168}41694170void AsmPrinter::addAsmPrinterHandler(4171std::unique_ptr<AsmPrinterHandler> Handler) {4172Handlers.insert(Handlers.begin(), std::move(Handler));4173NumUserHandlers++;4174}41754176void AsmPrinter::addDebugHandler(std::unique_ptr<DebugHandlerBase> Handler) {4177DebugHandlers.insert(DebugHandlers.begin(), std::move(Handler));4178NumUserDebugHandlers++;4179}41804181/// Pin vtable to this file.4182AsmPrinterHandler::~AsmPrinterHandler() = default;41834184void AsmPrinterHandler::markFunctionEnd() {}41854186// In the binary's "xray_instr_map" section, an array of these function entries4187// describes each instrumentation point. When XRay patches your code, the index4188// into this table will be given to your handler as a patch point identifier.4189void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out) const {4190auto Kind8 = static_cast<uint8_t>(Kind);4191Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));4192Out->emitBinaryData(4193StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1));4194Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1));4195auto Padding = (4 * Bytes) - ((2 * Bytes) + 3);4196assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size");4197Out->emitZeros(Padding);4198}41994200void AsmPrinter::emitXRayTable() {4201if (Sleds.empty())4202return;42034204auto PrevSection = OutStreamer->getCurrentSectionOnly();4205const Function &F = MF->getFunction();4206MCSection *InstMap = nullptr;4207MCSection *FnSledIndex = nullptr;4208const Triple &TT = TM.getTargetTriple();4209// Use PC-relative addresses on all targets.4210if (TT.isOSBinFormatELF()) {4211auto LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);4212auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;4213StringRef GroupName;4214if (F.hasComdat()) {4215Flags |= ELF::SHF_GROUP;4216GroupName = F.getComdat()->getName();4217}4218InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,4219Flags, 0, GroupName, F.hasComdat(),4220MCSection::NonUniqueID, LinkedToSym);42214222if (TM.Options.XRayFunctionIndex)4223FnSledIndex = OutContext.getELFSection(4224"xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, GroupName, F.hasComdat(),4225MCSection::NonUniqueID, LinkedToSym);4226} else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {4227InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map",4228MachO::S_ATTR_LIVE_SUPPORT,4229SectionKind::getReadOnlyWithRel());4230if (TM.Options.XRayFunctionIndex)4231FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx",4232MachO::S_ATTR_LIVE_SUPPORT,4233SectionKind::getReadOnly());4234} else {4235llvm_unreachable("Unsupported target");4236}42374238auto WordSizeBytes = MAI->getCodePointerSize();42394240// Now we switch to the instrumentation map section. Because this is done4241// per-function, we are able to create an index entry that will represent the4242// range of sleds associated with a function.4243auto &Ctx = OutContext;4244MCSymbol *SledsStart =4245OutContext.createLinkerPrivateSymbol("xray_sleds_start");4246OutStreamer->switchSection(InstMap);4247OutStreamer->emitLabel(SledsStart);4248for (const auto &Sled : Sleds) {4249MCSymbol *Dot = Ctx.createTempSymbol();4250OutStreamer->emitLabel(Dot);4251OutStreamer->emitValueImpl(4252MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx),4253MCSymbolRefExpr::create(Dot, Ctx), Ctx),4254WordSizeBytes);4255OutStreamer->emitValueImpl(4256MCBinaryExpr::createSub(4257MCSymbolRefExpr::create(CurrentFnBegin, Ctx),4258MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Dot, Ctx),4259MCConstantExpr::create(WordSizeBytes, Ctx),4260Ctx),4261Ctx),4262WordSizeBytes);4263Sled.emit(WordSizeBytes, OutStreamer.get());4264}4265MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_sleds_end", true);4266OutStreamer->emitLabel(SledsEnd);42674268// We then emit a single entry in the index per function. We use the symbols4269// that bound the instrumentation map as the range for a specific function.4270// Each entry here will be 2 * word size aligned, as we're writing down two4271// pointers. This should work for both 32-bit and 64-bit platforms.4272if (FnSledIndex) {4273OutStreamer->switchSection(FnSledIndex);4274OutStreamer->emitCodeAlignment(Align(2 * WordSizeBytes),4275&getSubtargetInfo());4276// For Mach-O, use an "l" symbol as the atom of this subsection. The label4277// difference uses a SUBTRACTOR external relocation which references the4278// symbol.4279MCSymbol *Dot = Ctx.createLinkerPrivateSymbol("xray_fn_idx");4280OutStreamer->emitLabel(Dot);4281OutStreamer->emitValueImpl(4282MCBinaryExpr::createSub(MCSymbolRefExpr::create(SledsStart, Ctx),4283MCSymbolRefExpr::create(Dot, Ctx), Ctx),4284WordSizeBytes);4285OutStreamer->emitValueImpl(MCConstantExpr::create(Sleds.size(), Ctx),4286WordSizeBytes);4287OutStreamer->switchSection(PrevSection);4288}4289Sleds.clear();4290}42914292void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI,4293SledKind Kind, uint8_t Version) {4294const Function &F = MI.getMF()->getFunction();4295auto Attr = F.getFnAttribute("function-instrument");4296bool LogArgs = F.hasFnAttribute("xray-log-args");4297bool AlwaysInstrument =4298Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always";4299if (Kind == SledKind::FUNCTION_ENTER && LogArgs)4300Kind = SledKind::LOG_ARGS_ENTER;4301Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind,4302AlwaysInstrument, &F, Version});4303}43044305void AsmPrinter::emitPatchableFunctionEntries() {4306const Function &F = MF->getFunction();4307unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0;4308(void)F.getFnAttribute("patchable-function-prefix")4309.getValueAsString()4310.getAsInteger(10, PatchableFunctionPrefix);4311(void)F.getFnAttribute("patchable-function-entry")4312.getValueAsString()4313.getAsInteger(10, PatchableFunctionEntry);4314if (!PatchableFunctionPrefix && !PatchableFunctionEntry)4315return;4316const unsigned PointerSize = getPointerSize();4317if (TM.getTargetTriple().isOSBinFormatELF()) {4318auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC;4319const MCSymbolELF *LinkedToSym = nullptr;4320StringRef GroupName;43214322// GNU as < 2.35 did not support section flag 'o'. GNU ld < 2.36 did not4323// support mixed SHF_LINK_ORDER and non-SHF_LINK_ORDER sections.4324if (MAI->useIntegratedAssembler() || MAI->binutilsIsAtLeast(2, 36)) {4325Flags |= ELF::SHF_LINK_ORDER;4326if (F.hasComdat()) {4327Flags |= ELF::SHF_GROUP;4328GroupName = F.getComdat()->getName();4329}4330LinkedToSym = cast<MCSymbolELF>(CurrentFnSym);4331}4332OutStreamer->switchSection(OutContext.getELFSection(4333"__patchable_function_entries", ELF::SHT_PROGBITS, Flags, 0, GroupName,4334F.hasComdat(), MCSection::NonUniqueID, LinkedToSym));4335emitAlignment(Align(PointerSize));4336OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize);4337}4338}43394340uint16_t AsmPrinter::getDwarfVersion() const {4341return OutStreamer->getContext().getDwarfVersion();4342}43434344void AsmPrinter::setDwarfVersion(uint16_t Version) {4345OutStreamer->getContext().setDwarfVersion(Version);4346}43474348bool AsmPrinter::isDwarf64() const {4349return OutStreamer->getContext().getDwarfFormat() == dwarf::DWARF64;4350}43514352unsigned int AsmPrinter::getDwarfOffsetByteSize() const {4353return dwarf::getDwarfOffsetByteSize(4354OutStreamer->getContext().getDwarfFormat());4355}43564357dwarf::FormParams AsmPrinter::getDwarfFormParams() const {4358return {getDwarfVersion(), uint8_t(MAI->getCodePointerSize()),4359OutStreamer->getContext().getDwarfFormat(),4360doesDwarfUseRelocationsAcrossSections()};4361}43624363unsigned int AsmPrinter::getUnitLengthFieldByteSize() const {4364return dwarf::getUnitLengthFieldByteSize(4365OutStreamer->getContext().getDwarfFormat());4366}43674368std::tuple<const MCSymbol *, uint64_t, const MCSymbol *,4369codeview::JumpTableEntrySize>4370AsmPrinter::getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr,4371const MCSymbol *BranchLabel) const {4372const auto TLI = MF->getSubtarget().getTargetLowering();4373const auto BaseExpr =4374TLI->getPICJumpTableRelocBaseExpr(MF, JTI, MMI->getContext());4375const auto Base = &cast<MCSymbolRefExpr>(BaseExpr)->getSymbol();43764377// By default, for the architectures that support CodeView,4378// EK_LabelDifference32 is implemented as an Int32 from the base address.4379return std::make_tuple(Base, 0, BranchLabel,4380codeview::JumpTableEntrySize::Int32);4381}438243834384