61#include "llvm/Config/config.h"
129#define DEBUG_TYPE "asm-printer"
146STATISTIC(EmittedInsts,
"Number of machine instrs printed");
148char AsmPrinter::ID = 0;
151class AddrLabelMapCallbackPtr final :
CallbackVH {
155 AddrLabelMapCallbackPtr() =
default;
171 struct AddrLabelSymEntry {
183 std::vector<AddrLabelMapCallbackPtr> BBCallbacks;
189 DeletedAddrLabelsNeedingEmission;
196 "Some labels for deleted blocks never got emitted");
202 std::vector<MCSymbol *> &Result);
210 "Shouldn't get label for block without address taken");
211 AddrLabelSymEntry &Entry = AddrLabelSymbols[BB];
214 if (!Entry.Symbols.empty()) {
216 return Entry.Symbols;
221 BBCallbacks.emplace_back(BB);
222 BBCallbacks.back().setMap(
this);
223 Entry.Index = BBCallbacks.size() - 1;
227 Entry.Symbols.push_back(Sym);
228 return Entry.Symbols;
233 Function *
F, std::vector<MCSymbol *> &Result) {
235 DeletedAddrLabelsNeedingEmission.find(
F);
238 if (
I == DeletedAddrLabelsNeedingEmission.end())
243 DeletedAddrLabelsNeedingEmission.erase(
I);
251 if (!AddrLabelSymbols)
252 AddrLabelSymbols = std::make_unique<AddrLabelMap>(
OutContext);
253 return AddrLabelSymbols->getAddrLabelSymbolToEmit(
258 const Function *
F, std::vector<MCSymbol *> &Result) {
260 if (!AddrLabelSymbols)
262 return AddrLabelSymbols->takeDeletedSymbolsForFunction(
270 AddrLabelSymEntry Entry = std::move(AddrLabelSymbols[BB]);
271 AddrLabelSymbols.erase(BB);
272 assert(!Entry.Symbols.empty() &&
"Didn't have a symbol, why a callback?");
273 BBCallbacks[Entry.Index] =
nullptr;
275#if !LLVM_MEMORY_SANITIZER_BUILD
278 "Block/parent mismatch");
281 for (
MCSymbol *Sym : Entry.Symbols) {
289 DeletedAddrLabelsNeedingEmission[Entry.Fn].push_back(Sym);
295 AddrLabelSymEntry OldEntry = std::move(AddrLabelSymbols[Old]);
296 AddrLabelSymbols.erase(Old);
297 assert(!OldEntry.Symbols.empty() &&
"Didn't have a symbol, why a callback?");
299 AddrLabelSymEntry &NewEntry = AddrLabelSymbols[New];
302 if (NewEntry.Symbols.empty()) {
303 BBCallbacks[OldEntry.Index].setPtr(New);
304 NewEntry = std::move(OldEntry);
308 BBCallbacks[OldEntry.Index] =
nullptr;
314void AddrLabelMapCallbackPtr::deleted() {
315 Map->UpdateForDeletedBlock(cast<BasicBlock>(getValPtr()));
318void AddrLabelMapCallbackPtr::allUsesReplacedWith(
Value *V2) {
319 Map->UpdateForRAUWBlock(cast<BasicBlock>(getValPtr()), cast<BasicBlock>(V2));
328 Alignment =
DL.getPreferredAlign(GVar);
331 if (InAlign > Alignment)
339 assert(GVAlign &&
"GVAlign must be set");
344 Alignment = *GVAlign;
350 OutContext(Streamer->getContext()), OutStreamer(
std::
move(Streamer)),
353 DwarfUsesRelocationsAcrossSections =
359 "Debug/EH info didn't get finalized");
386 assert(
MF &&
"getSubtargetInfo requires a valid MachineFunction!");
397 "Expected assembly output mode.");
420 auto *MMIWP = getAnalysisIfAvailable<MachineModuleInfoWrapperPass>();
421 MMI = MMIWP ? &MMIWP->getMMI() :
nullptr;
422 HasSplitStack =
false;
423 HasNoSplitStack =
false;
425 AddrLabelSymbols =
nullptr;
432 .getModuleMetadata(M);
445 Triple TVT(M.getDarwinTargetVariantTriple());
447 Target, M.getSDKVersion(),
448 M.getDarwinTargetVariantTriple().empty() ?
nullptr : &TVT,
449 M.getDarwinTargetVariantSDKVersion());
463 FileName = M.getSourceFileName();
466 const char VerStr[] =
467 PACKAGE_VENDOR
" " PACKAGE_NAME
" version " PACKAGE_VERSION;
469 const char VerStr[] = PACKAGE_NAME
" version " PACKAGE_VERSION;
472 OutStreamer->emitFileDirective(FileName, VerStr,
"",
"");
479 assert(
MI &&
"AsmPrinter didn't require GCModuleInfo?");
480 for (
const auto &
I : *
MI)
482 MP->beginAssembly(M, *
MI, *
this);
485 if (!M.getModuleInlineAsm().empty()) {
486 OutStreamer->AddComment(
"Start of file scope inline assembly");
490 OutStreamer->AddComment(
"End of file scope inline assembly");
495 bool EmitCodeView = M.getCodeViewFlag();
497 Handlers.emplace_back(std::make_unique<CodeViewDebug>(
this),
502 if (!EmitCodeView || M.getDwarfVersion()) {
525 for (
auto &
F : M.getFunctionList()) {
577 if (mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(
"cfguard")))
585 HI.Handler->beginModule(&M);
668 "No emulated TLS variables in the common section");
707 "Tagged symbols (-fsanitize=memtag-globals) are "
708 "only supported on aarch64 + Android.");
718 "' is already defined");
735 HI.TimerGroupName, HI.TimerGroupDescription,
737 HI.Handler->setSymbolSize(GVSym,
Size);
831 unsigned PtrSize =
DL.getPointerTypeSize(GV->
getType());
850 if (LocalAlias != EmittedInitSym)
871void AsmPrinter::emitFunctionHeaderComment() {}
875void AsmPrinter::emitFunctionHeader() {
880 <<
"-- Begin function "
908 if (
F.hasFnAttribute(Attribute::Cold))
913 false,
F.getParent());
914 emitFunctionHeaderComment();
919 if (
F.hasPrefixData()) {
942 unsigned PatchableFunctionPrefix = 0;
943 unsigned PatchableFunctionEntry = 0;
944 (void)
F.getFnAttribute(
"patchable-function-prefix")
946 .getAsInteger(10, PatchableFunctionPrefix);
947 (void)
F.getFnAttribute(
"patchable-function-entry")
949 .getAsInteger(10, PatchableFunctionEntry);
950 if (PatchableFunctionPrefix) {
955 }
else if (PatchableFunctionEntry) {
975 std::vector<MCSymbol*> DeadBlockSyms;
977 for (
MCSymbol *DeadBlockSym : DeadBlockSyms) {
978 OutStreamer->AddComment(
"Address taken block that was later removed");
994 for (
const HandlerInfo &HI :
Handlers) {
997 HI.Handler->beginFunction(
MF);
999 for (
const HandlerInfo &HI :
Handlers) {
1002 HI.Handler->beginBasicBlockSection(
MF->
front());
1006 if (
F.hasPrologueData())
1010 if (
const MDNode *MD =
F.getMetadata(LLVMContext::MD_func_sanitize)) {
1013 assert(MD->getNumOperands() == 2);
1015 auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
1016 auto *FTRTTIProxy = mdconst::extract<Constant>(MD->getOperand(1));
1017 assert(PrologueSig && FTRTTIProxy);
1037 "' is a protected alias");
1062 std::optional<unsigned>
Size;
1064 CommentOS << *
Size <<
"-byte Reload\n";
1065 }
else if ((
Size =
MI.getFoldedRestoreSize(
TII))) {
1068 CommentOS <<
"Unknown-size Folded Reload\n";
1070 CommentOS << *
Size <<
"-byte Folded Reload\n";
1072 }
else if ((
Size =
MI.getSpillSize(
TII))) {
1073 CommentOS << *
Size <<
"-byte Spill\n";
1074 }
else if ((
Size =
MI.getFoldedSpillSize(
TII))) {
1077 CommentOS <<
"Unknown-size Folded Spill\n";
1079 CommentOS << *
Size <<
"-byte Folded Spill\n";
1085 CommentOS <<
" Reload Reuse\n";
1095 OS <<
"implicit-def: "
1107 assert(Op.isReg() &&
"KILL instruction must have only register operands");
1108 OS <<
' ' << (Op.isDef() ?
"def " :
"killed ")
1120 if (
MI->isNonListDebugValue() &&
MI->getNumOperands() != 4)
1125 OS <<
"DEBUG_VALUE: ";
1128 if (
auto *SP = dyn_cast<DISubprogram>(V->
getScope())) {
1140 Expr = *NonVariadicExpr;
1145 for (
auto &Op : Expr->
expr_ops()) {
1147 for (
unsigned I = 0;
I < Op.getNumArgs(); ++
I)
1148 OS <<
' ' << Op.getArg(
I);
1155 if (&Op !=
MI->debug_operands().begin())
1157 switch (Op.getType()) {
1160 Type *ImmTy = Op.getFPImm()->getType();
1179 Op.getCImm()->getValue().print(OS,
false );
1183 OS <<
"!target-index(" << Op.getIndex() <<
"," << Op.getOffset() <<
")";
1189 std::optional<StackOffset>
Offset;
1203 if (
MI->isIndirectDebugValue())
1209 OS <<
'+' <<
Offset->getFixed() <<
']';
1226 if (
MI->getNumOperands() != 1)
1231 OS <<
"DEBUG_LABEL: ";
1234 if (
auto *SP = dyn_cast<DISubprogram>(
1250 if (
F.isDeclarationForLinker())
1254 F.needsUnwindTableEntry())
1289 auto *
MBB =
MI.getParent();
1290 auto I = std::next(
MI.getIterator());
1291 while (
I !=
MBB->
end() &&
I->isTransient())
1298 unsigned CFIIndex =
MI.getOperand(0).getCFIIndex();
1305 MCSymbol *FrameAllocSym =
MI.getOperand(0).getMCSymbol();
1306 int FrameOffset =
MI.getOperand(1).getImm();
1333 assert(BBAddrMapSection &&
".llvm_bb_addr_map section is not initialized.");
1340 uint8_t BBAddrMapVersion =
OutStreamer->getContext().getBBAddrMapVersion();
1346 OutStreamer->AddComment(
"number of basic blocks");
1348 const MCSymbol *PrevMBBEndSymbol = FunctionSymbol;
1354 if (BBAddrMapVersion > 1) {
1384 OutStreamer->emitAbsoluteSymbolDiff(Symbol, Loc, 4);
1391 if (
const MDNode *MD =
F.getMetadata(LLVMContext::MD_kcfi_type))
1393 mdconst::extract<ConstantInt>(MD->getOperand(0)));
1398 auto GUID =
MI.getOperand(0).getImm();
1399 auto Index =
MI.getOperand(1).getImm();
1400 auto Type =
MI.getOperand(2).getImm();
1401 auto Attr =
MI.getOperand(3).getImm();
1413 if (!StackSizeSection)
1444 if (StackUsageStream ==
nullptr) {
1449 errs() <<
"Could not open file: " << EC.message();
1456 *StackUsageStream <<
':' << DSP->getLine();
1458 *StackUsageStream <<
':' <<
MF.
getName() <<
'\t' << StackSize <<
'\t';
1460 *StackUsageStream <<
"dynamic\n";
1462 *StackUsageStream <<
"static\n";
1469 PCSectionsSymbols[&MD].emplace_back(S);
1474 if (PCSectionsSymbols.empty() && !
F.hasMetadata(LLVMContext::MD_pcsections))
1478 const unsigned RelativeRelocSize =
1488 assert(S &&
"PC section is not initialized");
1500 if (
auto *S = dyn_cast<MDString>(MDO)) {
1501 SwitchSection(S->getString());
1502 const MCSymbol *Prev = Syms.front();
1504 if (Sym == Prev || !Deltas) {
1518 assert(isa<MDNode>(MDO) &&
"expecting either string or tuple");
1519 const auto *AuxMDs = cast<MDNode>(MDO);
1520 for (
const MDOperand &AuxMDO : AuxMDs->operands()) {
1521 assert(isa<ConstantAsMetadata>(AuxMDO) &&
"expecting a constant");
1522 const auto *
C = cast<ConstantAsMetadata>(AuxMDO);
1531 if (
const MDNode *MD =
F.getMetadata(LLVMContext::MD_pcsections))
1534 for (
const auto &MS : PCSectionsSymbols)
1535 EmitForMD(*MS.first, MS.second,
false);
1537 PCSectionsSymbols.clear();
1559 emitFunctionHeader();
1566 MDT = getAnalysisIfAvailable<MachineDominatorTree>();
1568 OwnedMDT = std::make_unique<MachineDominatorTree>();
1569 OwnedMDT->getBase().recalculate(*
MF);
1570 MDT = OwnedMDT.get();
1574 MLI = getAnalysisIfAvailable<MachineLoopInfo>();
1576 OwnedMLI = std::make_unique<MachineLoopInfo>();
1578 MLI = OwnedMLI.get();
1583 bool HasAnyRealCode =
false;
1584 int NumInstsInFunction = 0;
1587 for (
auto &
MBB : *
MF) {
1591 for (
auto &
MI :
MBB) {
1593 if (!
MI.isPosition() && !
MI.isImplicitDef() && !
MI.isKill() &&
1594 !
MI.isDebugInstr()) {
1595 HasAnyRealCode =
true;
1596 ++NumInstsInFunction;
1603 if (
MDNode *MD =
MI.getPCSections())
1609 HI.Handler->beginInstruction(&
MI);
1615 switch (
MI.getOpcode()) {
1616 case TargetOpcode::CFI_INSTRUCTION:
1619 case TargetOpcode::LOCAL_ESCAPE:
1622 case TargetOpcode::ANNOTATION_LABEL:
1623 case TargetOpcode::EH_LABEL:
1624 case TargetOpcode::GC_LABEL:
1627 case TargetOpcode::INLINEASM:
1628 case TargetOpcode::INLINEASM_BR:
1631 case TargetOpcode::DBG_VALUE:
1632 case TargetOpcode::DBG_VALUE_LIST:
1638 case TargetOpcode::DBG_INSTR_REF:
1643 case TargetOpcode::DBG_PHI:
1647 case TargetOpcode::DBG_LABEL:
1653 case TargetOpcode::IMPLICIT_DEF:
1656 case TargetOpcode::KILL:
1659 case TargetOpcode::PSEUDO_PROBE:
1662 case TargetOpcode::ARITH_FENCE:
1666 case TargetOpcode::MEMBARRIER:
1671 if (CanDoExtraAnalysis) {
1688 HI.Handler->endInstruction();
1709 OutStreamer->emitELFSize(CurrentSectionBeginSym, SizeExp);
1717 if (CanDoExtraAnalysis) {
1728 for (
auto &KV : MnemonicCounts)
1731 sort(MnemonicVec, [](
const std::pair<StringRef, unsigned> &
A,
1732 const std::pair<StringRef, unsigned> &
B) {
1733 if (
A.second >
B.second)
1735 if (
A.second ==
B.second)
1740 for (
auto &KV : MnemonicVec) {
1741 auto Name = (
Twine(
"INST_") + getToken(KV.first.trim()).first).str();
1742 R << KV.first <<
": " <<
ore::NV(
Name, KV.second) <<
"\n";
1748 EmittedInsts += NumInstsInFunction;
1752 R <<
ore::NV(
"NumInstructions", NumInstsInFunction)
1753 <<
" instructions in function";
1766 (TT.isOSWindows() && TT.isOSBinFormatCOFF()))) {
1772 OutStreamer->AddComment(
"avoids zero-length function");
1781 for (
const auto &BB :
F) {
1782 if (!BB.hasAddressTaken())
1787 OutStreamer->AddComment(
"Address of block that was removed by CodeGen");
1806 if (EmitFunctionSize) {
1823 HI.Handler->endBasicBlockSection(
MF->
back());
1829 HI.Handler->markFunctionEnd();
1842 HI.Handler->endFunction(
MF);
1862 OutStreamer->getCommentOS() <<
"-- End function\n";
1872 if (isa<GlobalVariable>(
C))
1875 unsigned NumUses = 0;
1876 for (
const auto *
CU :
C->users())
1888 unsigned &NumGOTEquivUsers) {
1899 for (
const auto *U : GV->
users())
1902 return NumGOTEquivUsers > 0;
1916 for (
const auto &
G : M.globals()) {
1917 unsigned NumGOTEquivUsers = 0;
1936 unsigned Cnt =
I.second.second;
1942 for (
const auto *GV : FailedCandidates)
1960 "Visibility should be handled with emitLinkage() on AIX.");
2007 if (LocalAlias !=
Name)
2026 "IFunc is not supported on AIX.");
2044 if (LocalAlias !=
Name)
2054 std::optional<SmallString<128>> Filename;
2055 if (std::optional<StringRef> FilenameRef = RS.
getFilename()) {
2056 Filename = *FilenameRef;
2058 assert(!Filename->empty() &&
"The filename can't be empty.");
2063 std::unique_ptr<remarks::MetaSerializer> MetaSerializer =
2066 MetaSerializer->emit();
2089 for (
const auto &
G : M.globals())
2099 if (!
F.isDeclarationForLinker())
2114 if (
F.isIntrinsic())
2141 if (!Stubs.empty()) {
2146 for (
const auto &Stub : Stubs) {
2148 OutStreamer->emitSymbolValue(Stub.second.getPointer(),
2149 DL.getPointerSize());
2160 if (!Stubs.empty()) {
2163 for (
const auto &Stub : Stubs) {
2175 OutStreamer->emitSymbolValue(Stub.second.getPointer(),
2176 DL.getPointerSize());
2184 TS->emitConstantPools();
2196 HI.Handler->endModule();
2213 for (
const auto &GO : M.global_objects()) {
2214 if (!GO.hasExternalWeakLinkage())
2219 auto SymbolName =
"swift_async_extendedFramePointerFlags";
2220 auto Global = M.getGlobalVariable(SymbolName);
2237 for (
const auto &Alias : M.aliases()) {
2238 if (Alias.hasAvailableExternallyLinkage())
2241 Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {
2242 if (!AliasVisited.
insert(Cur).second)
2247 emitGlobalAlias(M, *AncestorAlias);
2250 for (
const auto &IFunc : M.ifuncs())
2251 emitGlobalIFunc(M, IFunc);
2254 assert(
MI &&
"AsmPrinter didn't require GCModuleInfo?");
2257 MP->finishAssembly(M, *
MI, *
this);
2260 emitModuleIdents(M);
2263 emitModuleCommandLines(M);
2270 if (HasNoSplitStack)
2277 Function *InitTrampolineIntrinsic = M.getFunction(
"llvm.init.trampoline");
2278 if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->
use_empty())
2286 if (!GV.use_empty() && !GV.isThreadLocal() &&
2287 !GV.hasDLLImportStorageClass() && !GV.getName().startswith(
"llvm.") &&
2288 !GV.hasAtLeastLocalUnnamedAddr())
2295 unsigned UniqueID = 0;
2297 if (!GV.hasPartition() || GV.isDeclarationForLinker() ||
2303 "",
false, ++UniqueID,
nullptr));
2317 AddrLabelSymbols =
nullptr;
2331 return Res.first->second;
2341 HasSplitStack =
true;
2344 HasNoSplitStack =
true;
2346 HasNoSplitStack =
true;
2353 "Only AIX uses the function descriptor hooks.");
2358 " initalized first.");
2367 CurrentSectionBeginSym =
nullptr;
2369 MBBSectionExceptionSyms.clear();
2371 if (
F.hasFnAttribute(
"patchable-function-entry") ||
2372 F.hasFnAttribute(
"function-instrument") ||
2373 F.hasFnAttribute(
"xray-instruction-threshold") ||
2377 if (NeedsLocalForSize)
2381 ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
2403 const std::vector<MachineConstantPoolEntry> &CP = MCP->
getConstants();
2404 if (CP.empty())
return;
2409 for (
unsigned i = 0, e = CP.size(); i != e; ++i) {
2425 unsigned SecIdx = CPSections.
size();
2426 while (SecIdx != 0) {
2427 if (CPSections[--SecIdx].S == S) {
2433 SecIdx = CPSections.
size();
2434 CPSections.
push_back(SectionCPs(S, Alignment));
2437 if (Alignment > CPSections[SecIdx].Alignment)
2438 CPSections[SecIdx].Alignment = Alignment;
2445 for (
unsigned i = 0, e = CPSections.
size(); i != e; ++i) {
2446 for (
unsigned j = 0, ee = CPSections[i].CPEs.
size(); j != ee; ++j) {
2447 unsigned CPI = CPSections[i].CPEs[j];
2452 if (CurSection != CPSections[i].S) {
2455 CurSection = CPSections[i].S;
2483 const std::vector<MachineJumpTableEntry> &JT = MJTI->
getJumpTables();
2484 if (JT.empty())
return;
2493 if (JTInDiffSection) {
2503 if (!JTInDiffSection)
2506 for (
unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
2507 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
2510 if (JTBBs.empty())
continue;
2536 if (JTInDiffSection &&
DL.hasLinkerPrivateGlobalPrefix())
2546 emitJumpTableEntry(MJTI,
MBB, JTI);
2548 if (!JTInDiffSection)
2556 unsigned UID)
const {
2620 if (GV->
getName() ==
"llvm.used") {
2635 if (GV->
getName() ==
"llvm.global_ctors") {
2642 if (GV->
getName() ==
"llvm.global_dtors") {
2654void AsmPrinter::emitLLVMUsedList(
const ConstantArray *InitList) {
2656 for (
unsigned i = 0, e = InitList->
getNumOperands(); i != e; ++i) {
2669 if (!isa<ConstantArray>(
List))
2673 for (
Value *O : cast<ConstantArray>(
List)->operands()) {
2674 auto *CS = cast<ConstantStruct>(O);
2675 if (CS->getOperand(1)->isNullValue())
2677 ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
2684 if (!CS->getOperand(2)->isNullValue()) {
2687 "associated data of XXStructor list is not yet supported on AIX");
2689 dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());
2705 if (Structors.
empty())
2711 std::reverse(Structors.
begin(), Structors.
end());
2739void AsmPrinter::emitModuleIdents(
Module &M) {
2743 if (
const NamedMDNode *NMD = M.getNamedMetadata(
"llvm.ident")) {
2744 for (
unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2745 const MDNode *
N = NMD->getOperand(i);
2746 assert(
N->getNumOperands() == 1 &&
2747 "llvm.ident metadata entry can have only one operand");
2748 const MDString *S = cast<MDString>(
N->getOperand(0));
2754void AsmPrinter::emitModuleCommandLines(
Module &M) {
2759 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
2768 assert(
N->getNumOperands() == 1 &&
2769 "llvm.commandline metadata entry can have only one operand");
2770 const MDString *S = cast<MDString>(
N->getOperand(0));
2800 unsigned Size)
const {
2809 bool IsSectionRelative)
const {
2833 unsigned MaxBytesToEmit)
const {
2837 if (Alignment ==
Align(1))
2846 OutStreamer->emitCodeAlignment(Alignment, STI, MaxBytesToEmit);
2848 OutStreamer->emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);
2861 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
2864 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
2867 if (
const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
2870 if (
const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
2884 switch (CE->getOpcode()) {
2887 case Instruction::AddrSpaceCast: {
2888 const Constant *Op = CE->getOperand(0);
2889 unsigned DstAS = CE->getType()->getPointerAddressSpace();
2890 unsigned SrcAS = Op->getType()->getPointerAddressSpace();
2896 case Instruction::GetElementPtr: {
2899 cast<GEPOperator>(CE)->accumulateConstantOffset(
getDataLayout(), OffsetAI);
2910 case Instruction::Trunc:
2916 case Instruction::BitCast:
2919 case Instruction::IntToPtr: {
2930 case Instruction::PtrToInt: {
2936 Type *Ty = CE->getType();
2945 if (
DL.getTypeAllocSize(Ty).getFixedValue() <=
2946 DL.getTypeAllocSize(Op->getType()).getFixedValue())
2952 case Instruction::Sub: {
2962 const MCExpr *RelocExpr =
2974 int64_t Addend = (LHSOffset - RHSOffset).getSExtValue();
2988 case Instruction::Add: {
3005 OS <<
"Unsupported expression in static initializer: ";
3006 CE->printAsOperand(OS,
false,
3025 assert(!
Data.empty() &&
"Empty aggregates should be CAZ node");
3027 for (
unsigned i = 1, e =
Data.size(); i != e; ++i)
3028 if (
Data[i] !=
C)
return -1;
3029 return static_cast<uint8_t
>(
C);
3036 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
3042 if (!
Value.isSplat(8))
3045 return Value.zextOrTrunc(8).getZExtValue();
3050 assert(CA->getNumOperands() != 0 &&
"Should be a CAZ");
3057 for (
unsigned i = 1, e = CA->getNumOperands(); i != e; ++i)
3058 if (CA->getOperand(i) != Op0)
3073 if (AliasIt != AliasList->
end()) {
3117 unsigned EmittedSize =
3119 assert(EmittedSize <=
Size &&
"Size cannot be less than EmittedSize!");
3120 if (
unsigned Padding =
Size - EmittedSize)
3150 uint64_t ElementSizeInBits =
DL.getTypeSizeInBits(ElementType);
3151 uint64_t ElementAllocSizeInBits =
DL.getTypeAllocSizeInBits(ElementType);
3153 if (ElementSizeInBits != ElementAllocSizeInBits) {
3165 "Cannot lower vector global with unusual element type");
3169 EmittedSize =
DL.getTypeStoreSize(CV->
getType());
3180 if (
unsigned Padding =
Size - EmittedSize)
3204 SizeSoFar += FieldSize + PadSize;
3212 "Layout of constant struct may be incorrect!");
3216 assert(ET &&
"Unknown float type");
3225 AP.
OutStreamer->getCommentOS() <<
' ' << StrVal <<
'\n';
3232 unsigned TrailingBytes = NumBytes %
sizeof(
uint64_t);
3241 AP.
OutStreamer->emitIntValueInHexWithPadding(p[Chunk--], TrailingBytes);
3243 for (; Chunk >= 0; --Chunk)
3247 for (Chunk = 0; Chunk < NumBytes /
sizeof(
uint64_t); ++Chunk)
3251 AP.
OutStreamer->emitIntValueInHexWithPadding(p[Chunk], TrailingBytes);
3256 AP.
OutStreamer->emitZeros(
DL.getTypeAllocSize(ET) -
DL.getTypeStoreSize(ET));
3271 unsigned ExtraBitsSize =
BitWidth & 63;
3273 if (ExtraBitsSize) {
3281 if (
DL.isBigEndian()) {
3290 ExtraBitsSize =
alignTo(ExtraBitsSize, 8);
3292 (((
uint64_t)-1) >> (64 - ExtraBitsSize));
3302 for (
unsigned i = 0, e =
BitWidth / 64; i != e; ++i) {
3303 uint64_t Val =
DL.isBigEndian() ? RawData[e - i - 1] : RawData[i];
3307 if (ExtraBitsSize) {
3314 (ExtraBits & (((
uint64_t)-1) >> (64 - ExtraBitsSize)))
3315 == ExtraBits &&
"Directive too small for extra bits.");
3347 if (!(*ME)->evaluateAsRelocatable(MV,
nullptr,
nullptr) || MV.
isAbsolute())
3358 const GlobalValue *BaseGV = dyn_cast_or_null<GlobalValue>(BaseCst);
3366 if (!SymB || BaseSym != &SymB->
getSymbol())
3377 if (GOTPCRelCst < 0)
3399 int NumUses = (int)Result.second;
3422 BaseCV = dyn_cast<Constant>(CV->
user_back());
3424 if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
3427 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
3430 if (StoreSize <= 8) {
3433 <<
format(
"0x%" PRIx64
"\n", CI->getZExtValue());
3434 AP.
OutStreamer->emitIntValue(CI->getZExtValue(), StoreSize);
3440 if (
Size != StoreSize)
3446 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
3449 if (isa<ConstantPointerNull>(CV)) {
3463 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
3466 if (CE->getOpcode() == Instruction::BitCast)
3510 for (
auto &AliasPair : *AliasList) {
3564 if (
MCSymbol *Sym = S->getCOMDATSymbol()) {
3565 if (Sym->isUndefined())
3607 unsigned FunctionNumber) {
3611 <<
"Parent Loop BB" << FunctionNumber <<
"_"
3619 unsigned FunctionNumber) {
3622 OS.
indent(CL->getLoopDepth()*2)
3623 <<
"Child Loop BB" << FunctionNumber <<
"_"
3624 << CL->getHeader()->getNumber() <<
" Depth " << CL->getLoopDepth()
3639 assert(Header &&
"No header for loop");
3643 if (Header != &
MBB) {
3644 AP.
OutStreamer->AddComment(
" in Loop: Header=BB" +
3675 HI.Handler->endFunclet();
3676 HI.Handler->beginFunclet(
MBB);
3692 if (Alignment !=
Align(1))
3714 if (BB->hasName()) {
3716 false, BB->getModule());
3721 assert(
MLI !=
nullptr &&
"MachineLoopInfo should has been computed");
3726 if (shouldEmitLabelForBasicBlock(
MBB)) {
3728 OutStreamer->AddComment(
"Label of block must be emitted");
3748 HI.Handler->beginBasicBlockSection(
MBB);
3756 HI.Handler->endBasicBlockSection(
MBB);
3760 bool IsDefinition)
const {
3763 switch (Visibility) {
3780bool AsmPrinter::shouldEmitLabelForBasicBlock(
3821 if (!
MI.isBranch() ||
MI.isIndirectBranch())
3830 if (
OP->isMBB() &&
OP->getMBB() ==
MBB)
3842 auto [GCPI, Inserted] = GCMetadataPrinters.insert({&S,
nullptr});
3844 return GCPI->second.get();
3850 if (
Name == GCMetaPrinter.getName()) {
3851 std::unique_ptr<GCMetadataPrinter> GMP = GCMetaPrinter.instantiate();
3853 GCPI->second = std::move(GMP);
3854 return GCPI->second.get();
3862 assert(
MI &&
"AsmPrinter didn't require GCModuleInfo?");
3863 bool NeedsDefault =
false;
3864 if (
MI->begin() ==
MI->end())
3866 NeedsDefault =
true;
3868 for (
const auto &
I : *
MI) {
3870 if (MP->emitStackMaps(
SM, *
this))
3874 NeedsDefault =
true;
3890 auto Kind8 =
static_cast<uint8_t
>(
Kind);
3895 auto Padding = (4 * Bytes) - ((2 * Bytes) + 3);
3896 assert(Padding >= 0 &&
"Instrumentation map entry > 4 * Word Size");
3904 auto PrevSection =
OutStreamer->getCurrentSectionOnly();
3910 if (TT.isOSBinFormatELF()) {
3914 if (
F.hasComdat()) {
3916 GroupName =
F.getComdat()->getName();
3919 Flags, 0, GroupName,
F.hasComdat(),
3945 for (
const auto &Sled :
Sleds) {
3946 MCSymbol *Dot = Ctx.createTempSymbol();
3973 OutStreamer->emitSymbolValue(SledsStart, WordSizeBytes,
false);
3974 OutStreamer->emitSymbolValue(SledsEnd, WordSizeBytes,
false);
3983 auto Attr =
F.getFnAttribute(
"function-instrument");
3984 bool LogArgs =
F.hasFnAttribute(
"xray-log-args");
3985 bool AlwaysInstrument =
3986 Attr.isStringAttribute() && Attr.getValueAsString() ==
"xray-always";
3990 AlwaysInstrument, &
F, Version});
3995 unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0;
3996 (void)
F.getFnAttribute(
"patchable-function-prefix")
3998 .getAsInteger(10, PatchableFunctionPrefix);
3999 (void)
F.getFnAttribute(
"patchable-function-entry")
4001 .getAsInteger(10, PatchableFunctionEntry);
4002 if (!PatchableFunctionPrefix && !PatchableFunctionEntry)
4014 if (
F.hasComdat()) {
4016 GroupName =
F.getComdat()->getName();
4029 return OutStreamer->getContext().getDwarfVersion();
4033 OutStreamer->getContext().setDwarfVersion(Version);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This header is deprecated in favour of llvm/TargetParser/Triple.h.
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 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[]
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 unsigned getBBAddrMapMetadata(const MachineBasicBlock &MBB)
Returns the BB metadata to be emitted in the .llvm_bb_addr_map section for a given basic block.
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
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
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
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
void emitGlobalGOTEquivs()
Constant expressions using GOT equivalent globals may not be eligible for PC relative GOT entry conve...
MCSymbol * getFunctionBegin() const
void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) const
Emit something like ".long Hi-Lo" where the size in bytes of the directive is specified by Size and H...
void emitKCFITrapEntry(const MachineFunction &MF, const MCSymbol *Symbol)
MCSymbol * getMBBExceptionSym(const MachineBasicBlock &MBB)
MCSymbol * getAddrLabelSymbol(const BasicBlock *BB)
Return the symbol to be used for the specified basic block when its address is taken.
const MCAsmInfo * MAI
Target Asm Printer information.
bool emitSpecialLLVMGlobal(const GlobalVariable *GV)
Check to see if the specified global is a special global used by LLVM.
MachineFunction * MF
The current machine function.
virtual void emitJumpTableInfo()
Print assembly representations of the jump tables used by the current function to the current output ...
void computeGlobalGOTEquivs(Module &M)
Unnamed constant global variables solely contaning a pointer to another globals variable act like a g...
static Align getGVAlignment(const GlobalObject *GV, const DataLayout &DL, Align InAlign=Align(1))
Return the alignment for the specified GV.
void emitInt8(int Value) const
Emit a byte directive and value.
CFISection getFunctionCFISectionType(const Function &F) const
Get the CFISection type for a function.
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const
Return true if the basic block has exactly one predecessor and the control transfer mechanism between...
void emitBBAddrMapSection(const MachineFunction &MF)
void emitPCSections(const MachineFunction &MF)
Emits the PC sections collected from instructions.
MapVector< unsigned, MBBSectionRange > MBBSectionRanges
MachineDominatorTree * MDT
This is a pointer to the current MachineDominatorTree.
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
virtual void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV)
void emitStackMaps()
Emit the stack maps.
virtual void emitFunctionBodyStart()
Targets can override this to emit stuff before the first basic block in the function.
std::pair< const GlobalVariable *, unsigned > GOTEquivUsePair
Map global GOT equivalent MCSymbols to GlobalVariables and keep track of its number of uses by other ...
void emitPatchableFunctionEntries()
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind, uint8_t Version=0)
virtual void emitEndOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the end of their file...
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
MCSymbol * GetJTSetSymbol(unsigned UID, unsigned MBBID) const
Return the symbol for the specified jump table .set FIXME: privatize to AsmPrinter.
virtual void emitImplicitDef(const MachineInstr *MI) const
Targets can override this to customize the output of IMPLICIT_DEF instructions in verbose mode.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
unsigned getFunctionNumber() const
Return a unique ID for the current function.
MachineOptimizationRemarkEmitter * ORE
Optimization remark emitter.
virtual bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
void emitGlobalConstant(const DataLayout &DL, const Constant *CV, AliasMapTy *AliasList=nullptr)
EmitGlobalConstant - Print a general LLVM constant to the .s file.
void emitFrameAlloc(const MachineInstr &MI)
void emitStackSizeSection(const MachineFunction &MF)
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
MCSymbol * CurrentFnSym
The symbol for the current function.
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
void emitCFIInstruction(const MachineInstr &MI)
MCSymbol * createTempSymbol(const Twine &Name) const
bool doFinalization(Module &M) override
Shut down the asmprinter.
void emitStackUsage(const MachineFunction &MF)
MCSymbol * GetExternalSymbolSymbol(StringRef Sym) const
Return the MCSymbol for the specified ExternalSymbol.
virtual void emitKCFITypeId(const MachineFunction &MF)
bool isPositionIndependent() const
virtual void emitXXStructorList(const DataLayout &DL, const Constant *List, bool IsCtor)
This method emits llvm.global_ctors or llvm.global_dtors list.
void emitPCSectionsLabel(const MachineFunction &MF, const MDNode &MD)
Emits a label as reference for PC sections.
MCSymbol * CurrentPatchableFunctionEntrySym
The symbol for the entry in __patchable_function_entires.
virtual void emitBasicBlockStart(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the start of a basic block.
void takeDeletedSymbolsForFunction(const Function *F, std::vector< MCSymbol * > &Result)
If the specified function has had any references to address-taken blocks generated,...
void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const
This emits visibility information about symbol, if this is supported by the target.
void emitInt32(int Value) const
Emit a long directive and value.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
virtual const MCExpr * lowerConstant(const Constant *CV)
Lower the specified LLVM Constant to an MCExpr.