5049 lines · cpp
1//===- AsmPrinter.cpp - Common AsmPrinter code ----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the AsmPrinter class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/CodeGen/AsmPrinter.h"14#include "CodeViewDebug.h"15#include "DwarfDebug.h"16#include "DwarfException.h"17#include "PseudoProbePrinter.h"18#include "WasmException.h"19#include "WinCFGuard.h"20#include "WinException.h"21#include "llvm/ADT/APFloat.h"22#include "llvm/ADT/APInt.h"23#include "llvm/ADT/BitmaskEnum.h"24#include "llvm/ADT/DenseMap.h"25#include "llvm/ADT/STLExtras.h"26#include "llvm/ADT/SmallPtrSet.h"27#include "llvm/ADT/SmallString.h"28#include "llvm/ADT/SmallVector.h"29#include "llvm/ADT/Statistic.h"30#include "llvm/ADT/StringExtras.h"31#include "llvm/ADT/StringRef.h"32#include "llvm/ADT/TinyPtrVector.h"33#include "llvm/ADT/Twine.h"34#include "llvm/Analysis/ConstantFolding.h"35#include "llvm/Analysis/MemoryLocation.h"36#include "llvm/Analysis/OptimizationRemarkEmitter.h"37#include "llvm/BinaryFormat/COFF.h"38#include "llvm/BinaryFormat/Dwarf.h"39#include "llvm/BinaryFormat/ELF.h"40#include "llvm/CodeGen/GCMetadata.h"41#include "llvm/CodeGen/GCMetadataPrinter.h"42#include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"43#include "llvm/CodeGen/MachineBasicBlock.h"44#include "llvm/CodeGen/MachineBlockHashInfo.h"45#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"46#include "llvm/CodeGen/MachineConstantPool.h"47#include "llvm/CodeGen/MachineDominators.h"48#include "llvm/CodeGen/MachineFrameInfo.h"49#include "llvm/CodeGen/MachineFunction.h"50#include "llvm/CodeGen/MachineFunctionPass.h"51#include "llvm/CodeGen/MachineInstr.h"52#include "llvm/CodeGen/MachineInstrBundle.h"53#include "llvm/CodeGen/MachineJumpTableInfo.h"54#include "llvm/CodeGen/MachineLoopInfo.h"55#include "llvm/CodeGen/MachineModuleInfo.h"56#include "llvm/CodeGen/MachineModuleInfoImpls.h"57#include "llvm/CodeGen/MachineOperand.h"58#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"59#include "llvm/CodeGen/StackMaps.h"60#include "llvm/CodeGen/TargetFrameLowering.h"61#include "llvm/CodeGen/TargetInstrInfo.h"62#include "llvm/CodeGen/TargetLowering.h"63#include "llvm/CodeGen/TargetOpcodes.h"64#include "llvm/CodeGen/TargetRegisterInfo.h"65#include "llvm/CodeGen/TargetSubtargetInfo.h"66#include "llvm/Config/config.h"67#include "llvm/IR/BasicBlock.h"68#include "llvm/IR/Comdat.h"69#include "llvm/IR/Constant.h"70#include "llvm/IR/Constants.h"71#include "llvm/IR/DataLayout.h"72#include "llvm/IR/DebugInfoMetadata.h"73#include "llvm/IR/DerivedTypes.h"74#include "llvm/IR/EHPersonalities.h"75#include "llvm/IR/Function.h"76#include "llvm/IR/GCStrategy.h"77#include "llvm/IR/GlobalAlias.h"78#include "llvm/IR/GlobalIFunc.h"79#include "llvm/IR/GlobalObject.h"80#include "llvm/IR/GlobalValue.h"81#include "llvm/IR/GlobalVariable.h"82#include "llvm/IR/Instruction.h"83#include "llvm/IR/Instructions.h"84#include "llvm/IR/LLVMRemarkStreamer.h"85#include "llvm/IR/Mangler.h"86#include "llvm/IR/Metadata.h"87#include "llvm/IR/Module.h"88#include "llvm/IR/Operator.h"89#include "llvm/IR/PseudoProbe.h"90#include "llvm/IR/Type.h"91#include "llvm/IR/Value.h"92#include "llvm/IR/ValueHandle.h"93#include "llvm/MC/MCAsmInfo.h"94#include "llvm/MC/MCContext.h"95#include "llvm/MC/MCDirectives.h"96#include "llvm/MC/MCExpr.h"97#include "llvm/MC/MCInst.h"98#include "llvm/MC/MCSchedule.h"99#include "llvm/MC/MCSection.h"100#include "llvm/MC/MCSectionCOFF.h"101#include "llvm/MC/MCSectionELF.h"102#include "llvm/MC/MCSectionMachO.h"103#include "llvm/MC/MCSectionXCOFF.h"104#include "llvm/MC/MCStreamer.h"105#include "llvm/MC/MCSubtargetInfo.h"106#include "llvm/MC/MCSymbol.h"107#include "llvm/MC/MCSymbolELF.h"108#include "llvm/MC/MCTargetOptions.h"109#include "llvm/MC/MCValue.h"110#include "llvm/MC/SectionKind.h"111#include "llvm/Object/ELFTypes.h"112#include "llvm/Pass.h"113#include "llvm/Remarks/RemarkStreamer.h"114#include "llvm/Support/Casting.h"115#include "llvm/Support/CommandLine.h"116#include "llvm/Support/Compiler.h"117#include "llvm/Support/ErrorHandling.h"118#include "llvm/Support/FileSystem.h"119#include "llvm/Support/Format.h"120#include "llvm/Support/MathExtras.h"121#include "llvm/Support/Path.h"122#include "llvm/Support/VCSRevision.h"123#include "llvm/Support/VirtualFileSystem.h"124#include "llvm/Support/raw_ostream.h"125#include "llvm/Target/TargetLoweringObjectFile.h"126#include "llvm/Target/TargetMachine.h"127#include "llvm/Target/TargetOptions.h"128#include "llvm/TargetParser/Triple.h"129#include <algorithm>130#include <cassert>131#include <cinttypes>132#include <cstdint>133#include <iterator>134#include <memory>135#include <optional>136#include <string>137#include <utility>138#include <vector>139 140using namespace llvm;141 142#define DEBUG_TYPE "asm-printer"143 144// This is a replication of fields of object::PGOAnalysisMap::Features. It145// should match the order of the fields so that146// `object::PGOAnalysisMap::Features::decode(PgoAnalysisMapFeatures.getBits())`147// succeeds.148enum class PGOMapFeaturesEnum {149 None,150 FuncEntryCount,151 BBFreq,152 BrProb,153 All,154};155static cl::bits<PGOMapFeaturesEnum> PgoAnalysisMapFeatures(156 "pgo-analysis-map", cl::Hidden, cl::CommaSeparated,157 cl::values(158 clEnumValN(PGOMapFeaturesEnum::None, "none", "Disable all options"),159 clEnumValN(PGOMapFeaturesEnum::FuncEntryCount, "func-entry-count",160 "Function Entry Count"),161 clEnumValN(PGOMapFeaturesEnum::BBFreq, "bb-freq",162 "Basic Block Frequency"),163 clEnumValN(PGOMapFeaturesEnum::BrProb, "br-prob", "Branch Probability"),164 clEnumValN(PGOMapFeaturesEnum::All, "all", "Enable all options")),165 cl::desc(166 "Enable extended information within the SHT_LLVM_BB_ADDR_MAP that is "167 "extracted from PGO related analysis."));168 169static cl::opt<bool> BBAddrMapSkipEmitBBEntries(170 "basic-block-address-map-skip-bb-entries",171 cl::desc("Skip emitting basic block entries in the SHT_LLVM_BB_ADDR_MAP "172 "section. It's used to save binary size when BB entries are "173 "unnecessary for some PGOAnalysisMap features."),174 cl::Hidden, cl::init(false));175 176static cl::opt<bool> EmitJumpTableSizesSection(177 "emit-jump-table-sizes-section",178 cl::desc("Emit a section containing jump table addresses and sizes"),179 cl::Hidden, cl::init(false));180 181// This isn't turned on by default, since several of the scheduling models are182// not completely accurate, and we don't want to be misleading.183static cl::opt<bool> PrintLatency(184 "asm-print-latency",185 cl::desc("Print instruction latencies as verbose asm comments"), cl::Hidden,186 cl::init(false));187 188extern cl::opt<bool> EmitBBHash;189 190STATISTIC(EmittedInsts, "Number of machine instrs printed");191 192char AsmPrinter::ID = 0;193 194namespace {195class AddrLabelMapCallbackPtr final : CallbackVH {196 AddrLabelMap *Map = nullptr;197 198public:199 AddrLabelMapCallbackPtr() = default;200 AddrLabelMapCallbackPtr(Value *V) : CallbackVH(V) {}201 202 void setPtr(BasicBlock *BB) {203 ValueHandleBase::operator=(BB);204 }205 206 void setMap(AddrLabelMap *map) { Map = map; }207 208 void deleted() override;209 void allUsesReplacedWith(Value *V2) override;210};211} // namespace212 213namespace callgraph {214LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();215enum Flags : uint8_t {216 None = 0,217 IsIndirectTarget = 1u << 0,218 HasDirectCallees = 1u << 1,219 HasIndirectCallees = 1u << 2,220 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ HasIndirectCallees)221};222} // namespace callgraph223 224class llvm::AddrLabelMap {225 MCContext &Context;226 struct AddrLabelSymEntry {227 /// The symbols for the label.228 TinyPtrVector<MCSymbol *> Symbols;229 230 Function *Fn; // The containing function of the BasicBlock.231 unsigned Index; // The index in BBCallbacks for the BasicBlock.232 };233 234 DenseMap<AssertingVH<BasicBlock>, AddrLabelSymEntry> AddrLabelSymbols;235 236 /// Callbacks for the BasicBlock's that we have entries for. We use this so237 /// we get notified if a block is deleted or RAUWd.238 std::vector<AddrLabelMapCallbackPtr> BBCallbacks;239 240 /// This is a per-function list of symbols whose corresponding BasicBlock got241 /// deleted. These symbols need to be emitted at some point in the file, so242 /// AsmPrinter emits them after the function body.243 DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>244 DeletedAddrLabelsNeedingEmission;245 246public:247 AddrLabelMap(MCContext &context) : Context(context) {}248 249 ~AddrLabelMap() {250 assert(DeletedAddrLabelsNeedingEmission.empty() &&251 "Some labels for deleted blocks never got emitted");252 }253 254 ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(BasicBlock *BB);255 256 void takeDeletedSymbolsForFunction(Function *F,257 std::vector<MCSymbol *> &Result);258 259 void UpdateForDeletedBlock(BasicBlock *BB);260 void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New);261};262 263ArrayRef<MCSymbol *> AddrLabelMap::getAddrLabelSymbolToEmit(BasicBlock *BB) {264 assert(BB->hasAddressTaken() &&265 "Shouldn't get label for block without address taken");266 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];267 268 // If we already had an entry for this block, just return it.269 if (!Entry.Symbols.empty()) {270 assert(BB->getParent() == Entry.Fn && "Parent changed");271 return Entry.Symbols;272 }273 274 // Otherwise, this is a new entry, create a new symbol for it and add an275 // entry to BBCallbacks so we can be notified if the BB is deleted or RAUWd.276 BBCallbacks.emplace_back(BB);277 BBCallbacks.back().setMap(this);278 Entry.Index = BBCallbacks.size() - 1;279 Entry.Fn = BB->getParent();280 MCSymbol *Sym = BB->hasAddressTaken() ? Context.createNamedTempSymbol()281 : Context.createTempSymbol();282 Entry.Symbols.push_back(Sym);283 return Entry.Symbols;284}285 286/// If we have any deleted symbols for F, return them.287void AddrLabelMap::takeDeletedSymbolsForFunction(288 Function *F, std::vector<MCSymbol *> &Result) {289 DenseMap<AssertingVH<Function>, std::vector<MCSymbol *>>::iterator I =290 DeletedAddrLabelsNeedingEmission.find(F);291 292 // If there are no entries for the function, just return.293 if (I == DeletedAddrLabelsNeedingEmission.end())294 return;295 296 // Otherwise, take the list.297 std::swap(Result, I->second);298 DeletedAddrLabelsNeedingEmission.erase(I);299}300 301//===- Address of Block Management ----------------------------------------===//302 303ArrayRef<MCSymbol *>304AsmPrinter::getAddrLabelSymbolToEmit(const BasicBlock *BB) {305 // Lazily create AddrLabelSymbols.306 if (!AddrLabelSymbols)307 AddrLabelSymbols = std::make_unique<AddrLabelMap>(OutContext);308 return AddrLabelSymbols->getAddrLabelSymbolToEmit(309 const_cast<BasicBlock *>(BB));310}311 312void AsmPrinter::takeDeletedSymbolsForFunction(313 const Function *F, std::vector<MCSymbol *> &Result) {314 // If no blocks have had their addresses taken, we're done.315 if (!AddrLabelSymbols)316 return;317 return AddrLabelSymbols->takeDeletedSymbolsForFunction(318 const_cast<Function *>(F), Result);319}320 321void AddrLabelMap::UpdateForDeletedBlock(BasicBlock *BB) {322 // If the block got deleted, there is no need for the symbol. If the symbol323 // was already emitted, we can just forget about it, otherwise we need to324 // queue it up for later emission when the function is output.325 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);326 AddrLabelSymbols.erase(BB);327 assert(!Entry.Symbols.empty() && "Didn't have a symbol, why a callback?");328 BBCallbacks[Entry.Index] = nullptr; // Clear the callback.329 330#if !LLVM_MEMORY_SANITIZER_BUILD331 // BasicBlock is destroyed already, so this access is UB detectable by msan.332 assert((BB->getParent() == nullptr || BB->getParent() == Entry.Fn) &&333 "Block/parent mismatch");334#endif335 336 for (MCSymbol *Sym : Entry.Symbols) {337 if (Sym->isDefined())338 return;339 340 // If the block is not yet defined, we need to emit it at the end of the341 // function. Add the symbol to the DeletedAddrLabelsNeedingEmission list342 // for the containing Function. Since the block is being deleted, its343 // parent may already be removed, we have to get the function from 'Entry'.344 DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);345 }346}347 348void AddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {349 // Get the entry for the RAUW'd block and remove it from our map.350 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);351 AddrLabelSymbols.erase(Old);352 assert(!OldEntry.Symbols.empty() && "Didn't have a symbol, why a callback?");353 354 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];355 356 // If New is not address taken, just move our symbol over to it.357 if (NewEntry.Symbols.empty()) {358 BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.359 NewEntry = std::move(OldEntry); // Set New's entry.360 return;361 }362 363 BBCallbacks[OldEntry.Index] = nullptr; // Update the callback.364 365 // Otherwise, we need to add the old symbols to the new block's set.366 llvm::append_range(NewEntry.Symbols, OldEntry.Symbols);367}368 369void AddrLabelMapCallbackPtr::deleted() {370 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));371}372 373void AddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) {374 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));375}376 377/// getGVAlignment - Return the alignment to use for the specified global378/// value. This rounds up to the preferred alignment if possible and legal.379Align AsmPrinter::getGVAlignment(const GlobalObject *GV, const DataLayout &DL,380 Align InAlign) {381 Align Alignment;382 if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))383 Alignment = DL.getPreferredAlign(GVar);384 385 // If InAlign is specified, round it to it.386 if (InAlign > Alignment)387 Alignment = InAlign;388 389 // If the GV has a specified alignment, take it into account.390 MaybeAlign GVAlign;391 if (auto *GVar = dyn_cast<GlobalVariable>(GV))392 GVAlign = GVar->getAlign();393 else if (auto *F = dyn_cast<Function>(GV))394 GVAlign = F->getAlign();395 if (!GVAlign)396 return Alignment;397 398 assert(GVAlign && "GVAlign must be set");399 400 // If the GVAlign is larger than NumBits, or if we are required to obey401 // NumBits because the GV has an assigned section, obey it.402 if (*GVAlign > Alignment || GV->hasSection())403 Alignment = *GVAlign;404 return Alignment;405}406 407AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer,408 char &ID)409 : MachineFunctionPass(ID), TM(tm), MAI(tm.getMCAsmInfo()),410 OutContext(Streamer->getContext()), OutStreamer(std::move(Streamer)),411 SM(*this) {412 VerboseAsm = OutStreamer->isVerboseAsm();413 DwarfUsesRelocationsAcrossSections =414 MAI->doesDwarfUseRelocationsAcrossSections();415}416 417AsmPrinter::~AsmPrinter() {418 assert(!DD && Handlers.size() == NumUserHandlers &&419 "Debug/EH info didn't get finalized");420}421 422bool AsmPrinter::isPositionIndependent() const {423 return TM.isPositionIndependent();424}425 426/// getFunctionNumber - Return a unique ID for the current function.427unsigned AsmPrinter::getFunctionNumber() const {428 return MF->getFunctionNumber();429}430 431const TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {432 return *TM.getObjFileLowering();433}434 435const DataLayout &AsmPrinter::getDataLayout() const {436 assert(MMI && "MMI could not be nullptr!");437 return MMI->getModule()->getDataLayout();438}439 440// Do not use the cached DataLayout because some client use it without a Module441// (dsymutil, llvm-dwarfdump).442unsigned AsmPrinter::getPointerSize() const {443 return TM.getPointerSize(0); // FIXME: Default address space444}445 446const MCSubtargetInfo &AsmPrinter::getSubtargetInfo() const {447 assert(MF && "getSubtargetInfo requires a valid MachineFunction!");448 return MF->getSubtarget<MCSubtargetInfo>();449}450 451void AsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {452 S.emitInstruction(Inst, getSubtargetInfo());453}454 455void AsmPrinter::emitInitialRawDwarfLocDirective(const MachineFunction &MF) {456 if (DD) {457 assert(OutStreamer->hasRawTextSupport() &&458 "Expected assembly output mode.");459 // This is NVPTX specific and it's unclear why.460 // PR51079: If we have code without debug information we need to give up.461 DISubprogram *MFSP = MF.getFunction().getSubprogram();462 if (!MFSP)463 return;464 (void)DD->emitInitialLocDirective(MF, /*CUID=*/0);465 }466}467 468/// getCurrentSection() - Return the current section we are emitting to.469const MCSection *AsmPrinter::getCurrentSection() const {470 return OutStreamer->getCurrentSectionOnly();471}472 473void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {474 AU.setPreservesAll();475 MachineFunctionPass::getAnalysisUsage(AU);476 AU.addRequired<MachineOptimizationRemarkEmitterPass>();477 AU.addRequired<GCModuleInfo>();478 AU.addRequired<LazyMachineBlockFrequencyInfoPass>();479 AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();480 if (EmitBBHash)481 AU.addRequired<MachineBlockHashInfo>();482}483 484bool AsmPrinter::doInitialization(Module &M) {485 VFS = vfs::getRealFileSystem();486 auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();487 MMI = MMIWP ? &MMIWP->getMMI() : nullptr;488 HasSplitStack = false;489 HasNoSplitStack = false;490 DbgInfoAvailable = !M.debug_compile_units().empty();491 492 AddrLabelSymbols = nullptr;493 494 // Initialize TargetLoweringObjectFile.495 TM.getObjFileLowering()->Initialize(OutContext, TM);496 497 TM.getObjFileLowering()->getModuleMetadata(M);498 499 // On AIX, we delay emitting any section information until500 // after emitting the .file pseudo-op. This allows additional501 // information (such as the embedded command line) to be associated502 // with all sections in the object file rather than a single section.503 if (!TM.getTargetTriple().isOSBinFormatXCOFF())504 OutStreamer->initSections(false, *TM.getMCSubtargetInfo());505 506 // Emit the version-min deployment target directive if needed.507 //508 // FIXME: If we end up with a collection of these sorts of Darwin-specific509 // or ELF-specific things, it may make sense to have a platform helper class510 // that will work with the target helper class. For now keep it here, as the511 // alternative is duplicated code in each of the target asm printers that512 // use the directive, where it would need the same conditionalization513 // anyway.514 const Triple &Target = TM.getTargetTriple();515 if (Target.isOSBinFormatMachO() && Target.isOSDarwin()) {516 Triple TVT(M.getDarwinTargetVariantTriple());517 OutStreamer->emitVersionForTarget(518 Target, M.getSDKVersion(),519 M.getDarwinTargetVariantTriple().empty() ? nullptr : &TVT,520 M.getDarwinTargetVariantSDKVersion());521 }522 523 // Allow the target to emit any magic that it wants at the start of the file.524 emitStartOfAsmFile(M);525 526 // Very minimal debug info. It is ignored if we emit actual debug info. If we527 // don't, this at least helps the user find where a global came from.528 if (MAI->hasSingleParameterDotFile()) {529 // .file "foo.c"530 if (MAI->isAIX()) {531 const char VerStr[] =532#ifdef PACKAGE_VENDOR533 PACKAGE_VENDOR " "534#endif535 PACKAGE_NAME " version " PACKAGE_VERSION536#ifdef LLVM_REVISION537 " (" LLVM_REVISION ")"538#endif539 ;540 // TODO: Add timestamp and description.541 OutStreamer->emitFileDirective(M.getSourceFileName(), VerStr, "", "");542 } else {543 OutStreamer->emitFileDirective(544 llvm::sys::path::filename(M.getSourceFileName()));545 }546 }547 548 // On AIX, emit bytes for llvm.commandline metadata after .file so that the549 // C_INFO symbol is preserved if any csect is kept by the linker.550 if (TM.getTargetTriple().isOSBinFormatXCOFF()) {551 emitModuleCommandLines(M);552 // Now we can generate section information.553 OutStreamer->switchSection(554 OutContext.getObjectFileInfo()->getTextSection());555 556 // To work around an AIX assembler and/or linker bug, generate557 // a rename for the default text-section symbol name. This call has558 // no effect when generating object code directly.559 MCSection *TextSection =560 OutStreamer->getContext().getObjectFileInfo()->getTextSection();561 MCSymbolXCOFF *XSym =562 static_cast<MCSectionXCOFF *>(TextSection)->getQualNameSymbol();563 if (XSym->hasRename())564 OutStreamer->emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());565 }566 567 GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();568 assert(MI && "AsmPrinter didn't require GCModuleInfo?");569 for (const auto &I : *MI)570 if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))571 MP->beginAssembly(M, *MI, *this);572 573 // Emit module-level inline asm if it exists.574 if (!M.getModuleInlineAsm().empty()) {575 OutStreamer->AddComment("Start of file scope inline assembly");576 OutStreamer->addBlankLine();577 emitInlineAsm(578 M.getModuleInlineAsm() + "\n", *TM.getMCSubtargetInfo(),579 TM.Options.MCOptions, nullptr,580 InlineAsm::AsmDialect(TM.getMCAsmInfo()->getAssemblerDialect()));581 OutStreamer->AddComment("End of file scope inline assembly");582 OutStreamer->addBlankLine();583 }584 585 if (MAI->doesSupportDebugInformation()) {586 bool EmitCodeView = M.getCodeViewFlag();587 // On Windows targets, emit minimal CodeView compiler info even when debug588 // info is disabled.589 if ((TM.getTargetTriple().isOSWindows() &&590 M.getNamedMetadata("llvm.dbg.cu")) ||591 (TM.getTargetTriple().isUEFI() && EmitCodeView))592 Handlers.push_back(std::make_unique<CodeViewDebug>(this));593 if (!EmitCodeView || M.getDwarfVersion()) {594 if (hasDebugInfo()) {595 DD = new DwarfDebug(this);596 Handlers.push_back(std::unique_ptr<DwarfDebug>(DD));597 }598 }599 }600 601 if (M.getNamedMetadata(PseudoProbeDescMetadataName))602 PP = std::make_unique<PseudoProbeHandler>(this);603 604 switch (MAI->getExceptionHandlingType()) {605 case ExceptionHandling::None:606 // We may want to emit CFI for debug.607 [[fallthrough]];608 case ExceptionHandling::SjLj:609 case ExceptionHandling::DwarfCFI:610 case ExceptionHandling::ARM:611 for (auto &F : M.getFunctionList()) {612 if (getFunctionCFISectionType(F) != CFISection::None)613 ModuleCFISection = getFunctionCFISectionType(F);614 // If any function needsUnwindTableEntry(), it needs .eh_frame and hence615 // the module needs .eh_frame. If we have found that case, we are done.616 if (ModuleCFISection == CFISection::EH)617 break;618 }619 assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI ||620 usesCFIWithoutEH() || ModuleCFISection != CFISection::EH);621 break;622 default:623 break;624 }625 626 EHStreamer *ES = nullptr;627 switch (MAI->getExceptionHandlingType()) {628 case ExceptionHandling::None:629 if (!usesCFIWithoutEH())630 break;631 [[fallthrough]];632 case ExceptionHandling::SjLj:633 case ExceptionHandling::DwarfCFI:634 case ExceptionHandling::ZOS:635 ES = new DwarfCFIException(this);636 break;637 case ExceptionHandling::ARM:638 ES = new ARMException(this);639 break;640 case ExceptionHandling::WinEH:641 switch (MAI->getWinEHEncodingType()) {642 default: llvm_unreachable("unsupported unwinding information encoding");643 case WinEH::EncodingType::Invalid:644 break;645 case WinEH::EncodingType::X86:646 case WinEH::EncodingType::Itanium:647 ES = new WinException(this);648 break;649 }650 break;651 case ExceptionHandling::Wasm:652 ES = new WasmException(this);653 break;654 case ExceptionHandling::AIX:655 ES = new AIXException(this);656 break;657 }658 if (ES)659 Handlers.push_back(std::unique_ptr<EHStreamer>(ES));660 661 // Emit tables for any value of cfguard flag (i.e. cfguard=1 or cfguard=2).662 if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("cfguard")))663 EHHandlers.push_back(std::make_unique<WinCFGuard>(this));664 665 for (auto &Handler : Handlers)666 Handler->beginModule(&M);667 for (auto &Handler : EHHandlers)668 Handler->beginModule(&M);669 670 return false;671}672 673static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI) {674 if (!MAI.hasWeakDefCanBeHiddenDirective())675 return false;676 677 return GV->canBeOmittedFromSymbolTable();678}679 680void AsmPrinter::emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {681 GlobalValue::LinkageTypes Linkage = GV->getLinkage();682 switch (Linkage) {683 case GlobalValue::CommonLinkage:684 case GlobalValue::LinkOnceAnyLinkage:685 case GlobalValue::LinkOnceODRLinkage:686 case GlobalValue::WeakAnyLinkage:687 case GlobalValue::WeakODRLinkage:688 if (MAI->isMachO()) {689 // .globl _foo690 OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);691 692 if (!canBeHidden(GV, *MAI))693 // .weak_definition _foo694 OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefinition);695 else696 OutStreamer->emitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate);697 } else if (MAI->avoidWeakIfComdat() && GV->hasComdat()) {698 // .globl _foo699 OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);700 //NOTE: linkonce is handled by the section the symbol was assigned to.701 } else {702 // .weak _foo703 OutStreamer->emitSymbolAttribute(GVSym, MCSA_Weak);704 }705 return;706 case GlobalValue::ExternalLinkage:707 OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);708 return;709 case GlobalValue::PrivateLinkage:710 case GlobalValue::InternalLinkage:711 return;712 case GlobalValue::ExternalWeakLinkage:713 case GlobalValue::AvailableExternallyLinkage:714 case GlobalValue::AppendingLinkage:715 llvm_unreachable("Should never emit this");716 }717 llvm_unreachable("Unknown linkage type!");718}719 720void AsmPrinter::getNameWithPrefix(SmallVectorImpl<char> &Name,721 const GlobalValue *GV) const {722 TM.getNameWithPrefix(Name, GV, getObjFileLowering().getMangler());723}724 725MCSymbol *AsmPrinter::getSymbol(const GlobalValue *GV) const {726 return TM.getSymbol(GV);727}728 729MCSymbol *AsmPrinter::getSymbolPreferLocal(const GlobalValue &GV) const {730 // On ELF, use .Lfoo$local if GV is a non-interposable GlobalObject with an731 // exact definion (intersection of GlobalValue::hasExactDefinition() and732 // !isInterposable()). These linkages include: external, appending, internal,733 // private. It may be profitable to use a local alias for external. The734 // assembler would otherwise be conservative and assume a global default735 // visibility symbol can be interposable, even if the code generator already736 // assumed it.737 if (TM.getTargetTriple().isOSBinFormatELF() && GV.canBenefitFromLocalAlias()) {738 const Module &M = *GV.getParent();739 if (TM.getRelocationModel() != Reloc::Static &&740 M.getPIELevel() == PIELevel::Default && GV.isDSOLocal())741 return getSymbolWithGlobalValueBase(&GV, "$local");742 }743 return TM.getSymbol(&GV);744}745 746/// EmitGlobalVariable - Emit the specified global variable to the .s file.747void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {748 bool IsEmuTLSVar = TM.useEmulatedTLS() && GV->isThreadLocal();749 assert(!(IsEmuTLSVar && GV->hasCommonLinkage()) &&750 "No emulated TLS variables in the common section");751 752 // Never emit TLS variable xyz in emulated TLS model.753 // The initialization value is in __emutls_t.xyz instead of xyz.754 if (IsEmuTLSVar)755 return;756 757 if (GV->hasInitializer()) {758 // Check to see if this is a special global used by LLVM, if so, emit it.759 if (emitSpecialLLVMGlobal(GV))760 return;761 762 // Skip the emission of global equivalents. The symbol can be emitted later763 // on by emitGlobalGOTEquivs in case it turns out to be needed.764 if (GlobalGOTEquivs.count(getSymbol(GV)))765 return;766 767 if (isVerbose()) {768 // When printing the control variable __emutls_v.*,769 // we don't need to print the original TLS variable name.770 GV->printAsOperand(OutStreamer->getCommentOS(),771 /*PrintType=*/false, GV->getParent());772 OutStreamer->getCommentOS() << '\n';773 }774 }775 776 MCSymbol *GVSym = getSymbol(GV);777 MCSymbol *EmittedSym = GVSym;778 779 // getOrCreateEmuTLSControlSym only creates the symbol with name and default780 // attributes.781 // GV's or GVSym's attributes will be used for the EmittedSym.782 emitVisibility(EmittedSym, GV->getVisibility(), !GV->isDeclaration());783 784 if (GV->isTagged()) {785 Triple T = TM.getTargetTriple();786 787 if (T.getArch() != Triple::aarch64 || !T.isAndroid())788 OutContext.reportError(SMLoc(),789 "tagged symbols (-fsanitize=memtag-globals) are "790 "only supported on AArch64 Android");791 OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_Memtag);792 }793 794 if (!GV->hasInitializer()) // External globals require no extra code.795 return;796 797 GVSym->redefineIfPossible();798 if (GVSym->isDefined() || GVSym->isVariable())799 OutContext.reportError(SMLoc(), "symbol '" + Twine(GVSym->getName()) +800 "' is already defined");801 802 if (MAI->hasDotTypeDotSizeDirective())803 OutStreamer->emitSymbolAttribute(EmittedSym, MCSA_ELF_TypeObject);804 805 SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);806 807 const DataLayout &DL = GV->getDataLayout();808 uint64_t Size = DL.getTypeAllocSize(GV->getValueType());809 810 // If the alignment is specified, we *must* obey it. Overaligning a global811 // with a specified alignment is a prompt way to break globals emitted to812 // sections and expected to be contiguous (e.g. ObjC metadata).813 const Align Alignment = getGVAlignment(GV, DL);814 815 for (auto &Handler : Handlers)816 Handler->setSymbolSize(GVSym, Size);817 818 // Handle common symbols819 if (GVKind.isCommon()) {820 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.821 // .comm _foo, 42, 4822 OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);823 return;824 }825 826 // Determine to which section this global should be emitted.827 MCSection *TheSection = getObjFileLowering().SectionForGlobal(GV, GVKind, TM);828 829 // If we have a bss global going to a section that supports the830 // zerofill directive, do so here.831 if (GVKind.isBSS() && MAI->isMachO() && TheSection->isBssSection()) {832 if (Size == 0)833 Size = 1; // zerofill of 0 bytes is undefined.834 emitLinkage(GV, GVSym);835 // .zerofill __DATA, __bss, _foo, 400, 5836 OutStreamer->emitZerofill(TheSection, GVSym, Size, Alignment);837 return;838 }839 840 // If this is a BSS local symbol and we are emitting in the BSS841 // section use .lcomm/.comm directive.842 if (GVKind.isBSSLocal() &&843 getObjFileLowering().getBSSSection() == TheSection) {844 if (Size == 0)845 Size = 1; // .comm Foo, 0 is undefined, avoid it.846 847 // Use .lcomm only if it supports user-specified alignment.848 // Otherwise, while it would still be correct to use .lcomm in some849 // cases (e.g. when Align == 1), the external assembler might enfore850 // some -unknown- default alignment behavior, which could cause851 // spurious differences between external and integrated assembler.852 // Prefer to simply fall back to .local / .comm in this case.853 if (MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {854 // .lcomm _foo, 42855 OutStreamer->emitLocalCommonSymbol(GVSym, Size, Alignment);856 return;857 }858 859 // .local _foo860 OutStreamer->emitSymbolAttribute(GVSym, MCSA_Local);861 // .comm _foo, 42, 4862 OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);863 return;864 }865 866 // Handle thread local data for mach-o which requires us to output an867 // additional structure of data and mangle the original symbol so that we868 // can reference it later.869 //870 // TODO: This should become an "emit thread local global" method on TLOF.871 // All of this macho specific stuff should be sunk down into TLOFMachO and872 // stuff like "TLSExtraDataSection" should no longer be part of the parent873 // TLOF class. This will also make it more obvious that stuff like874 // MCStreamer::EmitTBSSSymbol is macho specific and only called from macho875 // specific code.876 if (GVKind.isThreadLocal() && MAI->isMachO()) {877 // Emit the .tbss symbol878 MCSymbol *MangSym =879 OutContext.getOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));880 881 if (GVKind.isThreadBSS()) {882 TheSection = getObjFileLowering().getTLSBSSSection();883 OutStreamer->emitTBSSSymbol(TheSection, MangSym, Size, Alignment);884 } else if (GVKind.isThreadData()) {885 OutStreamer->switchSection(TheSection);886 887 emitAlignment(Alignment, GV);888 OutStreamer->emitLabel(MangSym);889 890 emitGlobalConstant(GV->getDataLayout(),891 GV->getInitializer());892 }893 894 OutStreamer->addBlankLine();895 896 // Emit the variable struct for the runtime.897 MCSection *TLVSect = getObjFileLowering().getTLSExtraDataSection();898 899 OutStreamer->switchSection(TLVSect);900 // Emit the linkage here.901 emitLinkage(GV, GVSym);902 OutStreamer->emitLabel(GVSym);903 904 // Three pointers in size:905 // - __tlv_bootstrap - used to make sure support exists906 // - spare pointer, used when mapped by the runtime907 // - pointer to mangled symbol above with initializer908 unsigned PtrSize = DL.getPointerTypeSize(GV->getType());909 OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),910 PtrSize);911 OutStreamer->emitIntValue(0, PtrSize);912 OutStreamer->emitSymbolValue(MangSym, PtrSize);913 914 OutStreamer->addBlankLine();915 return;916 }917 918 MCSymbol *EmittedInitSym = GVSym;919 920 OutStreamer->switchSection(TheSection);921 922 emitLinkage(GV, EmittedInitSym);923 emitAlignment(Alignment, GV);924 925 OutStreamer->emitLabel(EmittedInitSym);926 MCSymbol *LocalAlias = getSymbolPreferLocal(*GV);927 if (LocalAlias != EmittedInitSym)928 OutStreamer->emitLabel(LocalAlias);929 930 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());931 932 if (MAI->hasDotTypeDotSizeDirective())933 // .size foo, 42934 OutStreamer->emitELFSize(EmittedInitSym,935 MCConstantExpr::create(Size, OutContext));936 937 OutStreamer->addBlankLine();938}939 940/// Emit the directive and value for debug thread local expression941///942/// \p Value - The value to emit.943/// \p Size - The size of the integer (in bytes) to emit.944void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {945 OutStreamer->emitValue(Value, Size);946}947 948void AsmPrinter::emitFunctionHeaderComment() {}949 950void AsmPrinter::emitFunctionPrefix(ArrayRef<const Constant *> Prefix) {951 const Function &F = MF->getFunction();952 if (!MAI->hasSubsectionsViaSymbols()) {953 for (auto &C : Prefix)954 emitGlobalConstant(F.getDataLayout(), C);955 return;956 }957 // Preserving prefix-like data on platforms which use subsections-via-symbols958 // is a bit tricky. Here we introduce a symbol for the prefix-like data959 // and use the .alt_entry attribute to mark the function's real entry point960 // as an alternative entry point to the symbol that precedes the function..961 OutStreamer->emitLabel(OutContext.createLinkerPrivateTempSymbol());962 963 for (auto &C : Prefix) {964 emitGlobalConstant(F.getDataLayout(), C);965 }966 967 // Emit an .alt_entry directive for the actual function symbol.968 OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);969}970 971/// EmitFunctionHeader - This method emits the header for the current972/// function.973void AsmPrinter::emitFunctionHeader() {974 const Function &F = MF->getFunction();975 976 if (isVerbose())977 OutStreamer->getCommentOS()978 << "-- Begin function "979 << GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';980 981 // Print out constants referenced by the function982 emitConstantPool();983 984 // Print the 'header' of function.985 // If basic block sections are desired, explicitly request a unique section986 // for this function's entry block.987 if (MF->front().isBeginSection())988 MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM));989 else990 MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM));991 OutStreamer->switchSection(MF->getSection());992 993 if (MAI->isAIX())994 emitLinkage(&F, CurrentFnDescSym);995 else996 emitVisibility(CurrentFnSym, F.getVisibility());997 998 emitLinkage(&F, CurrentFnSym);999 if (MAI->hasFunctionAlignment())1000 emitAlignment(MF->getAlignment(), &F);1001 1002 if (MAI->hasDotTypeDotSizeDirective())1003 OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);1004 1005 if (F.hasFnAttribute(Attribute::Cold))1006 OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);1007 1008 // Emit the prefix data.1009 if (F.hasPrefixData())1010 emitFunctionPrefix({F.getPrefixData()});1011 1012 // Emit KCFI type information before patchable-function-prefix nops.1013 emitKCFITypeId(*MF);1014 1015 // Emit M NOPs for -fpatchable-function-entry=N,M where M>0. We arbitrarily1016 // place prefix data before NOPs.1017 unsigned PatchableFunctionPrefix = 0;1018 unsigned PatchableFunctionEntry = 0;1019 (void)F.getFnAttribute("patchable-function-prefix")1020 .getValueAsString()1021 .getAsInteger(10, PatchableFunctionPrefix);1022 (void)F.getFnAttribute("patchable-function-entry")1023 .getValueAsString()1024 .getAsInteger(10, PatchableFunctionEntry);1025 if (PatchableFunctionPrefix) {1026 CurrentPatchableFunctionEntrySym =1027 OutContext.createLinkerPrivateTempSymbol();1028 OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym);1029 emitNops(PatchableFunctionPrefix);1030 } else if (PatchableFunctionEntry) {1031 // May be reassigned when emitting the body, to reference the label after1032 // the initial BTI (AArch64) or endbr32/endbr64 (x86).1033 CurrentPatchableFunctionEntrySym = CurrentFnBegin;1034 }1035 1036 // Emit the function prologue data for the indirect call sanitizer.1037 if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) {1038 assert(MD->getNumOperands() == 2);1039 1040 auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));1041 auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1));1042 emitFunctionPrefix({PrologueSig, TypeHash});1043 }1044 1045 if (isVerbose()) {1046 F.printAsOperand(OutStreamer->getCommentOS(),1047 /*PrintType=*/false, F.getParent());1048 emitFunctionHeaderComment();1049 OutStreamer->getCommentOS() << '\n';1050 }1051 1052 // Emit the function descriptor. This is a virtual function to allow targets1053 // to emit their specific function descriptor. Right now it is only used by1054 // the AIX target. The PowerPC 64-bit V1 ELF target also uses function1055 // descriptors and should be converted to use this hook as well.1056 if (MAI->isAIX())1057 emitFunctionDescriptor();1058 1059 // Emit the CurrentFnSym. This is a virtual function to allow targets to do1060 // their wild and crazy things as required.1061 emitFunctionEntryLabel();1062 1063 // If the function had address-taken blocks that got deleted, then we have1064 // references to the dangling symbols. Emit them at the start of the function1065 // so that we don't get references to undefined symbols.1066 std::vector<MCSymbol*> DeadBlockSyms;1067 takeDeletedSymbolsForFunction(&F, DeadBlockSyms);1068 for (MCSymbol *DeadBlockSym : DeadBlockSyms) {1069 OutStreamer->AddComment("Address taken block that was later removed");1070 OutStreamer->emitLabel(DeadBlockSym);1071 }1072 1073 if (CurrentFnBegin) {1074 if (MAI->useAssignmentForEHBegin()) {1075 MCSymbol *CurPos = OutContext.createTempSymbol();1076 OutStreamer->emitLabel(CurPos);1077 OutStreamer->emitAssignment(CurrentFnBegin,1078 MCSymbolRefExpr::create(CurPos, OutContext));1079 } else {1080 OutStreamer->emitLabel(CurrentFnBegin);1081 }1082 }1083 1084 // Emit pre-function debug and/or EH information.1085 for (auto &Handler : Handlers) {1086 Handler->beginFunction(MF);1087 Handler->beginBasicBlockSection(MF->front());1088 }1089 for (auto &Handler : EHHandlers) {1090 Handler->beginFunction(MF);1091 Handler->beginBasicBlockSection(MF->front());1092 }1093 1094 // Emit the prologue data.1095 if (F.hasPrologueData())1096 emitGlobalConstant(F.getDataLayout(), F.getPrologueData());1097}1098 1099/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the1100/// function. This can be overridden by targets as required to do custom stuff.1101void AsmPrinter::emitFunctionEntryLabel() {1102 CurrentFnSym->redefineIfPossible();1103 OutStreamer->emitLabel(CurrentFnSym);1104 1105 if (TM.getTargetTriple().isOSBinFormatELF()) {1106 MCSymbol *Sym = getSymbolPreferLocal(MF->getFunction());1107 if (Sym != CurrentFnSym) {1108 CurrentFnBeginLocal = Sym;1109 OutStreamer->emitLabel(Sym);1110 OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);1111 }1112 }1113}1114 1115/// emitComments - Pretty-print comments for instructions.1116static void emitComments(const MachineInstr &MI, const MCSubtargetInfo *STI,1117 raw_ostream &CommentOS) {1118 const MachineFunction *MF = MI.getMF();1119 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();1120 1121 // Check for spills and reloads1122 1123 // We assume a single instruction only has a spill or reload, not1124 // both.1125 std::optional<LocationSize> Size;1126 if ((Size = MI.getRestoreSize(TII))) {1127 CommentOS << Size->getValue() << "-byte Reload\n";1128 } else if ((Size = MI.getFoldedRestoreSize(TII))) {1129 if (!Size->hasValue())1130 CommentOS << "Unknown-size Folded Reload\n";1131 else if (Size->getValue())1132 CommentOS << Size->getValue() << "-byte Folded Reload\n";1133 } else if ((Size = MI.getSpillSize(TII))) {1134 CommentOS << Size->getValue() << "-byte Spill\n";1135 } else if ((Size = MI.getFoldedSpillSize(TII))) {1136 if (!Size->hasValue())1137 CommentOS << "Unknown-size Folded Spill\n";1138 else if (Size->getValue())1139 CommentOS << Size->getValue() << "-byte Folded Spill\n";1140 }1141 1142 // Check for spill-induced copies1143 if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse))1144 CommentOS << " Reload Reuse\n";1145 1146 if (PrintLatency) {1147 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();1148 const MCSchedModel &SCModel = STI->getSchedModel();1149 int Latency = SCModel.computeInstrLatency<MCSubtargetInfo, MCInstrInfo,1150 InstrItineraryData, MachineInstr>(1151 *STI, *TII, MI);1152 // Report only interesting latencies.1153 if (1 < Latency)1154 CommentOS << " Latency: " << Latency << "\n";1155 }1156}1157 1158/// emitImplicitDef - This method emits the specified machine instruction1159/// that is an implicit def.1160void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const {1161 Register RegNo = MI->getOperand(0).getReg();1162 1163 SmallString<128> Str;1164 raw_svector_ostream OS(Str);1165 OS << "implicit-def: "1166 << printReg(RegNo, MF->getSubtarget().getRegisterInfo());1167 1168 OutStreamer->AddComment(OS.str());1169 OutStreamer->addBlankLine();1170}1171 1172static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {1173 std::string Str;1174 raw_string_ostream OS(Str);1175 OS << "kill:";1176 for (const MachineOperand &Op : MI->operands()) {1177 assert(Op.isReg() && "KILL instruction must have only register operands");1178 OS << ' ' << (Op.isDef() ? "def " : "killed ")1179 << printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo());1180 }1181 AP.OutStreamer->AddComment(Str);1182 AP.OutStreamer->addBlankLine();1183}1184 1185static void emitFakeUse(const MachineInstr *MI, AsmPrinter &AP) {1186 std::string Str;1187 raw_string_ostream OS(Str);1188 OS << "fake_use:";1189 for (const MachineOperand &Op : MI->operands()) {1190 // In some circumstances we can end up with fake uses of constants; skip1191 // these.1192 if (!Op.isReg())1193 continue;1194 OS << ' ' << printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo());1195 }1196 AP.OutStreamer->AddComment(OS.str());1197 AP.OutStreamer->addBlankLine();1198}1199 1200/// emitDebugValueComment - This method handles the target-independent form1201/// of DBG_VALUE, returning true if it was able to do so. A false return1202/// means the target will need to handle MI in EmitInstruction.1203static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {1204 // This code handles only the 4-operand target-independent form.1205 if (MI->isNonListDebugValue() && MI->getNumOperands() != 4)1206 return false;1207 1208 SmallString<128> Str;1209 raw_svector_ostream OS(Str);1210 OS << "DEBUG_VALUE: ";1211 1212 const DILocalVariable *V = MI->getDebugVariable();1213 if (auto *SP = dyn_cast<DISubprogram>(V->getScope())) {1214 StringRef Name = SP->getName();1215 if (!Name.empty())1216 OS << Name << ":";1217 }1218 OS << V->getName();1219 OS << " <- ";1220 1221 const DIExpression *Expr = MI->getDebugExpression();1222 // First convert this to a non-variadic expression if possible, to simplify1223 // the output.1224 if (auto NonVariadicExpr = DIExpression::convertToNonVariadicExpression(Expr))1225 Expr = *NonVariadicExpr;1226 // Then, output the possibly-simplified expression.1227 if (Expr->getNumElements()) {1228 OS << '[';1229 ListSeparator LS;1230 for (auto &Op : Expr->expr_ops()) {1231 OS << LS << dwarf::OperationEncodingString(Op.getOp());1232 for (unsigned I = 0; I < Op.getNumArgs(); ++I)1233 OS << ' ' << Op.getArg(I);1234 }1235 OS << "] ";1236 }1237 1238 // Register or immediate value. Register 0 means undef.1239 for (const MachineOperand &Op : MI->debug_operands()) {1240 if (&Op != MI->debug_operands().begin())1241 OS << ", ";1242 switch (Op.getType()) {1243 case MachineOperand::MO_FPImmediate: {1244 APFloat APF = APFloat(Op.getFPImm()->getValueAPF());1245 Type *ImmTy = Op.getFPImm()->getType();1246 if (ImmTy->isBFloatTy() || ImmTy->isHalfTy() || ImmTy->isFloatTy() ||1247 ImmTy->isDoubleTy()) {1248 OS << APF.convertToDouble();1249 } else {1250 // There is no good way to print long double. Convert a copy to1251 // double. Ah well, it's only a comment.1252 bool ignored;1253 APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,1254 &ignored);1255 OS << "(long double) " << APF.convertToDouble();1256 }1257 break;1258 }1259 case MachineOperand::MO_Immediate: {1260 OS << Op.getImm();1261 break;1262 }1263 case MachineOperand::MO_CImmediate: {1264 Op.getCImm()->getValue().print(OS, false /*isSigned*/);1265 break;1266 }1267 case MachineOperand::MO_TargetIndex: {1268 OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";1269 break;1270 }1271 case MachineOperand::MO_Register:1272 case MachineOperand::MO_FrameIndex: {1273 Register Reg;1274 std::optional<StackOffset> Offset;1275 if (Op.isReg()) {1276 Reg = Op.getReg();1277 } else {1278 const TargetFrameLowering *TFI =1279 AP.MF->getSubtarget().getFrameLowering();1280 Offset = TFI->getFrameIndexReference(*AP.MF, Op.getIndex(), Reg);1281 }1282 if (!Reg) {1283 // Suppress offset, it is not meaningful here.1284 OS << "undef";1285 break;1286 }1287 // The second operand is only an offset if it's an immediate.1288 if (MI->isIndirectDebugValue())1289 Offset = StackOffset::getFixed(MI->getDebugOffset().getImm());1290 if (Offset)1291 OS << '[';1292 OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());1293 if (Offset)1294 OS << '+' << Offset->getFixed() << ']';1295 break;1296 }1297 default:1298 llvm_unreachable("Unknown operand type");1299 }1300 }1301 1302 // NOTE: Want this comment at start of line, don't emit with AddComment.1303 AP.OutStreamer->emitRawComment(Str);1304 return true;1305}1306 1307/// This method handles the target-independent form of DBG_LABEL, returning1308/// true if it was able to do so. A false return means the target will need1309/// to handle MI in EmitInstruction.1310static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP) {1311 if (MI->getNumOperands() != 1)1312 return false;1313 1314 SmallString<128> Str;1315 raw_svector_ostream OS(Str);1316 OS << "DEBUG_LABEL: ";1317 1318 const DILabel *V = MI->getDebugLabel();1319 if (auto *SP = dyn_cast<DISubprogram>(1320 V->getScope()->getNonLexicalBlockFileScope())) {1321 StringRef Name = SP->getName();1322 if (!Name.empty())1323 OS << Name << ":";1324 }1325 OS << V->getName();1326 1327 // NOTE: Want this comment at start of line, don't emit with AddComment.1328 AP.OutStreamer->emitRawComment(OS.str());1329 return true;1330}1331 1332AsmPrinter::CFISection1333AsmPrinter::getFunctionCFISectionType(const Function &F) const {1334 // Ignore functions that won't get emitted.1335 if (F.isDeclarationForLinker())1336 return CFISection::None;1337 1338 if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&1339 F.needsUnwindTableEntry())1340 return CFISection::EH;1341 1342 if (MAI->usesCFIWithoutEH() && F.hasUWTable())1343 return CFISection::EH;1344 1345 if (hasDebugInfo() || TM.Options.ForceDwarfFrameSection)1346 return CFISection::Debug;1347 1348 return CFISection::None;1349}1350 1351AsmPrinter::CFISection1352AsmPrinter::getFunctionCFISectionType(const MachineFunction &MF) const {1353 return getFunctionCFISectionType(MF.getFunction());1354}1355 1356bool AsmPrinter::needsSEHMoves() {1357 return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry();1358}1359 1360bool AsmPrinter::usesCFIWithoutEH() const {1361 return MAI->usesCFIWithoutEH() && ModuleCFISection != CFISection::None;1362}1363 1364void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {1365 ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();1366 if (!usesCFIWithoutEH() &&1367 ExceptionHandlingType != ExceptionHandling::DwarfCFI &&1368 ExceptionHandlingType != ExceptionHandling::ARM)1369 return;1370 1371 if (getFunctionCFISectionType(*MF) == CFISection::None)1372 return;1373 1374 // If there is no "real" instruction following this CFI instruction, skip1375 // emitting it; it would be beyond the end of the function's FDE range.1376 auto *MBB = MI.getParent();1377 auto I = std::next(MI.getIterator());1378 while (I != MBB->end() && I->isTransient())1379 ++I;1380 if (I == MBB->instr_end() &&1381 MBB->getReverseIterator() == MBB->getParent()->rbegin())1382 return;1383 1384 const std::vector<MCCFIInstruction> &Instrs = MF->getFrameInstructions();1385 unsigned CFIIndex = MI.getOperand(0).getCFIIndex();1386 const MCCFIInstruction &CFI = Instrs[CFIIndex];1387 emitCFIInstruction(CFI);1388}1389 1390void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {1391 // The operands are the MCSymbol and the frame offset of the allocation.1392 MCSymbol *FrameAllocSym = MI.getOperand(0).getMCSymbol();1393 int FrameOffset = MI.getOperand(1).getImm();1394 1395 // Emit a symbol assignment.1396 OutStreamer->emitAssignment(FrameAllocSym,1397 MCConstantExpr::create(FrameOffset, OutContext));1398}1399 1400/// Returns the BB metadata to be emitted in the SHT_LLVM_BB_ADDR_MAP section1401/// for a given basic block. This can be used to capture more precise profile1402/// information.1403static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB) {1404 const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo();1405 return object::BBAddrMap::BBEntry::Metadata{1406 MBB.isReturnBlock(), !MBB.empty() && TII->isTailCall(MBB.back()),1407 MBB.isEHPad(), const_cast<MachineBasicBlock &>(MBB).canFallThrough(),1408 !MBB.empty() && MBB.rbegin()->isIndirectBranch()}1409 .encode();1410}1411 1412static llvm::object::BBAddrMap::Features1413getBBAddrMapFeature(const MachineFunction &MF, int NumMBBSectionRanges,1414 bool HasCalls) {1415 // Ensure that the user has not passed in additional options while also1416 // specifying all or none.1417 if ((PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::None) ||1418 PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::All)) &&1419 popcount(PgoAnalysisMapFeatures.getBits()) != 1) {1420 MF.getFunction().getContext().emitError(1421 "-pgo-anaylsis-map can accept only all or none with no additional "1422 "values.");1423 }1424 1425 bool NoFeatures = PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::None);1426 bool AllFeatures = PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::All);1427 bool FuncEntryCountEnabled =1428 AllFeatures || (!NoFeatures && PgoAnalysisMapFeatures.isSet(1429 PGOMapFeaturesEnum::FuncEntryCount));1430 bool BBFreqEnabled =1431 AllFeatures ||1432 (!NoFeatures && PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BBFreq));1433 bool BrProbEnabled =1434 AllFeatures ||1435 (!NoFeatures && PgoAnalysisMapFeatures.isSet(PGOMapFeaturesEnum::BrProb));1436 1437 if ((BBFreqEnabled || BrProbEnabled) && BBAddrMapSkipEmitBBEntries) {1438 MF.getFunction().getContext().emitError(1439 "BB entries info is required for BBFreq and BrProb "1440 "features");1441 }1442 return {FuncEntryCountEnabled, BBFreqEnabled, BrProbEnabled,1443 MF.hasBBSections() && NumMBBSectionRanges > 1,1444 // Use static_cast to avoid breakage of tests on windows.1445 static_cast<bool>(BBAddrMapSkipEmitBBEntries), HasCalls,1446 static_cast<bool>(EmitBBHash), false};1447}1448 1449void AsmPrinter::emitBBAddrMapSection(const MachineFunction &MF) {1450 MCSection *BBAddrMapSection =1451 getObjFileLowering().getBBAddrMapSection(*MF.getSection());1452 assert(BBAddrMapSection && ".llvm_bb_addr_map section is not initialized.");1453 bool HasCalls = !CurrentFnCallsiteEndSymbols.empty();1454 1455 const MCSymbol *FunctionSymbol = getFunctionBegin();1456 1457 OutStreamer->pushSection();1458 OutStreamer->switchSection(BBAddrMapSection);1459 OutStreamer->AddComment("version");1460 uint8_t BBAddrMapVersion = OutStreamer->getContext().getBBAddrMapVersion();1461 OutStreamer->emitInt8(BBAddrMapVersion);1462 OutStreamer->AddComment("feature");1463 auto Features = getBBAddrMapFeature(MF, MBBSectionRanges.size(), HasCalls);1464 OutStreamer->emitInt8(Features.encode());1465 // Emit BB Information for each basic block in the function.1466 if (Features.MultiBBRange) {1467 OutStreamer->AddComment("number of basic block ranges");1468 OutStreamer->emitULEB128IntValue(MBBSectionRanges.size());1469 }1470 // Number of blocks in each MBB section.1471 MapVector<MBBSectionID, unsigned> MBBSectionNumBlocks;1472 const MCSymbol *PrevMBBEndSymbol = nullptr;1473 if (!Features.MultiBBRange) {1474 OutStreamer->AddComment("function address");1475 OutStreamer->emitSymbolValue(FunctionSymbol, getPointerSize());1476 OutStreamer->AddComment("number of basic blocks");1477 OutStreamer->emitULEB128IntValue(MF.size());1478 PrevMBBEndSymbol = FunctionSymbol;1479 } else {1480 unsigned BBCount = 0;1481 for (const MachineBasicBlock &MBB : MF) {1482 BBCount++;1483 if (MBB.isEndSection()) {1484 // Store each section's basic block count when it ends.1485 MBBSectionNumBlocks[MBB.getSectionID()] = BBCount;1486 // Reset the count for the next section.1487 BBCount = 0;1488 }1489 }1490 }1491 // Emit the BB entry for each basic block in the function.1492 for (const MachineBasicBlock &MBB : MF) {1493 const MCSymbol *MBBSymbol =1494 MBB.isEntryBlock() ? FunctionSymbol : MBB.getSymbol();1495 bool IsBeginSection =1496 Features.MultiBBRange && (MBB.isBeginSection() || MBB.isEntryBlock());1497 if (IsBeginSection) {1498 OutStreamer->AddComment("base address");1499 OutStreamer->emitSymbolValue(MBBSymbol, getPointerSize());1500 OutStreamer->AddComment("number of basic blocks");1501 OutStreamer->emitULEB128IntValue(MBBSectionNumBlocks[MBB.getSectionID()]);1502 PrevMBBEndSymbol = MBBSymbol;1503 }1504 1505 auto MBHI =1506 Features.BBHash ? &getAnalysis<MachineBlockHashInfo>() : nullptr;1507 1508 if (!Features.OmitBBEntries) {1509 OutStreamer->AddComment("BB id");1510 // Emit the BB ID for this basic block.1511 // We only emit BaseID since CloneID is unset for1512 // -basic-block-adress-map.1513 // TODO: Emit the full BBID when labels and sections can be mixed1514 // together.1515 OutStreamer->emitULEB128IntValue(MBB.getBBID()->BaseID);1516 // Emit the basic block offset relative to the end of the previous block.1517 // This is zero unless the block is padded due to alignment.1518 emitLabelDifferenceAsULEB128(MBBSymbol, PrevMBBEndSymbol);1519 const MCSymbol *CurrentLabel = MBBSymbol;1520 if (HasCalls) {1521 auto CallsiteEndSymbols = CurrentFnCallsiteEndSymbols.lookup(&MBB);1522 OutStreamer->AddComment("number of callsites");1523 OutStreamer->emitULEB128IntValue(CallsiteEndSymbols.size());1524 for (const MCSymbol *CallsiteEndSymbol : CallsiteEndSymbols) {1525 // Emit the callsite offset.1526 emitLabelDifferenceAsULEB128(CallsiteEndSymbol, CurrentLabel);1527 CurrentLabel = CallsiteEndSymbol;1528 }1529 }1530 // Emit the offset to the end of the block, which can be used to compute1531 // the total block size.1532 emitLabelDifferenceAsULEB128(MBB.getEndSymbol(), CurrentLabel);1533 // Emit the Metadata.1534 OutStreamer->emitULEB128IntValue(getBBAddrMapMetadata(MBB));1535 // Emit the Hash.1536 if (MBHI) {1537 OutStreamer->emitInt64(MBHI->getMBBHash(MBB));1538 }1539 }1540 PrevMBBEndSymbol = MBB.getEndSymbol();1541 }1542 1543 if (Features.hasPGOAnalysis()) {1544 assert(BBAddrMapVersion >= 2 &&1545 "PGOAnalysisMap only supports version 2 or later");1546 1547 if (Features.FuncEntryCount) {1548 OutStreamer->AddComment("function entry count");1549 auto MaybeEntryCount = MF.getFunction().getEntryCount();1550 OutStreamer->emitULEB128IntValue(1551 MaybeEntryCount ? MaybeEntryCount->getCount() : 0);1552 }1553 const MachineBlockFrequencyInfo *MBFI =1554 Features.BBFreq1555 ? &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI()1556 : nullptr;1557 const MachineBranchProbabilityInfo *MBPI =1558 Features.BrProb1559 ? &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI()1560 : nullptr;1561 1562 if (Features.BBFreq || Features.BrProb) {1563 for (const MachineBasicBlock &MBB : MF) {1564 if (Features.BBFreq) {1565 OutStreamer->AddComment("basic block frequency");1566 OutStreamer->emitULEB128IntValue(1567 MBFI->getBlockFreq(&MBB).getFrequency());1568 }1569 if (Features.BrProb) {1570 unsigned SuccCount = MBB.succ_size();1571 OutStreamer->AddComment("basic block successor count");1572 OutStreamer->emitULEB128IntValue(SuccCount);1573 for (const MachineBasicBlock *SuccMBB : MBB.successors()) {1574 OutStreamer->AddComment("successor BB ID");1575 OutStreamer->emitULEB128IntValue(SuccMBB->getBBID()->BaseID);1576 OutStreamer->AddComment("successor branch probability");1577 OutStreamer->emitULEB128IntValue(1578 MBPI->getEdgeProbability(&MBB, SuccMBB).getNumerator());1579 }1580 }1581 }1582 }1583 }1584 1585 OutStreamer->popSection();1586}1587 1588void AsmPrinter::emitKCFITrapEntry(const MachineFunction &MF,1589 const MCSymbol *Symbol) {1590 MCSection *Section =1591 getObjFileLowering().getKCFITrapSection(*MF.getSection());1592 if (!Section)1593 return;1594 1595 OutStreamer->pushSection();1596 OutStreamer->switchSection(Section);1597 1598 MCSymbol *Loc = OutContext.createLinkerPrivateTempSymbol();1599 OutStreamer->emitLabel(Loc);1600 OutStreamer->emitAbsoluteSymbolDiff(Symbol, Loc, 4);1601 1602 OutStreamer->popSection();1603}1604 1605void AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {1606 const Function &F = MF.getFunction();1607 if (const MDNode *MD = F.getMetadata(LLVMContext::MD_kcfi_type))1608 emitGlobalConstant(F.getDataLayout(),1609 mdconst::extract<ConstantInt>(MD->getOperand(0)));1610}1611 1612void AsmPrinter::emitPseudoProbe(const MachineInstr &MI) {1613 if (PP) {1614 auto GUID = MI.getOperand(0).getImm();1615 auto Index = MI.getOperand(1).getImm();1616 auto Type = MI.getOperand(2).getImm();1617 auto Attr = MI.getOperand(3).getImm();1618 DILocation *DebugLoc = MI.getDebugLoc();1619 PP->emitPseudoProbe(GUID, Index, Type, Attr, DebugLoc);1620 }1621}1622 1623void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {1624 if (!MF.getTarget().Options.EmitStackSizeSection)1625 return;1626 1627 MCSection *StackSizeSection =1628 getObjFileLowering().getStackSizesSection(*MF.getSection());1629 if (!StackSizeSection)1630 return;1631 1632 const MachineFrameInfo &FrameInfo = MF.getFrameInfo();1633 // Don't emit functions with dynamic stack allocations.1634 if (FrameInfo.hasVarSizedObjects())1635 return;1636 1637 OutStreamer->pushSection();1638 OutStreamer->switchSection(StackSizeSection);1639 1640 const MCSymbol *FunctionSymbol = getFunctionBegin();1641 uint64_t StackSize =1642 FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize();1643 OutStreamer->emitSymbolValue(FunctionSymbol, TM.getProgramPointerSize());1644 OutStreamer->emitULEB128IntValue(StackSize);1645 1646 OutStreamer->popSection();1647}1648 1649void AsmPrinter::emitStackUsage(const MachineFunction &MF) {1650 const std::string &OutputFilename = MF.getTarget().Options.StackUsageOutput;1651 1652 // OutputFilename empty implies -fstack-usage is not passed.1653 if (OutputFilename.empty())1654 return;1655 1656 const MachineFrameInfo &FrameInfo = MF.getFrameInfo();1657 uint64_t StackSize =1658 FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize();1659 1660 if (StackUsageStream == nullptr) {1661 std::error_code EC;1662 StackUsageStream =1663 std::make_unique<raw_fd_ostream>(OutputFilename, EC, sys::fs::OF_Text);1664 if (EC) {1665 errs() << "Could not open file: " << EC.message();1666 return;1667 }1668 }1669 1670 if (const DISubprogram *DSP = MF.getFunction().getSubprogram())1671 *StackUsageStream << DSP->getFilename() << ':' << DSP->getLine();1672 else1673 *StackUsageStream << MF.getFunction().getParent()->getName();1674 1675 *StackUsageStream << ':' << MF.getName() << '\t' << StackSize << '\t';1676 if (FrameInfo.hasVarSizedObjects())1677 *StackUsageStream << "dynamic\n";1678 else1679 *StackUsageStream << "static\n";1680}1681 1682/// Extracts a generalized numeric type identifier of a Function's type from1683/// type metadata. Returns null if metadata cannot be found.1684static ConstantInt *extractNumericCGTypeId(const Function &F) {1685 SmallVector<MDNode *, 2> Types;1686 F.getMetadata(LLVMContext::MD_type, Types);1687 for (const auto &Type : Types) {1688 if (Type->hasGeneralizedMDString()) {1689 MDString *MDGeneralizedTypeId = cast<MDString>(Type->getOperand(1));1690 uint64_t TypeIdVal = llvm::MD5Hash(MDGeneralizedTypeId->getString());1691 IntegerType *Int64Ty = Type::getInt64Ty(F.getContext());1692 return ConstantInt::get(Int64Ty, TypeIdVal);1693 }1694 }1695 return nullptr;1696}1697 1698/// Emits .llvm.callgraph section.1699void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,1700 FunctionCallGraphInfo &FuncCGInfo) {1701 if (!MF.getTarget().Options.EmitCallGraphSection)1702 return;1703 1704 // Switch to the call graph section for the function1705 MCSection *FuncCGSection =1706 getObjFileLowering().getCallGraphSection(*getCurrentSection());1707 assert(FuncCGSection && "null callgraph section");1708 OutStreamer->pushSection();1709 OutStreamer->switchSection(FuncCGSection);1710 1711 const Function &F = MF.getFunction();1712 // If this function has external linkage or has its address taken and1713 // it is not a callback, then anything could call it.1714 bool IsIndirectTarget =1715 !F.hasLocalLinkage() || F.hasAddressTaken(nullptr,1716 /*IgnoreCallbackUses=*/true,1717 /*IgnoreAssumeLikeCalls=*/true,1718 /*IgnoreLLVMUsed=*/false);1719 1720 const auto &DirectCallees = FuncCGInfo.DirectCallees;1721 const auto &IndirectCalleeTypeIDs = FuncCGInfo.IndirectCalleeTypeIDs;1722 1723 using namespace callgraph;1724 Flags CGFlags = Flags::None;1725 if (IsIndirectTarget)1726 CGFlags |= Flags::IsIndirectTarget;1727 if (DirectCallees.size() > 0)1728 CGFlags |= Flags::HasDirectCallees;1729 if (IndirectCalleeTypeIDs.size() > 0)1730 CGFlags |= Flags::HasIndirectCallees;1731 1732 // Emit function's call graph information.1733 // 1) CallGraphSectionFormatVersion1734 // 2) Flags1735 // a. LSB bit 0 is set to 1 if the function is a potential indirect1736 // target.1737 // b. LSB bit 1 is set to 1 if there are direct callees.1738 // c. LSB bit 2 is set to 1 if there are indirect callees.1739 // d. Rest of the 5 bits in Flags are reserved for any future use.1740 // 3) Function entry PC.1741 // 4) FunctionTypeID if the function is indirect target and its type id1742 // is known, otherwise it is set to 0.1743 // 5) Number of unique direct callees, if at least one exists.1744 // 6) For each unique direct callee, the callee's PC.1745 // 7) Number of unique indirect target type IDs, if at least one exists.1746 // 8) Each unique indirect target type id.1747 OutStreamer->emitInt8(CallGraphSectionFormatVersion::V_0);1748 OutStreamer->emitInt8(static_cast<uint8_t>(CGFlags));1749 OutStreamer->emitSymbolValue(getSymbol(&F), TM.getProgramPointerSize());1750 const auto *TypeId = extractNumericCGTypeId(F);1751 if (IsIndirectTarget && TypeId)1752 OutStreamer->emitInt64(TypeId->getZExtValue());1753 else1754 OutStreamer->emitInt64(0);1755 1756 if (DirectCallees.size() > 0) {1757 OutStreamer->emitULEB128IntValue(DirectCallees.size());1758 for (const auto &CalleeSymbol : DirectCallees)1759 OutStreamer->emitSymbolValue(CalleeSymbol, TM.getProgramPointerSize());1760 FuncCGInfo.DirectCallees.clear();1761 }1762 if (IndirectCalleeTypeIDs.size() > 0) {1763 OutStreamer->emitULEB128IntValue(IndirectCalleeTypeIDs.size());1764 for (const auto &CalleeTypeId : IndirectCalleeTypeIDs)1765 OutStreamer->emitInt64(CalleeTypeId);1766 FuncCGInfo.IndirectCalleeTypeIDs.clear();1767 }1768 // End of emitting call graph section contents.1769 OutStreamer->popSection();1770}1771 1772void AsmPrinter::emitPCSectionsLabel(const MachineFunction &MF,1773 const MDNode &MD) {1774 MCSymbol *S = MF.getContext().createTempSymbol("pcsection");1775 OutStreamer->emitLabel(S);1776 PCSectionsSymbols[&MD].emplace_back(S);1777}1778 1779void AsmPrinter::emitPCSections(const MachineFunction &MF) {1780 const Function &F = MF.getFunction();1781 if (PCSectionsSymbols.empty() && !F.hasMetadata(LLVMContext::MD_pcsections))1782 return;1783 1784 const CodeModel::Model CM = MF.getTarget().getCodeModel();1785 const unsigned RelativeRelocSize =1786 (CM == CodeModel::Medium || CM == CodeModel::Large) ? getPointerSize()1787 : 4;1788 1789 // Switch to PCSection, short-circuiting the common case where the current1790 // section is still valid (assume most MD_pcsections contain just 1 section).1791 auto SwitchSection = [&, Prev = StringRef()](const StringRef &Sec) mutable {1792 if (Sec == Prev)1793 return;1794 MCSection *S = getObjFileLowering().getPCSection(Sec, MF.getSection());1795 assert(S && "PC section is not initialized");1796 OutStreamer->switchSection(S);1797 Prev = Sec;1798 };1799 // Emit symbols into sections and data as specified in the pcsections MDNode.1800 auto EmitForMD = [&](const MDNode &MD, ArrayRef<const MCSymbol *> Syms,1801 bool Deltas) {1802 // Expect the first operand to be a section name. After that, a tuple of1803 // constants may appear, which will simply be emitted into the current1804 // section (the user of MD_pcsections decides the format of encoded data).1805 assert(isa<MDString>(MD.getOperand(0)) && "first operand not a string");1806 bool ConstULEB128 = false;1807 for (const MDOperand &MDO : MD.operands()) {1808 if (auto *S = dyn_cast<MDString>(MDO)) {1809 // Found string, start of new section!1810 // Find options for this section "<section>!<opts>" - supported options:1811 // C = Compress constant integers of size 2-8 bytes as ULEB128.1812 const StringRef SecWithOpt = S->getString();1813 const size_t OptStart = SecWithOpt.find('!'); // likely npos1814 const StringRef Sec = SecWithOpt.substr(0, OptStart);1815 const StringRef Opts = SecWithOpt.substr(OptStart); // likely empty1816 ConstULEB128 = Opts.contains('C');1817#ifndef NDEBUG1818 for (char O : Opts)1819 assert((O == '!' || O == 'C') && "Invalid !pcsections options");1820#endif1821 SwitchSection(Sec);1822 const MCSymbol *Prev = Syms.front();1823 for (const MCSymbol *Sym : Syms) {1824 if (Sym == Prev || !Deltas) {1825 // Use the entry itself as the base of the relative offset.1826 MCSymbol *Base = MF.getContext().createTempSymbol("pcsection_base");1827 OutStreamer->emitLabel(Base);1828 // Emit relative relocation `addr - base`, which avoids a dynamic1829 // relocation in the final binary. User will get the address with1830 // `base + addr`.1831 emitLabelDifference(Sym, Base, RelativeRelocSize);1832 } else {1833 // Emit delta between symbol and previous symbol.1834 if (ConstULEB128)1835 emitLabelDifferenceAsULEB128(Sym, Prev);1836 else1837 emitLabelDifference(Sym, Prev, 4);1838 }1839 Prev = Sym;1840 }1841 } else {1842 // Emit auxiliary data after PC.1843 assert(isa<MDNode>(MDO) && "expecting either string or tuple");1844 const auto *AuxMDs = cast<MDNode>(MDO);1845 for (const MDOperand &AuxMDO : AuxMDs->operands()) {1846 assert(isa<ConstantAsMetadata>(AuxMDO) && "expecting a constant");1847 const Constant *C = cast<ConstantAsMetadata>(AuxMDO)->getValue();1848 const DataLayout &DL = F.getDataLayout();1849 const uint64_t Size = DL.getTypeStoreSize(C->getType());1850 1851 if (auto *CI = dyn_cast<ConstantInt>(C);1852 CI && ConstULEB128 && Size > 1 && Size <= 8) {1853 emitULEB128(CI->getZExtValue());1854 } else {1855 emitGlobalConstant(DL, C);1856 }1857 }1858 }1859 }1860 };1861 1862 OutStreamer->pushSection();1863 // Emit PCs for function start and function size.1864 if (const MDNode *MD = F.getMetadata(LLVMContext::MD_pcsections))1865 EmitForMD(*MD, {getFunctionBegin(), getFunctionEnd()}, true);1866 // Emit PCs for instructions collected.1867 for (const auto &MS : PCSectionsSymbols)1868 EmitForMD(*MS.first, MS.second, false);1869 OutStreamer->popSection();1870 PCSectionsSymbols.clear();1871}1872 1873/// Returns true if function begin and end labels should be emitted.1874static bool needFuncLabels(const MachineFunction &MF, const AsmPrinter &Asm) {1875 if (Asm.hasDebugInfo() || !MF.getLandingPads().empty() ||1876 MF.hasEHFunclets() ||1877 MF.getFunction().hasMetadata(LLVMContext::MD_pcsections))1878 return true;1879 1880 // We might emit an EH table that uses function begin and end labels even if1881 // we don't have any landingpads.1882 if (!MF.getFunction().hasPersonalityFn())1883 return false;1884 return !isNoOpWithoutInvoke(1885 classifyEHPersonality(MF.getFunction().getPersonalityFn()));1886}1887 1888// Return the mnemonic of a MachineInstr if available, or the MachineInstr1889// opcode name otherwise.1890static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {1891 const TargetInstrInfo *TII =1892 MI.getParent()->getParent()->getSubtarget().getInstrInfo();1893 MCInst MCI;1894 MCI.setOpcode(MI.getOpcode());1895 if (StringRef Name = Streamer.getMnemonic(MCI); !Name.empty())1896 return Name;1897 StringRef Name = TII->getName(MI.getOpcode());1898 assert(!Name.empty() && "Missing mnemonic and name for opcode");1899 return Name;1900}1901 1902void AsmPrinter::handleCallsiteForCallgraph(1903 FunctionCallGraphInfo &FuncCGInfo,1904 const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,1905 const MachineInstr &MI) {1906 assert(MI.isCall() && "This method is meant for call instructions only.");1907 const MachineOperand &CalleeOperand = MI.getOperand(0);1908 if (CalleeOperand.isGlobal() || CalleeOperand.isSymbol()) {1909 // Handle direct calls.1910 MCSymbol *CalleeSymbol = nullptr;1911 switch (CalleeOperand.getType()) {1912 case llvm::MachineOperand::MO_GlobalAddress:1913 CalleeSymbol = getSymbol(CalleeOperand.getGlobal());1914 break;1915 case llvm::MachineOperand::MO_ExternalSymbol:1916 CalleeSymbol = GetExternalSymbolSymbol(CalleeOperand.getSymbolName());1917 break;1918 default:1919 llvm_unreachable(1920 "Expected to only handle direct call instructions here.");1921 }1922 FuncCGInfo.DirectCallees.insert(CalleeSymbol);1923 return; // Early exit after handling the direct call instruction.1924 }1925 const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);1926 if (CallSiteInfo == CallSitesInfoMap.end())1927 return;1928 // Handle indirect callsite info.1929 // Only indirect calls have type identifiers set.1930 for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {1931 uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();1932 FuncCGInfo.IndirectCalleeTypeIDs.insert(CalleeTypeIdVal);1933 }1934}1935 1936/// EmitFunctionBody - This method emits the body and trailer for a1937/// function.1938void AsmPrinter::emitFunctionBody() {1939 emitFunctionHeader();1940 1941 // Emit target-specific gunk before the function body.1942 emitFunctionBodyStart();1943 1944 if (isVerbose()) {1945 // Get MachineDominatorTree or compute it on the fly if it's unavailable1946 auto MDTWrapper = getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();1947 MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;1948 if (!MDT) {1949 OwnedMDT = std::make_unique<MachineDominatorTree>();1950 OwnedMDT->recalculate(*MF);1951 MDT = OwnedMDT.get();1952 }1953 1954 // Get MachineLoopInfo or compute it on the fly if it's unavailable1955 auto *MLIWrapper = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();1956 MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;1957 if (!MLI) {1958 OwnedMLI = std::make_unique<MachineLoopInfo>();1959 OwnedMLI->analyze(*MDT);1960 MLI = OwnedMLI.get();1961 }1962 }1963 1964 // Print out code for the function.1965 bool HasAnyRealCode = false;1966 int NumInstsInFunction = 0;1967 bool IsEHa = MMI->getModule()->getModuleFlag("eh-asynch");1968 1969 const MCSubtargetInfo *STI = nullptr;1970 if (this->MF)1971 STI = &getSubtargetInfo();1972 else1973 STI = TM.getMCSubtargetInfo();1974 1975 bool CanDoExtraAnalysis = ORE->allowExtraAnalysis(DEBUG_TYPE);1976 // Create a slot for the entry basic block section so that the section1977 // order is preserved when iterating over MBBSectionRanges.1978 if (!MF->empty())1979 MBBSectionRanges[MF->front().getSectionID()] =1980 MBBSectionRange{CurrentFnBegin, nullptr};1981 1982 FunctionCallGraphInfo FuncCGInfo;1983 const auto &CallSitesInfoMap = MF->getCallSitesInfo();1984 for (auto &MBB : *MF) {1985 // Print a label for the basic block.1986 emitBasicBlockStart(MBB);1987 DenseMap<StringRef, unsigned> MnemonicCounts;1988 for (auto &MI : MBB) {1989 // Print the assembly for the instruction.1990 if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&1991 !MI.isDebugInstr()) {1992 HasAnyRealCode = true;1993 }1994 1995 // If there is a pre-instruction symbol, emit a label for it here.1996 if (MCSymbol *S = MI.getPreInstrSymbol())1997 OutStreamer->emitLabel(S);1998 1999 if (MDNode *MD = MI.getPCSections())2000 emitPCSectionsLabel(*MF, *MD);2001 2002 for (auto &Handler : Handlers)2003 Handler->beginInstruction(&MI);2004 2005 if (isVerbose())2006 emitComments(MI, STI, OutStreamer->getCommentOS());2007 2008 switch (MI.getOpcode()) {2009 case TargetOpcode::CFI_INSTRUCTION:2010 emitCFIInstruction(MI);2011 break;2012 case TargetOpcode::LOCAL_ESCAPE:2013 emitFrameAlloc(MI);2014 break;2015 case TargetOpcode::ANNOTATION_LABEL:2016 case TargetOpcode::GC_LABEL:2017 OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());2018 break;2019 case TargetOpcode::EH_LABEL:2020 OutStreamer->AddComment("EH_LABEL");2021 OutStreamer->emitLabel(MI.getOperand(0).getMCSymbol());2022 // For AsynchEH, insert a Nop if followed by a trap inst2023 // Or the exception won't be caught.2024 // (see MCConstantExpr::create(1,..) in WinException.cpp)2025 // Ignore SDiv/UDiv because a DIV with Const-0 divisor2026 // must have being turned into an UndefValue.2027 // Div with variable opnds won't be the first instruction in2028 // an EH region as it must be led by at least a Load2029 {2030 auto MI2 = std::next(MI.getIterator());2031 if (IsEHa && MI2 != MBB.end() &&2032 (MI2->mayLoadOrStore() || MI2->mayRaiseFPException()))2033 emitNops(1);2034 }2035 break;2036 case TargetOpcode::INLINEASM:2037 case TargetOpcode::INLINEASM_BR:2038 emitInlineAsm(&MI);2039 break;2040 case TargetOpcode::DBG_VALUE:2041 case TargetOpcode::DBG_VALUE_LIST:2042 if (isVerbose()) {2043 if (!emitDebugValueComment(&MI, *this))2044 emitInstruction(&MI);2045 }2046 break;2047 case TargetOpcode::DBG_INSTR_REF:2048 // This instruction reference will have been resolved to a machine2049 // location, and a nearby DBG_VALUE created. We can safely ignore2050 // the instruction reference.2051 break;2052 case TargetOpcode::DBG_PHI:2053 // This instruction is only used to label a program point, it's purely2054 // meta information.2055 break;2056 case TargetOpcode::DBG_LABEL:2057 if (isVerbose()) {2058 if (!emitDebugLabelComment(&MI, *this))2059 emitInstruction(&MI);2060 }2061 break;2062 case TargetOpcode::IMPLICIT_DEF:2063 if (isVerbose()) emitImplicitDef(&MI);2064 break;2065 case TargetOpcode::KILL:2066 if (isVerbose()) emitKill(&MI, *this);2067 break;2068 case TargetOpcode::FAKE_USE:2069 if (isVerbose())2070 emitFakeUse(&MI, *this);2071 break;2072 case TargetOpcode::PSEUDO_PROBE:2073 emitPseudoProbe(MI);2074 break;2075 case TargetOpcode::ARITH_FENCE:2076 if (isVerbose())2077 OutStreamer->emitRawComment("ARITH_FENCE");2078 break;2079 case TargetOpcode::MEMBARRIER:2080 OutStreamer->emitRawComment("MEMBARRIER");2081 break;2082 case TargetOpcode::JUMP_TABLE_DEBUG_INFO:2083 // This instruction is only used to note jump table debug info, it's2084 // purely meta information.2085 break;2086 case TargetOpcode::INIT_UNDEF:2087 // This is only used to influence register allocation behavior, no2088 // actual initialization is needed.2089 break;2090 case TargetOpcode::RELOC_NONE: {2091 // Generate a temporary label for the current PC.2092 MCSymbol *Sym = OutContext.createTempSymbol("reloc_none");2093 OutStreamer->emitLabel(Sym);2094 const MCExpr *Dot = MCSymbolRefExpr::create(Sym, OutContext);2095 const MCExpr *Value = MCSymbolRefExpr::create(2096 OutContext.getOrCreateSymbol(MI.getOperand(0).getSymbolName()),2097 OutContext);2098 OutStreamer->emitRelocDirective(*Dot, "BFD_RELOC_NONE", Value, SMLoc());2099 break;2100 }2101 default:2102 emitInstruction(&MI);2103 2104 auto CountInstruction = [&](const MachineInstr &MI) {2105 // Skip Meta instructions inside bundles.2106 if (MI.isMetaInstruction())2107 return;2108 ++NumInstsInFunction;2109 if (CanDoExtraAnalysis) {2110 StringRef Name = getMIMnemonic(MI, *OutStreamer);2111 ++MnemonicCounts[Name];2112 }2113 };2114 if (!MI.isBundle()) {2115 CountInstruction(MI);2116 break;2117 }2118 // Separately count all the instructions in a bundle.2119 for (auto It = std::next(MI.getIterator());2120 It != MBB.end() && It->isInsideBundle(); ++It) {2121 CountInstruction(*It);2122 }2123 break;2124 }2125 2126 if (MI.isCall() && MF->getTarget().Options.BBAddrMap)2127 OutStreamer->emitLabel(createCallsiteEndSymbol(MBB));2128 2129 if (TM.Options.EmitCallGraphSection && MI.isCall())2130 handleCallsiteForCallgraph(FuncCGInfo, CallSitesInfoMap, MI);2131 2132 // If there is a post-instruction symbol, emit a label for it here.2133 if (MCSymbol *S = MI.getPostInstrSymbol())2134 OutStreamer->emitLabel(S);2135 2136 for (auto &Handler : Handlers)2137 Handler->endInstruction();2138 }2139 2140 // We must emit temporary symbol for the end of this basic block, if either2141 // we have BBLabels enabled or if this basic blocks marks the end of a2142 // section.2143 if (MF->getTarget().Options.BBAddrMap ||2144 (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection()))2145 OutStreamer->emitLabel(MBB.getEndSymbol());2146 2147 if (MBB.isEndSection()) {2148 // The size directive for the section containing the entry block is2149 // handled separately by the function section.2150 if (!MBB.sameSection(&MF->front())) {2151 if (MAI->hasDotTypeDotSizeDirective()) {2152 // Emit the size directive for the basic block section.2153 const MCExpr *SizeExp = MCBinaryExpr::createSub(2154 MCSymbolRefExpr::create(MBB.getEndSymbol(), OutContext),2155 MCSymbolRefExpr::create(CurrentSectionBeginSym, OutContext),2156 OutContext);2157 OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);2158 }2159 assert(!MBBSectionRanges.contains(MBB.getSectionID()) &&2160 "Overwrite section range");2161 MBBSectionRanges[MBB.getSectionID()] =2162 MBBSectionRange{CurrentSectionBeginSym, MBB.getEndSymbol()};2163 }2164 }2165 emitBasicBlockEnd(MBB);2166 2167 if (CanDoExtraAnalysis) {2168 // Skip empty blocks.2169 if (MBB.empty())2170 continue;2171 2172 MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionMix",2173 MBB.begin()->getDebugLoc(), &MBB);2174 2175 // Generate instruction mix remark. First, sort counts in descending order2176 // by count and name.2177 SmallVector<std::pair<StringRef, unsigned>, 128> MnemonicVec;2178 for (auto &KV : MnemonicCounts)2179 MnemonicVec.emplace_back(KV.first, KV.second);2180 2181 sort(MnemonicVec, [](const std::pair<StringRef, unsigned> &A,2182 const std::pair<StringRef, unsigned> &B) {2183 if (A.second > B.second)2184 return true;2185 if (A.second == B.second)2186 return StringRef(A.first) < StringRef(B.first);2187 return false;2188 });2189 R << "BasicBlock: " << ore::NV("BasicBlock", MBB.getName()) << "\n";2190 for (auto &KV : MnemonicVec) {2191 auto Name = (Twine("INST_") + getToken(KV.first.trim()).first).str();2192 R << KV.first << ": " << ore::NV(Name, KV.second) << "\n";2193 }2194 ORE->emit(R);2195 }2196 }2197 2198 EmittedInsts += NumInstsInFunction;2199 MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount",2200 MF->getFunction().getSubprogram(),2201 &MF->front());2202 R << ore::NV("NumInstructions", NumInstsInFunction)2203 << " instructions in function";2204 ORE->emit(R);2205 2206 // If the function is empty and the object file uses .subsections_via_symbols,2207 // then we need to emit *something* to the function body to prevent the2208 // labels from collapsing together. Just emit a noop.2209 // Similarly, don't emit empty functions on Windows either. It can lead to2210 // duplicate entries (two functions with the same RVA) in the Guard CF Table2211 // after linking, causing the kernel not to load the binary:2212 // https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html2213 // FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer.2214 const Triple &TT = TM.getTargetTriple();2215 if (!HasAnyRealCode && (MAI->hasSubsectionsViaSymbols() ||2216 (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {2217 MCInst Noop = MF->getSubtarget().getInstrInfo()->getNop();2218 2219 // Targets can opt-out of emitting the noop here by leaving the opcode2220 // unspecified.2221 if (Noop.getOpcode()) {2222 OutStreamer->AddComment("avoids zero-length function");2223 emitNops(1);2224 }2225 }2226 2227 // Switch to the original section in case basic block sections was used.2228 OutStreamer->switchSection(MF->getSection());2229 2230 const Function &F = MF->getFunction();2231 for (const auto &BB : F) {2232 if (!BB.hasAddressTaken())2233 continue;2234 MCSymbol *Sym = GetBlockAddressSymbol(&BB);2235 if (Sym->isDefined())2236 continue;2237 OutStreamer->AddComment("Address of block that was removed by CodeGen");2238 OutStreamer->emitLabel(Sym);2239 }2240 2241 // Emit target-specific gunk after the function body.2242 emitFunctionBodyEnd();2243 2244 // Even though wasm supports .type and .size in general, function symbols2245 // are automatically sized.2246 bool EmitFunctionSize = MAI->hasDotTypeDotSizeDirective() && !TT.isWasm();2247 2248 // SPIR-V supports label instructions only inside a block, not after the2249 // function body.2250 if (TT.getObjectFormat() != Triple::SPIRV &&2251 (EmitFunctionSize || needFuncLabels(*MF, *this))) {2252 // Create a symbol for the end of function.2253 CurrentFnEnd = createTempSymbol("func_end");2254 OutStreamer->emitLabel(CurrentFnEnd);2255 }2256 2257 // If the target wants a .size directive for the size of the function, emit2258 // it.2259 if (EmitFunctionSize) {2260 // We can get the size as difference between the function label and the2261 // temp label.2262 const MCExpr *SizeExp = MCBinaryExpr::createSub(2263 MCSymbolRefExpr::create(CurrentFnEnd, OutContext),2264 MCSymbolRefExpr::create(CurrentFnSymForSize, OutContext), OutContext);2265 OutStreamer->emitELFSize(CurrentFnSym, SizeExp);2266 if (CurrentFnBeginLocal)2267 OutStreamer->emitELFSize(CurrentFnBeginLocal, SizeExp);2268 }2269 2270 // Call endBasicBlockSection on the last block now, if it wasn't already2271 // called.2272 if (!MF->back().isEndSection()) {2273 for (auto &Handler : Handlers)2274 Handler->endBasicBlockSection(MF->back());2275 for (auto &Handler : EHHandlers)2276 Handler->endBasicBlockSection(MF->back());2277 }2278 for (auto &Handler : Handlers)2279 Handler->markFunctionEnd();2280 for (auto &Handler : EHHandlers)2281 Handler->markFunctionEnd();2282 // Update the end label of the entry block's section.2283 MBBSectionRanges[MF->front().getSectionID()].EndLabel = CurrentFnEnd;2284 2285 // Print out jump tables referenced by the function.2286 emitJumpTableInfo();2287 2288 // Emit post-function debug and/or EH information.2289 for (auto &Handler : Handlers)2290 Handler->endFunction(MF);2291 for (auto &Handler : EHHandlers)2292 Handler->endFunction(MF);2293 2294 // Emit section containing BB address offsets and their metadata, when2295 // BB labels are requested for this function. Skip empty functions.2296 if (HasAnyRealCode) {2297 if (MF->getTarget().Options.BBAddrMap)2298 emitBBAddrMapSection(*MF);2299 else if (PgoAnalysisMapFeatures.getBits() != 0)2300 MF->getContext().reportWarning(2301 SMLoc(), "pgo-analysis-map is enabled for function " + MF->getName() +2302 " but it does not have labels");2303 }2304 2305 // Emit sections containing instruction and function PCs.2306 emitPCSections(*MF);2307 2308 // Emit section containing stack size metadata.2309 emitStackSizeSection(*MF);2310 2311 // Emit section containing call graph metadata.2312 emitCallGraphSection(*MF, FuncCGInfo);2313 2314 // Emit .su file containing function stack size information.2315 emitStackUsage(*MF);2316 2317 emitPatchableFunctionEntries();2318 2319 if (isVerbose())2320 OutStreamer->getCommentOS() << "-- End function\n";2321 2322 OutStreamer->addBlankLine();2323}2324 2325/// Compute the number of Global Variables that uses a Constant.2326static unsigned getNumGlobalVariableUses(const Constant *C,2327 bool &HasNonGlobalUsers) {2328 if (!C) {2329 HasNonGlobalUsers = true;2330 return 0;2331 }2332 2333 if (isa<GlobalVariable>(C))2334 return 1;2335 2336 unsigned NumUses = 0;2337 for (const auto *CU : C->users())2338 NumUses +=2339 getNumGlobalVariableUses(dyn_cast<Constant>(CU), HasNonGlobalUsers);2340 2341 return NumUses;2342}2343 2344/// Only consider global GOT equivalents if at least one user is a2345/// cstexpr inside an initializer of another global variables. Also, don't2346/// handle cstexpr inside instructions. During global variable emission,2347/// candidates are skipped and are emitted later in case at least one cstexpr2348/// isn't replaced by a PC relative GOT entry access.2349static bool isGOTEquivalentCandidate(const GlobalVariable *GV,2350 unsigned &NumGOTEquivUsers,2351 bool &HasNonGlobalUsers) {2352 // Global GOT equivalents are unnamed private globals with a constant2353 // pointer initializer to another global symbol. They must point to a2354 // GlobalVariable or Function, i.e., as GlobalValue.2355 if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() ||2356 !GV->isConstant() || !GV->isDiscardableIfUnused() ||2357 !isa<GlobalValue>(GV->getOperand(0)))2358 return false;2359 2360 // To be a got equivalent, at least one of its users need to be a constant2361 // expression used by another global variable.2362 for (const auto *U : GV->users())2363 NumGOTEquivUsers +=2364 getNumGlobalVariableUses(dyn_cast<Constant>(U), HasNonGlobalUsers);2365 2366 return NumGOTEquivUsers > 0;2367}2368 2369/// Unnamed constant global variables solely contaning a pointer to2370/// another globals variable is equivalent to a GOT table entry; it contains the2371/// the address of another symbol. Optimize it and replace accesses to these2372/// "GOT equivalents" by using the GOT entry for the final global instead.2373/// Compute GOT equivalent candidates among all global variables to avoid2374/// emitting them if possible later on, after it use is replaced by a GOT entry2375/// access.2376void AsmPrinter::computeGlobalGOTEquivs(Module &M) {2377 if (!getObjFileLowering().supportIndirectSymViaGOTPCRel())2378 return;2379 2380 for (const auto &G : M.globals()) {2381 unsigned NumGOTEquivUsers = 0;2382 bool HasNonGlobalUsers = false;2383 if (!isGOTEquivalentCandidate(&G, NumGOTEquivUsers, HasNonGlobalUsers))2384 continue;2385 // If non-global variables use it, we still need to emit it.2386 // Add 1 here, then emit it in `emitGlobalGOTEquivs`.2387 if (HasNonGlobalUsers)2388 NumGOTEquivUsers += 1;2389 const MCSymbol *GOTEquivSym = getSymbol(&G);2390 GlobalGOTEquivs[GOTEquivSym] = std::make_pair(&G, NumGOTEquivUsers);2391 }2392}2393 2394/// Constant expressions using GOT equivalent globals may not be eligible2395/// for PC relative GOT entry conversion, in such cases we need to emit such2396/// globals we previously omitted in EmitGlobalVariable.2397void AsmPrinter::emitGlobalGOTEquivs() {2398 if (!getObjFileLowering().supportIndirectSymViaGOTPCRel())2399 return;2400 2401 SmallVector<const GlobalVariable *, 8> FailedCandidates;2402 for (auto &I : GlobalGOTEquivs) {2403 const GlobalVariable *GV = I.second.first;2404 unsigned Cnt = I.second.second;2405 if (Cnt)2406 FailedCandidates.push_back(GV);2407 }2408 GlobalGOTEquivs.clear();2409 2410 for (const auto *GV : FailedCandidates)2411 emitGlobalVariable(GV);2412}2413 2414void AsmPrinter::emitGlobalAlias(const Module &M, const GlobalAlias &GA) {2415 MCSymbol *Name = getSymbol(&GA);2416 bool IsFunction = GA.getValueType()->isFunctionTy();2417 // Treat bitcasts of functions as functions also. This is important at least2418 // on WebAssembly where object and function addresses can't alias each other.2419 if (!IsFunction)2420 IsFunction = isa<Function>(GA.getAliasee()->stripPointerCasts());2421 2422 // AIX's assembly directive `.set` is not usable for aliasing purpose,2423 // so AIX has to use the extra-label-at-definition strategy. At this2424 // point, all the extra label is emitted, we just have to emit linkage for2425 // those labels.2426 if (TM.getTargetTriple().isOSBinFormatXCOFF()) {2427 // Linkage for alias of global variable has been emitted.2428 if (isa<GlobalVariable>(GA.getAliaseeObject()))2429 return;2430 2431 emitLinkage(&GA, Name);2432 // If it's a function, also emit linkage for aliases of function entry2433 // point.2434 if (IsFunction)2435 emitLinkage(&GA,2436 getObjFileLowering().getFunctionEntryPointSymbol(&GA, TM));2437 return;2438 }2439 2440 if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective())2441 OutStreamer->emitSymbolAttribute(Name, MCSA_Global);2442 else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())2443 OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);2444 else2445 assert(GA.hasLocalLinkage() && "Invalid alias linkage");2446 2447 // Set the symbol type to function if the alias has a function type.2448 // This affects codegen when the aliasee is not a function.2449 if (IsFunction) {2450 OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction);2451 if (TM.getTargetTriple().isOSBinFormatCOFF()) {2452 OutStreamer->beginCOFFSymbolDef(Name);2453 OutStreamer->emitCOFFSymbolStorageClass(2454 GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC2455 : COFF::IMAGE_SYM_CLASS_EXTERNAL);2456 OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION2457 << COFF::SCT_COMPLEX_TYPE_SHIFT);2458 OutStreamer->endCOFFSymbolDef();2459 }2460 }2461 2462 emitVisibility(Name, GA.getVisibility());2463 2464 const MCExpr *Expr = lowerConstant(GA.getAliasee());2465 2466 if (MAI->isMachO() && isa<MCBinaryExpr>(Expr))2467 OutStreamer->emitSymbolAttribute(Name, MCSA_AltEntry);2468 2469 // Emit the directives as assignments aka .set:2470 OutStreamer->emitAssignment(Name, Expr);2471 MCSymbol *LocalAlias = getSymbolPreferLocal(GA);2472 if (LocalAlias != Name)2473 OutStreamer->emitAssignment(LocalAlias, Expr);2474 2475 // If the aliasee does not correspond to a symbol in the output, i.e. the2476 // alias is not of an object or the aliased object is private, then set the2477 // size of the alias symbol from the type of the alias. We don't do this in2478 // other situations as the alias and aliasee having differing types but same2479 // size may be intentional.2480 const GlobalObject *BaseObject = GA.getAliaseeObject();2481 if (MAI->hasDotTypeDotSizeDirective() && GA.getValueType()->isSized() &&2482 (!BaseObject || BaseObject->hasPrivateLinkage())) {2483 const DataLayout &DL = M.getDataLayout();2484 uint64_t Size = DL.getTypeAllocSize(GA.getValueType());2485 OutStreamer->emitELFSize(Name, MCConstantExpr::create(Size, OutContext));2486 }2487}2488 2489void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {2490 assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&2491 "IFunc is not supported on AIX.");2492 2493 auto EmitLinkage = [&](MCSymbol *Sym) {2494 if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective())2495 OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);2496 else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage())2497 OutStreamer->emitSymbolAttribute(Sym, MCSA_WeakReference);2498 else2499 assert(GI.hasLocalLinkage() && "Invalid ifunc linkage");2500 };2501 2502 if (TM.getTargetTriple().isOSBinFormatELF()) {2503 MCSymbol *Name = getSymbol(&GI);2504 EmitLinkage(Name);2505 OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction);2506 emitVisibility(Name, GI.getVisibility());2507 2508 // Emit the directives as assignments aka .set:2509 const MCExpr *Expr = lowerConstant(GI.getResolver());2510 OutStreamer->emitAssignment(Name, Expr);2511 MCSymbol *LocalAlias = getSymbolPreferLocal(GI);2512 if (LocalAlias != Name)2513 OutStreamer->emitAssignment(LocalAlias, Expr);2514 2515 return;2516 }2517 2518 if (!TM.getTargetTriple().isOSBinFormatMachO() || !getIFuncMCSubtargetInfo())2519 reportFatalUsageError("IFuncs are not supported on this platform");2520 2521 // On Darwin platforms, emit a manually-constructed .symbol_resolver that2522 // implements the symbol resolution duties of the IFunc.2523 //2524 // Normally, this would be handled by linker magic, but unfortunately there2525 // are a few limitations in ld64 and ld-prime's implementation of2526 // .symbol_resolver that mean we can't always use them:2527 //2528 // * resolvers cannot be the target of an alias2529 // * resolvers cannot have private linkage2530 // * resolvers cannot have linkonce linkage2531 // * resolvers cannot appear in executables2532 // * resolvers cannot appear in bundles2533 //2534 // This works around that by emitting a close approximation of what the2535 // linker would have done.2536 2537 MCSymbol *LazyPointer =2538 GetExternalSymbolSymbol(GI.getName() + ".lazy_pointer");2539 MCSymbol *StubHelper = GetExternalSymbolSymbol(GI.getName() + ".stub_helper");2540 2541 OutStreamer->switchSection(OutContext.getObjectFileInfo()->getDataSection());2542 2543 const DataLayout &DL = M.getDataLayout();2544 emitAlignment(Align(DL.getPointerSize()));2545 OutStreamer->emitLabel(LazyPointer);2546 emitVisibility(LazyPointer, GI.getVisibility());2547 OutStreamer->emitValue(MCSymbolRefExpr::create(StubHelper, OutContext), 8);2548 2549 OutStreamer->switchSection(OutContext.getObjectFileInfo()->getTextSection());2550 2551 const TargetSubtargetInfo *STI =2552 TM.getSubtargetImpl(*GI.getResolverFunction());2553 const TargetLowering *TLI = STI->getTargetLowering();2554 Align TextAlign(TLI->getMinFunctionAlignment());2555 2556 MCSymbol *Stub = getSymbol(&GI);2557 EmitLinkage(Stub);2558 OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo());2559 OutStreamer->emitLabel(Stub);2560 emitVisibility(Stub, GI.getVisibility());2561 emitMachOIFuncStubBody(M, GI, LazyPointer);2562 2563 OutStreamer->emitCodeAlignment(TextAlign, getIFuncMCSubtargetInfo());2564 OutStreamer->emitLabel(StubHelper);2565 emitVisibility(StubHelper, GI.getVisibility());2566 emitMachOIFuncStubHelperBody(M, GI, LazyPointer);2567}2568 2569void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {2570 if (!RS.needsSection())2571 return;2572 if (!RS.getFilename())2573 return;2574 2575 MCSection *RemarksSection =2576 OutContext.getObjectFileInfo()->getRemarksSection();2577 if (!RemarksSection) {2578 OutContext.reportWarning(SMLoc(), "Current object file format does not "2579 "support remarks sections. Use the yaml "2580 "remark format instead.");2581 return;2582 }2583 2584 SmallString<128> Filename = *RS.getFilename();2585 sys::fs::make_absolute(Filename);2586 assert(!Filename.empty() && "The filename can't be empty.");2587 2588 std::string Buf;2589 raw_string_ostream OS(Buf);2590 2591 remarks::RemarkSerializer &RemarkSerializer = RS.getSerializer();2592 std::unique_ptr<remarks::MetaSerializer> MetaSerializer =2593 RemarkSerializer.metaSerializer(OS, Filename);2594 MetaSerializer->emit();2595 2596 // Switch to the remarks section.2597 OutStreamer->switchSection(RemarksSection);2598 OutStreamer->emitBinaryData(Buf);2599}2600 2601static uint64_t globalSize(const llvm::GlobalVariable &G) {2602 const Constant *Initializer = G.getInitializer();2603 return G.getParent()->getDataLayout().getTypeAllocSize(2604 Initializer->getType());2605}2606 2607static bool shouldTagGlobal(const llvm::GlobalVariable &G) {2608 // We used to do this in clang, but there are optimization passes that turn2609 // non-constant globals into constants. So now, clang only tells us whether2610 // it would *like* a global to be tagged, but we still make the decision here.2611 //2612 // For now, don't instrument constant data, as it'll be in .rodata anyway. It2613 // may be worth instrumenting these in future to stop them from being used as2614 // gadgets.2615 if (G.getName().starts_with("llvm.") || G.isThreadLocal() || G.isConstant())2616 return false;2617 2618 // Globals can be placed implicitly or explicitly in sections. There's two2619 // different types of globals that meet this criteria that cause problems:2620 // 1. Function pointers that are going into various init arrays (either2621 // explicitly through `__attribute__((section(<foo>)))` or implicitly2622 // through `__attribute__((constructor)))`, such as ".(pre)init(_array)",2623 // ".fini(_array)", ".ctors", and ".dtors". These function pointers end up2624 // overaligned and overpadded, making iterating over them problematic, and2625 // each function pointer is individually tagged (so the iteration over2626 // them causes SIGSEGV/MTE[AS]ERR).2627 // 2. Global variables put into an explicit section, where the section's name2628 // is a valid C-style identifier. The linker emits a `__start_<name>` and2629 // `__stop_<name>` symbol for the section, so that you can iterate over2630 // globals within this section. Unfortunately, again, these globals would2631 // be tagged and so iteration causes SIGSEGV/MTE[AS]ERR.2632 //2633 // To mitigate both these cases, and because specifying a section is rare2634 // outside of these two cases, disable MTE protection for globals in any2635 // section.2636 if (G.hasSection())2637 return false;2638 2639 return globalSize(G) > 0;2640}2641 2642static void tagGlobalDefinition(Module &M, GlobalVariable *G) {2643 uint64_t SizeInBytes = globalSize(*G);2644 2645 uint64_t NewSize = alignTo(SizeInBytes, 16);2646 if (SizeInBytes != NewSize) {2647 // Pad the initializer out to the next multiple of 16 bytes.2648 llvm::SmallVector<uint8_t> Init(NewSize - SizeInBytes, 0);2649 Constant *Padding = ConstantDataArray::get(M.getContext(), Init);2650 Constant *Initializer = G->getInitializer();2651 Initializer = ConstantStruct::getAnon({Initializer, Padding});2652 auto *NewGV = new GlobalVariable(2653 M, Initializer->getType(), G->isConstant(), G->getLinkage(),2654 Initializer, "", G, G->getThreadLocalMode(), G->getAddressSpace());2655 NewGV->copyAttributesFrom(G);2656 NewGV->setComdat(G->getComdat());2657 NewGV->copyMetadata(G, 0);2658 2659 NewGV->takeName(G);2660 G->replaceAllUsesWith(NewGV);2661 G->eraseFromParent();2662 G = NewGV;2663 }2664 2665 if (G->getAlign().valueOrOne() < 16)2666 G->setAlignment(Align(16));2667 2668 // Ensure that tagged globals don't get merged by ICF - as they should have2669 // different tags at runtime.2670 G->setUnnamedAddr(GlobalValue::UnnamedAddr::None);2671}2672 2673static void removeMemtagFromGlobal(GlobalVariable &G) {2674 auto Meta = G.getSanitizerMetadata();2675 Meta.Memtag = false;2676 G.setSanitizerMetadata(Meta);2677}2678 2679bool AsmPrinter::doFinalization(Module &M) {2680 // Set the MachineFunction to nullptr so that we can catch attempted2681 // accesses to MF specific features at the module level and so that2682 // we can conditionalize accesses based on whether or not it is nullptr.2683 MF = nullptr;2684 2685 std::vector<GlobalVariable *> GlobalsToTag;2686 for (GlobalVariable &G : M.globals()) {2687 if (G.isDeclaration() || !G.isTagged())2688 continue;2689 if (!shouldTagGlobal(G)) {2690 assert(G.hasSanitizerMetadata()); // because isTagged.2691 removeMemtagFromGlobal(G);2692 assert(!G.isTagged());2693 continue;2694 }2695 GlobalsToTag.push_back(&G);2696 }2697 for (GlobalVariable *G : GlobalsToTag)2698 tagGlobalDefinition(M, G);2699 2700 // Gather all GOT equivalent globals in the module. We really need two2701 // passes over the globals: one to compute and another to avoid its emission2702 // in EmitGlobalVariable, otherwise we would not be able to handle cases2703 // where the got equivalent shows up before its use.2704 computeGlobalGOTEquivs(M);2705 2706 // Emit global variables.2707 for (const auto &G : M.globals())2708 emitGlobalVariable(&G);2709 2710 // Emit remaining GOT equivalent globals.2711 emitGlobalGOTEquivs();2712 2713 const TargetLoweringObjectFile &TLOF = getObjFileLowering();2714 2715 // Emit linkage(XCOFF) and visibility info for declarations2716 for (const Function &F : M) {2717 if (!F.isDeclarationForLinker())2718 continue;2719 2720 MCSymbol *Name = getSymbol(&F);2721 // Function getSymbol gives us the function descriptor symbol for XCOFF.2722 2723 if (!TM.getTargetTriple().isOSBinFormatXCOFF()) {2724 GlobalValue::VisibilityTypes V = F.getVisibility();2725 if (V == GlobalValue::DefaultVisibility)2726 continue;2727 2728 emitVisibility(Name, V, false);2729 continue;2730 }2731 2732 if (F.isIntrinsic())2733 continue;2734 2735 // Handle the XCOFF case.2736 // Variable `Name` is the function descriptor symbol (see above). Get the2737 // function entry point symbol.2738 MCSymbol *FnEntryPointSym = TLOF.getFunctionEntryPointSymbol(&F, TM);2739 // Emit linkage for the function entry point.2740 emitLinkage(&F, FnEntryPointSym);2741 2742 // If a function's address is taken, which means it may be called via a2743 // function pointer, we need the function descriptor for it.2744 if (F.hasAddressTaken())2745 emitLinkage(&F, Name);2746 }2747 2748 // Emit the remarks section contents.2749 // FIXME: Figure out when is the safest time to emit this section. It should2750 // not come after debug info.2751 if (remarks::RemarkStreamer *RS = M.getContext().getMainRemarkStreamer())2752 emitRemarksSection(*RS);2753 2754 TLOF.emitModuleMetadata(*OutStreamer, M);2755 2756 if (TM.getTargetTriple().isOSBinFormatELF()) {2757 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();2758 2759 // Output stubs for external and common global variables.2760 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();2761 if (!Stubs.empty()) {2762 OutStreamer->switchSection(TLOF.getDataSection());2763 const DataLayout &DL = M.getDataLayout();2764 2765 emitAlignment(Align(DL.getPointerSize()));2766 for (const auto &Stub : Stubs) {2767 OutStreamer->emitLabel(Stub.first);2768 OutStreamer->emitSymbolValue(Stub.second.getPointer(),2769 DL.getPointerSize());2770 }2771 }2772 }2773 2774 if (TM.getTargetTriple().isOSBinFormatCOFF()) {2775 MachineModuleInfoCOFF &MMICOFF =2776 MMI->getObjFileInfo<MachineModuleInfoCOFF>();2777 2778 // Output stubs for external and common global variables.2779 MachineModuleInfoCOFF::SymbolListTy Stubs = MMICOFF.GetGVStubList();2780 if (!Stubs.empty()) {2781 const DataLayout &DL = M.getDataLayout();2782 2783 for (const auto &Stub : Stubs) {2784 SmallString<256> SectionName = StringRef(".rdata$");2785 SectionName += Stub.first->getName();2786 OutStreamer->switchSection(OutContext.getCOFFSection(2787 SectionName,2788 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |2789 COFF::IMAGE_SCN_LNK_COMDAT,2790 Stub.first->getName(), COFF::IMAGE_COMDAT_SELECT_ANY));2791 emitAlignment(Align(DL.getPointerSize()));2792 OutStreamer->emitSymbolAttribute(Stub.first, MCSA_Global);2793 OutStreamer->emitLabel(Stub.first);2794 OutStreamer->emitSymbolValue(Stub.second.getPointer(),2795 DL.getPointerSize());2796 }2797 }2798 }2799 2800 // This needs to happen before emitting debug information since that can end2801 // arbitrary sections.2802 if (auto *TS = OutStreamer->getTargetStreamer())2803 TS->emitConstantPools();2804 2805 // Emit Stack maps before any debug info. Mach-O requires that no data or2806 // text sections come after debug info has been emitted. This matters for2807 // stack maps as they are arbitrary data, and may even have a custom format2808 // through user plugins.2809 emitStackMaps();2810 2811 // Print aliases in topological order, that is, for each alias a = b,2812 // b must be printed before a.2813 // This is because on some targets (e.g. PowerPC) linker expects aliases in2814 // such an order to generate correct TOC information.2815 SmallVector<const GlobalAlias *, 16> AliasStack;2816 SmallPtrSet<const GlobalAlias *, 16> AliasVisited;2817 for (const auto &Alias : M.aliases()) {2818 if (Alias.hasAvailableExternallyLinkage())2819 continue;2820 for (const GlobalAlias *Cur = &Alias; Cur;2821 Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {2822 if (!AliasVisited.insert(Cur).second)2823 break;2824 AliasStack.push_back(Cur);2825 }2826 for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack))2827 emitGlobalAlias(M, *AncestorAlias);2828 AliasStack.clear();2829 }2830 2831 // IFuncs must come before deubginfo in case the backend decides to emit them2832 // as actual functions, since on Mach-O targets, we cannot create regular2833 // sections after DWARF.2834 for (const auto &IFunc : M.ifuncs())2835 emitGlobalIFunc(M, IFunc);2836 2837 // Finalize debug and EH information.2838 for (auto &Handler : Handlers)2839 Handler->endModule();2840 for (auto &Handler : EHHandlers)2841 Handler->endModule();2842 2843 // This deletes all the ephemeral handlers that AsmPrinter added, while2844 // keeping all the user-added handlers alive until the AsmPrinter is2845 // destroyed.2846 EHHandlers.clear();2847 Handlers.erase(Handlers.begin() + NumUserHandlers, Handlers.end());2848 DD = nullptr;2849 2850 // If the target wants to know about weak references, print them all.2851 if (MAI->getWeakRefDirective()) {2852 // FIXME: This is not lazy, it would be nice to only print weak references2853 // to stuff that is actually used. Note that doing so would require targets2854 // to notice uses in operands (due to constant exprs etc). This should2855 // happen with the MC stuff eventually.2856 2857 // Print out module-level global objects here.2858 for (const auto &GO : M.global_objects()) {2859 if (!GO.hasExternalWeakLinkage())2860 continue;2861 OutStreamer->emitSymbolAttribute(getSymbol(&GO), MCSA_WeakReference);2862 }2863 if (shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()) {2864 auto SymbolName = "swift_async_extendedFramePointerFlags";2865 auto Global = M.getGlobalVariable(SymbolName);2866 if (!Global) {2867 auto PtrTy = PointerType::getUnqual(M.getContext());2868 Global = new GlobalVariable(M, PtrTy, false,2869 GlobalValue::ExternalWeakLinkage, nullptr,2870 SymbolName);2871 OutStreamer->emitSymbolAttribute(getSymbol(Global), MCSA_WeakReference);2872 }2873 }2874 }2875 2876 GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();2877 assert(MI && "AsmPrinter didn't require GCModuleInfo?");2878 for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )2879 if (GCMetadataPrinter *MP = getOrCreateGCPrinter(**--I))2880 MP->finishAssembly(M, *MI, *this);2881 2882 // Emit llvm.ident metadata in an '.ident' directive.2883 emitModuleIdents(M);2884 2885 // Emit bytes for llvm.commandline metadata.2886 // The command line metadata is emitted earlier on XCOFF.2887 if (!TM.getTargetTriple().isOSBinFormatXCOFF())2888 emitModuleCommandLines(M);2889 2890 // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if2891 // split-stack is used.2892 if (TM.getTargetTriple().isOSBinFormatELF() && HasSplitStack) {2893 OutStreamer->switchSection(OutContext.getELFSection(".note.GNU-split-stack",2894 ELF::SHT_PROGBITS, 0));2895 if (HasNoSplitStack)2896 OutStreamer->switchSection(OutContext.getELFSection(2897 ".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));2898 }2899 2900 // If we don't have any trampolines, then we don't require stack memory2901 // to be executable. Some targets have a directive to declare this.2902 Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");2903 bool HasTrampolineUses =2904 InitTrampolineIntrinsic && !InitTrampolineIntrinsic->use_empty();2905 MCSection *S = MAI->getStackSection(OutContext, /*Exec=*/HasTrampolineUses);2906 if (S)2907 OutStreamer->switchSection(S);2908 2909 if (TM.Options.EmitAddrsig) {2910 // Emit address-significance attributes for all globals.2911 OutStreamer->emitAddrsig();2912 for (const GlobalValue &GV : M.global_values()) {2913 if (!GV.use_empty() && !GV.isThreadLocal() &&2914 !GV.hasDLLImportStorageClass() &&2915 !GV.getName().starts_with("llvm.") &&2916 !GV.hasAtLeastLocalUnnamedAddr())2917 OutStreamer->emitAddrsigSym(getSymbol(&GV));2918 }2919 }2920 2921 // Emit symbol partition specifications (ELF only).2922 if (TM.getTargetTriple().isOSBinFormatELF()) {2923 unsigned UniqueID = 0;2924 for (const GlobalValue &GV : M.global_values()) {2925 if (!GV.hasPartition() || GV.isDeclarationForLinker() ||2926 GV.getVisibility() != GlobalValue::DefaultVisibility)2927 continue;2928 2929 OutStreamer->switchSection(2930 OutContext.getELFSection(".llvm_sympart", ELF::SHT_LLVM_SYMPART, 0, 0,2931 "", false, ++UniqueID, nullptr));2932 OutStreamer->emitBytes(GV.getPartition());2933 OutStreamer->emitZeros(1);2934 OutStreamer->emitValue(2935 MCSymbolRefExpr::create(getSymbol(&GV), OutContext),2936 MAI->getCodePointerSize());2937 }2938 }2939 2940 // Allow the target to emit any magic that it wants at the end of the file,2941 // after everything else has gone out.2942 emitEndOfAsmFile(M);2943 2944 MMI = nullptr;2945 AddrLabelSymbols = nullptr;2946 2947 OutStreamer->finish();2948 OutStreamer->reset();2949 OwnedMLI.reset();2950 OwnedMDT.reset();2951 2952 return false;2953}2954 2955MCSymbol *AsmPrinter::getMBBExceptionSym(const MachineBasicBlock &MBB) {2956 auto Res = MBBSectionExceptionSyms.try_emplace(MBB.getSectionID());2957 if (Res.second)2958 Res.first->second = createTempSymbol("exception");2959 return Res.first->second;2960}2961 2962MCSymbol *AsmPrinter::createCallsiteEndSymbol(const MachineBasicBlock &MBB) {2963 MCContext &Ctx = MF->getContext();2964 MCSymbol *Sym = Ctx.createTempSymbol("BB" + Twine(MF->getFunctionNumber()) +2965 "_" + Twine(MBB.getNumber()) + "_CS");2966 CurrentFnCallsiteEndSymbols[&MBB].push_back(Sym);2967 return Sym;2968}2969 2970void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {2971 this->MF = &MF;2972 const Function &F = MF.getFunction();2973 2974 // Record that there are split-stack functions, so we will emit a special2975 // section to tell the linker.2976 if (MF.shouldSplitStack()) {2977 HasSplitStack = true;2978 2979 if (!MF.getFrameInfo().needsSplitStackProlog())2980 HasNoSplitStack = true;2981 } else2982 HasNoSplitStack = true;2983 2984 // Get the function symbol.2985 if (!MAI->isAIX()) {2986 CurrentFnSym = getSymbol(&MF.getFunction());2987 } else {2988 assert(TM.getTargetTriple().isOSAIX() &&2989 "Only AIX uses the function descriptor hooks.");2990 // AIX is unique here in that the name of the symbol emitted for the2991 // function body does not have the same name as the source function's2992 // C-linkage name.2993 assert(CurrentFnDescSym && "The function descriptor symbol needs to be"2994 " initalized first.");2995 2996 // Get the function entry point symbol.2997 CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&F, TM);2998 }2999 3000 CurrentFnSymForSize = CurrentFnSym;3001 CurrentFnBegin = nullptr;3002 CurrentFnBeginLocal = nullptr;3003 CurrentSectionBeginSym = nullptr;3004 CurrentFnCallsiteEndSymbols.clear();3005 MBBSectionRanges.clear();3006 MBBSectionExceptionSyms.clear();3007 bool NeedsLocalForSize = MAI->needsLocalForSize();3008 if (F.hasFnAttribute("patchable-function-entry") ||3009 F.hasFnAttribute("function-instrument") ||3010 F.hasFnAttribute("xray-instruction-threshold") ||3011 needFuncLabels(MF, *this) || NeedsLocalForSize ||3012 MF.getTarget().Options.EmitStackSizeSection ||3013 MF.getTarget().Options.EmitCallGraphSection ||3014 MF.getTarget().Options.BBAddrMap) {3015 CurrentFnBegin = createTempSymbol("func_begin");3016 if (NeedsLocalForSize)3017 CurrentFnSymForSize = CurrentFnBegin;3018 }3019 3020 ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();3021}3022 3023namespace {3024 3025// Keep track the alignment, constpool entries per Section.3026 struct SectionCPs {3027 MCSection *S;3028 Align Alignment;3029 SmallVector<unsigned, 4> CPEs;3030 3031 SectionCPs(MCSection *s, Align a) : S(s), Alignment(a) {}3032 };3033 3034} // end anonymous namespace3035 3036StringRef AsmPrinter::getConstantSectionSuffix(const Constant *C) const {3037 if (TM.Options.EnableStaticDataPartitioning && C && SDPI && PSI)3038 return SDPI->getConstantSectionPrefix(C, PSI);3039 3040 return "";3041}3042 3043/// EmitConstantPool - Print to the current output stream assembly3044/// representations of the constants in the constant pool MCP. This is3045/// used to print out constants which have been "spilled to memory" by3046/// the code generator.3047void AsmPrinter::emitConstantPool() {3048 const MachineConstantPool *MCP = MF->getConstantPool();3049 const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();3050 if (CP.empty()) return;3051 3052 // Calculate sections for constant pool entries. We collect entries to go into3053 // the same section together to reduce amount of section switch statements.3054 SmallVector<SectionCPs, 4> CPSections;3055 for (unsigned i = 0, e = CP.size(); i != e; ++i) {3056 const MachineConstantPoolEntry &CPE = CP[i];3057 Align Alignment = CPE.getAlign();3058 3059 SectionKind Kind = CPE.getSectionKind(&getDataLayout());3060 3061 const Constant *C = nullptr;3062 if (!CPE.isMachineConstantPoolEntry())3063 C = CPE.Val.ConstVal;3064 3065 MCSection *S = getObjFileLowering().getSectionForConstant(3066 getDataLayout(), Kind, C, Alignment, getConstantSectionSuffix(C));3067 3068 // The number of sections are small, just do a linear search from the3069 // last section to the first.3070 bool Found = false;3071 unsigned SecIdx = CPSections.size();3072 while (SecIdx != 0) {3073 if (CPSections[--SecIdx].S == S) {3074 Found = true;3075 break;3076 }3077 }3078 if (!Found) {3079 SecIdx = CPSections.size();3080 CPSections.push_back(SectionCPs(S, Alignment));3081 }3082 3083 if (Alignment > CPSections[SecIdx].Alignment)3084 CPSections[SecIdx].Alignment = Alignment;3085 CPSections[SecIdx].CPEs.push_back(i);3086 }3087 3088 // Now print stuff into the calculated sections.3089 const MCSection *CurSection = nullptr;3090 unsigned Offset = 0;3091 for (const SectionCPs &CPSection : CPSections) {3092 for (unsigned CPI : CPSection.CPEs) {3093 MCSymbol *Sym = GetCPISymbol(CPI);3094 if (!Sym->isUndefined())3095 continue;3096 3097 if (CurSection != CPSection.S) {3098 OutStreamer->switchSection(CPSection.S);3099 emitAlignment(Align(CPSection.Alignment));3100 CurSection = CPSection.S;3101 Offset = 0;3102 }3103 3104 MachineConstantPoolEntry CPE = CP[CPI];3105 3106 // Emit inter-object padding for alignment.3107 unsigned NewOffset = alignTo(Offset, CPE.getAlign());3108 OutStreamer->emitZeros(NewOffset - Offset);3109 3110 Offset = NewOffset + CPE.getSizeInBytes(getDataLayout());3111 3112 OutStreamer->emitLabel(Sym);3113 if (CPE.isMachineConstantPoolEntry())3114 emitMachineConstantPoolValue(CPE.Val.MachineCPVal);3115 else3116 emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);3117 }3118 }3119}3120 3121// Print assembly representations of the jump tables used by the current3122// function.3123void AsmPrinter::emitJumpTableInfo() {3124 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();3125 if (!MJTI) return;3126 3127 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();3128 if (JT.empty()) return;3129 3130 if (!TM.Options.EnableStaticDataPartitioning) {3131 emitJumpTableImpl(*MJTI, llvm::to_vector(llvm::seq<unsigned>(JT.size())));3132 return;3133 }3134 3135 SmallVector<unsigned> HotJumpTableIndices, ColdJumpTableIndices;3136 // When static data partitioning is enabled, collect jump table entries that3137 // go into the same section together to reduce the amount of section switch3138 // statements.3139 for (unsigned JTI = 0, JTSize = JT.size(); JTI < JTSize; ++JTI) {3140 if (JT[JTI].Hotness == MachineFunctionDataHotness::Cold) {3141 ColdJumpTableIndices.push_back(JTI);3142 } else {3143 HotJumpTableIndices.push_back(JTI);3144 }3145 }3146 3147 emitJumpTableImpl(*MJTI, HotJumpTableIndices);3148 emitJumpTableImpl(*MJTI, ColdJumpTableIndices);3149}3150 3151void AsmPrinter::emitJumpTableImpl(const MachineJumpTableInfo &MJTI,3152 ArrayRef<unsigned> JumpTableIndices) {3153 if (MJTI.getEntryKind() == MachineJumpTableInfo::EK_Inline ||3154 JumpTableIndices.empty())3155 return;3156 3157 const TargetLoweringObjectFile &TLOF = getObjFileLowering();3158 const Function &F = MF->getFunction();3159 const std::vector<MachineJumpTableEntry> &JT = MJTI.getJumpTables();3160 MCSection *JumpTableSection = nullptr;3161 3162 const bool UseLabelDifference =3163 MJTI.getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||3164 MJTI.getEntryKind() == MachineJumpTableInfo::EK_LabelDifference64;3165 // Pick the directive to use to print the jump table entries, and switch to3166 // the appropriate section.3167 const bool JTInDiffSection =3168 !TLOF.shouldPutJumpTableInFunctionSection(UseLabelDifference, F);3169 if (JTInDiffSection) {3170 if (TM.Options.EnableStaticDataPartitioning) {3171 JumpTableSection =3172 TLOF.getSectionForJumpTable(F, TM, &JT[JumpTableIndices.front()]);3173 } else {3174 JumpTableSection = TLOF.getSectionForJumpTable(F, TM);3175 }3176 OutStreamer->switchSection(JumpTableSection);3177 }3178 3179 const DataLayout &DL = MF->getDataLayout();3180 emitAlignment(Align(MJTI.getEntryAlignment(DL)));3181 3182 // Jump tables in code sections are marked with a data_region directive3183 // where that's supported.3184 if (!JTInDiffSection)3185 OutStreamer->emitDataRegion(MCDR_DataRegionJT32);3186 3187 for (const unsigned JumpTableIndex : JumpTableIndices) {3188 ArrayRef<MachineBasicBlock *> JTBBs = JT[JumpTableIndex].MBBs;3189 3190 // If this jump table was deleted, ignore it.3191 if (JTBBs.empty())3192 continue;3193 3194 // For the EK_LabelDifference32 entry, if using .set avoids a relocation,3195 /// emit a .set directive for each unique entry.3196 if (MJTI.getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&3197 MAI->doesSetDirectiveSuppressReloc()) {3198 SmallPtrSet<const MachineBasicBlock *, 16> EmittedSets;3199 const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();3200 const MCExpr *Base =3201 TLI->getPICJumpTableRelocBaseExpr(MF, JumpTableIndex, OutContext);3202 for (const MachineBasicBlock *MBB : JTBBs) {3203 if (!EmittedSets.insert(MBB).second)3204 continue;3205 3206 // .set LJTSet, LBB32-base3207 const MCExpr *LHS =3208 MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);3209 OutStreamer->emitAssignment(3210 GetJTSetSymbol(JumpTableIndex, MBB->getNumber()),3211 MCBinaryExpr::createSub(LHS, Base, OutContext));3212 }3213 }3214 3215 // On some targets (e.g. Darwin) we want to emit two consecutive labels3216 // before each jump table. The first label is never referenced, but tells3217 // the assembler and linker the extents of the jump table object. The3218 // second label is actually referenced by the code.3219 if (JTInDiffSection && DL.hasLinkerPrivateGlobalPrefix())3220 // FIXME: This doesn't have to have any specific name, just any randomly3221 // named and numbered local label started with 'l' would work. Simplify3222 // GetJTISymbol.3223 OutStreamer->emitLabel(GetJTISymbol(JumpTableIndex, true));3224 3225 MCSymbol *JTISymbol = GetJTISymbol(JumpTableIndex);3226 OutStreamer->emitLabel(JTISymbol);3227 3228 // Defer MCAssembler based constant folding due to a performance issue. The3229 // label differences will be evaluated at write time.3230 for (const MachineBasicBlock *MBB : JTBBs)3231 emitJumpTableEntry(MJTI, MBB, JumpTableIndex);3232 }3233 3234 if (EmitJumpTableSizesSection)3235 emitJumpTableSizesSection(MJTI, MF->getFunction());3236 3237 if (!JTInDiffSection)3238 OutStreamer->emitDataRegion(MCDR_DataRegionEnd);3239}3240 3241void AsmPrinter::emitJumpTableSizesSection(const MachineJumpTableInfo &MJTI,3242 const Function &F) const {3243 const std::vector<MachineJumpTableEntry> &JT = MJTI.getJumpTables();3244 3245 if (JT.empty())3246 return;3247 3248 StringRef GroupName = F.hasComdat() ? F.getComdat()->getName() : "";3249 MCSection *JumpTableSizesSection = nullptr;3250 StringRef sectionName = ".llvm_jump_table_sizes";3251 3252 bool isElf = TM.getTargetTriple().isOSBinFormatELF();3253 bool isCoff = TM.getTargetTriple().isOSBinFormatCOFF();3254 3255 if (!isCoff && !isElf)3256 return;3257 3258 if (isElf) {3259 auto *LinkedToSym = static_cast<MCSymbolELF *>(CurrentFnSym);3260 int Flags = F.hasComdat() ? static_cast<int>(ELF::SHF_GROUP) : 0;3261 3262 JumpTableSizesSection = OutContext.getELFSection(3263 sectionName, ELF::SHT_LLVM_JT_SIZES, Flags, 0, GroupName, F.hasComdat(),3264 MCSection::NonUniqueID, LinkedToSym);3265 } else if (isCoff) {3266 if (F.hasComdat()) {3267 JumpTableSizesSection = OutContext.getCOFFSection(3268 sectionName,3269 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ |3270 COFF::IMAGE_SCN_LNK_COMDAT | COFF::IMAGE_SCN_MEM_DISCARDABLE,3271 F.getComdat()->getName(), COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);3272 } else {3273 JumpTableSizesSection = OutContext.getCOFFSection(3274 sectionName, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |3275 COFF::IMAGE_SCN_MEM_READ |3276 COFF::IMAGE_SCN_MEM_DISCARDABLE);3277 }3278 }3279 3280 OutStreamer->switchSection(JumpTableSizesSection);3281 3282 for (unsigned JTI = 0, E = JT.size(); JTI != E; ++JTI) {3283 const std::vector<MachineBasicBlock *> &JTBBs = JT[JTI].MBBs;3284 OutStreamer->emitSymbolValue(GetJTISymbol(JTI), TM.getProgramPointerSize());3285 OutStreamer->emitIntValue(JTBBs.size(), TM.getProgramPointerSize());3286 }3287}3288 3289/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the3290/// current stream.3291void AsmPrinter::emitJumpTableEntry(const MachineJumpTableInfo &MJTI,3292 const MachineBasicBlock *MBB,3293 unsigned UID) const {3294 assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block");3295 const MCExpr *Value = nullptr;3296 switch (MJTI.getEntryKind()) {3297 case MachineJumpTableInfo::EK_Inline:3298 llvm_unreachable("Cannot emit EK_Inline jump table entry");3299 case MachineJumpTableInfo::EK_GPRel32BlockAddress:3300 case MachineJumpTableInfo::EK_GPRel64BlockAddress:3301 llvm_unreachable("MIPS specific");3302 case MachineJumpTableInfo::EK_Custom32:3303 Value = MF->getSubtarget().getTargetLowering()->LowerCustomJumpTableEntry(3304 &MJTI, MBB, UID, OutContext);3305 break;3306 case MachineJumpTableInfo::EK_BlockAddress:3307 // EK_BlockAddress - Each entry is a plain address of block, e.g.:3308 // .word LBB1233309 Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);3310 break;3311 3312 case MachineJumpTableInfo::EK_LabelDifference32:3313 case MachineJumpTableInfo::EK_LabelDifference64: {3314 // Each entry is the address of the block minus the address of the jump3315 // table. This is used for PIC jump tables where gprel32 is not supported.3316 // e.g.:3317 // .word LBB123 - LJTI1_23318 // If the .set directive avoids relocations, this is emitted as:3319 // .set L4_5_set_123, LBB123 - LJTI1_23320 // .word L4_5_set_1233321 if (MJTI.getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&3322 MAI->doesSetDirectiveSuppressReloc()) {3323 Value = MCSymbolRefExpr::create(GetJTSetSymbol(UID, MBB->getNumber()),3324 OutContext);3325 break;3326 }3327 Value = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);3328 const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();3329 const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF, UID, OutContext);3330 Value = MCBinaryExpr::createSub(Value, Base, OutContext);3331 break;3332 }3333 }3334 3335 assert(Value && "Unknown entry kind!");3336 3337 unsigned EntrySize = MJTI.getEntrySize(getDataLayout());3338 OutStreamer->emitValue(Value, EntrySize);3339}3340 3341/// EmitSpecialLLVMGlobal - Check to see if the specified global is a3342/// special global used by LLVM. If so, emit it and return true, otherwise3343/// do nothing and return false.3344bool AsmPrinter::emitSpecialLLVMGlobal(const GlobalVariable *GV) {3345 if (GV->getName() == "llvm.used") {3346 if (MAI->hasNoDeadStrip()) // No need to emit this at all.3347 emitLLVMUsedList(cast<ConstantArray>(GV->getInitializer()));3348 return true;3349 }3350 3351 // Ignore debug and non-emitted data. This handles llvm.compiler.used.3352 if (GV->getSection() == "llvm.metadata" ||3353 GV->hasAvailableExternallyLinkage())3354 return true;3355 3356 if (GV->getName() == "llvm.arm64ec.symbolmap") {3357 // For ARM64EC, print the table that maps between symbols and the3358 // corresponding thunks to translate between x64 and AArch64 code.3359 // This table is generated by AArch64Arm64ECCallLowering.3360 OutStreamer->switchSection(3361 OutContext.getCOFFSection(".hybmp$x", COFF::IMAGE_SCN_LNK_INFO));3362 auto *Arr = cast<ConstantArray>(GV->getInitializer());3363 for (auto &U : Arr->operands()) {3364 auto *C = cast<Constant>(U);3365 auto *Src = cast<GlobalValue>(C->getOperand(0)->stripPointerCasts());3366 auto *Dst = cast<GlobalValue>(C->getOperand(1)->stripPointerCasts());3367 int Kind = cast<ConstantInt>(C->getOperand(2))->getZExtValue();3368 3369 if (Src->hasDLLImportStorageClass()) {3370 // For now, we assume dllimport functions aren't directly called.3371 // (We might change this later to match MSVC.)3372 OutStreamer->emitCOFFSymbolIndex(3373 OutContext.getOrCreateSymbol("__imp_" + Src->getName()));3374 OutStreamer->emitCOFFSymbolIndex(getSymbol(Dst));3375 OutStreamer->emitInt32(Kind);3376 } else {3377 // FIXME: For non-dllimport functions, MSVC emits the same entry3378 // twice, for reasons I don't understand. I have to assume the linker3379 // ignores the redundant entry; there aren't any reasonable semantics3380 // to attach to it.3381 OutStreamer->emitCOFFSymbolIndex(getSymbol(Src));3382 OutStreamer->emitCOFFSymbolIndex(getSymbol(Dst));3383 OutStreamer->emitInt32(Kind);3384 }3385 }3386 return true;3387 }3388 3389 if (!GV->hasAppendingLinkage()) return false;3390 3391 assert(GV->hasInitializer() && "Not a special LLVM global!");3392 3393 if (GV->getName() == "llvm.global_ctors") {3394 emitXXStructorList(GV->getDataLayout(), GV->getInitializer(),3395 /* isCtor */ true);3396 3397 return true;3398 }3399 3400 if (GV->getName() == "llvm.global_dtors") {3401 emitXXStructorList(GV->getDataLayout(), GV->getInitializer(),3402 /* isCtor */ false);3403 3404 return true;3405 }3406 3407 GV->getContext().emitError(3408 "unknown special variable with appending linkage: " +3409 GV->getNameOrAsOperand());3410 return true;3411}3412 3413/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each3414/// global in the specified llvm.used list.3415void AsmPrinter::emitLLVMUsedList(const ConstantArray *InitList) {3416 // Should be an array of 'i8*'.3417 for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {3418 const GlobalValue *GV =3419 dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());3420 if (GV)3421 OutStreamer->emitSymbolAttribute(getSymbol(GV), MCSA_NoDeadStrip);3422 }3423}3424 3425void AsmPrinter::preprocessXXStructorList(const DataLayout &DL,3426 const Constant *List,3427 SmallVector<Structor, 8> &Structors) {3428 // Should be an array of '{ i32, void ()*, i8* }' structs. The first value is3429 // the init priority.3430 if (!isa<ConstantArray>(List))3431 return;3432 3433 // Gather the structors in a form that's convenient for sorting by priority.3434 for (Value *O : cast<ConstantArray>(List)->operands()) {3435 auto *CS = cast<ConstantStruct>(O);3436 if (CS->getOperand(1)->isNullValue())3437 break; // Found a null terminator, skip the rest.3438 ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));3439 if (!Priority)3440 continue; // Malformed.3441 Structors.push_back(Structor());3442 Structor &S = Structors.back();3443 S.Priority = Priority->getLimitedValue(65535);3444 S.Func = CS->getOperand(1);3445 if (!CS->getOperand(2)->isNullValue()) {3446 if (TM.getTargetTriple().isOSAIX()) {3447 CS->getContext().emitError(3448 "associated data of XXStructor list is not yet supported on AIX");3449 }3450 3451 S.ComdatKey =3452 dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());3453 }3454 }3455 3456 // Emit the function pointers in the target-specific order3457 llvm::stable_sort(Structors, [](const Structor &L, const Structor &R) {3458 return L.Priority < R.Priority;3459 });3460}3461 3462/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init3463/// priority.3464void AsmPrinter::emitXXStructorList(const DataLayout &DL, const Constant *List,3465 bool IsCtor) {3466 SmallVector<Structor, 8> Structors;3467 preprocessXXStructorList(DL, List, Structors);3468 if (Structors.empty())3469 return;3470 3471 // Emit the structors in reverse order if we are using the .ctor/.dtor3472 // initialization scheme.3473 if (!TM.Options.UseInitArray)3474 std::reverse(Structors.begin(), Structors.end());3475 3476 const Align Align = DL.getPointerPrefAlignment();3477 for (Structor &S : Structors) {3478 const TargetLoweringObjectFile &Obj = getObjFileLowering();3479 const MCSymbol *KeySym = nullptr;3480 if (GlobalValue *GV = S.ComdatKey) {3481 if (GV->isDeclarationForLinker())3482 // If the associated variable is not defined in this module3483 // (it might be available_externally, or have been an3484 // available_externally definition that was dropped by the3485 // EliminateAvailableExternally pass), some other TU3486 // will provide its dynamic initializer.3487 continue;3488 3489 KeySym = getSymbol(GV);3490 }3491 3492 MCSection *OutputSection =3493 (IsCtor ? Obj.getStaticCtorSection(S.Priority, KeySym)3494 : Obj.getStaticDtorSection(S.Priority, KeySym));3495 OutStreamer->switchSection(OutputSection);3496 if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())3497 emitAlignment(Align);3498 emitXXStructor(DL, S.Func);3499 }3500}3501 3502void AsmPrinter::emitModuleIdents(Module &M) {3503 if (!MAI->hasIdentDirective())3504 return;3505 3506 if (const NamedMDNode *NMD = M.getNamedMetadata("llvm.ident")) {3507 for (const MDNode *N : NMD->operands()) {3508 assert(N->getNumOperands() == 1 &&3509 "llvm.ident metadata entry can have only one operand");3510 const MDString *S = cast<MDString>(N->getOperand(0));3511 OutStreamer->emitIdent(S->getString());3512 }3513 }3514}3515 3516void AsmPrinter::emitModuleCommandLines(Module &M) {3517 MCSection *CommandLine = getObjFileLowering().getSectionForCommandLines();3518 if (!CommandLine)3519 return;3520 3521 const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");3522 if (!NMD || !NMD->getNumOperands())3523 return;3524 3525 OutStreamer->pushSection();3526 OutStreamer->switchSection(CommandLine);3527 OutStreamer->emitZeros(1);3528 for (const MDNode *N : NMD->operands()) {3529 assert(N->getNumOperands() == 1 &&3530 "llvm.commandline metadata entry can have only one operand");3531 const MDString *S = cast<MDString>(N->getOperand(0));3532 OutStreamer->emitBytes(S->getString());3533 OutStreamer->emitZeros(1);3534 }3535 OutStreamer->popSection();3536}3537 3538//===--------------------------------------------------------------------===//3539// Emission and print routines3540//3541 3542/// Emit a byte directive and value.3543///3544void AsmPrinter::emitInt8(int Value) const { OutStreamer->emitInt8(Value); }3545 3546/// Emit a short directive and value.3547void AsmPrinter::emitInt16(int Value) const { OutStreamer->emitInt16(Value); }3548 3549/// Emit a long directive and value.3550void AsmPrinter::emitInt32(int Value) const { OutStreamer->emitInt32(Value); }3551 3552/// EmitSLEB128 - emit the specified signed leb128 value.3553void AsmPrinter::emitSLEB128(int64_t Value, const char *Desc) const {3554 if (isVerbose() && Desc)3555 OutStreamer->AddComment(Desc);3556 3557 OutStreamer->emitSLEB128IntValue(Value);3558}3559 3560void AsmPrinter::emitULEB128(uint64_t Value, const char *Desc,3561 unsigned PadTo) const {3562 if (isVerbose() && Desc)3563 OutStreamer->AddComment(Desc);3564 3565 OutStreamer->emitULEB128IntValue(Value, PadTo);3566}3567 3568/// Emit a long long directive and value.3569void AsmPrinter::emitInt64(uint64_t Value) const {3570 OutStreamer->emitInt64(Value);3571}3572 3573/// Emit something like ".long Hi-Lo" where the size in bytes of the directive3574/// is specified by Size and Hi/Lo specify the labels. This implicitly uses3575/// .set if it avoids relocations.3576void AsmPrinter::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,3577 unsigned Size) const {3578 OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size);3579}3580 3581/// Emit something like ".uleb128 Hi-Lo".3582void AsmPrinter::emitLabelDifferenceAsULEB128(const MCSymbol *Hi,3583 const MCSymbol *Lo) const {3584 OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);3585}3586 3587/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"3588/// where the size in bytes of the directive is specified by Size and Label3589/// specifies the label. This implicitly uses .set if it is available.3590void AsmPrinter::emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,3591 unsigned Size,3592 bool IsSectionRelative) const {3593 if (MAI->needsDwarfSectionOffsetDirective() && IsSectionRelative) {3594 OutStreamer->emitCOFFSecRel32(Label, Offset);3595 if (Size > 4)3596 OutStreamer->emitZeros(Size - 4);3597 return;3598 }3599 3600 // Emit Label+Offset (or just Label if Offset is zero)3601 const MCExpr *Expr = MCSymbolRefExpr::create(Label, OutContext);3602 if (Offset)3603 Expr = MCBinaryExpr::createAdd(3604 Expr, MCConstantExpr::create(Offset, OutContext), OutContext);3605 3606 OutStreamer->emitValue(Expr, Size);3607}3608 3609//===----------------------------------------------------------------------===//3610 3611// EmitAlignment - Emit an alignment directive to the specified power of3612// two boundary. If a global value is specified, and if that global has3613// an explicit alignment requested, it will override the alignment request3614// if required for correctness.3615void AsmPrinter::emitAlignment(Align Alignment, const GlobalObject *GV,3616 unsigned MaxBytesToEmit) const {3617 if (GV)3618 Alignment = getGVAlignment(GV, GV->getDataLayout(), Alignment);3619 3620 if (Alignment == Align(1))3621 return; // 1-byte aligned: no need to emit alignment.3622 3623 if (getCurrentSection()->isText()) {3624 const MCSubtargetInfo *STI = nullptr;3625 if (this->MF)3626 STI = &getSubtargetInfo();3627 else3628 STI = TM.getMCSubtargetInfo();3629 OutStreamer->emitCodeAlignment(Alignment, STI, MaxBytesToEmit);3630 } else3631 OutStreamer->emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);3632}3633 3634//===----------------------------------------------------------------------===//3635// Constant emission.3636//===----------------------------------------------------------------------===//3637 3638const MCExpr *AsmPrinter::lowerConstant(const Constant *CV,3639 const Constant *BaseCV,3640 uint64_t Offset) {3641 MCContext &Ctx = OutContext;3642 3643 if (CV->isNullValue() || isa<UndefValue>(CV))3644 return MCConstantExpr::create(0, Ctx);3645 3646 if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))3647 return MCConstantExpr::create(CI->getZExtValue(), Ctx);3648 3649 if (const ConstantPtrAuth *CPA = dyn_cast<ConstantPtrAuth>(CV))3650 return lowerConstantPtrAuth(*CPA);3651 3652 if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))3653 return MCSymbolRefExpr::create(getSymbol(GV), Ctx);3654 3655 if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))3656 return lowerBlockAddressConstant(*BA);3657 3658 if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))3659 return getObjFileLowering().lowerDSOLocalEquivalent(3660 getSymbol(Equiv->getGlobalValue()), nullptr, 0, std::nullopt, TM);3661 3662 if (const NoCFIValue *NC = dyn_cast<NoCFIValue>(CV))3663 return MCSymbolRefExpr::create(getSymbol(NC->getGlobalValue()), Ctx);3664 3665 const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);3666 if (!CE) {3667 llvm_unreachable("Unknown constant value to lower!");3668 }3669 3670 // The constant expression opcodes are limited to those that are necessary3671 // to represent relocations on supported targets. Expressions involving only3672 // constant addresses are constant folded instead.3673 switch (CE->getOpcode()) {3674 default:3675 break; // Error3676 case Instruction::AddrSpaceCast: {3677 const Constant *Op = CE->getOperand(0);3678 unsigned DstAS = CE->getType()->getPointerAddressSpace();3679 unsigned SrcAS = Op->getType()->getPointerAddressSpace();3680 if (TM.isNoopAddrSpaceCast(SrcAS, DstAS))3681 return lowerConstant(Op);3682 3683 break; // Error3684 }3685 case Instruction::GetElementPtr: {3686 // Generate a symbolic expression for the byte address3687 APInt OffsetAI(getDataLayout().getPointerTypeSizeInBits(CE->getType()), 0);3688 cast<GEPOperator>(CE)->accumulateConstantOffset(getDataLayout(), OffsetAI);3689 3690 const MCExpr *Base = lowerConstant(CE->getOperand(0));3691 if (!OffsetAI)3692 return Base;3693 3694 int64_t Offset = OffsetAI.getSExtValue();3695 return MCBinaryExpr::createAdd(Base, MCConstantExpr::create(Offset, Ctx),3696 Ctx);3697 }3698 3699 case Instruction::Trunc:3700 // We emit the value and depend on the assembler to truncate the generated3701 // expression properly. This is important for differences between3702 // blockaddress labels. Since the two labels are in the same function, it3703 // is reasonable to treat their delta as a 32-bit value.3704 [[fallthrough]];3705 case Instruction::BitCast:3706 return lowerConstant(CE->getOperand(0), BaseCV, Offset);3707 3708 case Instruction::IntToPtr: {3709 const DataLayout &DL = getDataLayout();3710 3711 // Handle casts to pointers by changing them into casts to the appropriate3712 // integer type. This promotes constant folding and simplifies this code.3713 Constant *Op = CE->getOperand(0);3714 Op = ConstantFoldIntegerCast(Op, DL.getIntPtrType(CV->getType()),3715 /*IsSigned*/ false, DL);3716 if (Op)3717 return lowerConstant(Op);3718 3719 break; // Error3720 }3721 3722 case Instruction::PtrToAddr:3723 case Instruction::PtrToInt: {3724 const DataLayout &DL = getDataLayout();3725 3726 // Support only foldable casts to/from pointers that can be eliminated by3727 // changing the pointer to the appropriately sized integer type.3728 Constant *Op = CE->getOperand(0);3729 Type *Ty = CE->getType();3730 3731 const MCExpr *OpExpr = lowerConstant(Op);3732 3733 // We can emit the pointer value into this slot if the slot is an3734 // integer slot equal to the size of the pointer.3735 //3736 // If the pointer is larger than the resultant integer, then3737 // as with Trunc just depend on the assembler to truncate it.3738 if (DL.getTypeAllocSize(Ty).getFixedValue() <=3739 DL.getTypeAllocSize(Op->getType()).getFixedValue())3740 return OpExpr;3741 3742 break; // Error3743 }3744 3745 case Instruction::Sub: {3746 GlobalValue *LHSGV, *RHSGV;3747 APInt LHSOffset, RHSOffset;3748 DSOLocalEquivalent *DSOEquiv;3749 if (IsConstantOffsetFromGlobal(CE->getOperand(0), LHSGV, LHSOffset,3750 getDataLayout(), &DSOEquiv) &&3751 IsConstantOffsetFromGlobal(CE->getOperand(1), RHSGV, RHSOffset,3752 getDataLayout())) {3753 auto *LHSSym = getSymbol(LHSGV);3754 auto *RHSSym = getSymbol(RHSGV);3755 int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();3756 std::optional<int64_t> PCRelativeOffset;3757 if (getObjFileLowering().hasPLTPCRelative() && RHSGV == BaseCV)3758 PCRelativeOffset = Offset;3759 3760 // Try the generic symbol difference first.3761 const MCExpr *Res = getObjFileLowering().lowerRelativeReference(3762 LHSGV, RHSGV, Addend, PCRelativeOffset, TM);3763 3764 // (ELF-specific) If the generic symbol difference does not apply, and3765 // LHS is a dso_local_equivalent of a function, reference the PLT entry3766 // instead. Note: A default visibility symbol is by default preemptible3767 // during linking, and should not be referenced with PC-relative3768 // relocations. Therefore, use a PLT relocation even if the function is3769 // dso_local.3770 if (DSOEquiv && TM.getTargetTriple().isOSBinFormatELF())3771 Res = getObjFileLowering().lowerDSOLocalEquivalent(3772 LHSSym, RHSSym, Addend, PCRelativeOffset, TM);3773 3774 // Otherwise, return LHS-RHS+Addend.3775 if (!Res) {3776 Res =3777 MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHSSym, Ctx),3778 MCSymbolRefExpr::create(RHSSym, Ctx), Ctx);3779 if (Addend != 0)3780 Res = MCBinaryExpr::createAdd(3781 Res, MCConstantExpr::create(Addend, Ctx), Ctx);3782 }3783 return Res;3784 }3785 3786 const MCExpr *LHS = lowerConstant(CE->getOperand(0));3787 const MCExpr *RHS = lowerConstant(CE->getOperand(1));3788 return MCBinaryExpr::createSub(LHS, RHS, Ctx);3789 break;3790 }3791 3792 case Instruction::Add: {3793 const MCExpr *LHS = lowerConstant(CE->getOperand(0));3794 const MCExpr *RHS = lowerConstant(CE->getOperand(1));3795 return MCBinaryExpr::createAdd(LHS, RHS, Ctx);3796 }3797 }3798 3799 // If the code isn't optimized, there may be outstanding folding3800 // opportunities. Attempt to fold the expression using DataLayout as a3801 // last resort before giving up.3802 Constant *C = ConstantFoldConstant(CE, getDataLayout());3803 if (C != CE)3804 return lowerConstant(C);3805 3806 // Otherwise report the problem to the user.3807 std::string S;3808 raw_string_ostream OS(S);3809 OS << "unsupported expression in static initializer: ";3810 CE->printAsOperand(OS, /*PrintType=*/false,3811 !MF ? nullptr : MF->getFunction().getParent());3812 CE->getContext().emitError(S);3813 return MCConstantExpr::create(0, Ctx);3814}3815 3816static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *C,3817 AsmPrinter &AP,3818 const Constant *BaseCV = nullptr,3819 uint64_t Offset = 0,3820 AsmPrinter::AliasMapTy *AliasList = nullptr);3821 3822static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP);3823static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP);3824 3825/// isRepeatedByteSequence - Determine whether the given value is3826/// composed of a repeated sequence of identical bytes and return the3827/// byte value. If it is not a repeated sequence, return -1.3828static int isRepeatedByteSequence(const ConstantDataSequential *V) {3829 StringRef Data = V->getRawDataValues();3830 assert(!Data.empty() && "Empty aggregates should be CAZ node");3831 char C = Data[0];3832 for (unsigned i = 1, e = Data.size(); i != e; ++i)3833 if (Data[i] != C) return -1;3834 return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1.3835}3836 3837/// isRepeatedByteSequence - Determine whether the given value is3838/// composed of a repeated sequence of identical bytes and return the3839/// byte value. If it is not a repeated sequence, return -1.3840static int isRepeatedByteSequence(const Value *V, const DataLayout &DL) {3841 if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {3842 uint64_t Size = DL.getTypeAllocSizeInBits(V->getType());3843 assert(Size % 8 == 0);3844 3845 // Extend the element to take zero padding into account.3846 APInt Value = CI->getValue().zext(Size);3847 if (!Value.isSplat(8))3848 return -1;3849 3850 return Value.zextOrTrunc(8).getZExtValue();3851 }3852 if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) {3853 // Make sure all array elements are sequences of the same repeated3854 // byte.3855 assert(CA->getNumOperands() != 0 && "Should be a CAZ");3856 Constant *Op0 = CA->getOperand(0);3857 int Byte = isRepeatedByteSequence(Op0, DL);3858 if (Byte == -1)3859 return -1;3860 3861 // All array elements must be equal.3862 for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i)3863 if (CA->getOperand(i) != Op0)3864 return -1;3865 return Byte;3866 }3867 3868 if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V))3869 return isRepeatedByteSequence(CDS);3870 3871 return -1;3872}3873 3874static void emitGlobalAliasInline(AsmPrinter &AP, uint64_t Offset,3875 AsmPrinter::AliasMapTy *AliasList) {3876 if (AliasList) {3877 auto AliasIt = AliasList->find(Offset);3878 if (AliasIt != AliasList->end()) {3879 for (const GlobalAlias *GA : AliasIt->second)3880 AP.OutStreamer->emitLabel(AP.getSymbol(GA));3881 AliasList->erase(Offset);3882 }3883 }3884}3885 3886static void emitGlobalConstantDataSequential(3887 const DataLayout &DL, const ConstantDataSequential *CDS, AsmPrinter &AP,3888 AsmPrinter::AliasMapTy *AliasList) {3889 // See if we can aggregate this into a .fill, if so, emit it as such.3890 int Value = isRepeatedByteSequence(CDS, DL);3891 if (Value != -1) {3892 uint64_t Bytes = DL.getTypeAllocSize(CDS->getType());3893 // Don't emit a 1-byte object as a .fill.3894 if (Bytes > 1)3895 return AP.OutStreamer->emitFill(Bytes, Value);3896 }3897 3898 // If this can be emitted with .ascii/.asciz, emit it as such.3899 if (CDS->isString())3900 return AP.OutStreamer->emitBytes(CDS->getAsString());3901 3902 // Otherwise, emit the values in successive locations.3903 uint64_t ElementByteSize = CDS->getElementByteSize();3904 if (isa<IntegerType>(CDS->getElementType())) {3905 for (uint64_t I = 0, E = CDS->getNumElements(); I != E; ++I) {3906 emitGlobalAliasInline(AP, ElementByteSize * I, AliasList);3907 if (AP.isVerbose())3908 AP.OutStreamer->getCommentOS()3909 << format("0x%" PRIx64 "\n", CDS->getElementAsInteger(I));3910 AP.OutStreamer->emitIntValue(CDS->getElementAsInteger(I),3911 ElementByteSize);3912 }3913 } else {3914 Type *ET = CDS->getElementType();3915 for (uint64_t I = 0, E = CDS->getNumElements(); I != E; ++I) {3916 emitGlobalAliasInline(AP, ElementByteSize * I, AliasList);3917 emitGlobalConstantFP(CDS->getElementAsAPFloat(I), ET, AP);3918 }3919 }3920 3921 unsigned Size = DL.getTypeAllocSize(CDS->getType());3922 unsigned EmittedSize =3923 DL.getTypeAllocSize(CDS->getElementType()) * CDS->getNumElements();3924 assert(EmittedSize <= Size && "Size cannot be less than EmittedSize!");3925 if (unsigned Padding = Size - EmittedSize)3926 AP.OutStreamer->emitZeros(Padding);3927}3928 3929static void emitGlobalConstantArray(const DataLayout &DL,3930 const ConstantArray *CA, AsmPrinter &AP,3931 const Constant *BaseCV, uint64_t Offset,3932 AsmPrinter::AliasMapTy *AliasList) {3933 // See if we can aggregate some values. Make sure it can be3934 // represented as a series of bytes of the constant value.3935 int Value = isRepeatedByteSequence(CA, DL);3936 3937 if (Value != -1) {3938 uint64_t Bytes = DL.getTypeAllocSize(CA->getType());3939 AP.OutStreamer->emitFill(Bytes, Value);3940 } else {3941 for (unsigned I = 0, E = CA->getNumOperands(); I != E; ++I) {3942 emitGlobalConstantImpl(DL, CA->getOperand(I), AP, BaseCV, Offset,3943 AliasList);3944 Offset += DL.getTypeAllocSize(CA->getOperand(I)->getType());3945 }3946 }3947}3948 3949static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP);3950 3951static void emitGlobalConstantVector(const DataLayout &DL, const Constant *CV,3952 AsmPrinter &AP,3953 AsmPrinter::AliasMapTy *AliasList) {3954 auto *VTy = cast<FixedVectorType>(CV->getType());3955 Type *ElementType = VTy->getElementType();3956 uint64_t ElementSizeInBits = DL.getTypeSizeInBits(ElementType);3957 uint64_t ElementAllocSizeInBits = DL.getTypeAllocSizeInBits(ElementType);3958 uint64_t EmittedSize;3959 if (ElementSizeInBits != ElementAllocSizeInBits) {3960 // If the allocation size of an element is different from the size in bits,3961 // printing each element separately will insert incorrect padding.3962 //3963 // The general algorithm here is complicated; instead of writing it out3964 // here, just use the existing code in ConstantFolding.3965 Type *IntT =3966 IntegerType::get(CV->getContext(), DL.getTypeSizeInBits(CV->getType()));3967 ConstantInt *CI = dyn_cast_or_null<ConstantInt>(ConstantFoldConstant(3968 ConstantExpr::getBitCast(const_cast<Constant *>(CV), IntT), DL));3969 if (!CI) {3970 report_fatal_error(3971 "Cannot lower vector global with unusual element type");3972 }3973 emitGlobalAliasInline(AP, 0, AliasList);3974 emitGlobalConstantLargeInt(CI, AP);3975 EmittedSize = DL.getTypeStoreSize(CV->getType());3976 } else {3977 for (unsigned I = 0, E = VTy->getNumElements(); I != E; ++I) {3978 emitGlobalAliasInline(AP, DL.getTypeAllocSize(CV->getType()) * I, AliasList);3979 emitGlobalConstantImpl(DL, CV->getAggregateElement(I), AP);3980 }3981 EmittedSize = DL.getTypeAllocSize(ElementType) * VTy->getNumElements();3982 }3983 3984 unsigned Size = DL.getTypeAllocSize(CV->getType());3985 if (unsigned Padding = Size - EmittedSize)3986 AP.OutStreamer->emitZeros(Padding);3987}3988 3989static void emitGlobalConstantStruct(const DataLayout &DL,3990 const ConstantStruct *CS, AsmPrinter &AP,3991 const Constant *BaseCV, uint64_t Offset,3992 AsmPrinter::AliasMapTy *AliasList) {3993 // Print the fields in successive locations. Pad to align if needed!3994 uint64_t Size = DL.getTypeAllocSize(CS->getType());3995 const StructLayout *Layout = DL.getStructLayout(CS->getType());3996 uint64_t SizeSoFar = 0;3997 for (unsigned I = 0, E = CS->getNumOperands(); I != E; ++I) {3998 const Constant *Field = CS->getOperand(I);3999 4000 // Print the actual field value.4001 emitGlobalConstantImpl(DL, Field, AP, BaseCV, Offset + SizeSoFar,4002 AliasList);4003 4004 // Check if padding is needed and insert one or more 0s.4005 uint64_t FieldSize = DL.getTypeAllocSize(Field->getType());4006 uint64_t PadSize = ((I == E - 1 ? Size : Layout->getElementOffset(I + 1)) -4007 Layout->getElementOffset(I)) -4008 FieldSize;4009 SizeSoFar += FieldSize + PadSize;4010 4011 // Insert padding - this may include padding to increase the size of the4012 // current field up to the ABI size (if the struct is not packed) as well4013 // as padding to ensure that the next field starts at the right offset.4014 AP.OutStreamer->emitZeros(PadSize);4015 }4016 assert(SizeSoFar == Layout->getSizeInBytes() &&4017 "Layout of constant struct may be incorrect!");4018}4019 4020static void emitGlobalConstantFP(APFloat APF, Type *ET, AsmPrinter &AP) {4021 assert(ET && "Unknown float type");4022 APInt API = APF.bitcastToAPInt();4023 4024 // First print a comment with what we think the original floating-point value4025 // should have been.4026 if (AP.isVerbose()) {4027 SmallString<8> StrVal;4028 APF.toString(StrVal);4029 ET->print(AP.OutStreamer->getCommentOS());4030 AP.OutStreamer->getCommentOS() << ' ' << StrVal << '\n';4031 }4032 4033 // Now iterate through the APInt chunks, emitting them in endian-correct4034 // order, possibly with a smaller chunk at beginning/end (e.g. for x87 80-bit4035 // floats).4036 unsigned NumBytes = API.getBitWidth() / 8;4037 unsigned TrailingBytes = NumBytes % sizeof(uint64_t);4038 const uint64_t *p = API.getRawData();4039 4040 // PPC's long double has odd notions of endianness compared to how LLVM4041 // handles it: p[0] goes first for *big* endian on PPC.4042 if (AP.getDataLayout().isBigEndian() && !ET->isPPC_FP128Ty()) {4043 int Chunk = API.getNumWords() - 1;4044 4045 if (TrailingBytes)4046 AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk--], TrailingBytes);4047 4048 for (; Chunk >= 0; --Chunk)4049 AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t));4050 } else {4051 unsigned Chunk;4052 for (Chunk = 0; Chunk < NumBytes / sizeof(uint64_t); ++Chunk)4053 AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], sizeof(uint64_t));4054 4055 if (TrailingBytes)4056 AP.OutStreamer->emitIntValueInHexWithPadding(p[Chunk], TrailingBytes);4057 }4058 4059 // Emit the tail padding for the long double.4060 const DataLayout &DL = AP.getDataLayout();4061 AP.OutStreamer->emitZeros(DL.getTypeAllocSize(ET) - DL.getTypeStoreSize(ET));4062}4063 4064static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP) {4065 emitGlobalConstantFP(CFP->getValueAPF(), CFP->getType(), AP);4066}4067 4068static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP) {4069 const DataLayout &DL = AP.getDataLayout();4070 unsigned BitWidth = CI->getBitWidth();4071 4072 // Copy the value as we may massage the layout for constants whose bit width4073 // is not a multiple of 64-bits.4074 APInt Realigned(CI->getValue());4075 uint64_t ExtraBits = 0;4076 unsigned ExtraBitsSize = BitWidth & 63;4077 4078 if (ExtraBitsSize) {4079 // The bit width of the data is not a multiple of 64-bits.4080 // The extra bits are expected to be at the end of the chunk of the memory.4081 // Little endian:4082 // * Nothing to be done, just record the extra bits to emit.4083 // Big endian:4084 // * Record the extra bits to emit.4085 // * Realign the raw data to emit the chunks of 64-bits.4086 if (DL.isBigEndian()) {4087 // Basically the structure of the raw data is a chunk of 64-bits cells:4088 // 0 1 BitWidth / 644089 // [chunk1][chunk2] ... [chunkN].4090 // The most significant chunk is chunkN and it should be emitted first.4091 // However, due to the alignment issue chunkN contains useless bits.4092 // Realign the chunks so that they contain only useful information:4093 // ExtraBits 0 1 (BitWidth / 64) - 14094 // chu[nk1 chu][nk2 chu] ... [nkN-1 chunkN]4095 ExtraBitsSize = alignTo(ExtraBitsSize, 8);4096 ExtraBits = Realigned.getRawData()[0] &4097 (((uint64_t)-1) >> (64 - ExtraBitsSize));4098 if (BitWidth >= 64)4099 Realigned.lshrInPlace(ExtraBitsSize);4100 } else4101 ExtraBits = Realigned.getRawData()[BitWidth / 64];4102 }4103 4104 // We don't expect assemblers to support integer data directives4105 // for more than 64 bits, so we emit the data in at most 64-bit4106 // quantities at a time.4107 const uint64_t *RawData = Realigned.getRawData();4108 for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {4109 uint64_t Val = DL.isBigEndian() ? RawData[e - i - 1] : RawData[i];4110 AP.OutStreamer->emitIntValue(Val, 8);4111 }4112 4113 if (ExtraBitsSize) {4114 // Emit the extra bits after the 64-bits chunks.4115 4116 // Emit a directive that fills the expected size.4117 uint64_t Size = AP.getDataLayout().getTypeStoreSize(CI->getType());4118 Size -= (BitWidth / 64) * 8;4119 assert(Size && Size * 8 >= ExtraBitsSize &&4120 (ExtraBits & (((uint64_t)-1) >> (64 - ExtraBitsSize)))4121 == ExtraBits && "Directive too small for extra bits.");4122 AP.OutStreamer->emitIntValue(ExtraBits, Size);4123 }4124}4125 4126/// Transform a not absolute MCExpr containing a reference to a GOT4127/// equivalent global, by a target specific GOT pc relative access to the4128/// final symbol.4129static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,4130 const Constant *BaseCst,4131 uint64_t Offset) {4132 // The global @foo below illustrates a global that uses a got equivalent.4133 //4134 // @bar = global i32 424135 // @gotequiv = private unnamed_addr constant i32* @bar4136 // @foo = i32 trunc (i64 sub (i64 ptrtoint (i32** @gotequiv to i64),4137 // i64 ptrtoint (i32* @foo to i64))4138 // to i32)4139 //4140 // The cstexpr in @foo is converted into the MCExpr `ME`, where we actually4141 // check whether @foo is suitable to use a GOTPCREL. `ME` is usually in the4142 // form:4143 //4144 // foo = cstexpr, where4145 // cstexpr := <gotequiv> - "." + <cst>4146 // cstexpr := <gotequiv> - (<foo> - <offset from @foo base>) + <cst>4147 //4148 // After canonicalization by evaluateAsRelocatable `ME` turns into:4149 //4150 // cstexpr := <gotequiv> - <foo> + gotpcrelcst, where4151 // gotpcrelcst := <offset from @foo base> + <cst>4152 MCValue MV;4153 if (!(*ME)->evaluateAsRelocatable(MV, nullptr) || MV.isAbsolute())4154 return;4155 const MCSymbol *GOTEquivSym = MV.getAddSym();4156 if (!GOTEquivSym)4157 return;4158 4159 // Check that GOT equivalent symbol is cached.4160 if (!AP.GlobalGOTEquivs.count(GOTEquivSym))4161 return;4162 4163 const GlobalValue *BaseGV = dyn_cast_or_null<GlobalValue>(BaseCst);4164 if (!BaseGV)4165 return;4166 4167 // Check for a valid base symbol4168 const MCSymbol *BaseSym = AP.getSymbol(BaseGV);4169 const MCSymbol *SymB = MV.getSubSym();4170 4171 if (!SymB || BaseSym != SymB)4172 return;4173 4174 // Make sure to match:4175 //4176 // gotpcrelcst := <offset from @foo base> + <cst>4177 //4178 int64_t GOTPCRelCst = Offset + MV.getConstant();4179 if (!AP.getObjFileLowering().supportGOTPCRelWithOffset() && GOTPCRelCst != 0)4180 return;4181 4182 // Emit the GOT PC relative to replace the got equivalent global, i.e.:4183 //4184 // bar:4185 // .long 424186 // gotequiv:4187 // .quad bar4188 // foo:4189 // .long gotequiv - "." + <cst>4190 //4191 // is replaced by the target specific equivalent to:4192 //4193 // bar:4194 // .long 424195 // foo:4196 // .long bar@GOTPCREL+<gotpcrelcst>4197 AsmPrinter::GOTEquivUsePair Result = AP.GlobalGOTEquivs[GOTEquivSym];4198 const GlobalVariable *GV = Result.first;4199 int NumUses = (int)Result.second;4200 const GlobalValue *FinalGV = dyn_cast<GlobalValue>(GV->getOperand(0));4201 const MCSymbol *FinalSym = AP.getSymbol(FinalGV);4202 *ME = AP.getObjFileLowering().getIndirectSymViaGOTPCRel(4203 FinalGV, FinalSym, MV, Offset, AP.MMI, *AP.OutStreamer);4204 4205 // Update GOT equivalent usage information4206 --NumUses;4207 if (NumUses >= 0)4208 AP.GlobalGOTEquivs[GOTEquivSym] = std::make_pair(GV, NumUses);4209}4210 4211static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *CV,4212 AsmPrinter &AP, const Constant *BaseCV,4213 uint64_t Offset,4214 AsmPrinter::AliasMapTy *AliasList) {4215 assert((!AliasList || AP.TM.getTargetTriple().isOSBinFormatXCOFF()) &&4216 "AliasList only expected for XCOFF");4217 emitGlobalAliasInline(AP, Offset, AliasList);4218 uint64_t Size = DL.getTypeAllocSize(CV->getType());4219 4220 // Globals with sub-elements such as combinations of arrays and structs4221 // are handled recursively by emitGlobalConstantImpl. Keep track of the4222 // constant symbol base and the current position with BaseCV and Offset.4223 if (!BaseCV && CV->hasOneUse())4224 BaseCV = dyn_cast<Constant>(CV->user_back());4225 4226 if (isa<ConstantAggregateZero>(CV)) {4227 StructType *structType;4228 if (AliasList && (structType = llvm::dyn_cast<StructType>(CV->getType()))) {4229 unsigned numElements = {structType->getNumElements()};4230 if (numElements != 0) {4231 // Handle cases of aliases to direct struct elements4232 const StructLayout *Layout = DL.getStructLayout(structType);4233 uint64_t SizeSoFar = 0;4234 for (unsigned int i = 0; i < numElements - 1; ++i) {4235 uint64_t GapToNext = Layout->getElementOffset(i + 1) - SizeSoFar;4236 AP.OutStreamer->emitZeros(GapToNext);4237 SizeSoFar += GapToNext;4238 emitGlobalAliasInline(AP, Offset + SizeSoFar, AliasList);4239 }4240 AP.OutStreamer->emitZeros(Size - SizeSoFar);4241 return;4242 }4243 }4244 return AP.OutStreamer->emitZeros(Size);4245 }4246 4247 if (isa<UndefValue>(CV))4248 return AP.OutStreamer->emitZeros(Size);4249 4250 if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {4251 if (isa<VectorType>(CV->getType()))4252 return emitGlobalConstantVector(DL, CV, AP, AliasList);4253 4254 const uint64_t StoreSize = DL.getTypeStoreSize(CV->getType());4255 if (StoreSize <= 8) {4256 if (AP.isVerbose())4257 AP.OutStreamer->getCommentOS()4258 << format("0x%" PRIx64 "\n", CI->getZExtValue());4259 AP.OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize);4260 } else {4261 emitGlobalConstantLargeInt(CI, AP);4262 }4263 4264 // Emit tail padding if needed4265 if (Size != StoreSize)4266 AP.OutStreamer->emitZeros(Size - StoreSize);4267 4268 return;4269 }4270 4271 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {4272 if (isa<VectorType>(CV->getType()))4273 return emitGlobalConstantVector(DL, CV, AP, AliasList);4274 else4275 return emitGlobalConstantFP(CFP, AP);4276 }4277 4278 if (isa<ConstantPointerNull>(CV)) {4279 AP.OutStreamer->emitIntValue(0, Size);4280 return;4281 }4282 4283 if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV))4284 return emitGlobalConstantDataSequential(DL, CDS, AP, AliasList);4285 4286 if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))4287 return emitGlobalConstantArray(DL, CVA, AP, BaseCV, Offset, AliasList);4288 4289 if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))4290 return emitGlobalConstantStruct(DL, CVS, AP, BaseCV, Offset, AliasList);4291 4292 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {4293 // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of4294 // vectors).4295 if (CE->getOpcode() == Instruction::BitCast)4296 return emitGlobalConstantImpl(DL, CE->getOperand(0), AP);4297 4298 if (Size > 8) {4299 // If the constant expression's size is greater than 64-bits, then we have4300 // to emit the value in chunks. Try to constant fold the value and emit it4301 // that way.4302 Constant *New = ConstantFoldConstant(CE, DL);4303 if (New != CE)4304 return emitGlobalConstantImpl(DL, New, AP);4305 }4306 }4307 4308 if (isa<ConstantVector>(CV))4309 return emitGlobalConstantVector(DL, CV, AP, AliasList);4310 4311 // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it4312 // thread the streamer with EmitValue.4313 const MCExpr *ME = AP.lowerConstant(CV, BaseCV, Offset);4314 4315 // Since lowerConstant already folded and got rid of all IR pointer and4316 // integer casts, detect GOT equivalent accesses by looking into the MCExpr4317 // directly.4318 if (AP.getObjFileLowering().supportIndirectSymViaGOTPCRel())4319 handleIndirectSymViaGOTPCRel(AP, &ME, BaseCV, Offset);4320 4321 AP.OutStreamer->emitValue(ME, Size);4322}4323 4324/// EmitGlobalConstant - Print a general LLVM constant to the .s file.4325void AsmPrinter::emitGlobalConstant(const DataLayout &DL, const Constant *CV,4326 AliasMapTy *AliasList) {4327 uint64_t Size = DL.getTypeAllocSize(CV->getType());4328 if (Size)4329 emitGlobalConstantImpl(DL, CV, *this, nullptr, 0, AliasList);4330 else if (MAI->hasSubsectionsViaSymbols()) {4331 // If the global has zero size, emit a single byte so that two labels don't4332 // look like they are at the same location.4333 OutStreamer->emitIntValue(0, 1);4334 }4335 if (!AliasList)4336 return;4337 // TODO: These remaining aliases are not emitted in the correct location. Need4338 // to handle the case where the alias offset doesn't refer to any sub-element.4339 for (auto &AliasPair : *AliasList) {4340 for (const GlobalAlias *GA : AliasPair.second)4341 OutStreamer->emitLabel(getSymbol(GA));4342 }4343}4344 4345void AsmPrinter::emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {4346 // Target doesn't support this yet!4347 llvm_unreachable("Target does not support EmitMachineConstantPoolValue");4348}4349 4350void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const {4351 if (Offset > 0)4352 OS << '+' << Offset;4353 else if (Offset < 0)4354 OS << Offset;4355}4356 4357void AsmPrinter::emitNops(unsigned N) {4358 MCInst Nop = MF->getSubtarget().getInstrInfo()->getNop();4359 for (; N; --N)4360 EmitToStreamer(*OutStreamer, Nop);4361}4362 4363//===----------------------------------------------------------------------===//4364// Symbol Lowering Routines.4365//===----------------------------------------------------------------------===//4366 4367MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name) const {4368 return OutContext.createTempSymbol(Name, true);4369}4370 4371MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {4372 return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(4373 BA->getBasicBlock());4374}4375 4376MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {4377 return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB);4378}4379 4380const MCExpr *AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {4381 return MCSymbolRefExpr::create(GetBlockAddressSymbol(&BA), OutContext);4382}4383 4384/// GetCPISymbol - Return the symbol for the specified constant pool entry.4385MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {4386 if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment() ||4387 getSubtargetInfo().getTargetTriple().isUEFI()) {4388 const MachineConstantPoolEntry &CPE =4389 MF->getConstantPool()->getConstants()[CPID];4390 if (!CPE.isMachineConstantPoolEntry()) {4391 const DataLayout &DL = MF->getDataLayout();4392 SectionKind Kind = CPE.getSectionKind(&DL);4393 const Constant *C = CPE.Val.ConstVal;4394 Align Alignment = CPE.Alignment;4395 auto *S =4396 getObjFileLowering().getSectionForConstant(DL, Kind, C, Alignment);4397 if (S && TM.getTargetTriple().isOSBinFormatCOFF()) {4398 if (MCSymbol *Sym =4399 static_cast<const MCSectionCOFF *>(S)->getCOMDATSymbol()) {4400 if (Sym->isUndefined())4401 OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);4402 return Sym;4403 }4404 }4405 }4406 }4407 4408 const DataLayout &DL = getDataLayout();4409 return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +4410 "CPI" + Twine(getFunctionNumber()) + "_" +4411 Twine(CPID));4412}4413 4414/// GetJTISymbol - Return the symbol for the specified jump table entry.4415MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {4416 return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate);4417}4418 4419/// GetJTSetSymbol - Return the symbol for the specified jump table .set4420/// FIXME: privatize to AsmPrinter.4421MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const {4422 const DataLayout &DL = getDataLayout();4423 return OutContext.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +4424 Twine(getFunctionNumber()) + "_" +4425 Twine(UID) + "_set_" + Twine(MBBID));4426}4427 4428MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,4429 StringRef Suffix) const {4430 return getObjFileLowering().getSymbolWithGlobalValueBase(GV, Suffix, TM);4431}4432 4433/// Return the MCSymbol for the specified ExternalSymbol.4434MCSymbol *AsmPrinter::GetExternalSymbolSymbol(const Twine &Sym) const {4435 SmallString<60> NameStr;4436 Mangler::getNameWithPrefix(NameStr, Sym, getDataLayout());4437 return OutContext.getOrCreateSymbol(NameStr);4438}4439 4440/// PrintParentLoopComment - Print comments about parent loops of this one.4441static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,4442 unsigned FunctionNumber) {4443 if (!Loop) return;4444 PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber);4445 OS.indent(Loop->getLoopDepth()*2)4446 << "Parent Loop BB" << FunctionNumber << "_"4447 << Loop->getHeader()->getNumber()4448 << " Depth=" << Loop->getLoopDepth() << '\n';4449}4450 4451/// PrintChildLoopComment - Print comments about child loops within4452/// the loop for this basic block, with nesting.4453static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,4454 unsigned FunctionNumber) {4455 // Add child loop information4456 for (const MachineLoop *CL : *Loop) {4457 OS.indent(CL->getLoopDepth()*2)4458 << "Child Loop BB" << FunctionNumber << "_"4459 << CL->getHeader()->getNumber() << " Depth " << CL->getLoopDepth()4460 << '\n';4461 PrintChildLoopComment(OS, CL, FunctionNumber);4462 }4463}4464 4465/// emitBasicBlockLoopComments - Pretty-print comments for basic blocks.4466static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,4467 const MachineLoopInfo *LI,4468 const AsmPrinter &AP) {4469 // Add loop depth information4470 const MachineLoop *Loop = LI->getLoopFor(&MBB);4471 if (!Loop) return;4472 4473 MachineBasicBlock *Header = Loop->getHeader();4474 assert(Header && "No header for loop");4475 4476 // If this block is not a loop header, just print out what is the loop header4477 // and return.4478 if (Header != &MBB) {4479 AP.OutStreamer->AddComment(" in Loop: Header=BB" +4480 Twine(AP.getFunctionNumber())+"_" +4481 Twine(Loop->getHeader()->getNumber())+4482 " Depth="+Twine(Loop->getLoopDepth()));4483 return;4484 }4485 4486 // Otherwise, it is a loop header. Print out information about child and4487 // parent loops.4488 raw_ostream &OS = AP.OutStreamer->getCommentOS();4489 4490 PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());4491 4492 OS << "=>";4493 OS.indent(Loop->getLoopDepth()*2-2);4494 4495 OS << "This ";4496 if (Loop->isInnermost())4497 OS << "Inner ";4498 OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';4499 4500 PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());4501}4502 4503/// emitBasicBlockStart - This method prints the label for the specified4504/// MachineBasicBlock, an alignment (if present) and a comment describing4505/// it if appropriate.4506void AsmPrinter::emitBasicBlockStart(const MachineBasicBlock &MBB) {4507 // End the previous funclet and start a new one.4508 if (MBB.isEHFuncletEntry()) {4509 for (auto &Handler : Handlers) {4510 Handler->endFunclet();4511 Handler->beginFunclet(MBB);4512 }4513 for (auto &Handler : EHHandlers) {4514 Handler->endFunclet();4515 Handler->beginFunclet(MBB);4516 }4517 }4518 4519 // Switch to a new section if this basic block must begin a section. The4520 // entry block is always placed in the function section and is handled4521 // separately.4522 if (MBB.isBeginSection() && !MBB.isEntryBlock()) {4523 OutStreamer->switchSection(4524 getObjFileLowering().getSectionForMachineBasicBlock(MF->getFunction(),4525 MBB, TM));4526 CurrentSectionBeginSym = MBB.getSymbol();4527 }4528 4529 for (auto &Handler : Handlers)4530 Handler->beginCodeAlignment(MBB);4531 4532 // Emit an alignment directive for this block, if needed.4533 const Align Alignment = MBB.getAlignment();4534 if (Alignment != Align(1))4535 emitAlignment(Alignment, nullptr, MBB.getMaxBytesForAlignment());4536 4537 // If the block has its address taken, emit any labels that were used to4538 // reference the block. It is possible that there is more than one label4539 // here, because multiple LLVM BB's may have been RAUW'd to this block after4540 // the references were generated.4541 if (MBB.isIRBlockAddressTaken()) {4542 if (isVerbose())4543 OutStreamer->AddComment("Block address taken");4544 4545 BasicBlock *BB = MBB.getAddressTakenIRBlock();4546 assert(BB && BB->hasAddressTaken() && "Missing BB");4547 for (MCSymbol *Sym : getAddrLabelSymbolToEmit(BB))4548 OutStreamer->emitLabel(Sym);4549 } else if (isVerbose() && MBB.isMachineBlockAddressTaken()) {4550 OutStreamer->AddComment("Block address taken");4551 } else if (isVerbose() && MBB.isInlineAsmBrIndirectTarget()) {4552 OutStreamer->AddComment("Inline asm indirect target");4553 }4554 4555 // Print some verbose block comments.4556 if (isVerbose()) {4557 if (const BasicBlock *BB = MBB.getBasicBlock()) {4558 if (BB->hasName()) {4559 BB->printAsOperand(OutStreamer->getCommentOS(),4560 /*PrintType=*/false, BB->getModule());4561 OutStreamer->getCommentOS() << '\n';4562 }4563 }4564 4565 assert(MLI != nullptr && "MachineLoopInfo should has been computed");4566 emitBasicBlockLoopComments(MBB, MLI, *this);4567 }4568 4569 // Print the main label for the block.4570 if (shouldEmitLabelForBasicBlock(MBB)) {4571 if (isVerbose() && MBB.hasLabelMustBeEmitted())4572 OutStreamer->AddComment("Label of block must be emitted");4573 OutStreamer->emitLabel(MBB.getSymbol());4574 } else {4575 if (isVerbose()) {4576 // NOTE: Want this comment at start of line, don't emit with AddComment.4577 OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",4578 false);4579 }4580 }4581 4582 if (MBB.isEHContTarget() &&4583 MAI->getExceptionHandlingType() == ExceptionHandling::WinEH) {4584 OutStreamer->emitLabel(MBB.getEHContSymbol());4585 }4586 4587 // With BB sections, each basic block must handle CFI information on its own4588 // if it begins a section (Entry block call is handled separately, next to4589 // beginFunction).4590 if (MBB.isBeginSection() && !MBB.isEntryBlock()) {4591 for (auto &Handler : Handlers)4592 Handler->beginBasicBlockSection(MBB);4593 for (auto &Handler : EHHandlers)4594 Handler->beginBasicBlockSection(MBB);4595 }4596}4597 4598void AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {4599 // Check if CFI information needs to be updated for this MBB with basic block4600 // sections.4601 if (MBB.isEndSection()) {4602 for (auto &Handler : Handlers)4603 Handler->endBasicBlockSection(MBB);4604 for (auto &Handler : EHHandlers)4605 Handler->endBasicBlockSection(MBB);4606 }4607}4608 4609void AsmPrinter::emitVisibility(MCSymbol *Sym, unsigned Visibility,4610 bool IsDefinition) const {4611 MCSymbolAttr Attr = MCSA_Invalid;4612 4613 switch (Visibility) {4614 default: break;4615 case GlobalValue::HiddenVisibility:4616 if (IsDefinition)4617 Attr = MAI->getHiddenVisibilityAttr();4618 else4619 Attr = MAI->getHiddenDeclarationVisibilityAttr();4620 break;4621 case GlobalValue::ProtectedVisibility:4622 Attr = MAI->getProtectedVisibilityAttr();4623 break;4624 }4625 4626 if (Attr != MCSA_Invalid)4627 OutStreamer->emitSymbolAttribute(Sym, Attr);4628}4629 4630bool AsmPrinter::shouldEmitLabelForBasicBlock(4631 const MachineBasicBlock &MBB) const {4632 // With `-fbasic-block-sections=`, a label is needed for every non-entry block4633 // in the labels mode (option `=labels`) and every section beginning in the4634 // sections mode (`=all` and `=list=`).4635 if ((MF->getTarget().Options.BBAddrMap || MBB.isBeginSection()) &&4636 !MBB.isEntryBlock())4637 return true;4638 // A label is needed for any block with at least one predecessor (when that4639 // predecessor is not the fallthrough predecessor, or if it is an EH funclet4640 // entry, or if a label is forced).4641 return !MBB.pred_empty() &&4642 (!isBlockOnlyReachableByFallthrough(&MBB) || MBB.isEHFuncletEntry() ||4643 MBB.hasLabelMustBeEmitted());4644}4645 4646/// isBlockOnlyReachableByFallthough - Return true if the basic block has4647/// exactly one predecessor and the control transfer mechanism between4648/// the predecessor and this block is a fall-through.4649bool AsmPrinter::4650isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {4651 // If this is a landing pad, it isn't a fall through. If it has no preds,4652 // then nothing falls through to it.4653 if (MBB->isEHPad() || MBB->pred_empty())4654 return false;4655 4656 // If there isn't exactly one predecessor, it can't be a fall through.4657 if (MBB->pred_size() > 1)4658 return false;4659 4660 // The predecessor has to be immediately before this block.4661 MachineBasicBlock *Pred = *MBB->pred_begin();4662 if (!Pred->isLayoutSuccessor(MBB))4663 return false;4664 4665 // If the block is completely empty, then it definitely does fall through.4666 if (Pred->empty())4667 return true;4668 4669 // Check the terminators in the previous blocks4670 for (const auto &MI : Pred->terminators()) {4671 // If it is not a simple branch, we are in a table somewhere.4672 if (!MI.isBranch() || MI.isIndirectBranch())4673 return false;4674 4675 // If we are the operands of one of the branches, this is not a fall4676 // through. Note that targets with delay slots will usually bundle4677 // terminators with the delay slot instruction.4678 for (ConstMIBundleOperands OP(MI); OP.isValid(); ++OP) {4679 if (OP->isJTI())4680 return false;4681 if (OP->isMBB() && OP->getMBB() == MBB)4682 return false;4683 }4684 }4685 4686 return true;4687}4688 4689GCMetadataPrinter *AsmPrinter::getOrCreateGCPrinter(GCStrategy &S) {4690 if (!S.usesMetadata())4691 return nullptr;4692 4693 auto [GCPI, Inserted] = GCMetadataPrinters.try_emplace(&S);4694 if (!Inserted)4695 return GCPI->second.get();4696 4697 auto Name = S.getName();4698 4699 for (const GCMetadataPrinterRegistry::entry &GCMetaPrinter :4700 GCMetadataPrinterRegistry::entries())4701 if (Name == GCMetaPrinter.getName()) {4702 std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate();4703 GMP->S = &S;4704 GCPI->second = std::move(GMP);4705 return GCPI->second.get();4706 }4707 4708 report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));4709}4710 4711void AsmPrinter::emitStackMaps() {4712 GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();4713 assert(MI && "AsmPrinter didn't require GCModuleInfo?");4714 bool NeedsDefault = false;4715 if (MI->begin() == MI->end())4716 // No GC strategy, use the default format.4717 NeedsDefault = true;4718 else4719 for (const auto &I : *MI) {4720 if (GCMetadataPrinter *MP = getOrCreateGCPrinter(*I))4721 if (MP->emitStackMaps(SM, *this))4722 continue;4723 // The strategy doesn't have printer or doesn't emit custom stack maps.4724 // Use the default format.4725 NeedsDefault = true;4726 }4727 4728 if (NeedsDefault)4729 SM.serializeToStackMapSection();4730}4731 4732void AsmPrinter::addAsmPrinterHandler(4733 std::unique_ptr<AsmPrinterHandler> Handler) {4734 Handlers.insert(Handlers.begin(), std::move(Handler));4735 NumUserHandlers++;4736}4737 4738/// Pin vtables to this file.4739AsmPrinterHandler::~AsmPrinterHandler() = default;4740 4741void AsmPrinterHandler::markFunctionEnd() {}4742 4743// In the binary's "xray_instr_map" section, an array of these function entries4744// describes each instrumentation point. When XRay patches your code, the index4745// into this table will be given to your handler as a patch point identifier.4746void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out) const {4747 auto Kind8 = static_cast<uint8_t>(Kind);4748 Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));4749 Out->emitBinaryData(4750 StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1));4751 Out->emitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1));4752 auto Padding = (4 * Bytes) - ((2 * Bytes) + 3);4753 assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size");4754 Out->emitZeros(Padding);4755}4756 4757void AsmPrinter::emitXRayTable() {4758 if (Sleds.empty())4759 return;4760 4761 auto PrevSection = OutStreamer->getCurrentSectionOnly();4762 const Function &F = MF->getFunction();4763 MCSection *InstMap = nullptr;4764 MCSection *FnSledIndex = nullptr;4765 const Triple &TT = TM.getTargetTriple();4766 // Use PC-relative addresses on all targets.4767 if (TT.isOSBinFormatELF()) {4768 auto LinkedToSym = static_cast<const MCSymbolELF *>(CurrentFnSym);4769 auto Flags = ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;4770 StringRef GroupName;4771 if (F.hasComdat()) {4772 Flags |= ELF::SHF_GROUP;4773 GroupName = F.getComdat()->getName();4774 }4775 InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,4776 Flags, 0, GroupName, F.hasComdat(),4777 MCSection::NonUniqueID, LinkedToSym);4778 4779 if (TM.Options.XRayFunctionIndex)4780 FnSledIndex = OutContext.getELFSection(4781 "xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0, GroupName, F.hasComdat(),4782 MCSection::NonUniqueID, LinkedToSym);4783 } else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {4784 InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map",4785 MachO::S_ATTR_LIVE_SUPPORT,4786 SectionKind::getReadOnlyWithRel());4787 if (TM.Options.XRayFunctionIndex)4788 FnSledIndex = OutContext.getMachOSection("__DATA", "xray_fn_idx",4789 MachO::S_ATTR_LIVE_SUPPORT,4790 SectionKind::getReadOnly());4791 } else {4792 llvm_unreachable("Unsupported target");4793 }4794 4795 auto WordSizeBytes = MAI->getCodePointerSize();4796 4797 // Now we switch to the instrumentation map section. Because this is done4798 // per-function, we are able to create an index entry that will represent the4799 // range of sleds associated with a function.4800 auto &Ctx = OutContext;4801 MCSymbol *SledsStart =4802 OutContext.createLinkerPrivateSymbol("xray_sleds_start");4803 OutStreamer->switchSection(InstMap);4804 OutStreamer->emitLabel(SledsStart);4805 for (const auto &Sled : Sleds) {4806 MCSymbol *Dot = Ctx.createTempSymbol();4807 OutStreamer->emitLabel(Dot);4808 OutStreamer->emitValueImpl(4809 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Sled.Sled, Ctx),4810 MCSymbolRefExpr::create(Dot, Ctx), Ctx),4811 WordSizeBytes);4812 OutStreamer->emitValueImpl(4813 MCBinaryExpr::createSub(4814 MCSymbolRefExpr::create(CurrentFnBegin, Ctx),4815 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Dot, Ctx),4816 MCConstantExpr::create(WordSizeBytes, Ctx),4817 Ctx),4818 Ctx),4819 WordSizeBytes);4820 Sled.emit(WordSizeBytes, OutStreamer.get());4821 }4822 MCSymbol *SledsEnd = OutContext.createTempSymbol("xray_sleds_end", true);4823 OutStreamer->emitLabel(SledsEnd);4824 4825 // We then emit a single entry in the index per function. We use the symbols4826 // that bound the instrumentation map as the range for a specific function.4827 // Each entry contains 2 words and needs to be word-aligned.4828 if (FnSledIndex) {4829 OutStreamer->switchSection(FnSledIndex);4830 OutStreamer->emitValueToAlignment(Align(WordSizeBytes));4831 // For Mach-O, use an "l" symbol as the atom of this subsection. The label4832 // difference uses a SUBTRACTOR external relocation which references the4833 // symbol.4834 MCSymbol *Dot = Ctx.createLinkerPrivateSymbol("xray_fn_idx");4835 OutStreamer->emitLabel(Dot);4836 OutStreamer->emitValueImpl(4837 MCBinaryExpr::createSub(MCSymbolRefExpr::create(SledsStart, Ctx),4838 MCSymbolRefExpr::create(Dot, Ctx), Ctx),4839 WordSizeBytes);4840 OutStreamer->emitValueImpl(MCConstantExpr::create(Sleds.size(), Ctx),4841 WordSizeBytes);4842 OutStreamer->switchSection(PrevSection);4843 }4844 Sleds.clear();4845}4846 4847void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI,4848 SledKind Kind, uint8_t Version) {4849 const Function &F = MI.getMF()->getFunction();4850 auto Attr = F.getFnAttribute("function-instrument");4851 bool LogArgs = F.hasFnAttribute("xray-log-args");4852 bool AlwaysInstrument =4853 Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always";4854 if (Kind == SledKind::FUNCTION_ENTER && LogArgs)4855 Kind = SledKind::LOG_ARGS_ENTER;4856 Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind,4857 AlwaysInstrument, &F, Version});4858}4859 4860void AsmPrinter::emitPatchableFunctionEntries() {4861 const Function &F = MF->getFunction();4862 unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0;4863 (void)F.getFnAttribute("patchable-function-prefix")4864 .getValueAsString()4865 .getAsInteger(10, PatchableFunctionPrefix);4866 (void)F.getFnAttribute("patchable-function-entry")4867 .getValueAsString()4868 .getAsInteger(10, PatchableFunctionEntry);4869 if (!PatchableFunctionPrefix && !PatchableFunctionEntry)4870 return;4871 const unsigned PointerSize = getPointerSize();4872 if (TM.getTargetTriple().isOSBinFormatELF()) {4873 auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC;4874 const MCSymbolELF *LinkedToSym = nullptr;4875 StringRef GroupName, SectionName;4876 4877 if (F.hasFnAttribute("patchable-function-entry-section"))4878 SectionName = F.getFnAttribute("patchable-function-entry-section")4879 .getValueAsString();4880 if (SectionName.empty())4881 SectionName = "__patchable_function_entries";4882 4883 // GNU as < 2.35 did not support section flag 'o'. GNU ld < 2.36 did not4884 // support mixed SHF_LINK_ORDER and non-SHF_LINK_ORDER sections.4885 if (MAI->useIntegratedAssembler() || MAI->binutilsIsAtLeast(2, 36)) {4886 Flags |= ELF::SHF_LINK_ORDER;4887 if (F.hasComdat()) {4888 Flags |= ELF::SHF_GROUP;4889 GroupName = F.getComdat()->getName();4890 }4891 LinkedToSym = static_cast<const MCSymbolELF *>(CurrentFnSym);4892 }4893 OutStreamer->switchSection(OutContext.getELFSection(4894 SectionName, ELF::SHT_PROGBITS, Flags, 0, GroupName, F.hasComdat(),4895 MCSection::NonUniqueID, LinkedToSym));4896 emitAlignment(Align(PointerSize));4897 OutStreamer->emitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize);4898 }4899}4900 4901uint16_t AsmPrinter::getDwarfVersion() const {4902 return OutStreamer->getContext().getDwarfVersion();4903}4904 4905void AsmPrinter::setDwarfVersion(uint16_t Version) {4906 OutStreamer->getContext().setDwarfVersion(Version);4907}4908 4909bool AsmPrinter::isDwarf64() const {4910 return OutStreamer->getContext().getDwarfFormat() == dwarf::DWARF64;4911}4912 4913unsigned int AsmPrinter::getDwarfOffsetByteSize() const {4914 return dwarf::getDwarfOffsetByteSize(4915 OutStreamer->getContext().getDwarfFormat());4916}4917 4918dwarf::FormParams AsmPrinter::getDwarfFormParams() const {4919 return {getDwarfVersion(), uint8_t(MAI->getCodePointerSize()),4920 OutStreamer->getContext().getDwarfFormat(),4921 doesDwarfUseRelocationsAcrossSections()};4922}4923 4924unsigned int AsmPrinter::getUnitLengthFieldByteSize() const {4925 return dwarf::getUnitLengthFieldByteSize(4926 OutStreamer->getContext().getDwarfFormat());4927}4928 4929std::tuple<const MCSymbol *, uint64_t, const MCSymbol *,4930 codeview::JumpTableEntrySize>4931AsmPrinter::getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr,4932 const MCSymbol *BranchLabel) const {4933 const auto TLI = MF->getSubtarget().getTargetLowering();4934 const auto BaseExpr =4935 TLI->getPICJumpTableRelocBaseExpr(MF, JTI, MMI->getContext());4936 const auto Base = &cast<MCSymbolRefExpr>(BaseExpr)->getSymbol();4937 4938 // By default, for the architectures that support CodeView,4939 // EK_LabelDifference32 is implemented as an Int32 from the base address.4940 return std::make_tuple(Base, 0, BranchLabel,4941 codeview::JumpTableEntrySize::Int32);4942}4943 4944void AsmPrinter::emitCOFFReplaceableFunctionData(Module &M) {4945 const Triple &TT = TM.getTargetTriple();4946 assert(TT.isOSBinFormatCOFF());4947 4948 bool IsTargetArm64EC = TT.isWindowsArm64EC();4949 SmallVector<char> Buf;4950 SmallVector<MCSymbol *> FuncOverrideDefaultSymbols;4951 bool SwitchedToDirectiveSection = false;4952 for (const Function &F : M.functions()) {4953 if (F.hasFnAttribute("loader-replaceable")) {4954 if (!SwitchedToDirectiveSection) {4955 OutStreamer->switchSection(4956 OutContext.getObjectFileInfo()->getDrectveSection());4957 SwitchedToDirectiveSection = true;4958 }4959 4960 StringRef Name = F.getName();4961 4962 // For hybrid-patchable targets, strip the prefix so that we can mark4963 // the real function as replaceable.4964 if (IsTargetArm64EC && Name.ends_with(HybridPatchableTargetSuffix)) {4965 Name = Name.drop_back(HybridPatchableTargetSuffix.size());4966 }4967 4968 MCSymbol *FuncOverrideSymbol =4969 MMI->getContext().getOrCreateSymbol(Name + "_$fo$");4970 OutStreamer->beginCOFFSymbolDef(FuncOverrideSymbol);4971 OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);4972 OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);4973 OutStreamer->endCOFFSymbolDef();4974 4975 MCSymbol *FuncOverrideDefaultSymbol =4976 MMI->getContext().getOrCreateSymbol(Name + "_$fo_default$");4977 OutStreamer->beginCOFFSymbolDef(FuncOverrideDefaultSymbol);4978 OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);4979 OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);4980 OutStreamer->endCOFFSymbolDef();4981 FuncOverrideDefaultSymbols.push_back(FuncOverrideDefaultSymbol);4982 4983 OutStreamer->emitBytes((Twine(" /ALTERNATENAME:") +4984 FuncOverrideSymbol->getName() + "=" +4985 FuncOverrideDefaultSymbol->getName())4986 .toStringRef(Buf));4987 Buf.clear();4988 }4989 }4990 4991 if (SwitchedToDirectiveSection)4992 OutStreamer->popSection();4993 4994 if (FuncOverrideDefaultSymbols.empty())4995 return;4996 4997 // MSVC emits the symbols for the default variables pointing at the start of4998 // the .data section, but doesn't actually allocate any space for them. LLVM4999 // can't do this, so have all of the variables pointing at a single byte5000 // instead.5001 OutStreamer->switchSection(OutContext.getObjectFileInfo()->getDataSection());5002 for (MCSymbol *Symbol : FuncOverrideDefaultSymbols) {5003 OutStreamer->emitLabel(Symbol);5004 }5005 OutStreamer->emitZeros(1);5006 OutStreamer->popSection();5007}5008 5009void AsmPrinter::emitCOFFFeatureSymbol(Module &M) {5010 const Triple &TT = TM.getTargetTriple();5011 assert(TT.isOSBinFormatCOFF());5012 5013 // Emit an absolute @feat.00 symbol.5014 MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));5015 OutStreamer->beginCOFFSymbolDef(S);5016 OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);5017 OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);5018 OutStreamer->endCOFFSymbolDef();5019 int64_t Feat00Value = 0;5020 5021 if (TT.getArch() == Triple::x86) {5022 // According to the PE-COFF spec, the LSB of this value marks the object5023 // for "registered SEH". This means that all SEH handler entry points5024 // must be registered in .sxdata. Use of any unregistered handlers will5025 // cause the process to terminate immediately. LLVM does not know how to5026 // register any SEH handlers, so its object files should be safe.5027 Feat00Value |= COFF::Feat00Flags::SafeSEH;5028 }5029 5030 if (M.getModuleFlag("cfguard")) {5031 // Object is CFG-aware.5032 Feat00Value |= COFF::Feat00Flags::GuardCF;5033 }5034 5035 if (M.getModuleFlag("ehcontguard")) {5036 // Object also has EHCont.5037 Feat00Value |= COFF::Feat00Flags::GuardEHCont;5038 }5039 5040 if (M.getModuleFlag("ms-kernel")) {5041 // Object is compiled with /kernel.5042 Feat00Value |= COFF::Feat00Flags::Kernel;5043 }5044 5045 OutStreamer->emitSymbolAttribute(S, MCSA_Global);5046 OutStreamer->emitAssignment(5047 S, MCConstantExpr::create(Feat00Value, MMI->getContext()));5048}5049