61#include "llvm/Config/config.h"
131#define DEBUG_TYPE "asm-printer"
135 cl::desc(
"Basic block profile dump for external cost modelling. If "
136 "matching up BBs with afterwards, the compilation must be "
137 "performed with -basic-block-sections=labels. Enabling this "
138 "flag during in-process ThinLTO is not supported."));
155STATISTIC(EmittedInsts,
"Number of machine instrs printed");
157char AsmPrinter::ID = 0;
160class AddrLabelMapCallbackPtr final :
CallbackVH {
164 AddrLabelMapCallbackPtr() =
default;
180 struct AddrLabelSymEntry {
192 std::vector<AddrLabelMapCallbackPtr> BBCallbacks;
198 DeletedAddrLabelsNeedingEmission;
205 "Some labels for deleted blocks never got emitted");
211 std::vector<MCSymbol *> &Result);
219 "Shouldn't get label for block without address taken");
220 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
223 if (!Entry.Symbols.empty()) {
225 return Entry.Symbols;
230 BBCallbacks.emplace_back(BB);
231 BBCallbacks.back().setMap(
this);
232 Entry.Index = BBCallbacks.size() - 1;
236 Entry.Symbols.push_back(
Sym);
237 return Entry.Symbols;
242 Function *
F, std::vector<MCSymbol *> &Result) {
244 DeletedAddrLabelsNeedingEmission.find(
F);
247 if (
I == DeletedAddrLabelsNeedingEmission.end())
252 DeletedAddrLabelsNeedingEmission.erase(
I);
260 if (!AddrLabelSymbols)
261 AddrLabelSymbols = std::make_unique<AddrLabelMap>(
OutContext);
262 return AddrLabelSymbols->getAddrLabelSymbolToEmit(
267 const Function *
F, std::vector<MCSymbol *> &Result) {
269 if (!AddrLabelSymbols)
271 return AddrLabelSymbols->takeDeletedSymbolsForFunction(
279 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
280 AddrLabelSymbols.erase(BB);
281 assert(!Entry.Symbols.empty() &&
"Didn't have a symbol, why a callback?");
282 BBCallbacks[Entry.Index] =
nullptr;
284#if !LLVM_MEMORY_SANITIZER_BUILD
287 "Block/parent mismatch");
291 if (
Sym->isDefined())
298 DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(
Sym);
304 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
305 AddrLabelSymbols.erase(Old);
306 assert(!OldEntry.Symbols.empty() &&
"Didn't have a symbol, why a callback?");
308 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
311 if (NewEntry.Symbols.empty()) {
312 BBCallbacks[OldEntry.Index].setPtr(New);
313 NewEntry = std::move(OldEntry);
317 BBCallbacks[OldEntry.Index] =
nullptr;
323void AddrLabelMapCallbackPtr::deleted() {
324 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
327void AddrLabelMapCallbackPtr::allUsesReplacedWith(
Value *V2) {
328 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
337 Alignment =
DL.getPreferredAlign(GVar);
340 if (InAlign > Alignment)
348 assert(GVAlign &&
"GVAlign must be set");
353 Alignment = *GVAlign;
359 OutContext(Streamer->getContext()), OutStreamer(
std::
move(Streamer)),
362 DwarfUsesRelocationsAcrossSections =
368 "Debug/EH info didn't get finalized");
395 assert(
MF &&
"getSubtargetInfo requires a valid MachineFunction!");
406 "Expected assembly output mode.");
430 auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
431 MMI = MMIWP ? &MMIWP->getMMI() :
nullptr;
432 HasSplitStack =
false;
433 HasNoSplitStack =
false;
435 AddrLabelSymbols =
nullptr;
442 .getModuleMetadata(M);
455 Triple TVT(M.getDarwinTargetVariantTriple());
457 Target, M.getSDKVersion(),
458 M.getDarwinTargetVariantTriple().empty() ?
nullptr : &TVT,
459 M.getDarwinTargetVariantSDKVersion());
473 FileName = M.getSourceFileName();
476 const char VerStr[] =
477 PACKAGE_VENDOR
" " PACKAGE_NAME
" version " PACKAGE_VERSION;
479 const char VerStr[] = PACKAGE_NAME
" version " PACKAGE_VERSION;
482 OutStreamer->emitFileDirective(FileName, VerStr,
"",
"");
489 assert(
MI &&
"AsmPrinter didn't require GCModuleInfo?");
490 for (
const auto &
I : *
MI)
492 MP->beginAssembly(M, *
MI, *
this);
495 if (!M.getModuleInlineAsm().empty()) {
496 OutStreamer->AddComment(
"Start of file scope inline assembly");
500 OutStreamer->AddComment(
"End of file scope inline assembly");
505 bool EmitCodeView = M.getCodeViewFlag();
507 Handlers.emplace_back(std::make_unique<CodeViewDebug>(
this),
512 if (!EmitCodeView || M.getDwarfVersion()) {
535 for (
auto &
F : M.getFunctionList()) {
587 if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(
"cfguard")))
595 HI.Handler->beginModule(&M);
599 std::error_code PossibleFileError;
600 MBBProfileDumpFileOutput = std::make_unique<raw_fd_ostream>(
602 if (PossibleFileError) {
603 M.getContext().emitError(
"Failed to open file for MBB Profile Dump: " +
604 PossibleFileError.message() +
"\n");
688 "No emulated TLS variables in the common section");
727 "Tagged symbols (-fsanitize=memtag-globals) are "
728 "only supported on aarch64 + Android.");
738 "' is already defined");
755 HI.TimerGroupName, HI.TimerGroupDescription,
757 HI.Handler->setSymbolSize(GVSym,
Size);
851 unsigned PtrSize =
DL.getPointerTypeSize(GV->
getType());
870 if (LocalAlias != EmittedInitSym)
891void AsmPrinter::emitFunctionHeaderComment() {}
895void AsmPrinter::emitFunctionHeader() {
900 <<
"-- Begin function "
928 if (
F.hasFnAttribute(Attribute::Cold))
932 if (
F.hasPrefixData()) {
955 unsigned PatchableFunctionPrefix = 0;
956 unsigned PatchableFunctionEntry = 0;
957 (void)
F.getFnAttribute(
"patchable-function-prefix")
959 .getAsInteger(10, PatchableFunctionPrefix);
960 (void)
F.getFnAttribute(
"patchable-function-entry")
962 .getAsInteger(10, PatchableFunctionEntry);
963 if (PatchableFunctionPrefix) {
968 }
else if (PatchableFunctionEntry) {
975 if (
const MDNode *MD =
F.getMetadata(LLVMContext::MD_func_sanitize)) {
976 assert(MD->getNumOperands() == 2);
978 auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
979 auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1));
986 false,
F.getParent());
987 emitFunctionHeaderComment();
1005 std::vector<MCSymbol*> DeadBlockSyms;
1007 for (
MCSymbol *DeadBlockSym : DeadBlockSyms) {
1008 OutStreamer->AddComment(
"Address taken block that was later removed");
1024 for (
const HandlerInfo &HI :
Handlers) {
1027 HI.Handler->beginFunction(
MF);
1029 for (
const HandlerInfo &HI :
Handlers) {
1032 HI.Handler->beginBasicBlockSection(
MF->
front());
1036 if (
F.hasPrologueData())
1049 "' is a protected alias");
1074 std::optional<unsigned>
Size;
1076 CommentOS << *
Size <<
"-byte Reload\n";
1077 }
else if ((
Size =
MI.getFoldedRestoreSize(
TII))) {
1080 CommentOS <<
"Unknown-size Folded Reload\n";
1082 CommentOS << *
Size <<
"-byte Folded Reload\n";
1084 }
else if ((
Size =
MI.getSpillSize(
TII))) {
1085 CommentOS << *
Size <<
"-byte Spill\n";
1086 }
else if ((
Size =
MI.getFoldedSpillSize(
TII))) {
1089 CommentOS <<
"Unknown-size Folded Spill\n";
1091 CommentOS << *
Size <<
"-byte Folded Spill\n";
1097 CommentOS <<
" Reload Reuse\n";
1107 OS <<
"implicit-def: "
1119 assert(Op.isReg() &&
"KILL instruction must have only register operands");
1120 OS <<
' ' << (Op.isDef() ?
"def " :
"killed ")
1132 if (
MI->isNonListDebugValue() &&
MI->getNumOperands() != 4)
1137 OS <<
"DEBUG_VALUE: ";
1140 if (
auto *SP = dyn_cast<DISubprogram>(V->getScope())) {
1152 Expr = *NonVariadicExpr;
1157 for (
auto &Op : Expr->
expr_ops()) {
1159 for (
unsigned I = 0;
I < Op.getNumArgs(); ++
I)
1160 OS <<
' ' << Op.getArg(
I);
1167 if (&Op !=
MI->debug_operands().begin())
1169 switch (Op.getType()) {
1172 Type *ImmTy = Op.getFPImm()->getType();
1191 Op.getCImm()->getValue().print(
OS,
false );
1195 OS <<
"!target-index(" << Op.getIndex() <<
"," << Op.getOffset() <<
")";
1201 std::optional<StackOffset>
Offset;
1215 if (
MI->isIndirectDebugValue())
1221 OS <<
'+' <<
Offset->getFixed() <<
']';
1238 if (
MI->getNumOperands() != 1)
1243 OS <<
"DEBUG_LABEL: ";
1246 if (
auto *SP = dyn_cast<DISubprogram>(
1247 V->getScope()->getNonLexicalBlockFileScope())) {
1262 if (
F.isDeclarationForLinker())
1266 F.needsUnwindTableEntry())
1269 assert(
MMI !=
nullptr &&
"Invalid machine module info");
1302 auto *
MBB =
MI.getParent();
1303 auto I = std::next(
MI.getIterator());
1304 while (
I !=
MBB->
end() &&
I->isTransient())
1311 unsigned CFIIndex =
MI.getOperand(0).getCFIIndex();
1318 MCSymbol *FrameAllocSym =
MI.getOperand(0).getMCSymbol();
1319 int FrameOffset =
MI.getOperand(1).getImm();
1341 assert(BBAddrMapSection &&
".llvm_bb_addr_map section is not initialized.");
1348 uint8_t BBAddrMapVersion =
OutStreamer->getContext().getBBAddrMapVersion();
1354 OutStreamer->AddComment(
"number of basic blocks");
1356 const MCSymbol *PrevMBBEndSymbol = FunctionSymbol;
1362 if (BBAddrMapVersion > 1) {
1392 OutStreamer->emitAbsoluteSymbolDiff(Symbol, Loc, 4);
1399 if (
const MDNode *MD =
F.getMetadata(LLVMContext::MD_kcfi_type))
1401 mdconst::extract<ConstantInt>(MD->getOperand(0)));
1406 auto GUID =
MI.getOperand(0).getImm();
1407 auto Index =
MI.getOperand(1).getImm();
1408 auto Type =
MI.getOperand(2).getImm();
1409 auto Attr =
MI.getOperand(3).getImm();
1421 if (!StackSizeSection)
1452 if (StackUsageStream ==
nullptr) {
1457 errs() <<
"Could not open file: " << EC.message();
1464 *StackUsageStream <<
':' << DSP->getLine();
1466 *StackUsageStream <<
':' <<
MF.
getName() <<
'\t' << StackSize <<
'\t';
1468 *StackUsageStream <<
"dynamic\n";
1470 *StackUsageStream <<
"static\n";
1477 PCSectionsSymbols[&MD].emplace_back(S);
1482 if (PCSectionsSymbols.empty() && !
F.hasMetadata(LLVMContext::MD_pcsections))
1486 const unsigned RelativeRelocSize =
1496 assert(S &&
"PC section is not initialized");
1507 bool ConstULEB128 =
false;
1509 if (
auto *S = dyn_cast<MDString>(MDO)) {
1513 const StringRef SecWithOpt = S->getString();
1514 const size_t OptStart = SecWithOpt.
find(
'!');
1520 assert((O ==
'!' || O ==
'C') &&
"Invalid !pcsections options");
1523 const MCSymbol *Prev = Syms.front();
1525 if (
Sym == Prev || !Deltas) {
1544 assert(isa<MDNode>(MDO) &&
"expecting either string or tuple");
1545 const auto *AuxMDs = cast<MDNode>(MDO);
1546 for (
const MDOperand &AuxMDO : AuxMDs->operands()) {
1547 assert(isa<ConstantAsMetadata>(AuxMDO) &&
"expecting a constant");
1548 const Constant *
C = cast<ConstantAsMetadata>(AuxMDO)->getValue();
1552 if (
auto *CI = dyn_cast<ConstantInt>(
C);
1553 CI && ConstULEB128 &&
Size > 1 &&
Size <= 8) {
1565 if (
const MDNode *MD =
F.getMetadata(LLVMContext::MD_pcsections))
1568 for (
const auto &MS : PCSectionsSymbols)
1569 EmitForMD(*MS.first, MS.second,
false);
1571 PCSectionsSymbols.clear();
1593 emitFunctionHeader();
1600 MDT = getAnalysisIfAvailable<MachineDominatorTree>();
1602 OwnedMDT = std::make_unique<MachineDominatorTree>();
1603 OwnedMDT->getBase().recalculate(*
MF);
1604 MDT = OwnedMDT.get();
1608 MLI = getAnalysisIfAvailable<MachineLoopInfo>();
1610 OwnedMLI = std::make_unique<MachineLoopInfo>();
1612 MLI = OwnedMLI.get();
1617 bool HasAnyRealCode =
false;
1618 int NumInstsInFunction = 0;
1622 for (
auto &
MBB : *
MF) {
1626 for (
auto &
MI :
MBB) {
1628 if (!
MI.isPosition() && !
MI.isImplicitDef() && !
MI.isKill() &&
1629 !
MI.isDebugInstr()) {
1630 HasAnyRealCode =
true;
1631 ++NumInstsInFunction;
1638 if (
MDNode *MD =
MI.getPCSections())
1644 HI.Handler->beginInstruction(&
MI);
1650 switch (
MI.getOpcode()) {
1651 case TargetOpcode::CFI_INSTRUCTION:
1654 case TargetOpcode::LOCAL_ESCAPE:
1657 case TargetOpcode::ANNOTATION_LABEL:
1658 case TargetOpcode::GC_LABEL:
1661 case TargetOpcode::EH_LABEL:
1671 auto MI2 = std::next(
MI.getIterator());
1672 if (IsEHa && MI2 !=
MBB.
end() &&
1673 (MI2->mayLoadOrStore() || MI2->mayRaiseFPException()))
1677 case TargetOpcode::INLINEASM:
1678 case TargetOpcode::INLINEASM_BR:
1681 case TargetOpcode::DBG_VALUE:
1682 case TargetOpcode::DBG_VALUE_LIST:
1688 case TargetOpcode::DBG_INSTR_REF:
1693 case TargetOpcode::DBG_PHI:
1697 case TargetOpcode::DBG_LABEL:
1703 case TargetOpcode::IMPLICIT_DEF:
1706 case TargetOpcode::KILL:
1709 case TargetOpcode::PSEUDO_PROBE:
1712 case TargetOpcode::ARITH_FENCE:
1716 case TargetOpcode::MEMBARRIER:
1721 if (CanDoExtraAnalysis) {
1738 HI.Handler->endInstruction();
1759 OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);
1767 if (CanDoExtraAnalysis) {
1778 for (
auto &KV : MnemonicCounts)
1781 sort(MnemonicVec, [](
const std::pair<StringRef, unsigned> &
A,
1782 const std::pair<StringRef, unsigned> &
B) {
1783 if (
A.second >
B.second)
1785 if (
A.second ==
B.second)
1790 for (
auto &KV : MnemonicVec) {
1791 auto Name = (
Twine(
"INST_") + getToken(KV.first.trim()).first).str();
1792 R << KV.first <<
": " <<
ore::NV(
Name, KV.second) <<
"\n";
1798 EmittedInsts += NumInstsInFunction;
1802 R <<
ore::NV(
"NumInstructions", NumInstsInFunction)
1803 <<
" instructions in function";
1816 (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {
1822 OutStreamer->AddComment(
"avoids zero-length function");
1831 for (
const auto &BB :
F) {
1832 if (!BB.hasAddressTaken())
1835 if (
Sym->isDefined())
1837 OutStreamer->AddComment(
"Address of block that was removed by CodeGen");
1856 if (EmitFunctionSize) {
1873 HI.Handler->endBasicBlockSection(
MF->
back());
1879 HI.Handler->markFunctionEnd();
1892 HI.Handler->endFunction(
MF);
1912 OutStreamer->getCommentOS() <<
"-- End function\n";
1918 if (MBBProfileDumpFileOutput) {
1922 "Unable to find BB labels for MBB profile dump. -mbb-profile-dump "
1923 "must be called with -basic-block-sections=labels");
1925 getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI();
1926 for (
const auto &
MBB : *
MF) {
1927 *MBBProfileDumpFileOutput.get()
1939 if (isa<GlobalVariable>(
C))
1942 unsigned NumUses = 0;
1943 for (
const auto *
CU :
C->users())
1955 unsigned &NumGOTEquivUsers) {
1966 for (
const auto *U : GV->
users())
1969 return NumGOTEquivUsers > 0;
1983 for (
const auto &
G : M.globals()) {
1984 unsigned NumGOTEquivUsers = 0;
2003 unsigned Cnt =
I.second.second;
2009 for (
const auto *GV : FailedCandidates)
2027 "Visibility should be handled with emitLinkage() on AIX.");
2074 if (LocalAlias !=
Name)
2093 "IFunc is not supported on AIX.");
2111 if (LocalAlias !=
Name)
2121 std::optional<SmallString<128>> Filename;
2122 if (std::optional<StringRef> FilenameRef = RS.
getFilename()) {
2123 Filename = *FilenameRef;
2125 assert(!Filename->empty() &&
"The filename can't be empty.");
2130 std::unique_ptr<remarks::MetaSerializer> MetaSerializer =
2133 MetaSerializer->emit();
2156 for (
const auto &
G : M.globals())
2166 if (!
F.isDeclarationForLinker())
2181 if (
F.isIntrinsic())
2208 if (!Stubs.empty()) {
2213 for (
const auto &Stub : Stubs) {
2215 OutStreamer->emitSymbolValue(Stub.second.getPointer(),
2216 DL.getPointerSize());
2227 if (!Stubs.empty()) {
2230 for (
const auto &Stub : Stubs) {
2242 OutStreamer->emitSymbolValue(Stub.second.getPointer(),
2243 DL.getPointerSize());
2251 TS->emitConstantPools();
2263 HI.Handler->endModule();
2280 for (
const auto &GO : M.global_objects()) {
2281 if (!GO.hasExternalWeakLinkage())
2286 auto SymbolName =
"swift_async_extendedFramePointerFlags";
2287 auto Global = M.getGlobalVariable(SymbolName);
2304 for (
const auto &Alias : M.aliases()) {
2305 if (Alias.hasAvailableExternallyLinkage())
2308 Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {
2309 if (!AliasVisited.
insert(Cur).second)
2314 emitGlobalAlias(M, *AncestorAlias);
2317 for (
const auto &IFunc : M.ifuncs())
2318 emitGlobalIFunc(M, IFunc);
2321 assert(
MI &&
"AsmPrinter didn't require GCModuleInfo?");
2324 MP->finishAssembly(M, *
MI, *
this);
2327 emitModuleIdents(M);
2330 emitModuleCommandLines(M);
2337 if (HasNoSplitStack)
2344 Function *InitTrampolineIntrinsic = M.getFunction(
"llvm.init.trampoline");
2345 if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->
use_empty())
2353 if (!GV.use_empty() && !GV.isThreadLocal() &&
2354 !GV.hasDLLImportStorageClass() && !GV.getName().startswith(
"llvm.") &&
2355 !GV.hasAtLeastLocalUnnamedAddr())
2362 unsigned UniqueID = 0;
2364 if (!GV.hasPartition() || GV.isDeclarationForLinker() ||
2370 "",
false, ++UniqueID,
nullptr));
2384 AddrLabelSymbols =
nullptr;
2398 return Res.first->second;
2408 HasSplitStack =
true;
2411 HasNoSplitStack =
true;
2413 HasNoSplitStack =
true;
2420 "Only AIX uses the function descriptor hooks.");
2425 " initalized first.");
2434 CurrentSectionBeginSym =
nullptr;
2436 MBBSectionExceptionSyms.clear();
2438 if (
F.hasFnAttribute(
"patchable-function-entry") ||
2439 F.hasFnAttribute(
"function-instrument") ||
2440 F.hasFnAttribute(
"xray-instruction-threshold") ||
2444 if (NeedsLocalForSize)
2448 ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
2470 const std::vector<MachineConstantPoolEntry> &CP = MCP->
getConstants();
2471 if (CP.empty())
return;
2476 for (
unsigned i = 0, e = CP.size(); i != e; ++i) {
2492 unsigned SecIdx = CPSections.
size();
2493 while (SecIdx != 0) {
2494 if (CPSections[--SecIdx].S == S) {
2500 SecIdx = CPSections.
size();
2501 CPSections.
push_back(SectionCPs(S, Alignment));
2504 if (Alignment > CPSections[SecIdx].Alignment)
2505 CPSections[SecIdx].Alignment = Alignment;
2512 for (
unsigned i = 0, e = CPSections.
size(); i != e; ++i) {
2513 for (
unsigned j = 0, ee = CPSections[i].CPEs.
size(); j != ee; ++j) {
2514 unsigned CPI = CPSections[i].CPEs[j];
2516 if (!
Sym->isUndefined())
2519 if (CurSection != CPSections[i].S) {
2522 CurSection = CPSections[i].S;
2550 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
2551 if (JT.empty())
return;
2560 if (JTInDiffSection) {
2570 if (!JTInDiffSection)
2573 for (
unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
2574 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
2577 if (JTBBs.empty())
continue;
2603 if (JTInDiffSection &&
DL.hasLinkerPrivateGlobalPrefix())
2613 emitJumpTableEntry(MJTI,
MBB, JTI);
2615 if (!JTInDiffSection)
2623 unsigned UID)
const {
2687 if (GV->
getName() ==
"llvm.used") {
2702 if (GV->
getName() ==
"llvm.global_ctors") {
2709 if (GV->
getName() ==
"llvm.global_dtors") {
2721void AsmPrinter::emitLLVMUsedList(
const ConstantArray *InitList) {
2723 for (
unsigned i = 0, e = InitList->
getNumOperands(); i != e; ++i) {
2736 if (!isa<ConstantArray>(
List))
2740 for (
Value *O : cast<ConstantArray>(
List)->operands()) {
2741 auto *CS = cast<ConstantStruct>(O);
2742 if (CS->getOperand(1)->isNullValue())
2744 ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
2751 if (!CS->getOperand(2)->isNullValue()) {
2754 "associated data of XXStructor list is not yet supported on AIX");
2756 dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());
2762 return L.Priority < R.Priority;
2772 if (Structors.
empty())
2778 std::reverse(Structors.
begin(), Structors.
end());
2806void AsmPrinter::emitModuleIdents(
Module &M) {
2810 if (
const NamedMDNode *NMD = M.getNamedMetadata(
"llvm.ident")) {
2811 for (
unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2812 const MDNode *
N = NMD->getOperand(i);
2813 assert(
N->getNumOperands() == 1 &&
2814 "llvm.ident metadata entry can have only one operand");
2815 const MDString *S = cast<MDString>(
N->getOperand(0));
2821void AsmPrinter::emitModuleCommandLines(
Module &M) {
2826 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
2835 assert(
N->getNumOperands() == 1 &&
2836 "llvm.commandline metadata entry can have only one operand");
2837 const MDString *S = cast<MDString>(
N->getOperand(0));
2867 unsigned PadTo)
const {
2883 unsigned Size)
const {
2898 bool IsSectionRelative)
const {
2922 unsigned MaxBytesToEmit)
const {
2926 if (Alignment ==
Align(1))
2935 OutStreamer->emitCodeAlignment(Alignment, STI, MaxBytesToEmit);
2937 OutStreamer->emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);
2950 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
2953 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
2956 if (
const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
2959 if (
const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
2973 switch (CE->getOpcode()) {
2976 case Instruction::AddrSpaceCast: {
2977 const Constant *Op = CE->getOperand(0);
2978 unsigned DstAS = CE->getType()->getPointerAddressSpace();
2979 unsigned SrcAS = Op->getType()->getPointerAddressSpace();
2985 case Instruction::GetElementPtr: {
2988 cast<GEPOperator>(CE)->accumulateConstantOffset(
getDataLayout(), OffsetAI);
2999 case Instruction::Trunc:
3005 case Instruction::BitCast:
3008 case Instruction::IntToPtr: {
3019 case Instruction::PtrToInt: {
3025 Type *Ty = CE->getType();
3034 if (
DL.getTypeAllocSize(Ty).getFixedValue() <=
3035 DL.getTypeAllocSize(Op->getType()).getFixedValue())
3041 case Instruction::Sub: {
3051 const MCExpr *RelocExpr =
3063 int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();
3077 case Instruction::Add: {
3094 OS <<
"Unsupported expression in static initializer: ";
3095 CE->printAsOperand(
OS,
false,
3114 assert(!
Data.empty() &&
"Empty aggregates should be CAZ node");
3116 for (
unsigned i = 1, e =
Data.size(); i != e; ++i)
3117 if (
Data[i] !=
C)
return -1;
3118 return static_cast<uint8_t
>(
C);
3125 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
3131 if (!
Value.isSplat(8))
3134 return Value.zextOrTrunc(8).getZExtValue();
3139 assert(CA->getNumOperands() != 0 &&
"Should be a CAZ");
3146 for (
unsigned i = 1, e = CA->getNumOperands(); i != e; ++i)
3147 if (CA->getOperand(i) != Op0)
3162 if (AliasIt != AliasList->
end()) {
3206 unsigned EmittedSize =
3208 assert(EmittedSize <=
Size &&
"Size cannot be less than EmittedSize!");
3209 if (
unsigned Padding =
Size - EmittedSize)
3239 uint64_t ElementSizeInBits =
DL.getTypeSizeInBits(ElementType);
3240 uint64_t ElementAllocSizeInBits =
DL.getTypeAllocSizeInBits(ElementType);
3242 if (ElementSizeInBits != ElementAllocSizeInBits) {
3254 "Cannot lower vector global with unusual element type");
3258 EmittedSize =
DL.getTypeStoreSize(CV->
getType());
3269 if (
unsigned Padding =
Size - EmittedSize)
3293 SizeSoFar += FieldSize + PadSize;
3301 "Layout of constant struct may be incorrect!");
3305 assert(ET &&
"Unknown float type");
3314 AP.
OutStreamer->getCommentOS() <<
' ' << StrVal <<
'\n';
3321 unsigned TrailingBytes = NumBytes %
sizeof(
uint64_t);
3330 AP.
OutStreamer->emitIntValueInHexWithPadding(p[Chunk--], TrailingBytes);
3332 for (; Chunk >= 0; --Chunk)
3336 for (Chunk = 0; Chunk < NumBytes /
sizeof(
uint64_t); ++Chunk)
3340 AP.
OutStreamer->emitIntValueInHexWithPadding(p[Chunk], TrailingBytes);
3345 AP.
OutStreamer->emitZeros(
DL.getTypeAllocSize(ET) -
DL.getTypeStoreSize(ET));
3360 unsigned ExtraBitsSize =
BitWidth & 63;
3362 if (ExtraBitsSize) {
3370 if (
DL.isBigEndian()) {
3379 ExtraBitsSize =
alignTo(ExtraBitsSize, 8);
3381 (((
uint64_t)-1) >> (64 - ExtraBitsSize));
3392 for (
unsigned i = 0, e =
BitWidth / 64; i != e; ++i) {
3393 uint64_t Val =
DL.isBigEndian() ? RawData[e - i - 1] : RawData[i];
3397 if (ExtraBitsSize) {
3404 (ExtraBits & (((
uint64_t)-1) >> (64 - ExtraBitsSize)))
3405 == ExtraBits &&
"Directive too small for extra bits.");
3437 if (!(*ME)->evaluateAsRelocatable(MV,
nullptr,
nullptr) || MV.
isAbsolute())
3448 const GlobalValue *BaseGV = dyn_cast_or_null<GlobalValue>(BaseCst);
3456 if (!SymB || BaseSym != &SymB->
getSymbol())
3467 if (GOTPCRelCst < 0)
3489 int NumUses = (int)Result.second;
3512 BaseCV = dyn_cast<Constant>(CV->
user_back());
3514 if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
3517 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
3520 if (StoreSize <= 8) {
3523 <<
format(
"0x%" PRIx64
"\n", CI->getZExtValue());
3524 AP.
OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize);
3530 if (
Size != StoreSize)
3536 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
3539 if (isa<ConstantPointerNull>(CV)) {
3553 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
3556 if (CE->getOpcode() == Instruction::BitCast)
3600 for (
auto &AliasPair : *AliasList) {
3655 if (
Sym->isUndefined())
3697 unsigned FunctionNumber) {
3701 <<
"Parent Loop BB" << FunctionNumber <<
"_"
3709 unsigned FunctionNumber) {
3713 <<
"Child Loop BB" << FunctionNumber <<
"_"
3714 << CL->getHeader()->getNumber() <<
" Depth " << CL->getLoopDepth()
3729 assert(Header &&
"No header for loop");
3733 if (Header != &
MBB) {
3734 AP.
OutStreamer->AddComment(
" in Loop: Header=BB" +
3765 HI.Handler->endFunclet();
3766 HI.Handler->beginFunclet(
MBB);
3782 if (Alignment !=
Align(1))
3804 if (BB->hasName()) {
3806 false, BB->getModule());
3811 assert(
MLI !=
nullptr &&
"MachineLoopInfo should has been computed");
3816 if (shouldEmitLabelForBasicBlock(
MBB)) {
3818 OutStreamer->AddComment(
"Label of block must be emitted");
3838 HI.Handler->beginBasicBlockSection(
MBB);
3846 HI.Handler->endBasicBlockSection(
MBB);
3850 bool IsDefinition)
const {
3853 switch (Visibility) {
3870bool AsmPrinter::shouldEmitLabelForBasicBlock(
3911 if (!
MI.isBranch() ||
MI.isIndirectBranch())
3920 if (
OP->isMBB() &&
OP->getMBB() ==
MBB)
3932 auto [GCPI, Inserted] = GCMetadataPrinters.insert({&S,
nullptr});
3934 return GCPI->second.get();
3940 if (
Name == GCMetaPrinter.getName()) {
3941 std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate();
3943 GCPI->second = std::move(GMP);
3944 return GCPI->second.get();
3952 assert(
MI &&
"AsmPrinter didn't require GCModuleInfo?");
3953 bool NeedsDefault =
false;
3954 if (
MI->begin() ==
MI->end())
3956 NeedsDefault =
true;
3958 for (
const auto &
I : *
MI) {
3960 if (MP->emitStackMaps(
SM, *
this))
3964 NeedsDefault =
true;
3980 auto Kind8 =
static_cast<uint8_t
>(
Kind);
3985 auto Padding = (4 * Bytes) - ((2 * Bytes) + 3);
3986 assert(Padding >= 0 &&
"Instrumentation map entry > 4 * Word Size");
3994 auto PrevSection =
OutStreamer->getCurrentSectionOnly();
4000 if (TT.isOSBinFormatELF()) {
4004 if (
F.hasComdat()) {
4006 GroupName =
F.getComdat()->getName();
4009 Flags, 0, GroupName,
F.hasComdat(),
4035 for (
const auto &Sled :
Sleds) {
4036 MCSymbol *Dot = Ctx.createTempSymbol();
4063 OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes,
false);
4064 OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes,
false);
4073 auto Attr =
F.getFnAttribute(
"function-instrument");
4074 bool LogArgs =
F.hasFnAttribute(
"xray-log-args");
4075 bool AlwaysInstrument =
4076 Attr.isStringAttribute() && Attr.getValueAsString() ==
"xray-always";
4080 AlwaysInstrument, &
F, Version});
4085 unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0;
4086 (void)
F.getFnAttribute(
"patchable-function-prefix")
4088 .getAsInteger(10, PatchableFunctionPrefix);
4089 (void)
F.getFnAttribute(
"patchable-function-entry")
4091 .getAsInteger(10, PatchableFunctionEntry);
4092 if (!PatchableFunctionPrefix && !PatchableFunctionEntry)
4104 if (
F.hasComdat()) {
4106 GroupName =
F.getComdat()->getName();
4119 return OutStreamer->getContext().getDwarfVersion();
4123 OutStreamer->getContext().setDwarfVersion(Version);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP)
emitDebugValueComment - This method handles the target-independent form of DBG_VALUE,...
const char CFGuardDescription[]
static void emitGlobalConstantVector(const DataLayout &DL, const ConstantVector *CV, AsmPrinter &AP, AsmPrinter::AliasMapTy *AliasList)
static uint32_t getBBAddrMapMetadata(const MachineBasicBlock &MBB)
Returns the BB metadata to be emitted in the SHT_LLVM_BB_ADDR_MAP section for a given basic block.
static void emitGlobalConstantFP(const ConstantFP *CFP, AsmPrinter &AP)
static bool isGOTEquivalentCandidate(const GlobalVariable *GV, unsigned &NumGOTEquivUsers)
Only consider global GOT equivalents if at least one user is a cstexpr inside an initializer of anoth...
static unsigned getNumGlobalVariableUses(const Constant *C)
Compute the number of Global Variables that uses a Constant.
const char EHTimerDescription[]
const char CodeViewLineTablesGroupDescription[]
static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB, const MachineLoopInfo *LI, const AsmPrinter &AP)
emitBasicBlockLoopComments - Pretty-print comments for basic blocks.
static bool needFuncLabels(const MachineFunction &MF)
Returns true if function begin and end labels should be emitted.
static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME, const Constant *BaseCst, uint64_t Offset)
Transform a not absolute MCExpr containing a reference to a GOT equivalent global,...
static int isRepeatedByteSequence(const ConstantDataSequential *V)
isRepeatedByteSequence - Determine whether the given value is composed of a repeated sequence of iden...
static void emitGlobalAliasInline(AsmPrinter &AP, uint64_t Offset, AsmPrinter::AliasMapTy *AliasList)
const char PPGroupDescription[]
const char PPTimerDescription[]
const char DWARFGroupDescription[]
static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, unsigned FunctionNumber)
PrintChildLoopComment - Print comments about child loops within the loop for this basic block,...
const char CodeViewLineTablesGroupName[]
static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, unsigned FunctionNumber)
PrintParentLoopComment - Print comments about parent loops of this one.
static void emitGlobalConstantStruct(const DataLayout &DL, const ConstantStruct *CS, AsmPrinter &AP, const Constant *BaseCV, uint64_t Offset, AsmPrinter::AliasMapTy *AliasList)
static void emitGlobalConstantDataSequential(const DataLayout &DL, const ConstantDataSequential *CDS, AsmPrinter &AP, AsmPrinter::AliasMapTy *AliasList)
static void emitKill(const MachineInstr *MI, AsmPrinter &AP)
const char DbgTimerName[]
static cl::opt< std::string > BasicBlockProfileDump("mbb-profile-dump", cl::Hidden, cl::desc("Basic block profile dump for external cost modelling. If " "matching up BBs with afterwards, the compilation must be " "performed with -basic-block-sections=labels. Enabling this " "flag during in-process ThinLTO is not supported."))
const char DbgTimerDescription[]
static void emitGlobalConstantImpl(const DataLayout &DL, const Constant *C, AsmPrinter &AP, const Constant *BaseCV=nullptr, uint64_t Offset=0, AsmPrinter::AliasMapTy *AliasList=nullptr)
const char DWARFGroupName[]
static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS)
emitComments - Pretty-print comments for instructions.
static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP)
This method handles the target-independent form of DBG_LABEL, returning true if it was able to do so.
static bool canBeHidden(const GlobalValue *GV, const MCAsmInfo &MAI)
static void emitGlobalConstantArray(const DataLayout &DL, const ConstantArray *CA, AsmPrinter &AP, const Constant *BaseCV, uint64_t Offset, AsmPrinter::AliasMapTy *AliasList)
static void emitGlobalConstantLargeInt(const ConstantInt *CI, AsmPrinter &AP)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Looks at all the uses of the given value Returns the Liveness deduced from the uses of this value Adds all uses that cause the result to be MaybeLive to MaybeLiveRetUses If the result is MaybeLiveUses might be modified but its content should be ignored(since it might not be complete). DeadArgumentEliminationPass
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
This file contains the declaration of the GlobalIFunc class, which represents a single indirect funct...
const HexagonInstrInfo * TII
===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*–===//
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static cl::opt< std::string > OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::init("-"))
This file provides utility analysis objects describing memory locations.
Module.h This file contains the declarations for the Module class.
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
double convertToDouble() const
Converts this APFloat to host double value.
void toString(SmallVectorImpl< char > &Str, unsigned FormatPrecision=0, unsigned FormatMaxPadding=3, bool TruncateZero=true) const
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned getNumWords() const
Get the number of words.
const uint64_t * getRawData() const
This function returns a pointer to the internal storage of the APInt.
int64_t getSExtValue() const
Get sign extended value.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
AddrLabelMap(MCContext &context)
void UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New)
void takeDeletedSymbolsForFunction(Function *F, std::vector< MCSymbol * > &Result)
If we have any deleted symbols for F, return them.
void UpdateForDeletedBlock(BasicBlock *BB)
ArrayRef< MCSymbol * > getAddrLabelSymbolToEmit(BasicBlock *BB)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
virtual ~AsmPrinterHandler()
Pin vtable to this file.
virtual void markFunctionEnd()
This class is intended to be used as a driving class for all asm writers.
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix) const
Return the MCSymbol for a private symbol with global value name as its base, with the specified suffi...
MCSymbol * getSymbol(const GlobalValue *GV) const
void emitULEB128(uint64_t Value, const char *Desc=nullptr, unsigned PadTo=0) const
Emit the specified unsigned leb128 value.
SmallVector< XRayFunctionEntry, 4 > Sleds
void emitNops(unsigned N)
Emit N NOP instructions.
MCSymbol * CurrentFnBegin
MachineLoopInfo * MLI
This is a pointer to the current MachineLoopInfo.
virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const
Emit the directive and value for debug thread local expression.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
virtual void emitConstantPool()
Print to the current output stream assembly representations of the constants in the constant pool MCP...
virtual void emitGlobalVariable(const GlobalVariable *GV)
Emit the specified global variable to the .s file.
unsigned int getUnitLengthFieldByteSize() const
Returns 4 for DWARF32 and 12 for DWARF64.
void emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset, unsigned Size, bool IsSectionRelative=false) const
Emit something like ".long Label+Offset" where the size in bytes of the directive is specified by Siz...
TargetMachine & TM
Target machine description.
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual void emitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
MCSymbol * CurrentFnDescSym
The symbol for the current function descriptor on AIX.
MCSymbol * CurrentFnBeginLocal
For dso_local functions, the current $local alias for the function.
MapVector< const MCSymbol *, GOTEquivUsePair > GlobalGOTEquivs