33#include "llvm/Config/llvm-config.h"
97 cl::desc(
"Print addresses of instructions when dumping"));
101 cl::desc(
"Pretty print debug locations of instructions when dumping"));
105 cl::desc(
"Pretty print perf data (branch weights, etc) when dumping"));
109 cl::desc(
"Preserve use-list order when writing LLVM assembly."));
113 cl::desc(
"Print address space names"));
132 return VAM->getValue();
145 for (
const Value *
Op :
C->operands())
152 unsigned ID = OM.size() + 1;
159 auto OrderConstantValue = [&OM](
const Value *V) {
164 auto OrderConstantFromMetadata = [&](
Metadata *MD) {
166 OrderConstantValue(VAM->getValue());
168 for (
const auto *VAM : AL->getArgs())
169 OrderConstantValue(VAM->getValue());
174 if (
G.hasInitializer())
190 for (
const Use &U :
F.operands())
196 if (
F.isDeclaration())
209 OrderConstantFromMetadata(DVR.getRawLocation());
210 if (DVR.isDbgAssign())
211 OrderConstantFromMetadata(DVR.getRawAddress());
214 for (
const Value *
Op :
I.operands()) {
227static std::vector<unsigned>
230 using Entry = std::pair<const Use *, unsigned>;
234 if (OM.lookup(U.getUser()))
235 List.
push_back(std::make_pair(&U, List.size()));
246 ID = OM.lookup(BA->getBasicBlock());
247 llvm::sort(List, [&](
const Entry &L,
const Entry &R) {
248 const Use *LU = L.first;
249 const Use *RU = R.first;
253 auto LID = OM.lookup(LU->getUser());
254 auto RID = OM.lookup(RU->getUser());
274 return LU->getOperandNo() < RU->getOperandNo();
275 return LU->getOperandNo() > RU->getOperandNo();
283 std::vector<unsigned> Shuffle(List.size());
284 for (
size_t I = 0,
E = List.size();
I !=
E; ++
I)
285 Shuffle[
I] = List[
I].second;
292 for (
const auto &Pair : OM) {
293 const Value *V = Pair.first;
294 if (V->use_empty() || std::next(V->use_begin()) == V->use_end())
297 std::vector<unsigned> Shuffle =
304 F =
I->getFunction();
309 ULOM[
F][V] = std::move(Shuffle);
316 return MA->getParent() ? MA->getParent()->getParent() :
nullptr;
319 return BB->getParent() ? BB->getParent()->getParent() :
nullptr;
322 const Function *M =
I->getParent() ?
I->getParent()->getParent() :
nullptr;
323 return M ? M->getParent() :
nullptr;
327 return GV->getParent();
352 default: Out <<
"cc" << cc;
break;
375 Out <<
"aarch64_sve_vector_pcs";
378 Out <<
"aarch64_sme_preservemost_from_x0";
381 Out <<
"aarch64_sme_preservemost_from_x1";
384 Out <<
"aarch64_sme_preservemost_from_x2";
412 Out <<
"amdgpu_cs_chain";
415 Out <<
"amdgpu_cs_chain_preserve";
420 Out <<
"amdgpu_gfx_whole_wave";
424 Out <<
"riscv_vector_cc";
426#define CC_VLS_CASE(ABI_VLEN) \
427 case CallingConv::RISCV_VLSCall_##ABI_VLEN: \
428 Out << "riscv_vls_cc(" #ABI_VLEN ")"; \
444 Out <<
"cheriot_compartmentcallcc";
447 Out <<
"cheriot_compartmentcalleecc";
450 Out <<
"cheriot_librarycallcc";
464 assert(!Name.empty() &&
"Cannot get empty name!");
467 bool NeedsQuotes = isdigit(
static_cast<unsigned char>(Name[0]));
469 for (
unsigned char C : Name) {
474 if (!isalnum(
C) &&
C !=
'-' &&
C !=
'.' &&
C !=
'_') {
528 Out << Mask.size() <<
" x i32> ";
530 Out <<
"zeroinitializer";
536 for (
int Elt : Mask) {
551 TypePrinting(
const Module *M =
nullptr)
552 : M(M), TypesIncorporated(M == nullptr) {}
554 TypePrinting(
const TypePrinting &) =
delete;
555 TypePrinting &operator=(
const TypePrinting &) =
delete;
558 TypeFinder &getNamedTypes();
561 std::vector<StructType *> &getNumberedTypes();
567 void printStructBody(StructType *Ty, raw_ostream &OS);
570 void incorporateTypes();
574 bool TypesIncorporated;
576 TypeFinder NamedTypes;
579 DenseMap<StructType *, unsigned> Type2Number;
581 std::vector<StructType *> NumberedTypes;
591std::vector<StructType *> &TypePrinting::getNumberedTypes() {
597 if (NumberedTypes.size() == Type2Number.size())
598 return NumberedTypes;
600 NumberedTypes.resize(Type2Number.size());
601 for (
const auto &
P : Type2Number) {
602 assert(
P.second < NumberedTypes.size() &&
"Didn't get a dense numbering?");
603 assert(!NumberedTypes[
P.second] &&
"Didn't get a unique numbering?");
604 NumberedTypes[
P.second] =
P.first;
606 return NumberedTypes;
609bool TypePrinting::empty() {
611 return NamedTypes.
empty() && Type2Number.empty();
614void TypePrinting::incorporateTypes() {
615 if (TypesIncorporated)
618 NamedTypes.
run(*M,
false);
619 TypesIncorporated =
true;
623 unsigned NextNumber = 0;
625 std::vector<StructType *>::iterator NextToUse = NamedTypes.
begin();
626 for (StructType *STy : NamedTypes) {
628 if (STy->isLiteral())
631 if (STy->getName().empty())
632 Type2Number[STy] = NextNumber++;
637 NamedTypes.erase(NextToUse, NamedTypes.end());
642 bool ForcePrint =
false) {
643 if (AS == 0 && !ForcePrint)
645 OS << Prefix <<
"addrspace(";
649 OS <<
"\"" << ASName <<
"\"";
657void TypePrinting::print(
Type *Ty, raw_ostream &OS) {
659 case Type::VoidTyID: OS <<
"void";
return;
660 case Type::HalfTyID: OS <<
"half";
return;
661 case Type::BFloatTyID: OS <<
"bfloat";
return;
662 case Type::FloatTyID: OS <<
"float";
return;
663 case Type::DoubleTyID: OS <<
"double";
return;
664 case Type::X86_FP80TyID: OS <<
"x86_fp80";
return;
665 case Type::FP128TyID: OS <<
"fp128";
return;
666 case Type::PPC_FP128TyID: OS <<
"ppc_fp128";
return;
667 case Type::LabelTyID: OS <<
"label";
return;
668 case Type::MetadataTyID:
671 case Type::X86_AMXTyID: OS <<
"x86_amx";
return;
672 case Type::TokenTyID: OS <<
"token";
return;
676 case Type::IntegerTyID:
677 OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
680 case Type::FunctionTyID: {
682 print(FTy->getReturnType(), OS);
685 for (
Type *Ty : FTy->params()) {
694 case Type::StructTyID: {
698 return printStructBody(STy, OS);
704 const auto I = Type2Number.find(STy);
705 if (
I != Type2Number.end())
706 OS <<
'%' <<
I->second;
708 OS <<
"%\"type " << STy <<
'\"';
711 case Type::PointerTyID: {
717 case Type::ArrayTyID: {
719 OS <<
'[' << ATy->getNumElements() <<
" x ";
720 print(ATy->getElementType(), OS);
724 case Type::FixedVectorTyID:
725 case Type::ScalableVectorTyID: {
727 ElementCount
EC = PTy->getElementCount();
731 OS <<
EC.getKnownMinValue() <<
" x ";
732 print(PTy->getElementType(), OS);
736 case Type::TypedPointerTyID: {
742 case Type::TargetExtTyID:
749 Inner->print(OS,
false,
true);
752 OS <<
", " << IntParam;
759void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
801 const Function* TheFunction =
nullptr;
802 bool FunctionProcessed =
false;
803 bool ShouldTrackMetadataDefinitions;
808 ProcessFunctionHookFn;
829 unsigned ModulePathNext = 0;
833 unsigned GUIDNext = 0;
837 unsigned TypeIdNext = 0;
842 unsigned TypeIdCompatibleVtableNext = 0;
848 bool ShouldTrackMetadataDefinitions =
false);
884 FunctionProcessed =
false;
892 void purgeFunction();
899 unsigned mdn_size()
const {
return mdnMap.size(); }
907 unsigned as_size()
const {
return asMap.size(); }
923 void CreateMetadataSlot(
const MDNode *
N);
926 void CreateFunctionSlot(
const Value *V);
931 inline void CreateModulePathSlot(
StringRef Path);
934 void CreateTypeIdCompatibleVtableSlot(
StringRef Id);
948 : M(M), F(F), Machine(&Machine) {}
951 : ShouldCreateStorage(M), M(M) {}
956 if (!ShouldCreateStorage)
959 ShouldCreateStorage =
false;
960 MachineStorage = std::make_unique<SlotTracker>(M);
961 Machine = MachineStorage.get();
962 if (ProcessModuleHookFn)
963 Machine->setProcessHook(ProcessModuleHookFn);
964 if (ProcessFunctionHookFn)
965 Machine->setProcessHook(ProcessFunctionHookFn);
978 Machine->purgeFunction();
979 Machine->incorporateFunction(&F);
984 assert(F &&
"No function incorporated");
985 return Machine->getLocalSlot(V);
990 ProcessModuleHookFn = std::move(Fn);
995 ProcessFunctionHookFn = std::move(Fn);
1025#define ST_DEBUG(X) dbgs() << X
1034 ShouldTrackMetadataDefinitions(ShouldTrackMetadataDefinitions) {}
1039 : TheModule(
F ?
F->
getParent() : nullptr), TheFunction(
F),
1040 ShouldTrackMetadataDefinitions(
false) {}
1043 : TheModule(nullptr), ShouldTrackMetadataDefinitions(
false),
1049 TheModule =
nullptr;
1052 if (TheFunction && !FunctionProcessed)
1059 int NumSlots = processIndex();
1066void SlotTracker::processModule() {
1067 ST_DEBUG(
"begin processModule!\n");
1072 CreateModuleSlot(&Var);
1073 auto Attrs = Var.getAttributes();
1074 if (Attrs.hasAttributes())
1075 CreateAttributeSetSlot(Attrs);
1080 CreateModuleSlot(&
A);
1083 for (
const GlobalIFunc &
I : TheModule->ifuncs()) {
1085 CreateModuleSlot(&
I);
1091 CreateModuleSlot(&
F);
1095 AttributeSet FnAttrs =
F.getAttributes().getFnAttrs();
1097 CreateAttributeSetSlot(FnAttrs);
1100 if (ProcessModuleHookFn)
1101 ProcessModuleHookFn(
this, TheModule);
1107void SlotTracker::processFunction() {
1108 ST_DEBUG(
"begin processFunction!\n");
1113 AE = TheFunction->arg_end(); AI != AE; ++AI)
1115 CreateFunctionSlot(&*AI);
1117 ST_DEBUG(
"Inserting Instructions:\n");
1120 for (
auto &BB : *TheFunction) {
1122 CreateFunctionSlot(&BB);
1124 for (
auto &
I : BB) {
1125 if (!
I.getType()->isVoidTy() && !
I.hasName())
1126 CreateFunctionSlot(&
I);
1133 if (
Attrs.hasAttributes())
1134 CreateAttributeSetSlot(Attrs);
1139 if (ProcessFunctionHookFn)
1140 ProcessFunctionHookFn(
this, TheFunction);
1142 FunctionProcessed =
true;
1144 ST_DEBUG(
"end processFunction!\n");
1148int SlotTracker::processIndex() {
1155 std::vector<StringRef> ModulePaths;
1156 for (
auto &[ModPath,
_] : TheIndex->modulePaths())
1157 ModulePaths.push_back(ModPath);
1159 for (
auto &ModPath : ModulePaths)
1160 CreateModulePathSlot(ModPath);
1163 GUIDNext = ModulePathNext;
1166 for (
const auto &GlobalList : TheIndex->sortedGlobalValueSummariesRange())
1167 CreateGUIDSlot(GlobalList.first);
1170 TypeIdCompatibleVtableNext = GUIDNext;
1171 for (
auto &TId : TheIndex->typeIdCompatibleVtableMap())
1172 CreateTypeIdCompatibleVtableSlot(TId.first);
1175 TypeIdNext = TypeIdCompatibleVtableNext;
1176 for (
const auto &TID : TheIndex->typeIds())
1177 CreateTypeIdSlot(TID.second.first);
1184class MetadataNodeVisitor {
1186 SmallPtrSet<const MDNode *, 32> VisitedMDNodes;
1187 function_ref<void(
const MDNode *)> Visit;
1189 void visit(
const MDNode *
N) {
1194 for (
const MDOperand &
Op :
N->operands())
1199 void visitGlobalObjectMetadata(
const GlobalObject &GO) {
1202 for (
auto &MD : MDs)
1206 void visitDbgRecordMetadata(
const DbgRecord &DR) {
1210 if (DVR->getRawVariable())
1211 visit(DVR->getRawVariable());
1212 if (DVR->isDbgAssign()) {
1213 if (
auto *AssignID = DVR->getRawAssignID())
1219 visit(DLR->getRawLabel());
1227 void visitInstructionMetadata(
const Instruction &
I) {
1229 if (
Function *
F = CI->getCalledFunction())
1230 if (
F->isIntrinsic())
1231 for (
auto &
Op :
I.operands())
1237 I.getAllMetadata(MDs);
1238 for (
auto &MD : MDs)
1242 void visitFunctionMetadata(
const Function &
F) {
1243 visitGlobalObjectMetadata(
F);
1244 for (
const BasicBlock &BB :
F)
1245 for (
const Instruction &
I : BB) {
1246 for (
const DbgRecord &DR :
I.getDbgRecordRange())
1247 visitDbgRecordMetadata(DR);
1248 visitInstructionMetadata(
I);
1253 MetadataNodeVisitor(function_ref<
void(
const MDNode *)> Visit)
1256 void visitModuleMetadata(
const Module &M) {
1257 for (
const GlobalVariable &Var :
M.globals())
1258 visitGlobalObjectMetadata(Var);
1259 for (
const GlobalIFunc &
I :
M.ifuncs())
1260 visitGlobalObjectMetadata(
I);
1261 for (
const NamedMDNode &NMD :
M.named_metadata())
1262 for (
const MDNode *
N : NMD.operands())
1265 visitFunctionMetadata(
F);
1276class MetadataIDRenumberer {
1277 uint32_t NextID = 0;
1283 bool IsAdditionalMetadata =
false;
1284 auto Renumber = [&](
const MDNode *
N) {
1285 N->getContext().pImpl->setMetadataPrintID(
const_cast<MDNode *
>(
N),
1287 if (IsAdditionalMetadata && AdditionalMetadataNodes)
1288 AdditionalMetadataNodes->emplace_back(
1289 N->getContext().pImpl->getMetadataPrintID(
N),
N);
1291 MetadataNodeVisitor Visitor(Renumber);
1293 Visitor.visitModuleMetadata(M);
1295 IsAdditionalMetadata =
true;
1296 Visitor.visitMetadata(AdditionalMetadata);
1300 M.getContext().pImpl->getAllMetadataNodes(RemainingNodes);
1302 return Visitor.contains(
N) ||
1303 M.getContext().pImpl->getMetadataPrintID(
N) >= NextID;
1306 return M.getContext().pImpl->getMetadataPrintID(
LHS) <
1307 M.getContext().pImpl->getMetadataPrintID(
RHS);
1309 for (MDNode *
N : RemainingNodes)
1310 M.getContext().pImpl->setMetadataPrintID(
1311 N,
M.getContext().pImpl->allocateMetadataPrintID());
1313 if (AdditionalMetadataNodes)
1320 MetadataIDRenumberer().run(*
this, {});
1326 assert(M &&
"metadata renumbering requires a module");
1327 MetadataIDRenumberer().run(*M, AdditionalMetadata, AdditionalMetadataNodes);
1333 assert(M &&
"metadata collection requires a module");
1334 bool IsAdditionalMetadata =
false;
1335 auto Collect = [&](
const MDNode *
N) {
1336 if (IsAdditionalMetadata)
1338 N->getContext().pImpl->getMetadataPrintID(
N),
N);
1340 MetadataNodeVisitor Visitor(Collect);
1341 Visitor.visitModuleMetadata(*M);
1342 IsAdditionalMetadata =
true;
1343 Visitor.visitMetadata(AdditionalMetadata);
1351 ST_DEBUG(
"begin purgeFunction!\n");
1353 TheFunction =
nullptr;
1354 FunctionProcessed =
false;
1365 return MI == mMap.end() ? -1 : (int)
MI->second;
1370 ProcessModuleHookFn = std::move(Fn);
1375 ProcessFunctionHookFn = std::move(Fn);
1388 if (ShouldTrackMetadataDefinitions)
1389 CreateMetadataSlot(
N);
1390 return N->getContext().pImpl->getMetadataPrintID(
N);
1401 return FI == fMap.end() ? -1 : (int)FI->second;
1410 return AI == asMap.end() ? -1 : (int)AI->second;
1418 auto I = ModulePathMap.find(Path);
1419 return I == ModulePathMap.end() ? -1 : (int)
I->second;
1428 return I == GUIDMap.end() ? -1 : (int)
I->second;
1436 auto I = TypeIdMap.find(Id);
1437 return I == TypeIdMap.end() ? -1 : (int)
I->second;
1445 auto I = TypeIdCompatibleVtableMap.find(Id);
1446 return I == TypeIdCompatibleVtableMap.end() ? -1 : (int)
I->second;
1450void SlotTracker::CreateModuleSlot(
const GlobalValue *V) {
1451 assert(V &&
"Can't insert a null Value into SlotTracker!");
1452 assert(!V->getType()->isVoidTy() &&
"Doesn't need a slot!");
1453 assert(!V->hasName() &&
"Doesn't need a slot!");
1455 unsigned DestSlot = mNext++;
1458 ST_DEBUG(
" Inserting value [" << V->getType() <<
"] = " << V <<
" slot=" <<
1468void SlotTracker::CreateFunctionSlot(
const Value *V) {
1469 assert(!V->getType()->isVoidTy() && !V->hasName() &&
"Doesn't need a slot!");
1471 unsigned DestSlot = fNext++;
1475 ST_DEBUG(
" Inserting value [" << V->getType() <<
"] = " << V <<
" slot=" <<
1476 DestSlot <<
" [o]\n");
1480void SlotTracker::CreateMetadataSlot(
const MDNode *
N) {
1481 assert(
N &&
"Can't insert a null Value into SlotTracker!");
1486 unsigned ID =
N->getContext().pImpl->getMetadataPrintID(
N);
1487 if (!mdnMap.try_emplace(
N, ID).second)
1490 for (
const MDOperand &
Op :
N->operands())
1492 CreateMetadataSlot(OpNode);
1495void SlotTracker::CreateAttributeSetSlot(
AttributeSet AS) {
1498 if (asMap.try_emplace(AS, asNext).second)
1503void SlotTracker::CreateModulePathSlot(
StringRef Path) {
1504 ModulePathMap[
Path] = ModulePathNext++;
1509 GUIDMap[
GUID] = GUIDNext++;
1513void SlotTracker::CreateTypeIdSlot(
StringRef Id) {
1514 TypeIdMap[
Id] = TypeIdNext++;
1518void SlotTracker::CreateTypeIdCompatibleVtableSlot(
StringRef Id) {
1519 TypeIdCompatibleVtableMap[
Id] = TypeIdCompatibleVtableNext++;
1524struct AsmWriterContext {
1525 TypePrinting *TypePrinter =
nullptr;
1526 SlotTracker *
Machine =
nullptr;
1528 const ModuleSlotTracker *MST =
nullptr;
1530 AsmWriterContext(TypePrinting *TP, SlotTracker *ST,
const Module *M =
nullptr,
1531 const ModuleSlotTracker *MST =
nullptr)
1534 static AsmWriterContext &getEmpty() {
1535 static AsmWriterContext EmptyCtx(
nullptr,
nullptr);
1541 virtual void onWriteMetadataAsOperand(
const Metadata *) {}
1543 virtual ~AsmWriterContext() =
default;
1552 AsmWriterContext &WriterCtx,
1553 bool PrintType =
false);
1556 AsmWriterContext &WriterCtx,
1557 bool FromValue =
false);
1561 Out << FPO->getFastMathFlags();
1564 if (OBO->hasNoUnsignedWrap())
1566 if (OBO->hasNoSignedWrap())
1572 if (PDI->isDisjoint())
1575 if (
GEP->isInBounds())
1577 else if (
GEP->hasNoUnsignedSignedWrap())
1579 if (
GEP->hasNoUnsignedWrap())
1582 Out <<
" inrange(" <<
InRange->getLower() <<
", " <<
InRange->getUpper()
1586 if (NNI->hasNonNeg())
1589 if (TI->hasNoUnsignedWrap())
1591 if (TI->hasNoSignedWrap())
1594 if (ICmp->hasSameSign())
1597 if (ASC->hasNonNull())
1605 unsigned NumDigits = std::max((Val.
getBitWidth() + 3) / 4, 1U);
1607 for (
unsigned i = 0; i < NumDigits - Bits.size(); i++)
1613 bool ForceBitwiseOutput =
false;
1619 ForceBitwiseOutput = !HiWord.
isZero();
1622 if (!ForceBitwiseOutput) {
1625 Out << (APF.
isNegative() ?
'-' :
'+') <<
"inf";
1667 AsmWriterContext &WriterCtx) {
1669 Type *Ty = CI->getType();
1671 if (Ty->isVectorTy()) {
1673 WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
1677 if (Ty->getScalarType()->isIntegerTy(1))
1678 Out << (CI->getZExtValue() ?
"true" :
"false");
1680 Out << CI->getValue();
1682 if (Ty->isVectorTy())
1689 Type *Ty = CB->getType();
1691 if (Ty->isVectorTy()) {
1693 WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
1697 Out << CB->getValue();
1699 if (Ty->isVectorTy())
1706 Type *Ty = CFP->getType();
1708 if (Ty->isVectorTy()) {
1709 if (CFP->getValue().bitcastToAPInt().isZero()) {
1710 Out <<
"zeroinitializer";
1715 WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
1721 if (Ty->isVectorTy())
1728 Out <<
"zeroinitializer";
1733 Out <<
"blockaddress(";
1742 Out <<
"dso_local_equivalent ";
1757 unsigned NumOpsToWrite = 2;
1758 if (!CPA->getOperand(2)->isNullValue())
1766 for (
unsigned i = 0, e = NumOpsToWrite; i != e; ++i) {
1778 for (
const Value *
Op : CA->operands()) {
1789 if (CA->isString()) {
1798 for (
uint64_t i = 0, e = CA->getNumElements(); i != e; ++i) {
1808 if (CS->getType()->isPacked())
1811 if (CS->getNumOperands() != 0) {
1814 for (
const Value *
Op : CS->operands()) {
1821 if (CS->getType()->isPacked())
1846 for (
unsigned i = 0, e = CVVTy->getNumElements(); i != e; ++i) {
1890 if (CE->getOpcode() == Instruction::ShuffleVector) {
1891 if (
auto *SplatVal = CE->getSplatValue()) {
1902 Out << CE->getOpcodeName();
1907 WriterCtx.TypePrinter->print(
GEP->getSourceElementType(), Out);
1912 for (
const Value *
Op : CE->operands()) {
1919 WriterCtx.TypePrinter->print(CE->getType(), Out);
1922 if (CE->getOpcode() == Instruction::ShuffleVector)
1929 Out <<
"<placeholder or erroneous Constant>";
1933 AsmWriterContext &WriterCtx) {
1941 Value *V = MDV->getValue();
1945 WriterCtx.onWriteMetadataAsOperand(MD);
1954struct MDFieldPrinter {
1957 AsmWriterContext &WriterCtx;
1959 explicit MDFieldPrinter(raw_ostream &Out)
1960 : Out(Out), WriterCtx(AsmWriterContext::getEmpty()) {}
1961 MDFieldPrinter(raw_ostream &Out, AsmWriterContext &Ctx)
1962 : Out(Out), WriterCtx(Ctx) {}
1964 void printTag(
const DINode *
N);
1965 void printMacinfoType(
const DIMacroNode *
N);
1966 void printChecksum(
const DIFile::ChecksumInfo<StringRef> &
N);
1967 void printString(StringRef Name, StringRef
Value,
1968 bool ShouldSkipEmpty =
true);
1969 void printMetadata(StringRef Name,
const Metadata *MD,
1970 bool ShouldSkipNull =
true);
1971 void printMetadataOrInt(StringRef Name,
const Metadata *MD,
bool IsUnsigned,
1972 bool ShouldSkipZero =
true);
1973 template <
class IntTy>
1974 void printInt(StringRef Name, IntTy
Int,
bool ShouldSkipZero =
true);
1975 void printAPInt(StringRef Name,
const APInt &
Int,
bool IsUnsigned,
1976 bool ShouldSkipZero);
1977 void printBool(StringRef Name,
bool Value,
1978 std::optional<bool>
Default = std::nullopt);
1981 template <
class IntTy,
class Stringifier>
1982 void printDwarfEnum(StringRef Name, IntTy
Value, Stringifier
toString,
1983 bool ShouldSkipZero =
true);
1985 void printNameTableKind(StringRef Name,
1992void MDFieldPrinter::printTag(
const DINode *
N) {
1993 Out <<
FS <<
"tag: ";
2001void MDFieldPrinter::printMacinfoType(
const DIMacroNode *
N) {
2002 Out <<
FS <<
"type: ";
2007 Out <<
N->getMacinfoType();
2010void MDFieldPrinter::printChecksum(
2013 printString(
"checksum", Checksum.
Value,
false);
2017 bool ShouldSkipEmpty) {
2018 if (ShouldSkipEmpty &&
Value.empty())
2021 Out <<
FS <<
Name <<
": \"";
2027 AsmWriterContext &WriterCtx) {
2033 WriterCtx.onWriteMetadataAsOperand(MD);
2037 bool ShouldSkipNull) {
2038 if (ShouldSkipNull && !MD)
2041 Out <<
FS <<
Name <<
": ";
2046 bool IsUnsigned,
bool ShouldSkipZero) {
2053 printInt(Name, CV->getZExtValue(), ShouldSkipZero);
2055 printInt(Name, CV->getSExtValue(), ShouldSkipZero);
2057 printMetadata(Name, MD);
2060template <
class IntTy>
2061void MDFieldPrinter::printInt(
StringRef Name, IntTy
Int,
bool ShouldSkipZero) {
2062 if (ShouldSkipZero && !
Int)
2069 bool IsUnsigned,
bool ShouldSkipZero) {
2070 if (ShouldSkipZero &&
Int.isZero())
2073 Out <<
FS <<
Name <<
": ";
2074 Int.print(Out, !IsUnsigned);
2078 std::optional<bool>
Default) {
2081 Out <<
FS <<
Name <<
": " << (
Value ?
"true" :
"false");
2088 Out <<
FS <<
Name <<
": ";
2094 for (
auto F : SplitFlags) {
2096 assert(!StringF.empty() &&
"Expected valid flag");
2097 Out << FlagsFS << StringF;
2099 if (Extra || SplitFlags.empty())
2100 Out << FlagsFS << Extra;
2103void MDFieldPrinter::printDISPFlags(
StringRef Name,
2107 Out <<
FS <<
Name <<
": ";
2118 for (
auto F : SplitFlags) {
2120 assert(!StringF.empty() &&
"Expected valid flag");
2121 Out << FlagsFS << StringF;
2123 if (Extra || SplitFlags.empty())
2124 Out << FlagsFS << Extra;
2127void MDFieldPrinter::printEmissionKind(
StringRef Name,
2132void MDFieldPrinter::printNameTableKind(
StringRef Name,
2139void MDFieldPrinter::printFixedPointKind(
StringRef Name,
2144template <
class IntTy,
class Stringifier>
2146 Stringifier
toString,
bool ShouldSkipZero) {
2147 if (ShouldSkipZero && !
Value)
2150 Out <<
FS <<
Name <<
": ";
2159 AsmWriterContext &WriterCtx) {
2160 Out <<
"!GenericDINode(";
2161 MDFieldPrinter
Printer(Out, WriterCtx);
2163 Printer.printString(
"header",
N->getHeader());
2164 if (
N->getNumDwarfOperands()) {
2165 Out <<
Printer.FS <<
"operands: {";
2167 for (
auto &
I :
N->dwarf_operands()) {
2177 AsmWriterContext &WriterCtx) {
2178 Out <<
"!DILocation(";
2179 MDFieldPrinter
Printer(Out, WriterCtx);
2181 Printer.printInt(
"line",
DL->getLine(),
false);
2182 Printer.printInt(
"column",
DL->getColumn());
2183 Printer.printMetadata(
"scope",
DL->getRawScope(),
false);
2184 Printer.printMetadata(
"inlinedAt",
DL->getRawInlinedAt());
2185 Printer.printBool(
"isImplicitCode",
DL->isImplicitCode(),
2187 Printer.printInt(
"atomGroup",
DL->getAtomGroup());
2188 Printer.printInt<
unsigned>(
"atomRank",
DL->getAtomRank());
2193 AsmWriterContext &WriterCtx) {
2194 Out <<
"!DIAssignID()";
2195 MDFieldPrinter
Printer(Out, WriterCtx);
2199 AsmWriterContext &WriterCtx) {
2200 Out <<
"!DISubrange(";
2201 MDFieldPrinter
Printer(Out, WriterCtx);
2203 Printer.printMetadataOrInt(
"count",
N->getRawCountNode(),
2209 Printer.printMetadataOrInt(
"lowerBound",
N->getRawLowerBound(),
2212 Printer.printMetadataOrInt(
"upperBound",
N->getRawUpperBound(),
2215 Printer.printMetadataOrInt(
"stride",
N->getRawStride(),
2223 AsmWriterContext &WriterCtx) {
2224 Out <<
"!DIGenericSubrange(";
2225 MDFieldPrinter
Printer(Out, WriterCtx);
2227 auto GetConstant = [&](
Metadata *Bound) -> std::optional<int64_t> {
2230 return std::nullopt;
2231 if (BE->isConstant() &&
2233 *BE->isConstant()) {
2234 return static_cast<int64_t
>(BE->getElement(1));
2236 return std::nullopt;
2239 auto *
Count =
N->getRawCountNode();
2240 if (
auto ConstantCount = GetConstant(
Count))
2241 Printer.printInt(
"count", *ConstantCount,
2246 auto *LBound =
N->getRawLowerBound();
2247 if (
auto ConstantLBound = GetConstant(LBound))
2248 Printer.printInt(
"lowerBound", *ConstantLBound,
2251 Printer.printMetadata(
"lowerBound", LBound,
true);
2253 auto *UBound =
N->getRawUpperBound();
2254 if (
auto ConstantUBound = GetConstant(UBound))
2255 Printer.printInt(
"upperBound", *ConstantUBound,
2258 Printer.printMetadata(
"upperBound", UBound,
true);
2260 auto *Stride =
N->getRawStride();
2261 if (
auto ConstantStride = GetConstant(Stride))
2262 Printer.printInt(
"stride", *ConstantStride,
2265 Printer.printMetadata(
"stride", Stride,
true);
2271 AsmWriterContext &) {
2272 Out <<
"!DIEnumerator(";
2274 Printer.printString(
"name",
N->getName(),
false);
2275 Printer.printAPInt(
"value",
N->getValue(),
N->isUnsigned(),
2277 if (
N->isUnsigned())
2278 Printer.printBool(
"isUnsigned",
true);
2283 AsmWriterContext &WriterCtx) {
2284 Out <<
"!DIBasicType(";
2285 MDFieldPrinter
Printer(Out, WriterCtx);
2286 if (
N->getTag() != dwarf::DW_TAG_base_type)
2288 Printer.printString(
"name",
N->getName());
2289 Printer.printMetadata(
"scope",
N->getRawScope());
2290 Printer.printMetadata(
"file",
N->getRawFile());
2291 Printer.printInt(
"line",
N->getLine());
2292 Printer.printMetadataOrInt(
"size",
N->getRawSizeInBits(),
true);
2293 Printer.printInt(
"align",
N->getAlignInBits());
2294 Printer.printInt(
"dataSize",
N->getDataSizeInBits());
2295 Printer.printDwarfEnum(
"encoding",
N->getEncoding(),
2297 Printer.printInt(
"num_extra_inhabitants",
N->getNumExtraInhabitants());
2298 Printer.printDIFlags(
"flags",
N->getFlags());
2303 AsmWriterContext &WriterCtx) {
2304 Out <<
"!DIFixedPointType(";
2305 MDFieldPrinter
Printer(Out, WriterCtx);
2306 if (
N->getTag() != dwarf::DW_TAG_base_type)
2308 Printer.printString(
"name",
N->getName());
2309 Printer.printMetadata(
"scope",
N->getRawScope());
2310 Printer.printMetadata(
"file",
N->getRawFile());
2311 Printer.printInt(
"line",
N->getLine());
2312 Printer.printMetadataOrInt(
"size",
N->getRawSizeInBits(),
true);
2313 Printer.printInt(
"align",
N->getAlignInBits());
2314 Printer.printDwarfEnum(
"encoding",
N->getEncoding(),
2316 Printer.printDIFlags(
"flags",
N->getFlags());
2317 Printer.printFixedPointKind(
"kind",
N->getKind());
2318 if (
N->isRational()) {
2319 bool IsUnsigned = !
N->isSigned();
2320 Printer.printAPInt(
"numerator",
N->getNumerator(), IsUnsigned,
false);
2321 Printer.printAPInt(
"denominator",
N->getDenominator(), IsUnsigned,
false);
2323 Printer.printInt(
"factor",
N->getFactor());
2329 AsmWriterContext &WriterCtx) {
2330 Out <<
"!DIStringType(";
2331 MDFieldPrinter
Printer(Out, WriterCtx);
2332 if (
N->getTag() != dwarf::DW_TAG_string_type)
2334 Printer.printString(
"name",
N->getName());
2335 Printer.printMetadata(
"stringLength",
N->getRawStringLength());
2336 Printer.printMetadata(
"stringLengthExpression",
N->getRawStringLengthExp());
2337 Printer.printMetadata(
"stringLocationExpression",
2338 N->getRawStringLocationExp());
2339 Printer.printMetadataOrInt(
"size",
N->getRawSizeInBits(),
true);
2340 Printer.printInt(
"align",
N->getAlignInBits());
2341 Printer.printDwarfEnum(
"encoding",
N->getEncoding(),
2347 AsmWriterContext &WriterCtx) {
2348 Out <<
"!DIDerivedType(";
2349 MDFieldPrinter
Printer(Out, WriterCtx);
2351 Printer.printString(
"name",
N->getName());
2352 Printer.printMetadata(
"scope",
N->getRawScope());
2353 Printer.printMetadata(
"file",
N->getRawFile());
2354 Printer.printInt(
"line",
N->getLine());
2355 Printer.printMetadata(
"baseType",
N->getRawBaseType(),
2357 Printer.printMetadataOrInt(
"size",
N->getRawSizeInBits(),
true);
2358 Printer.printInt(
"align",
N->getAlignInBits());
2359 Printer.printMetadataOrInt(
"offset",
N->getRawOffsetInBits(),
true);
2360 Printer.printDIFlags(
"flags",
N->getFlags());
2361 Printer.printMetadata(
"extraData",
N->getRawExtraData());
2362 if (
const auto &DWARFAddressSpace =
N->getDWARFAddressSpace())
2363 Printer.printInt(
"dwarfAddressSpace", *DWARFAddressSpace,
2365 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2366 if (
auto PtrAuthData =
N->getPtrAuthData()) {
2367 Printer.printInt(
"ptrAuthKey", PtrAuthData->key());
2368 Printer.printBool(
"ptrAuthIsAddressDiscriminated",
2369 PtrAuthData->isAddressDiscriminated());
2370 Printer.printInt(
"ptrAuthExtraDiscriminator",
2371 PtrAuthData->extraDiscriminator());
2372 Printer.printBool(
"ptrAuthIsaPointer", PtrAuthData->isaPointer());
2373 Printer.printBool(
"ptrAuthAuthenticatesNullValues",
2374 PtrAuthData->authenticatesNullValues());
2380 AsmWriterContext &WriterCtx) {
2381 Out <<
"!DISubrangeType(";
2382 MDFieldPrinter
Printer(Out, WriterCtx);
2383 Printer.printString(
"name",
N->getName());
2384 Printer.printMetadata(
"scope",
N->getRawScope());
2385 Printer.printMetadata(
"file",
N->getRawFile());
2386 Printer.printInt(
"line",
N->getLine());
2387 Printer.printMetadataOrInt(
"size",
N->getRawSizeInBits(),
true);
2388 Printer.printInt(
"align",
N->getAlignInBits());
2389 Printer.printDIFlags(
"flags",
N->getFlags());
2390 Printer.printMetadata(
"baseType",
N->getRawBaseType(),
2392 Printer.printMetadata(
"lowerBound",
N->getRawLowerBound());
2393 Printer.printMetadata(
"upperBound",
N->getRawUpperBound());
2394 Printer.printMetadata(
"stride",
N->getRawStride());
2395 Printer.printMetadata(
"bias",
N->getRawBias());
2400 AsmWriterContext &WriterCtx) {
2401 Out <<
"!DICompositeType(";
2402 MDFieldPrinter
Printer(Out, WriterCtx);
2404 Printer.printString(
"name",
N->getName());
2405 Printer.printMetadata(
"scope",
N->getRawScope());
2406 Printer.printMetadata(
"file",
N->getRawFile());
2407 Printer.printInt(
"line",
N->getLine());
2408 Printer.printMetadata(
"baseType",
N->getRawBaseType());
2409 Printer.printMetadataOrInt(
"size",
N->getRawSizeInBits(),
true);
2410 Printer.printInt(
"align",
N->getAlignInBits());
2411 Printer.printMetadataOrInt(
"offset",
N->getRawOffsetInBits(),
true);
2412 Printer.printInt(
"num_extra_inhabitants",
N->getNumExtraInhabitants());
2413 Printer.printDIFlags(
"flags",
N->getFlags());
2414 Printer.printMetadata(
"elements",
N->getRawElements());
2415 Printer.printDwarfEnum(
"runtimeLang",
N->getRuntimeLang(),
2417 Printer.printMetadata(
"vtableHolder",
N->getRawVTableHolder());
2418 Printer.printMetadata(
"templateParams",
N->getRawTemplateParams());
2419 Printer.printString(
"identifier",
N->getIdentifier());
2420 Printer.printMetadata(
"discriminator",
N->getRawDiscriminator());
2421 Printer.printMetadata(
"dataLocation",
N->getRawDataLocation());
2422 Printer.printMetadata(
"associated",
N->getRawAssociated());
2423 Printer.printMetadata(
"allocated",
N->getRawAllocated());
2424 if (
auto *RankConst =
N->getRankConst())
2425 Printer.printInt(
"rank", RankConst->getSExtValue(),
2428 Printer.printMetadata(
"rank",
N->getRawRank(),
true);
2429 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2430 if (
auto *Specification =
N->getRawSpecification())
2431 Printer.printMetadata(
"specification", Specification);
2433 if (
auto EnumKind =
N->getEnumKind())
2437 Printer.printMetadata(
"bitStride",
N->getRawBitStride());
2442 AsmWriterContext &WriterCtx) {
2443 Out <<
"!DISubroutineType(";
2444 MDFieldPrinter
Printer(Out, WriterCtx);
2445 Printer.printDIFlags(
"flags",
N->getFlags());
2447 Printer.printMetadata(
"types",
N->getRawTypeArray(),
2455 Printer.printString(
"filename",
N->getFilename(),
2457 Printer.printString(
"directory",
N->getDirectory(),
2460 if (
N->getChecksum())
2461 Printer.printChecksum(*
N->getChecksum());
2463 Printer.printString(
"source", *
N->getSource(),
2469 AsmWriterContext &WriterCtx) {
2470 Out <<
"!DICompileUnit(";
2471 MDFieldPrinter
Printer(Out, WriterCtx);
2477 "sourceLanguageName",
2489 Printer.printMetadata(
"file",
N->getRawFile(),
false);
2490 Printer.printString(
"producer",
N->getProducer());
2491 Printer.printBool(
"isOptimized",
N->isOptimized());
2492 Printer.printString(
"flags",
N->getFlags());
2493 Printer.printInt(
"runtimeVersion",
N->getRuntimeVersion(),
2495 Printer.printString(
"splitDebugFilename",
N->getSplitDebugFilename());
2496 Printer.printEmissionKind(
"emissionKind",
N->getEmissionKind());
2497 Printer.printMetadata(
"enums",
N->getRawEnumTypes());
2498 Printer.printMetadata(
"retainedTypes",
N->getRawRetainedTypes());
2499 Printer.printMetadata(
"globals",
N->getRawGlobalVariables());
2500 Printer.printMetadata(
"imports",
N->getRawImportedEntities());
2501 Printer.printMetadata(
"macros",
N->getRawMacros());
2502 Printer.printInt(
"dwoId",
N->getDWOId());
2503 Printer.printBool(
"splitDebugInlining",
N->getSplitDebugInlining(),
true);
2504 Printer.printBool(
"debugInfoForProfiling",
N->getDebugInfoForProfiling(),
2506 Printer.printNameTableKind(
"nameTableKind",
N->getNameTableKind());
2507 Printer.printBool(
"rangesBaseAddress",
N->getRangesBaseAddress(),
false);
2508 Printer.printString(
"sysroot",
N->getSysRoot());
2509 Printer.printString(
"sdk",
N->getSDK());
2516 AsmWriterContext &WriterCtx) {
2517 Out <<
"!DISubprogram(";
2518 MDFieldPrinter
Printer(Out, WriterCtx);
2519 Printer.printString(
"name",
N->getName());
2520 Printer.printString(
"linkageName",
N->getLinkageName());
2521 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2522 Printer.printMetadata(
"file",
N->getRawFile());
2523 Printer.printInt(
"line",
N->getLine());
2524 Printer.printMetadata(
"type",
N->getRawType());
2525 Printer.printInt(
"scopeLine",
N->getScopeLine());
2526 Printer.printMetadata(
"containingType",
N->getRawContainingType());
2527 if (
N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
2528 N->getVirtualIndex() != 0)
2529 Printer.printInt(
"virtualIndex",
N->getVirtualIndex(),
false);
2530 Printer.printInt(
"thisAdjustment",
N->getThisAdjustment());
2531 Printer.printDIFlags(
"flags",
N->getFlags());
2532 Printer.printDISPFlags(
"spFlags",
N->getSPFlags());
2533 Printer.printMetadata(
"unit",
N->getRawUnit());
2534 Printer.printMetadata(
"templateParams",
N->getRawTemplateParams());
2535 Printer.printMetadata(
"declaration",
N->getRawDeclaration());
2536 Printer.printMetadata(
"retainedNodes",
N->getRawRetainedNodes());
2537 Printer.printMetadata(
"thrownTypes",
N->getRawThrownTypes());
2538 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2539 Printer.printString(
"targetFuncName",
N->getTargetFuncName());
2540 Printer.printBool(
"keyInstructions",
N->getKeyInstructionsEnabled(),
false);
2545 AsmWriterContext &WriterCtx) {
2546 Out <<
"!DILexicalBlock(";
2547 MDFieldPrinter
Printer(Out, WriterCtx);
2548 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2549 Printer.printMetadata(
"file",
N->getRawFile());
2550 Printer.printInt(
"line",
N->getLine());
2551 Printer.printInt(
"column",
N->getColumn());
2557 AsmWriterContext &WriterCtx) {
2558 Out <<
"!DILexicalBlockFile(";
2559 MDFieldPrinter
Printer(Out, WriterCtx);
2560 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2561 Printer.printMetadata(
"file",
N->getRawFile());
2562 Printer.printInt(
"discriminator",
N->getDiscriminator(),
2568 AsmWriterContext &WriterCtx) {
2569 Out <<
"!DINamespace(";
2570 MDFieldPrinter
Printer(Out, WriterCtx);
2571 Printer.printString(
"name",
N->getName());
2572 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2573 Printer.printBool(
"exportSymbols",
N->getExportSymbols(),
false);
2578 AsmWriterContext &WriterCtx) {
2579 Out <<
"!DICommonBlock(";
2580 MDFieldPrinter
Printer(Out, WriterCtx);
2581 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2582 Printer.printMetadata(
"declaration",
N->getRawDecl(),
false);
2583 Printer.printString(
"name",
N->getName());
2584 Printer.printMetadata(
"file",
N->getRawFile());
2585 Printer.printInt(
"line",
N->getLineNo());
2590 AsmWriterContext &WriterCtx) {
2592 MDFieldPrinter
Printer(Out, WriterCtx);
2594 Printer.printInt(
"line",
N->getLine());
2595 Printer.printString(
"name",
N->getName());
2596 Printer.printString(
"value",
N->getValue());
2601 AsmWriterContext &WriterCtx) {
2602 Out <<
"!DIMacroFile(";
2603 MDFieldPrinter
Printer(Out, WriterCtx);
2604 Printer.printInt(
"line",
N->getLine());
2605 Printer.printMetadata(
"file",
N->getRawFile(),
false);
2606 Printer.printMetadata(
"nodes",
N->getRawElements());
2611 AsmWriterContext &WriterCtx) {
2612 Out <<
"!DIModule(";
2613 MDFieldPrinter
Printer(Out, WriterCtx);
2614 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2615 Printer.printString(
"name",
N->getName());
2616 Printer.printString(
"configMacros",
N->getConfigurationMacros());
2617 Printer.printString(
"includePath",
N->getIncludePath());
2618 Printer.printString(
"apinotes",
N->getAPINotesFile());
2619 Printer.printMetadata(
"file",
N->getRawFile());
2620 Printer.printInt(
"line",
N->getLineNo());
2621 Printer.printBool(
"isDecl",
N->getIsDecl(),
false);
2627 AsmWriterContext &WriterCtx) {
2628 Out <<
"!DITemplateTypeParameter(";
2629 MDFieldPrinter
Printer(Out, WriterCtx);
2630 Printer.printString(
"name",
N->getName());
2631 Printer.printMetadata(
"type",
N->getRawType(),
false);
2632 Printer.printBool(
"defaulted",
N->isDefault(),
false);
2638 AsmWriterContext &WriterCtx) {
2639 Out <<
"!DITemplateValueParameter(";
2640 MDFieldPrinter
Printer(Out, WriterCtx);
2641 if (
N->getTag() != dwarf::DW_TAG_template_value_parameter)
2643 Printer.printString(
"name",
N->getName());
2644 Printer.printMetadata(
"type",
N->getRawType());
2645 Printer.printBool(
"defaulted",
N->isDefault(),
false);
2646 Printer.printMetadata(
"value",
N->getValue(),
false);
2651 AsmWriterContext &WriterCtx) {
2652 Out <<
"!DIGlobalVariable(";
2653 MDFieldPrinter
Printer(Out, WriterCtx);
2654 Printer.printString(
"name",
N->getName());
2655 Printer.printString(
"linkageName",
N->getLinkageName());
2656 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2657 Printer.printMetadata(
"file",
N->getRawFile());
2658 Printer.printInt(
"line",
N->getLine());
2659 Printer.printMetadata(
"type",
N->getRawType());
2660 Printer.printBool(
"isLocal",
N->isLocalToUnit());
2661 Printer.printBool(
"isDefinition",
N->isDefinition());
2662 Printer.printMetadata(
"declaration",
N->getRawStaticDataMemberDeclaration());
2663 Printer.printMetadata(
"templateParams",
N->getRawTemplateParams());
2664 Printer.printInt(
"align",
N->getAlignInBits());
2665 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2670 AsmWriterContext &WriterCtx) {
2671 Out <<
"!DILocalVariable(";
2672 MDFieldPrinter
Printer(Out, WriterCtx);
2673 Printer.printString(
"name",
N->getName());
2674 Printer.printInt(
"arg",
N->getArg());
2675 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2676 Printer.printMetadata(
"file",
N->getRawFile());
2677 Printer.printInt(
"line",
N->getLine());
2678 Printer.printMetadata(
"type",
N->getRawType());
2679 Printer.printDIFlags(
"flags",
N->getFlags());
2680 Printer.printInt(
"align",
N->getAlignInBits());
2681 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2686 AsmWriterContext &WriterCtx) {
2688 MDFieldPrinter
Printer(Out, WriterCtx);
2689 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2690 Printer.printString(
"name",
N->getName());
2691 Printer.printMetadata(
"file",
N->getRawFile());
2692 Printer.printInt(
"line",
N->getLine(),
false);
2693 Printer.printInt(
"column",
N->getColumn());
2694 Printer.printBool(
"isArtificial",
N->isArtificial(),
false);
2695 if (
N->getCoroSuspendIdx())
2696 Printer.printInt(
"coroSuspendIdx", *
N->getCoroSuspendIdx(),
2702 AsmWriterContext &WriterCtx) {
2703 Out <<
"!DIExpression(";
2708 assert(!OpStr.empty() &&
"Expected valid opcode");
2712 Out << FS << Convert.getBitSize();
2715 for (
unsigned A = 0, AE =
Op.getNumArgs();
A != AE; ++
A)
2716 Out << FS <<
Op.getArg(
A);
2720 for (
const auto &
I :
N->getElements())
2727 AsmWriterContext &WriterCtx,
2728 bool FromValue =
false) {
2730 "Unexpected DIArgList metadata outside of value argument");
2731 Out <<
"!DIArgList(";
2733 MDFieldPrinter
Printer(Out, WriterCtx);
2734 for (
const Metadata *Arg :
N->getArgs()) {
2743 AsmWriterContext &WriterCtx) {
2744 Out <<
"!DIGlobalVariableExpression(";
2745 MDFieldPrinter
Printer(Out, WriterCtx);
2746 Printer.printMetadata(
"var",
N->getVariable());
2747 Printer.printMetadata(
"expr",
N->getExpression());
2752 AsmWriterContext &WriterCtx) {
2753 Out <<
"!DIObjCProperty(";
2754 MDFieldPrinter
Printer(Out, WriterCtx);
2755 Printer.printString(
"name",
N->getName());
2756 Printer.printMetadata(
"file",
N->getRawFile());
2757 Printer.printInt(
"line",
N->getLine());
2758 Printer.printString(
"setter",
N->getSetterName());
2759 Printer.printString(
"getter",
N->getGetterName());
2760 Printer.printInt(
"attributes",
N->getAttributes());
2761 Printer.printMetadata(
"type",
N->getRawType());
2766 AsmWriterContext &WriterCtx) {
2767 Out <<
"!DIProperty(";
2768 MDFieldPrinter
Printer(Out, WriterCtx);
2769 Printer.printString(
"name",
N->getName());
2770 Printer.printMetadata(
"file",
N->getRawFile());
2771 Printer.printInt(
"line",
N->getLine());
2772 Printer.printMetadata(
"type",
N->getRawType());
2773 Printer.printMetadata(
"backing_storage",
N->getRawBackingStorage());
2778 AsmWriterContext &WriterCtx) {
2779 Out <<
"!DIImportedEntity(";
2780 MDFieldPrinter
Printer(Out, WriterCtx);
2782 Printer.printString(
"name",
N->getName());
2783 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2784 Printer.printMetadata(
"entity",
N->getRawEntity());
2785 Printer.printMetadata(
"file",
N->getRawFile());
2786 Printer.printInt(
"line",
N->getLine());
2787 Printer.printMetadata(
"elements",
N->getRawElements());
2792 AsmWriterContext &Ctx) {
2793 if (
Node->isDistinct())
2795 else if (
Node->isTemporary())
2796 Out <<
"<temporary!> ";
2798 switch (
Node->getMetadataID()) {
2801#define HANDLE_MDNODE_LEAF(CLASS) \
2802 case Metadata::CLASS##Kind: \
2803 write##CLASS(Out, cast<CLASS>(Node), Ctx); \
2805#include "llvm/IR/Metadata.def"
2812 AsmWriterContext &WriterCtx,
2815 WriterCtx.TypePrinter->print(V->getType(), Out);
2826 assert(WriterCtx.TypePrinter &&
"Constants require TypePrinting!");
2833 if (IA->hasSideEffects())
2834 Out <<
"sideeffect ";
2835 if (IA->isAlignStack())
2836 Out <<
"alignstack ";
2839 Out <<
"inteldialect ";
2858 auto *
Machine = WriterCtx.Machine;
2862 Slot =
Machine->getGlobalSlot(GV);
2865 Slot =
Machine->getLocalSlot(V);
2872 Slot =
Machine->getLocalSlot(V);
2879 Slot =
Machine->getGlobalSlot(GV);
2882 Slot =
Machine->getLocalSlot(V);
2891 Out << Prefix << Slot;
2897 AsmWriterContext &WriterCtx,
2912 Loc && WriterCtx.MST &&
2918 std::unique_ptr<SlotTracker> MachineStorage;
2920 if (!WriterCtx.Machine) {
2921 MachineStorage = std::make_unique<SlotTracker>(WriterCtx.Context);
2922 WriterCtx.Machine = MachineStorage.get();
2932 Out <<
"<" <<
N <<
">";
2946 assert(WriterCtx.TypePrinter &&
"TypePrinter required for metadata values");
2948 "Unexpected function-local metadata outside of value argument");
2955class AssemblyWriter {
2956 formatted_raw_ostream &Out;
2957 const Module *TheModule =
nullptr;
2958 const ModuleSummaryIndex *TheIndex =
nullptr;
2959 std::unique_ptr<SlotTracker> SlotTrackerStorage;
2961 TypePrinting TypePrinter;
2962 AssemblyAnnotationWriter *AnnotationWriter =
nullptr;
2963 SetVector<const Comdat *> Comdats;
2965 bool ShouldPreserveUseListOrder;
2970 DenseMap<const GlobalValueSummary *, GlobalValue::GUID> SummaryToGUIDMap;
2974 AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const Module *M,
2975 AssemblyAnnotationWriter *AAW,
bool IsForDebug,
2976 bool ShouldPreserveUseListOrder =
false);
2978 AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
2979 const ModuleSummaryIndex *Index,
bool IsForDebug);
2982 return AsmWriterContext(&TypePrinter, &
Machine, TheModule);
2985 void printMDNodeBody(
const MDNode *MD);
2986 void printNamedMDNode(
const NamedMDNode *NMD);
2988 void printModule(
const Module *M);
2990 void writeOperand(
const Value *
Op,
bool PrintType);
2991 void writeParamOperand(
const Value *Operand, AttributeSet Attrs);
2992 void writeOperandBundles(
const CallBase *
Call);
2993 void writeSyncScope(
const LLVMContext &
Context,
2995 void writeAtomic(
const LLVMContext &
Context,
2998 void writeAtomicCmpXchg(
const LLVMContext &
Context,
3003 void writeAllMDNodes();
3004 void writeMDNode(
unsigned Slot,
const MDNode *Node);
3005 void writeAttribute(
const Attribute &Attr,
bool InAttrGroup =
false);
3006 void writeAttributeSet(
const AttributeSet &AttrSet,
bool InAttrGroup =
false);
3007 void writeAllAttributeGroups();
3009 void printTypeIdentities();
3010 void printGlobal(
const GlobalVariable *GV);
3011 void printAlias(
const GlobalAlias *GA);
3012 void printIFunc(
const GlobalIFunc *GI);
3013 void printComdat(
const Comdat *
C);
3015 void printArgument(
const Argument *FA, AttributeSet Attrs);
3017 void printInstructionLine(
const Instruction &
I);
3018 void printInstruction(
const Instruction &
I);
3019 void printDbgMarker(
const DbgMarker &DPI);
3020 void printDbgVariableRecord(
const DbgVariableRecord &DVR);
3021 void printDbgLabelRecord(
const DbgLabelRecord &DLR);
3022 void printDbgRecord(
const DbgRecord &DR);
3023 void printDbgRecordLine(
const DbgRecord &DR);
3025 void printUseListOrder(
const Value *V, ArrayRef<unsigned> Shuffle);
3028 void printModuleSummaryIndex();
3029 void printSummaryInfo(
unsigned Slot,
const ValueInfo &VI);
3030 void printSummary(
const GlobalValueSummary &Summary);
3031 void printAliasSummary(
const AliasSummary *AS);
3032 void printGlobalVarSummary(
const GlobalVarSummary *GS);
3033 void printFunctionSummary(
const FunctionSummary *FS);
3034 void printTypeIdSummary(
const TypeIdSummary &TIS);
3036 void printTypeTestResolution(
const TypeTestResolution &TTRes);
3037 void printArgs(ArrayRef<uint64_t> Args);
3038 void printWPDRes(
const WholeProgramDevirtResolution &WPDRes);
3039 void printTypeIdInfo(
const FunctionSummary::TypeIdInfo &TIDInfo);
3040 void printVFuncId(
const FunctionSummary::VFuncId VFId);
3048 void printMetadataAttachments(
3049 const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
3050 StringRef Separator);
3054 void printInfoComment(
const Value &V,
bool isMaterializable =
false);
3058 void printGCRelocateComment(
const GCRelocateInst &Relocate);
3065 bool IsForDebug,
bool ShouldPreserveUseListOrder)
3066 : Out(
o), TheModule(
M),
Machine(Mac), TypePrinter(
M), AnnotationWriter(AAW),
3067 IsForDebug(IsForDebug),
3068 ShouldPreserveUseListOrder(
3071 : ShouldPreserveUseListOrder) {
3074 for (
const GlobalObject &GO : TheModule->global_objects())
3081 : Out(
o), TheIndex(Index),
Machine(Mac), TypePrinter(nullptr),
3082 IsForDebug(IsForDebug),
3085void AssemblyWriter::writeOperand(
const Value *Operand,
bool PrintType) {
3087 Out <<
"<null operand!>";
3094void AssemblyWriter::writeSyncScope(
const LLVMContext &
Context,
3102 Context.getSyncScopeNames(SSNs);
3104 Out <<
" syncscope(\"";
3112void AssemblyWriter::writeAtomic(
const LLVMContext &
Context,
3115 if (Ordering == AtomicOrdering::NotAtomic)
3118 writeSyncScope(
Context, SSID);
3122void AssemblyWriter::writeAtomicCmpXchg(
const LLVMContext &
Context,
3126 assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
3127 FailureOrdering != AtomicOrdering::NotAtomic);
3129 writeSyncScope(
Context, SSID);
3134void AssemblyWriter::writeParamOperand(
const Value *Operand,
3135 AttributeSet Attrs) {
3137 Out <<
"<null operand!>";
3142 TypePrinter.print(Operand->
getType(), Out);
3144 if (
Attrs.hasAttributes()) {
3146 writeAttributeSet(Attrs);
3154void AssemblyWriter::writeOperandBundles(
const CallBase *
Call) {
3170 ListSeparator InnerLS;
3172 for (
const auto &Input : BU.
Inputs) {
3174 if (Input ==
nullptr)
3175 Out <<
"<null operand bundle!>";
3186void AssemblyWriter::printModule(
const Module *M) {
3189 if (ShouldPreserveUseListOrder)
3192 if (!
M->getModuleIdentifier().empty() &&
3195 M->getModuleIdentifier().find(
'\n') == std::string::npos)
3196 Out <<
"; ModuleID = '" <<
M->getModuleIdentifier() <<
"'\n";
3198 if (!
M->getSourceFileName().empty()) {
3199 Out <<
"source_filename = \"";
3204 const std::string &
DL =
M->getDataLayoutStr();
3206 Out <<
"target datalayout = \"" <<
DL <<
"\"\n";
3207 if (!
M->getTargetTriple().empty())
3208 Out <<
"target triple = \"" <<
M->getTargetTriple().str() <<
"\"\n";
3210 if (
M->hasModuleInlineAsm()) {
3213 for (
const Module::GlobalAsmFragment &Frag :
M->getModuleInlineAsm()) {
3214 Out <<
"module asm";
3216 Frag.Props.getAsStrings();
3217 if (!Props.
empty()) {
3222 Out <<
Key <<
": \"";
3230 StringRef
Asm = Frag.Asm;
3233 std::tie(Front, Asm) =
Asm.split(
'\n');
3240 }
while (!
Asm.empty());
3244 printTypeIdentities();
3247 if (!Comdats.empty())
3249 for (
const Comdat *
C : Comdats) {
3251 if (
C != Comdats.back())
3256 if (!
M->global_empty()) Out <<
'\n';
3257 for (
const GlobalVariable &GV :
M->globals()) {
3258 printGlobal(&GV); Out <<
'\n';
3262 if (!
M->alias_empty()) Out <<
"\n";
3263 for (
const GlobalAlias &GA :
M->aliases())
3267 if (!
M->ifunc_empty()) Out <<
"\n";
3268 for (
const GlobalIFunc &GI :
M->ifuncs())
3278 printUseLists(
nullptr);
3283 writeAllAttributeGroups();
3287 if (!
M->named_metadata_empty()) Out <<
'\n';
3289 for (
const NamedMDNode &Node :
M->named_metadata())
3290 printNamedMDNode(&Node);
3299void AssemblyWriter::printModuleSummaryIndex() {
3301 int NumSlots =
Machine.initializeIndexIfNeeded();
3307 std::vector<std::pair<std::string, ModuleHash>> moduleVec;
3308 std::string RegularLTOModuleName =
3311 for (
auto &[ModPath, ModHash] : TheIndex->
modulePaths())
3312 moduleVec[
Machine.getModulePathSlot(ModPath)] = std::make_pair(
3315 ModPath.empty() ? RegularLTOModuleName : std::string(ModPath), ModHash);
3318 for (
auto &ModPair : moduleVec) {
3319 Out <<
"^" << i++ <<
" = module: (";
3322 Out <<
"\", hash: (";
3324 for (
auto Hash : ModPair.second)
3334 for (
const auto &GlobalList : SortedGVS) {
3335 auto GUID = GlobalList.first;
3336 for (
auto &Summary : GlobalList.second.getSummaryList())
3341 for (
const auto &GlobalList : SortedGVS) {
3342 auto GUID = GlobalList.first;
3344 printSummaryInfo(
Machine.getGUIDSlot(GUID), VI);
3348 for (
const auto &TID : TheIndex->
typeIds()) {
3349 Out <<
"^" <<
Machine.getTypeIdSlot(TID.second.first)
3350 <<
" = typeid: (name: \"" << TID.second.first <<
"\"";
3351 printTypeIdSummary(TID.second.second);
3352 Out <<
") ; guid = " << TID.first <<
"\n";
3358 Out <<
"^" <<
Machine.getTypeIdCompatibleVtableSlot(TId.first)
3359 <<
" = typeidCompatibleVTable: (name: \"" << TId.first <<
"\"";
3360 printTypeIdCompatibleVtableSummary(TId.second);
3361 Out <<
") ; guid = " <<
GUID <<
"\n";
3366 Out <<
"^" << NumSlots <<
" = flags: " << TheIndex->
getFlags() <<
"\n";
3370 Out <<
"^" << NumSlots <<
" = blockcount: " << TheIndex->
getBlockCount()
3380 return "singleImpl";
3382 return "branchFunnel";
3393 return "uniformRetVal";
3395 return "uniqueRetVal";
3397 return "virtualConstProp";
3420void AssemblyWriter::printTypeTestResolution(
const TypeTestResolution &TTRes) {
3427 Out <<
", alignLog2: " << TTRes.
AlignLog2;
3429 Out <<
", sizeM1: " << TTRes.
SizeM1;
3432 Out <<
", bitMask: " << (unsigned)TTRes.
BitMask;
3439void AssemblyWriter::printTypeIdSummary(
const TypeIdSummary &TIS) {
3440 Out <<
", summary: (";
3441 printTypeTestResolution(TIS.
TTRes);
3442 if (!TIS.
WPDRes.empty()) {
3443 Out <<
", wpdResolutions: (";
3445 for (
auto &WPDRes : TIS.
WPDRes) {
3447 Out <<
"(offset: " << WPDRes.first <<
", ";
3448 printWPDRes(WPDRes.second);
3456void AssemblyWriter::printTypeIdCompatibleVtableSummary(
3458 Out <<
", summary: (";
3460 for (
auto &
P : TI) {
3462 Out <<
"(offset: " <<
P.AddressPointOffset <<
", ";
3463 Out <<
"^" <<
Machine.getGUIDSlot(
P.VTableVI.getGUID());
3469void AssemblyWriter::printArgs(ArrayRef<uint64_t> Args) {
3473void AssemblyWriter::printWPDRes(
const WholeProgramDevirtResolution &WPDRes) {
3474 Out <<
"wpdRes: (kind: ";
3481 Out <<
", resByArg: (";
3483 for (
auto &ResByArg : WPDRes.
ResByArg) {
3485 printArgs(ResByArg.first);
3486 Out <<
", byArg: (kind: ";
3488 if (ResByArg.second.TheKind ==
3490 ResByArg.second.TheKind ==
3492 Out <<
", info: " << ResByArg.second.Info;
3496 if (ResByArg.second.Byte || ResByArg.second.Bit)
3497 Out <<
", byte: " << ResByArg.second.Byte
3498 <<
", bit: " << ResByArg.second.Bit;
3519void AssemblyWriter::printAliasSummary(
const AliasSummary *AS) {
3520 Out <<
", aliasee: ";
3530void AssemblyWriter::printGlobalVarSummary(
const GlobalVarSummary *GS) {
3531 auto VTableFuncs =
GS->vTableFuncs();
3532 Out <<
", varFlags: (readonly: " <<
GS->VarFlags.MaybeReadOnly <<
", "
3533 <<
"writeonly: " <<
GS->VarFlags.MaybeWriteOnly <<
", "
3534 <<
"constant: " <<
GS->VarFlags.Constant;
3535 if (!VTableFuncs.empty())
3537 <<
"vcall_visibility: " <<
GS->VarFlags.VCallVisibility;
3540 if (!VTableFuncs.empty()) {
3541 Out <<
", vTableFuncs: (";
3543 for (
auto &
P : VTableFuncs) {
3545 Out <<
"(virtFunc: ^" <<
Machine.getGUIDSlot(
P.FuncVI.getGUID())
3546 <<
", offset: " <<
P.VTableOffset;
3564 return "linkonce_odr";
3574 return "extern_weak";
3576 return "available_externally";
3605 return "definition";
3607 return "declaration";
3612void AssemblyWriter::printFunctionSummary(
const FunctionSummary *FS) {
3613 Out <<
", insts: " <<
FS->instCount();
3614 if (
FS->fflags().anyFlagSet())
3615 Out <<
", " <<
FS->fflags();
3617 if (!
FS->calls().empty()) {
3618 Out <<
", calls: (";
3620 for (
auto &
Call :
FS->calls()) {
3622 Out <<
"(callee: ^" <<
Machine.getGUIDSlot(
Call.first.getGUID());
3623 if (
Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
3627 if (
Call.second.HasTailCall)
3634 if (
const auto *TIdInfo =
FS->getTypeIdInfo())
3635 printTypeIdInfo(*TIdInfo);
3639 auto AllocTypeName = [](uint8_t
Type) ->
const char * {
3641 case (uint8_t)AllocationType::None:
3643 case (uint8_t)AllocationType::NotCold:
3645 case (uint8_t)AllocationType::Cold:
3647 case (uint8_t)AllocationType::Hot:
3653 if (!
FS->allocs().empty()) {
3654 Out <<
", allocs: (";
3656 for (
auto &AI :
FS->allocs()) {
3658 Out <<
"(versions: (";
3660 for (
auto V : AI.Versions) {
3662 Out << AllocTypeName(V);
3664 Out <<
"), memProf: (";
3665 ListSeparator MIBFS;
3666 for (
auto &MIB : AI.MIBs) {
3668 Out <<
"(type: " << AllocTypeName((uint8_t)MIB.AllocType);
3669 Out <<
", stackIds: (";
3670 ListSeparator SIDFS;
3671 for (
auto Id : MIB.StackIdIndices) {
3682 if (!
FS->callsites().empty()) {
3683 Out <<
", callsites: (";
3685 for (
auto &CI :
FS->callsites()) {
3688 Out <<
"(callee: ^" <<
Machine.getGUIDSlot(CI.Callee.getGUID());
3690 Out <<
"(callee: null";
3691 Out <<
", clones: (";
3693 for (
auto V : CI.Clones) {
3697 Out <<
"), stackIds: (";
3698 ListSeparator SIDFS;
3699 for (
auto Id : CI.StackIdIndices) {
3708 auto PrintRange = [&](
const ConstantRange &
Range) {
3712 if (!
FS->paramAccesses().empty()) {
3713 Out <<
", params: (";
3715 for (
auto &PS :
FS->paramAccesses()) {
3717 Out <<
"(param: " << PS.ParamNo;
3718 Out <<
", offset: ";
3720 if (!PS.Calls.empty()) {
3721 Out <<
", calls: (";
3723 for (
auto &
Call : PS.Calls) {
3725 Out <<
"(callee: ^" <<
Machine.getGUIDSlot(
Call.Callee.getGUID());
3726 Out <<
", param: " <<
Call.ParamNo;
3727 Out <<
", offset: ";
3728 PrintRange(
Call.Offsets);
3739void AssemblyWriter::printTypeIdInfo(
3740 const FunctionSummary::TypeIdInfo &TIDInfo) {
3741 Out <<
", typeIdInfo: (";
3742 ListSeparator TIDFS;
3745 Out <<
"typeTests: (";
3748 auto TidIter = TheIndex->
typeIds().equal_range(GUID);
3749 if (TidIter.first == TidIter.second) {
3755 for (
const auto &[GUID, TypeIdPair] :
make_range(TidIter)) {
3757 auto Slot =
Machine.getTypeIdSlot(TypeIdPair.first);
3775 "typeTestAssumeConstVCalls");
3780 "typeCheckedLoadConstVCalls");
3785void AssemblyWriter::printVFuncId(
const FunctionSummary::VFuncId VFId) {
3786 auto TidIter = TheIndex->
typeIds().equal_range(VFId.
GUID);
3787 if (TidIter.first == TidIter.second) {
3788 Out <<
"vFuncId: (";
3789 Out <<
"guid: " << VFId.
GUID;
3790 Out <<
", offset: " << VFId.
Offset;
3796 for (
const auto &[GUID, TypeIdPair] :
make_range(TidIter)) {
3798 Out <<
"vFuncId: (";
3799 auto Slot =
Machine.getTypeIdSlot(TypeIdPair.first);
3802 Out <<
", offset: " << VFId.
Offset;
3807void AssemblyWriter::printNonConstVCalls(
3809 Out <<
Tag <<
": (";
3811 for (
auto &VFuncId : VCallList) {
3813 printVFuncId(VFuncId);
3818void AssemblyWriter::printConstVCalls(
3820 Out <<
Tag <<
": (";
3822 for (
auto &ConstVCall : VCallList) {
3825 printVFuncId(ConstVCall.VFunc);
3826 if (!ConstVCall.Args.empty()) {
3828 printArgs(ConstVCall.Args);
3835void AssemblyWriter::printSummary(
const GlobalValueSummary &Summary) {
3836 GlobalValueSummary::GVFlags GVFlags =
Summary.flags();
3839 Out <<
"(module: ^" <<
Machine.getModulePathSlot(
Summary.modulePath())
3842 Out <<
", visibility: "
3845 Out <<
", live: " << GVFlags.
Live;
3846 Out <<
", dsoLocal: " << GVFlags.
DSOLocal;
3848 Out <<
", importType: "
3860 auto RefList =
Summary.refs();
3861 if (!RefList.empty()) {
3864 for (
auto &
Ref : RefList) {
3866 if (
Ref.isReadOnly())
3868 else if (
Ref.isWriteOnly())
3869 Out <<
"writeonly ";
3870 Out <<
"^" <<
Machine.getGUIDSlot(
Ref.getGUID());
3878void AssemblyWriter::printSummaryInfo(
unsigned Slot,
const ValueInfo &VI) {
3879 Out <<
"^" <<
Slot <<
" = gv: (";
3880 if (
VI.hasName() && !
VI.name().empty())
3881 Out <<
"name: \"" <<
VI.name() <<
"\"";
3883 Out <<
"guid: " <<
VI.getGUID();
3884 if (!
VI.getSummaryList().empty()) {
3885 Out <<
", summaries: (";
3887 for (
auto &Summary :
VI.getSummaryList()) {
3889 printSummary(*Summary);
3894 if (
VI.hasName() && !
VI.name().empty())
3895 Out <<
" ; guid = " <<
VI.getGUID();
3902 Out <<
"<empty name> ";
3904 unsigned char FirstC =
static_cast<unsigned char>(Name[0]);
3905 if (isalpha(FirstC) || FirstC ==
'-' || FirstC ==
'$' || FirstC ==
'.' ||
3910 for (
unsigned i = 1, e = Name.size(); i != e; ++i) {
3911 unsigned char C = Name[i];
3912 if (isalnum(
C) ||
C ==
'-' ||
C ==
'$' ||
C ==
'.' ||
C ==
'_')
3920void AssemblyWriter::printNamedMDNode(
const NamedMDNode *NMD) {
3955 Out <<
"dso_local ";
3973 Out <<
"thread_local ";
3976 Out <<
"thread_local(localdynamic) ";
3979 Out <<
"thread_local(initialexec) ";
3982 Out <<
"thread_local(localexec) ";
3992 return "local_unnamed_addr";
3994 return "unnamed_addr";
4017void AssemblyWriter::printGlobal(
const GlobalVariable *GV) {
4019 Out <<
"; Materializable\n";
4040 Out << (GV->
isConstant() ?
"constant " :
"global ");
4049 Out <<
", section \"";
4054 Out <<
", partition \"";
4059 Out <<
", code_model \"";
4084 Out <<
", no_sanitize_address";
4086 Out <<
", no_sanitize_hwaddress";
4088 Out <<
", sanitize_memtag";
4090 Out <<
", sanitize_address_dyninit";
4095 Out <<
", align " <<
A->value();
4099 printMetadataAttachments(MDs,
", ");
4102 if (
Attrs.hasAttributes())
4103 Out <<
" #" <<
Machine.getAttributeGroupSlot(Attrs);
4108void AssemblyWriter::printAlias(
const GlobalAlias *GA) {
4110 Out <<
"; Materializable\n";
4130 if (
const Constant *Aliasee = GA->
getAliasee()) {
4133 TypePrinter.print(GA->
getType(), Out);
4134 Out <<
" <<NULL ALIASEE>>";
4138 Out <<
", partition \"";
4147void AssemblyWriter::printIFunc(
const GlobalIFunc *GI) {
4149 Out <<
"; Materializable\n";
4164 if (
const Constant *Resolver = GI->
getResolver()) {
4167 TypePrinter.print(GI->
getType(), Out);
4168 Out <<
" <<NULL RESOLVER>>";
4172 Out <<
", partition \"";
4179 printMetadataAttachments(MDs,
", ");
4186void AssemblyWriter::printComdat(
const Comdat *
C) {
4190void AssemblyWriter::printTypeIdentities() {
4191 if (TypePrinter.empty())
4197 auto &NumberedTypes = TypePrinter.getNumberedTypes();
4198 for (
unsigned I = 0,
E = NumberedTypes.size();
I !=
E; ++
I) {
4199 Out <<
'%' <<
I <<
" = type ";
4203 TypePrinter.printStructBody(NumberedTypes[
I], Out);
4207 auto &NamedTypes = TypePrinter.getNamedTypes();
4208 for (StructType *NamedType : NamedTypes) {
4214 TypePrinter.printStructBody(NamedType, Out);
4220void AssemblyWriter::printFunction(
const Function *
F) {
4221 if (
F->isMaterializable())
4222 Out <<
"; Materializable\n";
4223 else if (AnnotationWriter)
4226 const AttributeList &
Attrs =
F->getAttributes();
4227 if (
Attrs.hasFnAttrs()) {
4228 AttributeSet AS =
Attrs.getFnAttrs();
4229 std::string AttrStr;
4232 if (!Attr.isStringAttribute()) {
4233 if (!AttrStr.empty()) AttrStr +=
' ';
4234 AttrStr += Attr.getAsString();
4238 if (!AttrStr.empty())
4239 Out <<
"; Function Attrs: " << AttrStr <<
'\n';
4243 Out <<
"; Unknown intrinsic\n";
4247 if (
F->isDeclaration()) {
4250 F->getAllMetadata(MDs);
4251 printMetadataAttachments(MDs,
" ");
4262 if (
F->getCallingConv() != CallingConv::C) {
4267 FunctionType *FT =
F->getFunctionType();
4268 if (
Attrs.hasRetAttrs())
4269 Out <<
Attrs.getAsString(AttributeList::ReturnIndex) <<
' ';
4270 TypePrinter.print(
F->getReturnType(), Out);
4277 if (
F->isDeclaration() && !IsForDebug) {
4280 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
4283 TypePrinter.print(FT->getParamType(
I), Out);
4285 AttributeSet ArgAttrs =
Attrs.getParamAttrs(
I);
4288 writeAttributeSet(ArgAttrs);
4294 for (
const Argument &Arg :
F->args()) {
4296 printArgument(&Arg,
Attrs.getParamAttrs(Arg.getArgNo()));
4301 if (FT->isVarArg()) {
4302 if (FT->getNumParams()) Out <<
", ";
4313 bool ForcePrintAddressSpace =
4314 !
Mod ||
Mod->getDataLayout().getProgramAddressSpace() != 0;
4316 "", ForcePrintAddressSpace);
4317 if (
Attrs.hasFnAttrs())
4318 Out <<
" #" <<
Machine.getAttributeGroupSlot(
Attrs.getFnAttrs());
4319 if (
F->hasSection()) {
4320 Out <<
" section \"";
4324 if (
F->hasPartition()) {
4325 Out <<
" partition \"";
4330 if (MaybeAlign
A =
F->getAlign())
4331 Out <<
" align " <<
A->value();
4332 if (MaybeAlign
A =
F->getPreferredAlignment())
4333 Out <<
" prefalign(" <<
A->value() <<
')';
4335 Out <<
" gc \"" <<
F->getGC() <<
'"';
4336 if (
F->hasPrefixData()) {
4338 writeOperand(
F->getPrefixData(),
true);
4340 if (
F->hasPrologueData()) {
4341 Out <<
" prologue ";
4342 writeOperand(
F->getPrologueData(),
true);
4344 if (
F->hasPersonalityFn()) {
4345 Out <<
" personality ";
4346 writeOperand(
F->getPersonalityFn(),
true);
4350 if (
auto *MDProf =
F->getMetadata(LLVMContext::MD_prof)) {
4352 MDProf->print(Out, TheModule,
true);
4356 if (
F->isDeclaration()) {
4360 F->getAllMetadata(MDs);
4361 printMetadataAttachments(MDs,
" ");
4365 for (
const BasicBlock &BB : *
F)
4379void AssemblyWriter::printArgument(
const Argument *Arg, AttributeSet Attrs) {
4381 TypePrinter.print(Arg->
getType(), Out);
4384 if (
Attrs.hasAttributes()) {
4386 writeAttributeSet(Attrs);
4395 assert(Slot != -1 &&
"expect argument in function here");
4396 Out <<
" %" <<
Slot;
4407 }
else if (!IsEntryBlock) {
4409 int Slot =
Machine.getLocalSlot(BB);
4416 if (!IsEntryBlock) {
4421 Out <<
" No predecessors!";
4427 writeOperand(Pred,
false);
4438 for (
const DbgRecord &DR :
I.getDbgRecordRange())
4439 printDbgRecordLine(DR);
4440 printInstructionLine(
I);
4447void AssemblyWriter::printInstructionLine(
const Instruction &
I) {
4448 printInstruction(
I);
4454void AssemblyWriter::printGCRelocateComment(
const GCRelocateInst &Relocate) {
4457 writeOperand(BasePtr,
false);
4462 writeOperand(DerivedPtr,
false);
4470void AssemblyWriter::printInfoComment(
const Value &V,
bool isMaterializable) {
4472 printGCRelocateComment(*Relocate);
4474 if (AnnotationWriter && !isMaterializable)
4479 if (
I->getDebugLoc()) {
4481 I->getDebugLoc().print(Out);
4487 if (
auto *MD =
I->getMetadata(LLVMContext::MD_prof)) {
4489 MD->print(Out, TheModule,
true);
4500 if (Operand ==
nullptr) {
4501 Out <<
" <cannot get addrspace!>";
4511 bool ForcePrintAddrSpace =
4512 !
Mod ||
Mod->getDataLayout().getProgramAddressSpace() != 0;
4514 ForcePrintAddrSpace);
4518void AssemblyWriter::printInstruction(
const Instruction &
I) {
4528 }
else if (!
I.getType()->isVoidTy()) {
4530 int SlotNum =
Machine.getLocalSlot(&
I);
4532 Out <<
"<badref> = ";
4534 Out <<
'%' << SlotNum <<
" = ";
4538 if (CI->isMustTailCall())
4540 else if (CI->isTailCall())
4542 else if (CI->isNoTailCall())
4547 Out <<
I.getOpcodeName();
4567 Out <<
" elementwise";
4574 Out <<
' ' << CI->getPredicate();
4578 if (RMWI->isElementwise())
4579 Out <<
" elementwise";
4584 const Value *Operand =
I.getNumOperands() ?
I.getOperand(0) :
nullptr;
4589 writeOperand(BI->getCondition(),
true);
4591 writeOperand(BI->getSuccessor(0),
true);
4593 writeOperand(BI->getSuccessor(1),
true);
4598 writeOperand(
SI.getCondition(),
true);
4600 writeOperand(
SI.getDefaultDest(),
true);
4602 for (
auto Case :
SI.cases()) {
4604 writeOperand(Case.getCaseValue(),
true);
4606 writeOperand(Case.getCaseSuccessor(),
true);
4612 writeOperand(Operand,
true);
4616 for (
unsigned i = 1, e =
I.getNumOperands(); i != e; ++i) {
4618 writeOperand(
I.getOperand(i),
true);
4623 TypePrinter.print(
I.getType(), Out);
4627 for (
const auto &[V,
Block] :
4628 zip_equal(PN->incoming_values(), PN->blocks())) {
4630 writeOperand(V,
false);
4632 writeOperand(
Block,
false);
4637 writeOperand(
I.getOperand(0),
true);
4642 writeOperand(
I.getOperand(0),
true); Out <<
", ";
4643 writeOperand(
I.getOperand(1),
true);
4648 TypePrinter.print(
I.getType(), Out);
4649 if (LPI->isCleanup() || LPI->getNumClauses() != 0)
4652 if (LPI->isCleanup())
4655 for (
unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
4656 if (i != 0 || LPI->isCleanup()) Out <<
"\n";
4657 if (LPI->isCatch(i))
4662 writeOperand(LPI->getClause(i),
true);
4666 writeOperand(CatchSwitch->getParentPad(),
false);
4669 for (
const BasicBlock *PadBB : CatchSwitch->handlers()) {
4671 writeOperand(PadBB,
true);
4674 if (
const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
4675 writeOperand(UnwindDest,
true);
4680 writeOperand(FPI->getParentPad(),
false);
4683 for (
const Value *
Op : FPI->arg_operands()) {
4685 writeOperand(
Op,
true);
4692 writeOperand(CRI->getOperand(0),
false);
4695 writeOperand(CRI->getOperand(1),
true);
4698 writeOperand(CRI->getOperand(0),
false);
4701 if (CRI->hasUnwindDest())
4702 writeOperand(CRI->getOperand(1),
true);
4707 if (CI->getCallingConv() != CallingConv::C) {
4712 Operand = CI->getCalledOperand();
4713 FunctionType *FTy = CI->getFunctionType();
4714 Type *RetTy = FTy->getReturnType();
4715 const AttributeList &PAL = CI->getAttributes();
4717 if (PAL.hasRetAttrs())
4718 Out <<
' ' << PAL.getAsString(AttributeList::ReturnIndex);
4727 TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
4729 writeOperand(Operand,
false);
4731 bool HasPrettyPrintedArgs =
4736 Function *CalledFunc = CI->getCalledFunction();
4737 auto PrintArgComment = [&](
unsigned ArgNo) {
4739 if (!ConstArg || !CalledFunc)
4741 std::string ArgComment;
4742 raw_string_ostream ArgCommentStream(ArgComment);
4745 if (ArgComment.empty())
4747 Out <<
"/* " << ArgComment <<
" */ ";
4749 if (HasPrettyPrintedArgs) {
4750 for (
unsigned ArgNo = 0, NumArgs = CI->arg_size(); ArgNo < NumArgs;
4753 PrintArgComment(ArgNo);
4754 writeParamOperand(CI->getArgOperand(ArgNo), PAL.getParamAttrs(ArgNo));
4757 for (
unsigned ArgNo = 0, NumArgs = CI->arg_size(); ArgNo < NumArgs;
4760 writeParamOperand(CI->getArgOperand(ArgNo), PAL.getParamAttrs(ArgNo));
4765 if (CI->isMustTailCall() && CI->getParent() &&
4766 CI->getParent()->getParent() &&
4767 CI->getParent()->getParent()->isVarArg()) {
4768 if (CI->arg_size() > 0)
4774 if (PAL.hasFnAttrs())
4775 Out <<
" #" <<
Machine.getAttributeGroupSlot(PAL.getFnAttrs());
4777 writeOperandBundles(CI);
4779 Operand =
II->getCalledOperand();
4780 FunctionType *FTy =
II->getFunctionType();
4781 Type *RetTy = FTy->getReturnType();
4782 const AttributeList &PAL =
II->getAttributes();
4785 if (
II->getCallingConv() != CallingConv::C) {
4790 if (PAL.hasRetAttrs())
4791 Out <<
' ' << PAL.getAsString(AttributeList::ReturnIndex);
4801 TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
4803 writeOperand(Operand,
false);
4806 for (
unsigned op = 0, Eop =
II->arg_size();
op < Eop; ++
op) {
4808 writeParamOperand(
II->getArgOperand(
op), PAL.getParamAttrs(
op));
4812 if (PAL.hasFnAttrs())
4813 Out <<
" #" <<
Machine.getAttributeGroupSlot(PAL.getFnAttrs());
4815 writeOperandBundles(
II);
4818 writeOperand(
II->getNormalDest(),
true);
4820 writeOperand(
II->getUnwindDest(),
true);
4822 Operand = CBI->getCalledOperand();
4823 FunctionType *FTy = CBI->getFunctionType();
4824 Type *RetTy = FTy->getReturnType();
4825 const AttributeList &PAL = CBI->getAttributes();
4828 if (CBI->getCallingConv() != CallingConv::C) {
4833 if (PAL.hasRetAttrs())
4834 Out <<
' ' << PAL.getAsString(AttributeList::ReturnIndex);
4841 TypePrinter.print(FTy->isVarArg() ? FTy : RetTy, Out);
4843 writeOperand(Operand,
false);
4845 ListSeparator ArgLS;
4846 for (
unsigned op = 0, Eop = CBI->arg_size();
op < Eop; ++
op) {
4848 writeParamOperand(CBI->getArgOperand(
op), PAL.getParamAttrs(
op));
4852 if (PAL.hasFnAttrs())
4853 Out <<
" #" <<
Machine.getAttributeGroupSlot(PAL.getFnAttrs());
4855 writeOperandBundles(CBI);
4858 writeOperand(CBI->getDefaultDest(),
true);
4860 ListSeparator DestLS;
4861 for (
const BasicBlock *Dest : CBI->getIndirectDests()) {
4863 writeOperand(Dest,
true);
4868 if (AI->isUsedWithInAlloca())
4870 if (AI->isSwiftError())
4871 Out <<
"swifterror ";
4872 TypePrinter.print(AI->getAllocatedType(), Out);
4878 if (!AI->getArraySize() || AI->isArrayAllocation() ||
4879 !AI->getArraySize()->getType()->isIntegerTy(32)) {
4881 writeOperand(AI->getArraySize(),
true);
4883 if (MaybeAlign
A = AI->getAlign()) {
4884 Out <<
", align " <<
A->value();
4892 writeOperand(Operand,
true);
4895 TypePrinter.print(
I.getType(), Out);
4899 writeOperand(Operand,
true);
4902 TypePrinter.print(
I.getType(), Out);
4903 }
else if (Operand) {
4906 TypePrinter.print(
GEP->getSourceElementType(), Out);
4910 TypePrinter.print(LI->getType(), Out);
4917 bool PrintAllTypes =
false;
4925 PrintAllTypes =
true;
4927 for (
unsigned i = 1,
E =
I.getNumOperands(); i !=
E; ++i) {
4928 Operand =
I.getOperand(i);
4931 if (Operand && Operand->
getType() != TheType) {
4932 PrintAllTypes =
true;
4938 if (!PrintAllTypes) {
4940 TypePrinter.print(TheType, Out);
4945 for (
const Value *
Op :
I.operands()) {
4947 writeOperand(
Op, PrintAllTypes);
4954 writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID());
4955 if (MaybeAlign
A = LI->getAlign())
4956 Out <<
", align " <<
A->value();
4959 writeAtomic(
SI->getContext(),
SI->getOrdering(),
SI->getSyncScopeID());
4960 if (MaybeAlign
A =
SI->getAlign())
4961 Out <<
", align " <<
A->value();
4963 writeAtomicCmpXchg(CXI->getContext(), CXI->getSuccessOrdering(),
4964 CXI->getFailureOrdering(), CXI->getSyncScopeID());
4965 Out <<
", align " << CXI->getAlign().value();
4967 writeAtomic(RMWI->getContext(), RMWI->getOrdering(),
4968 RMWI->getSyncScopeID());
4969 Out <<
", align " << RMWI->getAlign().value();
4971 writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
4979 printMetadataAttachments(InstMD,
", ");
4982 printInfoComment(
I);
4985void AssemblyWriter::printDbgMarker(
const DbgMarker &Marker) {
4989 printDbgRecord(DPR);
4993 Out <<
" DbgMarker -> { ";
4998void AssemblyWriter::printDbgRecord(
const DbgRecord &DR) {
5000 printDbgVariableRecord(*DVR);
5002 printDbgLabelRecord(*DLR);
5007void AssemblyWriter::printDbgVariableRecord(
const DbgVariableRecord &DVR) {
5011 case DbgVariableRecord::LocationType::Value:
5014 case DbgVariableRecord::LocationType::Declare:
5017 case DbgVariableRecord::LocationType::DeclareValue:
5018 Out <<
"declare_value";
5020 case DbgVariableRecord::LocationType::Assign:
5025 "Tried to print a DbgVariableRecord with an invalid LocationType!");
5056void AssemblyWriter::printDbgRecordLine(
const DbgRecord &DR) {
5063void AssemblyWriter::printDbgLabelRecord(
const DbgLabelRecord &Label) {
5065 Out <<
"#dbg_label(";
5072void AssemblyWriter::printMetadataAttachments(
5073 const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
5074 StringRef Separator) {
5078 if (MDNames.empty())
5079 MDs[0].second->getContext().getMDKindNames(MDNames);
5082 for (
const auto &
I : MDs) {
5083 unsigned Kind =
I.first;
5085 if (Kind < MDNames.size()) {
5089 Out <<
"!<unknown kind #" <<
Kind <<
">";
5095void AssemblyWriter::writeMDNode(
unsigned Slot,
const MDNode *Node) {
5096 if (AnnotationWriter)
5099 Out <<
'!' <<
Slot <<
" = ";
5100 printMDNodeBody(Node);
5104void AssemblyWriter::writeAllMDNodes() {
5111 for (
auto [Slot, Node] : Nodes)
5112 writeMDNode(Slot, Node);
5115void AssemblyWriter::printMDNodeBody(
const MDNode *Node) {
5120void AssemblyWriter::writeAttribute(
const Attribute &Attr,
bool InAttrGroup) {
5126 Out << Attribute::getNameFromAttrKind(Attr.
getKindAsEnum());
5129 TypePrinter.print(Ty, Out);
5134void AssemblyWriter::writeAttributeSet(
const AttributeSet &AttrSet,
5136 ListSeparator
LS(
" ");
5137 for (
const auto &Attr : AttrSet) {
5139 writeAttribute(Attr, InAttrGroup);
5143void AssemblyWriter::writeAllAttributeGroups() {
5144 std::vector<std::pair<AttributeSet, unsigned>> asVec;
5145 asVec.resize(
Machine.as_size());
5148 asVec[
I.second] =
I;
5150 for (
const auto &
I : asVec)
5151 Out <<
"attributes #" <<
I.second <<
" = { "
5152 <<
I.first.getAsString(
true) <<
" }\n";
5155void AssemblyWriter::printUseListOrder(
const Value *V,
5156 ArrayRef<unsigned> Shuffle) {
5160 Out <<
"uselistorder ";
5161 writeOperand(V,
true);
5163 assert(Shuffle.
size() >= 2 &&
"Shuffle too small");
5167void AssemblyWriter::printUseLists(
const Function *
F) {
5168 auto It = UseListOrders.find(
F);
5169 if (It == UseListOrders.end())
5172 Out <<
"\n; uselistorder directives\n";
5173 for (
const auto &Pair : It->second)
5174 printUseListOrder(Pair.first, Pair.second);
5182 bool ShouldPreserveUseListOrder,
bool IsForDebug)
const {
5185 AssemblyWriter W(OS, SlotTable, this->
getParent(), AAW, IsForDebug,
5186 ShouldPreserveUseListOrder);
5187 W.printFunction(
this);
5191 bool ShouldPreserveUseListOrder,
5192 bool IsForDebug)
const {
5195 AssemblyWriter W(OS, SlotTable, this->
getModule(), AAW, IsForDebug,
5196 ShouldPreserveUseListOrder);
5197 W.printBasicBlock(
this);
5201 bool ShouldPreserveUseListOrder,
bool IsForDebug)
const {
5204 AssemblyWriter W(OS, SlotTable,
this, AAW, IsForDebug,
5205 ShouldPreserveUseListOrder);
5206 W.printModule(
this);
5212 AssemblyWriter W(OS, SlotTable,
getParent(),
nullptr, IsForDebug);
5213 W.printNamedMDNode(
this);
5217 bool IsForDebug)
const {
5218 std::optional<SlotTracker> LocalST;
5224 SlotTable = &*LocalST;
5228 AssemblyWriter W(OS, *SlotTable,
getParent(),
nullptr, IsForDebug);
5229 W.printNamedMDNode(
this);
5234 ROS <<
" = comdat ";
5241 ROS <<
"exactmatch";
5247 ROS <<
"nodeduplicate";
5259 TP.print(
const_cast<Type*
>(
this), OS);
5268 TP.printStructBody(STy, OS);
5275 print(ROS, MST, IsForDebug);
5281 print(ROS, MST, IsForDebug);
5285 bool IsForDebug)
const {
5293 AssemblyWriter W(OS, SlotTable,
getModuleFromDPI(
this),
nullptr, IsForDebug);
5294 W.printDbgMarker(*
this);
5300 print(ROS, MST, IsForDebug);
5304 bool IsForDebug)
const {
5310 ?
Marker->getParent()->getParent()
5314 AssemblyWriter W(OS, SlotTable,
getModuleFromDPI(
this),
nullptr, IsForDebug);
5315 W.printDbgVariableRecord(*
this);
5319 bool IsForDebug)
const {
5325 Marker->getParent() ?
Marker->getParent()->getParent() :
nullptr;
5329 AssemblyWriter W(OS, SlotTable,
getModuleFromDPI(
this),
nullptr, IsForDebug);
5330 W.printDbgLabelRecord(*
this);
5335 F->print(ROS,
nullptr,
false, IsForDebug);
5339 BB->print(ROS,
nullptr,
false, IsForDebug);
5344 print(ROS, MST, IsForDebug);
5348 bool IsForDebug)
const {
5353 auto IncorporateFunction = [&](
const Function *
F) {
5359 IncorporateFunction(
I->getParent() ?
I->getParent()->getParent() :
nullptr);
5361 W.printInstruction(*
I);
5363 IncorporateFunction(BB->getParent());
5364 AssemblyWriter W(OS, SlotTable,
getModuleFromVal(BB),
nullptr, IsForDebug);
5365 W.printBasicBlock(BB);
5367 AssemblyWriter W(OS, SlotTable, GV->
getParent(),
nullptr, IsForDebug);
5381 TypePrinting TypePrinter;
5382 TypePrinter.print(
C->getType(), OS);
5384 AsmWriterContext WriterCtx(&TypePrinter, MST.
getMachine());
5400 AsmWriterContext WriterCtx(
nullptr,
Machine, M);
5409 TypePrinting TypePrinter(MST.
getModule());
5439 AsmWriterContext &WriterCtx) {
5452struct MDTreeAsmWriterContext :
public AsmWriterContext {
5455 using EntryTy = std::pair<unsigned, std::string>;
5459 SmallPtrSet<const Metadata *, 4> Visited;
5461 raw_ostream &MainOS;
5463 MDTreeAsmWriterContext(TypePrinting *TP, SlotTracker *ST,
const Module *M,
5464 const ModuleSlotTracker *MST, raw_ostream &OS,
5466 : AsmWriterContext(TP,
ST,
M, MST),
Level(0
U), Visited({InitMD}),
5469 void onWriteMetadataAsOperand(
const Metadata *MD)
override {
5470 if (!Visited.
insert(MD).second)
5474 raw_string_ostream
SS(Str);
5479 unsigned InsertIdx = Buffer.
size() - 1;
5482 Buffer[InsertIdx].second = std::move(
SS.str());
5486 ~MDTreeAsmWriterContext()
override {
5487 for (
const auto &Entry : Buffer) {
5489 unsigned NumIndent =
Entry.first * 2U;
5498 bool OnlyAsOperand,
bool PrintAsTree =
false) {
5501 TypePrinting TypePrinter(M);
5503 std::unique_ptr<AsmWriterContext> WriterCtx;
5504 if (PrintAsTree && !OnlyAsOperand)
5505 WriterCtx = std::make_unique<MDTreeAsmWriterContext>(
5506 &TypePrinter, MST.
getMachine(), M, &MST, OS, &MD);
5508 WriterCtx = std::make_unique<AsmWriterContext>(&TypePrinter,
5538 const Module *M,
bool )
const {
5557 AssemblyWriter W(OS, SlotTable,
this, IsForDebug);
5558 W.printModuleSummaryIndex();
5567 L.push_back(std::make_pair(
I.second,
I.first));
5570#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu next use AMDGPU Next Use Analysis Printer
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...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static void writeDIMacro(raw_ostream &Out, const DIMacro *N, AsmWriterContext &WriterCtx)
static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD, AsmWriterContext &WriterCtx)
static void writeDIGlobalVariableExpression(raw_ostream &Out, const DIGlobalVariableExpression *N, AsmWriterContext &WriterCtx)
static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, AsmWriterContext &WriterCtx)
static void writeDIFixedPointType(raw_ostream &Out, const DIFixedPointType *N, AsmWriterContext &WriterCtx)
static void printDSOLocation(const GlobalValue &GV, formatted_raw_ostream &Out)
static const char * getWholeProgDevirtResKindName(WholeProgramDevirtResolution::Kind K)
static void writeDISubrangeType(raw_ostream &Out, const DISubrangeType *N, AsmWriterContext &WriterCtx)
static void WriteFullHexAPInt(raw_ostream &Out, const APInt &Val)
static void writeAPFloatInternal(raw_ostream &Out, const APFloat &APF)
static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD, ModuleSlotTracker &MST, const Module *M, bool OnlyAsOperand, bool PrintAsTree=false)
static void writeDIStringType(raw_ostream &Out, const DIStringType *N, AsmWriterContext &WriterCtx)
static std::string getLinkageNameWithSpace(GlobalValue::LinkageTypes LT)
static cl::opt< bool > PreserveAssemblyUseListOrder("preserve-ll-uselistorder", cl::Hidden, cl::init(false), cl::desc("Preserve use-list order when writing LLVM assembly."))
static std::vector< unsigned > predictValueUseListOrder(const Value *V, unsigned ID, const OrderMap &OM)
static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N, AsmWriterContext &WriterCtx)
static void orderValue(const Value *V, OrderMap &OM)
static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N, AsmWriterContext &WriterCtx)
static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA)
static const char * getWholeProgDevirtResByArgKindName(WholeProgramDevirtResolution::ByArg::Kind K)
static void writeMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node, AsmWriterContext &Ctx)
static void writeDIModule(raw_ostream &Out, const DIModule *N, AsmWriterContext &WriterCtx)
static void writeDIFile(raw_ostream &Out, const DIFile *N, AsmWriterContext &)
static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N, AsmWriterContext &WriterCtx)
static cl::opt< bool > PrintAddrspaceName("print-addrspace-name", cl::Hidden, cl::init(false), cl::desc("Print address space names"))
static void writeOptimizationInfo(raw_ostream &Out, const User *U)
#define CC_VLS_CASE(ABI_VLEN)
static void writeDILabel(raw_ostream &Out, const DILabel *N, AsmWriterContext &WriterCtx)
static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N, AsmWriterContext &WriterCtx)
static void printMetadataIdentifier(StringRef Name, formatted_raw_ostream &Out)
static void printShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef< int > Mask)
static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N, AsmWriterContext &WriterCtx)
static const Module * getModuleFromDPI(const DbgMarker *Marker)
static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType, ModuleSlotTracker &MST)
static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N, AsmWriterContext &WriterCtx)
static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, AsmWriterContext &WriterCtx)
static const char * getSummaryKindName(GlobalValueSummary::SummaryKind SK)
static OrderMap orderModule(const Module *M)
static const char * getVisibilityName(GlobalValue::VisibilityTypes Vis)
static void printCallingConv(unsigned cc, raw_ostream &Out)
static void printAddressSpace(const Module *M, unsigned AS, raw_ostream &OS, StringRef Prefix=" ", StringRef Suffix="", bool ForcePrint=false)
static cl::opt< bool > PrintInstDebugLocs("print-inst-debug-locs", cl::Hidden, cl::desc("Pretty print debug locations of instructions when dumping"))
static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD, AsmWriterContext &WriterCtx)
Recursive version of printMetadataImpl.
static SlotTracker * createSlotTracker(const Value *V)
static void writeDILocation(raw_ostream &Out, const DILocation *DL, AsmWriterContext &WriterCtx)
static void writeDINamespace(raw_ostream &Out, const DINamespace *N, AsmWriterContext &WriterCtx)
DenseMap< const Function *, MapVector< const Value *, std::vector< unsigned > > > UseListOrderMap
static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N, AsmWriterContext &WriterCtx)
static UseListOrderMap predictUseListOrder(const Module *M)
static void printThreadLocalModel(GlobalVariable::ThreadLocalMode TLM, formatted_raw_ostream &Out)
static std::string getLinkageName(GlobalValue::LinkageTypes LT)
static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N, AsmWriterContext &WriterCtx)
static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N, AsmWriterContext &WriterCtx)
static const char * getTTResKindName(TypeTestResolution::Kind K)
static void writeDITemplateTypeParameter(raw_ostream &Out, const DITemplateTypeParameter *N, AsmWriterContext &WriterCtx)
static const char * getImportTypeName(GlobalValueSummary::ImportKind IK)
static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, AsmWriterContext &WriterCtx)
static const Module * getModuleFromVal(const Value *V)
static void printLLVMName(raw_ostream &OS, StringRef Name, PrefixType Prefix)
Turn the specified name into an 'LLVM name', which is either prefixed with % (if the string only cont...
static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I, raw_ostream &Out)
static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N, AsmWriterContext &WriterCtx)
static void writeDISubrange(raw_ostream &Out, const DISubrange *N, AsmWriterContext &WriterCtx)
static void writeDIProperty(raw_ostream &Out, const DIProperty *N, AsmWriterContext &WriterCtx)
static void writeDILexicalBlockFile(raw_ostream &Out, const DILexicalBlockFile *N, AsmWriterContext &WriterCtx)
static void writeConstantInternal(raw_ostream &Out, const Constant *CV, AsmWriterContext &WriterCtx)
static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N, AsmWriterContext &)
static void writeAsOperandInternal(raw_ostream &Out, const Value *V, AsmWriterContext &WriterCtx, bool PrintType=false)
static void printVisibility(GlobalValue::VisibilityTypes Vis, formatted_raw_ostream &Out)
static cl::opt< bool > PrintProfData("print-prof-data", cl::Hidden, cl::desc("Pretty print perf data (branch weights, etc) when dumping"))
static void writeMDTuple(raw_ostream &Out, const MDTuple *Node, AsmWriterContext &WriterCtx)
static void writeDIExpression(raw_ostream &Out, const DIExpression *N, AsmWriterContext &WriterCtx)
static cl::opt< bool > PrintInstAddrs("print-inst-addrs", cl::Hidden, cl::desc("Print addresses of instructions when dumping"))
static void writeDIAssignID(raw_ostream &Out, const DIAssignID *DL, AsmWriterContext &WriterCtx)
static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N, AsmWriterContext &WriterCtx)
static void maybePrintComdat(formatted_raw_ostream &Out, const GlobalObject &GO)
static void printDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT, formatted_raw_ostream &Out)
static bool printWithoutType(const Value &V, raw_ostream &O, SlotTracker *Machine, const Module *M)
Print without a type, skipping the TypePrinting object.
static void writeDIArgList(raw_ostream &Out, const DIArgList *N, AsmWriterContext &WriterCtx, bool FromValue=false)
static void writeDITemplateValueParameter(raw_ostream &Out, const DITemplateValueParameter *N, AsmWriterContext &WriterCtx)
static const Value * skipMetadataWrapper(const Value *V)
Look for a value that might be wrapped as metadata, e.g.
static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N, AsmWriterContext &WriterCtx)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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...
GlobalValue::SanitizerMetadata SanitizerMetadata
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This file contains an interface for creating legacy passes to print out IR in various granularities.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
Machine Check Debug Module
static bool InRange(int64_t Value, unsigned short Shift, int LBound, int HBound)
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
static bool processModule(Module &M, NVPTXTargetMachine &TM)
static bool processFunction(Function &F, NVPTXTargetMachine &TM)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
Function const char TargetMachine * Machine
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file provides utility classes that use RAII to save and restore values.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallString class.
This file defines the SmallVector class.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static UseListOrderStack predictUseListOrder(const Module &M)
static const fltSemantics & PPCDoubleDouble()
void toString(SmallVectorImpl< char > &Str, unsigned FormatPrecision=0, unsigned FormatMaxPadding=3, bool TruncateZero=true) const
const fltSemantics & getSemantics() const
APInt bitcastToAPInt() const
APInt getNaNPayload() const
If the value is a NaN value, return an integer containing the payload of this value.
Class for arbitrary precision integers.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
void toStringUnsigned(SmallVectorImpl< char > &Str, unsigned Radix=10) const
Considers the APInt to be unsigned and converts it into a string in the radix given.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isSignMask() const
Check if the APInt's value is returned by getSignMask.
unsigned getBitWidth() const
Return the number of bits in the APInt.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Abstract interface of slot tracker storage.
virtual ~AbstractSlotTrackerStorage()
const GlobalValueSummary & getAliasee() const
This class represents an incoming formal argument to a Function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
virtual void emitMDNodeAnnot(const MDNode *, formatted_raw_ostream &)
emitMDNodeAnnot - This may be implemented to emit a string right before a metadata node is emitted.
virtual void emitBasicBlockStartAnnot(const BasicBlock *, formatted_raw_ostream &)
emitBasicBlockStartAnnot - This may be implemented to emit a string right after the basic block label...
virtual void emitBasicBlockEndAnnot(const BasicBlock *, formatted_raw_ostream &)
emitBasicBlockEndAnnot - This may be implemented to emit a string right after the basic block.
virtual void emitFunctionAnnot(const Function *, formatted_raw_ostream &)
emitFunctionAnnot - This may be implemented to emit a string right before the start of a function.
virtual void emitInstructionAnnot(const Instruction *, formatted_raw_ostream &)
emitInstructionAnnot - This may be implemented to emit a string right before an instruction is emitte...
virtual void printInfoComment(const Value &, formatted_raw_ostream &)
printInfoComment - This may be implemented to emit a comment to the right of an instruction or global...
virtual ~AssemblyAnnotationWriter()
static LLVM_ABI StringRef getOperationName(BinOp Op)
This class holds the attributes for a particular argument, parameter, function, or return value.
bool hasAttributes() const
Return true if attributes exists in this set.
LLVM_ABI std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
LLVM_ABI Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
LLVM_ABI bool isTypeAttribute() const
Return true if the attribute is a type attribute.
LLVM_ABI Type * getValueAsType() const
Return the attribute's value as a Type.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW=nullptr, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the basic block to an output stream with an optional AssemblyAnnotationWriter.
LLVM_ABI bool isEntryBlock() const
Return true if this is the entry block of the containing function.
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
OperandBundleUse getOperandBundleAt(unsigned Index) const
Return the operand bundle at a specific index.
unsigned getNumOperandBundles() const
Return the number of operand bundles associated with this User.
AttributeList getAttributes() const
Return the attributes for this call.
bool hasOperandBundles() const
Return true if this User has any operand bundles.
LLVM_ABI void print(raw_ostream &OS, bool IsForDebug=false) const
LLVM_ABI void dump() const
@ Largest
The linker will choose the largest COMDAT.
@ SameSize
The data referenced by the COMDAT must be the same size.
@ Any
The linker may choose any COMDAT.
@ NoDeduplicate
No deduplication is performed.
@ ExactMatch
The data referenced by the COMDAT must be the same.
SelectionKind getSelectionKind() const
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
LLVM_ABI APInt getSignedMin() const
Return the smallest signed value contained in the ConstantRange.
LLVM_ABI APInt getSignedMax() const
Return the largest signed value contained in the ConstantRange.
This is an important base class in LLVM.
LLVM_ABI Constant * getSplatValue(bool AllowPoison=false) const
If all elements of the vector constant have the same value, return that value.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
List of ValueAsMetadata, to be used as an argument to a dbg.value intrinsic.
Basic type, like 'int' or 'float'.
static LLVM_ABI const char * nameTableKindString(DebugNameTableKind PK)
static LLVM_ABI const char * emissionKindString(DebugEmissionKind EK)
A lightweight wrapper around an expression operand.
static LLVM_ABI const char * fixedPointKindString(FixedPointKind)
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Macro Info DWARF-like metadata node.
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
Tagged DWARF-like metadata node.
static LLVM_ABI DIFlags splitFlags(DIFlags Flags, SmallVectorImpl< DIFlags > &SplitFlags)
Split up a flags bitfield.
static LLVM_ABI StringRef getFlagString(DIFlags Flag)
A property of a class or structure.
Wrapper structure that holds source language identity metadata that includes language name,...
uint32_t getVersion() const
Returns language version. Only valid for versioned language names.
uint16_t getDialect() const
bool hasVersionedName() const
uint16_t getName() const
Returns a versioned or unversioned language name.
String type, Fortran CHARACTER(n)
Subprogram description. Uses SubclassData1.
static LLVM_ABI DISPFlags splitFlags(DISPFlags Flags, SmallVectorImpl< DISPFlags > &SplitFlags)
Split up a flags bitfield for easier printing.
static LLVM_ABI StringRef getFlagString(DISPFlags Flag)
DISPFlags
Debug info subprogram flags.
Type array for a subprogram.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Per-instruction record of debug-info.
LLVM_ABI void dump() const
Instruction * MarkedInstr
Link back to the Instruction that owns this marker.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on DbgMarker.
LLVM_ABI const BasicBlock * getParent() const
simple_ilist< DbgRecord > StoredDbgRecords
List of DbgRecords, the non-instruction equivalent of llvm.dbg.
Base class for non-instruction debug metadata records that have positions within IR.
DebugLoc getDebugLoc() const
LLVM_ABI void dump() const
DbgMarker * Marker
Marker that this DbgRecord is linked into.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
LocationType getType() const
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
MDNode * getRawExpression() const
MDNode * getRawAddressExpression() const
Metadata * getRawAssignID() const
MDNode * getRawVariable() const
Metadata * getRawLocation() const
Returns the metadata operand for the first location description.
Metadata * getRawAddress() const
LLVM_ABI MDNode * getAsMDNode() const
Return this as a bar MDNode.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW=nullptr, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the function to an output stream with an optional AssemblyAnnotationWriter.
const Function & getFunction() const
const Argument * const_arg_iterator
LLVM_ABI Value * getBasePtr() const
LLVM_ABI Value * getDerivedPtr() const
Generic tagged DWARF-like metadata node.
const Constant * getAliasee() const
const Constant * getResolver() const
StringRef getSection() const
Get the custom section of this global if it has one.
LLVM_ABI void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
const Comdat * getComdat() const
bool hasSection() const
Check if this global has a custom object file section.
SummaryKind
Sububclass discriminator (for dyn_cast<> et al.)
bool hasPartition() const
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
LLVM_ABI const SanitizerMetadata & getSanitizerMetadata() const
bool hasExternalLinkage() const
VisibilityTypes getVisibility() const
bool isImplicitDSOLocal() const
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
ThreadLocalMode getThreadLocalMode() const
DLLStorageClassTypes
Storage classes of global values for PE targets.
@ DLLExportStorageClass
Function to be accessible from DLL.
@ DLLImportStorageClass
Function to be imported from DLL.
bool hasSanitizerMetadata() const
LLVM_ABI StringRef getPartition() const
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
LLVM_ABI bool isMaterializable() const
If this function's Module is being lazily streamed in functions from disk or some other source,...
UnnamedAddr getUnnamedAddr() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AppendingLinkage
Special purpose, only applies to global arrays.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
DLLStorageClassTypes getDLLStorageClass() const
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isExternallyInitialized() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
AttributeSet getAttributes() const
Return the attribute set for this global.
std::optional< CodeModel::Model > getCodeModel() const
Get the custom code model of this global if it has one.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
A helper class to return the specified delimiter string after the first invocation of operator String...
LLVM_ABI void printTree(raw_ostream &OS, const Module *M=nullptr) const
Print in tree shape.
LLVM_ABI void dumpTree() const
User-friendly dump in tree shape.
This class implements a map that also provides access to all stored values in a deterministic order.
Manage lifetime of a slot tracker for printing IR.
const Module * getModule() const
ModuleSlotTracker(SlotTracker &Machine, const Module *M, const Function *F=nullptr)
Wrap a preinitialized SlotTracker.
void renumberMetadataForAssembly(ArrayRef< const MDNode * > AdditionalMetadata, MachineMDNodeListType *AdditionalMetadataNodes=nullptr) const
Renumber module metadata and then additional metadata for canonical assembly output.
void collectMDNodes(MachineMDNodeListType &L) const
void setProcessHook(std::function< void(AbstractSlotTrackerStorage *, const Module *)>)
virtual ~ModuleSlotTracker()
Destructor to clean up storage.
void collectAdditionalMetadata(ArrayRef< const MDNode * > AdditionalMetadata, MachineMDNodeListType &AdditionalMetadataNodes) const
Collect metadata reachable from AdditionalMetadata but not from the module.
int getLocalSlot(const Value *V)
Return the slot number of the specified local value.
virtual bool shouldPrintDebugLocationInline(const DILocation *) const
Return whether a debug location should be printed inline instead of by ID.
SlotTracker * getMachine()
Lazily creates a slot tracker.
SmallVector< std::pair< unsigned, const MDNode * >, 0 > MachineMDNodeListType
void incorporateFunction(const Function &F)
Incorporate the given function.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
uint64_t getBlockCount() const
const TypeIdSummaryMapTy & typeIds() const
ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const
Return a ValueInfo for the index value_type (convenient when iterating index).
static constexpr const char * getRegularLTOModuleName()
const auto & typeIdCompatibleVtableMap() const
const StringMap< ModuleHash > & modulePaths() const
Table of modules, containing module hash and id.
LLVM_ABI void dump() const
Dump to stderr (for debugging).
GlobalValueSummaryMapTy::SortedEntriesRange sortedGlobalValueSummariesRange() const
uint64_t getStackIdAtIndex(unsigned Index) const
LLVM_ABI void print(raw_ostream &OS, bool IsForDebug=false) const
Print to an output stream.
LLVM_ABI uint64_t getFlags() const
A Module instance is used to store all the information related to an LLVM module.
void renumberMetadataForAssembly()
Renumber the IDs stored in metadata nodes into canonical assembly order.
iterator_range< alias_iterator > aliases()
iterator_range< global_iterator > globals()
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const
Print the module to an output stream with an optional AssemblyAnnotationWriter.
void dump() const
Dump the module to stderr (for debugging).
LLVM_ABI void dump() const
LLVM_ABI StringRef getName() const
LLVM_ABI void print(raw_ostream &ROS, bool IsForDebug=false) const
iterator_range< op_iterator > operands()
unsigned getAddressSpace() const
Return the address space of the Pointer type.
This class provides computation of slot numbers for LLVM Assembly writing.
DenseMap< const Value *, unsigned > ValueMap
ValueMap - A mapping of Values to slot numbers.
int getMetadataSlot(const MDNode *N) override
getMetadataSlot - Get the slot number of a MDNode.
~SlotTracker() override=default
int getTypeIdCompatibleVtableSlot(StringRef Id)
int getModulePathSlot(StringRef Path)
unsigned mdn_size() const
SlotTracker(const SlotTracker &)=delete
void purgeFunction()
After calling incorporateFunction, use this method to remove the most recently incorporated function ...
int getTypeIdSlot(StringRef Id)
void initializeIfNeeded()
These functions do the actual initialization.
int getGlobalSlot(const GlobalValue *V)
getGlobalSlot - Get the slot number of a global value.
SlotTracker(const Module *M, bool ShouldTrackMetadataDefinitions=false)
Construct from a module.
const Function * getFunction() const
DenseMap< GlobalValue::GUID, unsigned >::iterator guid_iterator
GUID map iterators.
void incorporateFunction(const Function *F)
If you'd like to deal with a function instead of just a module, use this method to get its data into ...
int getLocalSlot(const Value *V)
Return the slot number of the specified value in it's type plane.
int getAttributeGroupSlot(AttributeSet AS)
void setProcessHook(std::function< void(AbstractSlotTrackerStorage *, const Module *)>)
void createMetadataSlot(const MDNode *N) override
getMetadataSlot - Get the slot number of a MDNode.
DenseMap< const MDNode *, unsigned >::iterator mdn_iterator
MDNode map iterators.
SlotTracker & operator=(const SlotTracker &)=delete
int getGUIDSlot(GlobalValue::GUID GUID)
int initializeIndexIfNeeded()
DenseMap< AttributeSet, unsigned >::iterator as_iterator
AttributeSet map iterators.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
ArrayRef< Type * > elements() const
unsigned getNumElements() const
Random access to the elements.
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition.
bool isOpaque() const
Return true if this is a type with an identity that has no body specified yet.
LLVM_ABI StringRef getName() const
Return the name for this struct type if it has an identity.
ArrayRef< Type * > type_params() const
Return the type parameters for this particular target extension type.
ArrayRef< unsigned > int_params() const
Return the integer parameters for this particular target extension type.
TypeFinder - Walk over a module, identifying all of the types that are used by the module.
LLVM_ABI void run(const Module &M, bool onlyNamed)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
LLVM_ABI StringRef getTargetExtName() const
Type(LLVMContext &C, TypeID tid)
LLVM_ABI void dump() const
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false, bool NoDetails=false) const
Print the current type.
LLVM_ABI unsigned getByteBitWidth() const
TypeID getTypeID() const
Return the type id for the type.
Type * getElementType() const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
iterator_range< user_iterator > users()
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
LLVM_ABI StringRef LanguageDialectString(unsigned LanguageDialect)
LLVM_ABI StringRef SourceLanguageNameString(SourceLanguageName Lang)
LLVM_ABI StringRef EnumKindString(unsigned EnumKind)
LLVM_ABI StringRef LanguageString(unsigned Language)
LLVM_ABI StringRef AttributeEncodingString(unsigned Encoding)
LLVM_ABI StringRef ConventionString(unsigned Convention)
LLVM_ABI StringRef MacinfoString(unsigned Encoding)
LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)
LLVM_ABI StringRef TagString(unsigned Tag)
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
@ X86_64_SysV
The C convention as specified in the x86-64 supplement to the System V ABI, used on most non-Windows ...
@ RISCV_VectorCall
Calling convention used for RISC-V V-extension.
@ AMDGPU_CS
Used for Mesa/AMDPAL compute shaders.
@ AMDGPU_VS
Used for Mesa vertex shaders, or AMDPAL last shader stage before rasterization (vertex shader if tess...
@ AVR_SIGNAL
Used for AVR signal routines.
@ Swift
Calling convention for Swift.
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
@ ARM_APCS
ARM Procedure Calling Standard (obsolete, but still used on some targets).
@ CHERIoT_CompartmentCall
Calling convention used for CHERIoT when crossing a protection boundary.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
@ AVR_INTR
Used for AVR interrupt routines.
@ PreserveMost
Used for runtime calls that preserves most registers.
@ AnyReg
OBSOLETED - Used for stack based JavaScript calls.
@ AMDGPU_Gfx
Used for AMD graphics targets.
@ DUMMY_HHVM
Placeholders for HHVM calling conventions (deprecated, removed).
@ AMDGPU_CS_ChainPreserve
Used on AMDGPUs to give the middle-end more control over argument placement.
@ AMDGPU_HS
Used for Mesa/AMDPAL hull shaders (= tessellation control shaders).
@ ARM_AAPCS
ARM Architecture Procedure Calling Standard calling convention (aka EABI).
@ CHERIoT_CompartmentCallee
Calling convention used for the callee of CHERIoT_CompartmentCall.
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2
Preserve X2-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ CHERIoT_LibraryCall
Calling convention used for CHERIoT for cross-library calls to a stateless compartment.
@ CXX_FAST_TLS
Used for access functions.
@ X86_INTR
x86 hardware interrupt context.
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0
Preserve X0-X13, X19-X29, SP, Z0-Z31, P0-P15.
@ AMDGPU_CS_Chain
Used on AMDGPUs to give the middle-end more control over argument placement.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1
Preserve X1-X15, X19-X29, SP, Z0-Z31, P0-P15.
@ X86_ThisCall
Similar to X86_StdCall.
@ PTX_Device
Call to a PTX device function.
@ SPIR_KERNEL
Used for SPIR kernel functions.
@ PreserveAll
Used for runtime calls that preserves (almost) all registers.
@ X86_StdCall
stdcall is mostly used by the Win32 API.
@ SPIR_FUNC
Used for SPIR non-kernel device functions.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ MSP430_INTR
Used for MSP430 interrupt routines.
@ X86_VectorCall
MSVC calling convention that passes vectors and vector aggregates in SSE registers.
@ Intel_OCL_BI
Used for Intel OpenCL built-ins.
@ PreserveNone
Used for runtime calls that preserves none general registers.
@ AMDGPU_ES
Used for AMDPAL shader stage before geometry shader if geometry is in use.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
@ PTX_Kernel
Call to a PTX kernel. Passes all arguments in parameter space.
@ SwiftTail
This follows the Swift calling convention in how arguments are passed but guarantees tail calls will ...
@ GRAAL
Used by GraalVM. Two additional registers are reserved.
@ AMDGPU_LS
Used for AMDPAL vertex shader if tessellation is in use.
@ ARM_AAPCS_VFP
Same as ARM_AAPCS, but uses hard floating point ABI.
@ X86_RegCall
Register calling convention used for parameters transfer optimization.
@ M68k_RTD
Used for M68k rtd-based CC (similar to X86's stdcall).
@ X86_FastCall
'fast' analog of X86_StdCall.
LLVM_ABI void printImmArg(ID IID, unsigned ArgIdx, raw_ostream &OS, const Constant *ImmArgVal)
Print the argument info for the arguments with ArgInfo.
LLVM_ABI bool hasPrettyPrintedArgs(ID id)
Returns true if the intrinsic has pretty printed immediate arguments.
constexpr bool isAtomic(const T &...O)
@ System
Synchronized with respect to all concurrently executing threads.
initializer< Ty > init(const Ty &Val)
DXILDebugInfoMap run(Module &M)
bool isElementwise(const VPValue *V)
Return true if V is elementwise, i.e. none of the lanes are permuted.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
InterleavedRange< Range > interleaved(const Range &R, StringRef Separator=", ", StringRef Prefix="", StringRef Suffix="")
Output range R as a sequence of interleaved elements.
const char * getHotnessName(CalleeInfo::HotnessType HT)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI void printEscapedString(StringRef Name, raw_ostream &Out)
Print each character of the specified string, escaping it if it is not printable or if it is an escap...
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
const char * toIRString(AtomicOrdering ao)
String used by LLVM IR to represent atomic ordering.
auto dyn_cast_or_null(const Y &Val)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char hexdigit(unsigned X, bool LowerCase=false)
hexdigit - Return the hexadecimal character for the given number X (which should be less than 16).
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
constexpr int PoisonMaskElem
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Ref
The access may reference the value stored in memory.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
LLVM_ABI Printable printBasicBlock(const BasicBlock *BB)
Print BasicBlock BB as an operand or print "<nullptr>" if BB is a nullptr.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
bool pred_empty(const BasicBlock *BB)
std::vector< TypeIdOffsetVtableInfo > TypeIdCompatibleVtableInfo
List of vtable definitions decorated by a particular type identifier, and their corresponding offsets...
static auto filterDbgVars(iterator_range< simple_ilist< DbgRecord >::iterator > R)
Filter the DbgRecord range to DbgVariableRecord types only and downcast.
LLVM_ABI void printLLVMNameWithoutPrefix(raw_ostream &OS, StringRef Name)
Print out a name of an LLVM value without any prefixes.
@ Default
The result value is uniform if and only if all operands are uniform.
A single checksum, represented by a Kind and a Value (a string).
T Value
The string value of the checksum.
StringRef getKindAsString() const
std::vector< ConstVCall > TypeCheckedLoadConstVCalls
std::vector< VFuncId > TypeCheckedLoadVCalls
std::vector< ConstVCall > TypeTestAssumeConstVCalls
List of virtual calls made by this function using (respectively) llvm.assume(llvm....
std::vector< GlobalValue::GUID > TypeTests
List of type identifiers used by this function in llvm.type.test intrinsics referenced by something o...
std::vector< VFuncId > TypeTestAssumeVCalls
List of virtual calls made by this function using (respectively) llvm.assume(llvm....
unsigned NoRenameOnPromotion
This field is written by the ThinLTO prelink stage to decide whether a particular static global value...
unsigned DSOLocal
Indicates that the linker resolved the symbol to a definition from within the same linkage unit.
unsigned CanAutoHide
In the per-module summary, indicates that the global value is linkonce_odr and global unnamed addr (s...
unsigned ImportType
This field is written by the ThinLTO indexing step to postlink combined summary.
unsigned NotEligibleToImport
Indicate if the global value cannot be imported (e.g.
unsigned Linkage
The linkage type of the associated global value.
unsigned Visibility
Indicates the visibility.
unsigned Live
In per-module summary, indicate that the global value must be considered a live root for index-based ...
StringRef getTagName() const
Return the tag of this operand bundle as a string.
A utility class that uses RAII to save and restore the value of a variable.
std::map< uint64_t, WholeProgramDevirtResolution > WPDRes
Mapping from byte offset to whole-program devirt resolution for that (typeid, byte offset) pair.
Kind
Specifies which kind of type check we should emit for this byte array.
@ Unknown
Unknown (analysis not performed, don't lower)
@ Single
Single element (last example in "Short Inline Bit Vectors")
@ Inline
Inlined bit vector ("Short Inline Bit Vectors")
@ Unsat
Unsatisfiable type (i.e. no global has this type metadata)
@ AllOnes
All-ones bit vector ("Eliminating Bit Vector Checks for All-Ones Bit Vectors")
@ ByteArray
Test a byte array (first example)
unsigned SizeM1BitWidth
Range of size-1 expressed as a bit width.
enum llvm::TypeTestResolution::Kind TheKind
@ UniformRetVal
Uniform return value optimization.
@ VirtualConstProp
Virtual constant propagation.
@ UniqueRetVal
Unique return value optimization.
@ Indir
Just do a regular virtual call.
enum llvm::WholeProgramDevirtResolution::Kind TheKind
std::map< std::vector< uint64_t >, ByArg > ResByArg
Resolutions for calls with all constant integer arguments (excluding the first argument,...
std::string SingleImplName
@ SingleImpl
Single implementation devirtualization.
@ Indir
Just do a regular virtual call.
@ BranchFunnel
When retpoline mitigation is enabled, use a branch funnel that is defined in the merged module.
Function object to check whether the second component of a container supported by std::get (like std:...