31#include "llvm/Config/llvm-config.h"
106 if (
const auto *MAV = dyn_cast<MetadataAsValue>(V))
107 if (
const auto *VAM = dyn_cast<ValueAsMetadata>(MAV->getMetadata()))
108 return VAM->getValue();
116 if (
const Constant *
C = dyn_cast<Constant>(V))
117 if (
C->getNumOperands() && !isa<GlobalValue>(
C))
118 for (
const Value *
Op :
C->operands())
119 if (!isa<BasicBlock>(
Op) && !isa<GlobalValue>(
Op))
124 unsigned ID = OM.size() + 1;
132 if (
G.hasInitializer())
133 if (!isa<GlobalValue>(
G.getInitializer()))
138 if (!isa<GlobalValue>(
A.getAliasee()))
143 if (!isa<GlobalValue>(
I.getResolver()))
148 for (
const Use &U :
F.operands())
149 if (!isa<GlobalValue>(U.get()))
154 if (
F.isDeclaration())
162 for (
const Value *
Op :
I.operands()) {
164 if ((isa<Constant>(*
Op) && !isa<GlobalValue>(*
Op)) ||
175static std::vector<unsigned>
178 using Entry = std::pair<const Use *, unsigned>;
180 for (
const Use &U : V->uses())
182 if (OM.lookup(U.getUser()))
183 List.push_back(std::make_pair(&U,
List.size()));
192 bool GetsReversed = !isa<BasicBlock>(V);
193 if (
auto *BA = dyn_cast<BlockAddress>(V))
194 ID = OM.lookup(BA->getBasicBlock());
196 const Use *LU = L.first;
197 const Use *RU = R.first;
201 auto LID = OM.lookup(LU->getUser());
202 auto RID = OM.lookup(RU->getUser());
222 return LU->getOperandNo() < RU->getOperandNo();
223 return LU->getOperandNo() > RU->getOperandNo();
231 std::vector<unsigned> Shuffle(
List.size());
232 for (
size_t I = 0,
E =
List.size();
I !=
E; ++
I)
233 Shuffle[
I] =
List[
I].second;
240 for (
const auto &Pair : OM) {
241 const Value *V = Pair.first;
242 if (V->use_empty() || std::next(V->use_begin()) == V->use_end())
245 std::vector<unsigned> Shuffle =
251 if (
auto *
I = dyn_cast<Instruction>(V))
252 F =
I->getFunction();
253 if (
auto *
A = dyn_cast<Argument>(V))
255 if (
auto *BB = dyn_cast<BasicBlock>(V))
257 ULOM[
F][V] = std::move(Shuffle);
263 if (
const Argument *MA = dyn_cast<Argument>(V))
264 return MA->getParent() ? MA->getParent()->getParent() :
nullptr;
266 if (
const BasicBlock *BB = dyn_cast<BasicBlock>(V))
267 return BB->getParent() ? BB->getParent()->getParent() :
nullptr;
270 const Function *M =
I->getParent() ?
I->getParent()->getParent() :
nullptr;
271 return M ? M->getParent() :
nullptr;
274 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V))
275 return GV->getParent();
277 if (
const auto *MAV = dyn_cast<MetadataAsValue>(V)) {
278 for (
const User *U : MAV->users())
279 if (isa<Instruction>(U))
290 default: Out <<
"cc" << cc;
break;
312 Out <<
"aarch64_sve_vector_pcs";
315 Out <<
"aarch64_sme_preservemost_from_x0";
318 Out <<
"aarch64_sme_preservemost_from_x2";
346 Out <<
"amdgpu_cs_chain";
349 Out <<
"amdgpu_cs_chain_preserve";
365 assert(!
Name.empty() &&
"Cannot get empty name!");
368 bool NeedsQuotes = isdigit(
static_cast<unsigned char>(
Name[0]));
370 for (
unsigned char C :
Name) {
375 if (!isalnum(
static_cast<unsigned char>(
C)) &&
C !=
'-' &&
C !=
'.' &&
392 printEscapedString(
Name,
OS);
428 if (isa<ScalableVectorType>(Ty))
430 Out << Mask.size() <<
" x i32> ";
431 bool FirstElt =
true;
432 if (
all_of(Mask, [](
int Elt) {
return Elt == 0; })) {
433 Out <<
"zeroinitializer";
438 for (
int Elt : Mask) {
457 TypePrinting(
const Module *M =
nullptr) : DeferredM(
M) {}
459 TypePrinting(
const TypePrinting &) =
delete;
460 TypePrinting &operator=(
const TypePrinting &) =
delete;
466 std::vector<StructType *> &getNumberedTypes();
475 void incorporateTypes();
485 std::vector<StructType *> NumberedTypes;
495std::vector<StructType *> &TypePrinting::getNumberedTypes() {
501 if (NumberedTypes.size() == Type2Number.size())
502 return NumberedTypes;
504 NumberedTypes.resize(Type2Number.size());
505 for (
const auto &
P : Type2Number) {
506 assert(
P.second < NumberedTypes.size() &&
"Didn't get a dense numbering?");
507 assert(!NumberedTypes[
P.second] &&
"Didn't get a unique numbering?");
508 NumberedTypes[
P.second] =
P.first;
510 return NumberedTypes;
513bool TypePrinting::empty() {
515 return NamedTypes.empty() && Type2Number.empty();
518void TypePrinting::incorporateTypes() {
522 NamedTypes.run(*DeferredM,
false);
527 unsigned NextNumber = 0;
529 std::vector<StructType *>::iterator NextToUse = NamedTypes.begin();
532 if (STy->isLiteral())
535 if (STy->getName().empty())
536 Type2Number[STy] = NextNumber++;
541 NamedTypes.erase(NextToUse, NamedTypes.end());
562 OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
567 print(FTy->getReturnType(),
OS);
570 for (
Type *Ty : FTy->params()) {
583 return printStructBody(STy,
OS);
589 const auto I = Type2Number.find(STy);
590 if (
I != Type2Number.end())
591 OS <<
'%' <<
I->second;
593 OS <<
"%\"type " << STy <<
'\"';
605 OS <<
'[' << ATy->getNumElements() <<
" x ";
606 print(ATy->getElementType(),
OS);
617 OS <<
EC.getKnownMinValue() <<
" x ";
618 print(PTy->getElementType(),
OS);
634 OS <<
", " << *Inner;
636 OS <<
", " << IntParam;
687 const Function* TheFunction =
nullptr;
688 bool FunctionProcessed =
false;
689 bool ShouldInitializeAllMetadata;
694 ProcessFunctionHookFn;
709 unsigned mdnNext = 0;
717 unsigned ModulePathNext = 0;
721 unsigned GUIDNext = 0;
725 unsigned TypeIdNext = 0;
734 bool ShouldInitializeAllMetadata =
false);
742 bool ShouldInitializeAllMetadata =
false);
775 FunctionProcessed =
false;
814 void CreateMetadataSlot(
const MDNode *
N);
817 void CreateFunctionSlot(
const Value *V);
822 inline void CreateModulePathSlot(
StringRef Path);
828 void processModule();
833 void processFunction();
836 void processGlobalObjectMetadata(
const GlobalObject &GO);
839 void processFunctionMetadata(
const Function &
F);
849 : M(M),
F(
F), Machine(&Machine) {}
852 bool ShouldInitializeAllMetadata)
853 : ShouldCreateStorage(M),
854 ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {}
859 if (!ShouldCreateStorage)
862 ShouldCreateStorage =
false;
864 std::make_unique<SlotTracker>(M, ShouldInitializeAllMetadata);
865 Machine = MachineStorage.get();
866 if (ProcessModuleHookFn)
868 if (ProcessFunctionHookFn)
888 assert(F &&
"No function incorporated");
895 ProcessModuleHookFn = Fn;
901 ProcessFunctionHookFn = Fn;
905 if (
const Argument *FA = dyn_cast<Argument>(V))
912 if (
const BasicBlock *BB = dyn_cast<BasicBlock>(V))
918 if (
const GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
921 if (
const GlobalIFunc *GIF = dyn_cast<GlobalIFunc>(V))
924 if (
const Function *Func = dyn_cast<Function>(V))
931#define ST_DEBUG(X) dbgs() << X
939 : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
944 : TheModule(
F ?
F->
getParent() : nullptr), TheFunction(
F),
945 ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
948 : TheModule(nullptr), ShouldInitializeAllMetadata(
false), TheIndex(
Index) {}
956 if (TheFunction && !FunctionProcessed)
963 int NumSlots = processIndex();
970void SlotTracker::processModule() {
976 CreateModuleSlot(&Var);
977 processGlobalObjectMetadata(Var);
978 auto Attrs = Var.getAttributes();
979 if (Attrs.hasAttributes())
980 CreateAttributeSetSlot(Attrs);
985 CreateModuleSlot(&
A);
990 CreateModuleSlot(&
I);
995 for (
unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
996 CreateMetadataSlot(NMD.getOperand(i));
1002 CreateModuleSlot(&
F);
1004 if (ShouldInitializeAllMetadata)
1005 processFunctionMetadata(
F);
1011 CreateAttributeSetSlot(FnAttrs);
1014 if (ProcessModuleHookFn)
1015 ProcessModuleHookFn(
this, TheModule, ShouldInitializeAllMetadata);
1021void SlotTracker::processFunction() {
1022 ST_DEBUG(
"begin processFunction!\n");
1026 if (!ShouldInitializeAllMetadata)
1027 processFunctionMetadata(*TheFunction);
1031 AE = TheFunction->
arg_end(); AI != AE; ++AI)
1033 CreateFunctionSlot(&*AI);
1035 ST_DEBUG(
"Inserting Instructions:\n");
1038 for (
auto &BB : *TheFunction) {
1040 CreateFunctionSlot(&BB);
1042 for (
auto &
I : BB) {
1043 if (!
I.getType()->isVoidTy() && !
I.hasName())
1044 CreateFunctionSlot(&
I);
1048 if (
const auto *Call = dyn_cast<CallBase>(&
I)) {
1051 if (
Attrs.hasAttributes())
1052 CreateAttributeSetSlot(Attrs);
1057 if (ProcessFunctionHookFn)
1058 ProcessFunctionHookFn(
this, TheFunction, ShouldInitializeAllMetadata);
1060 FunctionProcessed =
true;
1062 ST_DEBUG(
"end processFunction!\n");
1066int SlotTracker::processIndex() {
1073 std::vector<StringRef> ModulePaths;
1075 ModulePaths.push_back(ModPath);
1076 llvm::sort(ModulePaths.begin(), ModulePaths.end());
1077 for (
auto &ModPath : ModulePaths)
1078 CreateModulePathSlot(ModPath);
1081 GUIDNext = ModulePathNext;
1083 for (
auto &GlobalList : *TheIndex)
1084 CreateGUIDSlot(GlobalList.first);
1086 for (
auto &TId : TheIndex->typeIdCompatibleVtableMap())
1090 TypeIdNext = GUIDNext;
1091 for (
const auto &TID : TheIndex->typeIds())
1092 CreateTypeIdSlot(TID.second.first);
1098void SlotTracker::processGlobalObjectMetadata(
const GlobalObject &GO) {
1101 for (
auto &MD : MDs)
1102 CreateMetadataSlot(MD.second);
1105void SlotTracker::processFunctionMetadata(
const Function &
F) {
1106 processGlobalObjectMetadata(
F);
1107 for (
auto &BB :
F) {
1109 processInstructionMetadata(
I);
1113void SlotTracker::processInstructionMetadata(
const Instruction &
I) {
1115 if (
const CallInst *CI = dyn_cast<CallInst>(&
I))
1116 if (
Function *
F = CI->getCalledFunction())
1117 if (
F->isIntrinsic())
1118 for (
auto &
Op :
I.operands())
1119 if (
auto *V = dyn_cast_or_null<MetadataAsValue>(
Op))
1120 if (
MDNode *
N = dyn_cast<MDNode>(
V->getMetadata()))
1121 CreateMetadataSlot(
N);
1125 I.getAllMetadata(MDs);
1126 for (
auto &MD : MDs)
1127 CreateMetadataSlot(MD.second);
1134 ST_DEBUG(
"begin purgeFunction!\n");
1136 TheFunction =
nullptr;
1137 FunctionProcessed =
false;
1148 return MI == mMap.
end() ? -1 : (int)
MI->second;
1154 ProcessModuleHookFn = Fn;
1160 ProcessFunctionHookFn = Fn;
1173 return MI == mdnMap.
end() ? -1 : (int)
MI->second;
1178 assert(!isa<Constant>(V) &&
"Can't get a constant or global slot with this!");
1184 return FI == fMap.
end() ? -1 : (int)FI->second;
1193 return AI == asMap.
end() ? -1 : (int)AI->second;
1201 auto I = ModulePathMap.
find(Path);
1202 return I == ModulePathMap.
end() ? -1 : (int)
I->second;
1211 return I == GUIDMap.
end() ? -1 : (int)
I->second;
1219 auto I = TypeIdMap.
find(Id);
1220 return I == TypeIdMap.
end() ? -1 : (int)
I->second;
1224void SlotTracker::CreateModuleSlot(
const GlobalValue *V) {
1225 assert(V &&
"Can't insert a null Value into SlotTracker!");
1226 assert(!V->getType()->isVoidTy() &&
"Doesn't need a slot!");
1227 assert(!V->hasName() &&
"Doesn't need a slot!");
1229 unsigned DestSlot = mNext++;
1232 ST_DEBUG(
" Inserting value [" << V->getType() <<
"] = " << V <<
" slot=" <<
1235 ST_DEBUG((isa<GlobalVariable>(V) ?
'G' :
1236 (isa<Function>(V) ?
'F' :
1237 (isa<GlobalAlias>(V) ?
'A' :
1238 (isa<GlobalIFunc>(V) ?
'I' :
'o')))) <<
"]\n");
1242void SlotTracker::CreateFunctionSlot(
const Value *V) {
1243 assert(!V->getType()->isVoidTy() && !V->hasName() &&
"Doesn't need a slot!");
1245 unsigned DestSlot = fNext++;
1249 ST_DEBUG(
" Inserting value [" << V->getType() <<
"] = " << V <<
" slot=" <<
1250 DestSlot <<
" [o]\n");
1254void SlotTracker::CreateMetadataSlot(
const MDNode *
N) {
1255 assert(
N &&
"Can't insert a null Value into SlotTracker!");
1259 if (isa<DIExpression>(
N) || isa<DIArgList>(
N))
1262 unsigned DestSlot = mdnNext;
1263 if (!mdnMap.
insert(std::make_pair(
N, DestSlot)).second)
1268 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i)
1269 if (
const MDNode *
Op = dyn_cast_or_null<MDNode>(
N->getOperand(i)))
1270 CreateMetadataSlot(
Op);
1273void SlotTracker::CreateAttributeSetSlot(
AttributeSet AS) {
1277 if (
I != asMap.
end())
1280 unsigned DestSlot = asNext++;
1281 asMap[AS] = DestSlot;
1285void SlotTracker::CreateModulePathSlot(
StringRef Path) {
1286 ModulePathMap[
Path] = ModulePathNext++;
1291 GUIDMap[GUID] = GUIDNext++;
1295void SlotTracker::CreateTypeIdSlot(
StringRef Id) {
1296 TypeIdMap[
Id] = TypeIdNext++;
1301struct AsmWriterContext {
1302 TypePrinting *TypePrinter =
nullptr;
1307 : TypePrinter(TP), Machine(
ST),
Context(
M) {}
1309 static AsmWriterContext &getEmpty() {
1310 static AsmWriterContext EmptyCtx(
nullptr,
nullptr);
1316 virtual void onWriteMetadataAsOperand(
const Metadata *) {}
1318 virtual ~AsmWriterContext() =
default;
1327 AsmWriterContext &WriterCtx);
1330 AsmWriterContext &WriterCtx,
1331 bool FromValue =
false);
1334 if (
const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U))
1335 Out << FPO->getFastMathFlags();
1338 dyn_cast<OverflowingBinaryOperator>(U)) {
1339 if (OBO->hasNoUnsignedWrap())
1341 if (OBO->hasNoSignedWrap())
1344 dyn_cast<PossiblyExactOperator>(U)) {
1348 if (
GEP->isInBounds())
1354 AsmWriterContext &WriterCtx) {
1355 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
1356 if (CI->getType()->isIntegerTy(1)) {
1357 Out << (CI->getZExtValue() ?
"true" :
"false");
1360 Out << CI->getValue();
1364 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
1365 const APFloat &APF = CFP->getValueAPF();
1376 bool isNaN = APF.
isNaN();
1377 if (!isInf && !isNaN) {
1385 assert((
isDigit(StrVal[0]) || ((StrVal[0] ==
'-' || StrVal[0] ==
'+') &&
1387 "[-+]?[0-9] regex does not match!");
1398 static_assert(
sizeof(double) ==
sizeof(
uint64_t),
1399 "assuming that double is 64 bits!");
1456 if (isa<ConstantAggregateZero>(CV) || isa<ConstantTargetNone>(CV)) {
1457 Out <<
"zeroinitializer";
1461 if (
const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
1462 Out <<
"blockaddress(";
1470 if (
const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) {
1471 Out <<
"dso_local_equivalent ";
1476 if (
const auto *
NC = dyn_cast<NoCFIValue>(CV)) {
1482 if (
const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
1483 Type *ETy = CA->getType()->getElementType();
1485 WriterCtx.TypePrinter->print(ETy, Out);
1488 for (
unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
1490 WriterCtx.TypePrinter->print(ETy, Out);
1501 if (CA->isString()) {
1503 printEscapedString(CA->getAsString(), Out);
1508 Type *ETy = CA->getType()->getElementType();
1510 WriterCtx.TypePrinter->print(ETy, Out);
1513 for (
unsigned i = 1, e = CA->getNumElements(); i != e; ++i) {
1515 WriterCtx.TypePrinter->print(ETy, Out);
1524 if (CS->getType()->isPacked())
1527 unsigned N = CS->getNumOperands();
1530 WriterCtx.TypePrinter->print(CS->getOperand(0)->getType(), Out);
1535 for (
unsigned i = 1; i <
N; i++) {
1537 WriterCtx.TypePrinter->print(CS->getOperand(i)->getType(), Out);
1546 if (CS->getType()->isPacked())
1551 if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) {
1552 auto *CVVTy = cast<FixedVectorType>(CV->
getType());
1553 Type *ETy = CVVTy->getElementType();
1555 WriterCtx.TypePrinter->print(ETy, Out);
1558 for (
unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) {
1560 WriterCtx.TypePrinter->print(ETy, Out);
1568 if (isa<ConstantPointerNull>(CV)) {
1573 if (isa<ConstantTokenNone>(CV)) {
1578 if (isa<PoisonValue>(CV)) {
1583 if (isa<UndefValue>(CV)) {
1588 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
1589 Out << CE->getOpcodeName();
1591 if (CE->isCompare())
1592 Out << ' ' << static_cast<CmpInst::Predicate>(CE->getPredicate());
1595 std::optional<unsigned> InRangeOp;
1597 WriterCtx.TypePrinter->print(
GEP->getSourceElementType(), Out);
1599 InRangeOp =
GEP->getInRangeIndex();
1605 if (InRangeOp &&
unsigned(OI - CE->op_begin()) == *InRangeOp)
1607 WriterCtx.TypePrinter->print((*OI)->getType(), Out);
1610 if (OI+1 != CE->op_end())
1616 WriterCtx.TypePrinter->print(CE->getType(), Out);
1619 if (CE->getOpcode() == Instruction::ShuffleVector)
1626 Out <<
"<placeholder or erroneous Constant>";
1630 AsmWriterContext &WriterCtx) {
1632 for (
unsigned mi = 0, me =
Node->getNumOperands(); mi != me; ++mi) {
1636 else if (
auto *MDV = dyn_cast<ValueAsMetadata>(MD)) {
1637 Value *V = MDV->getValue();
1638 WriterCtx.TypePrinter->print(V->getType(), Out);
1643 WriterCtx.onWriteMetadataAsOperand(MD);
1654struct FieldSeparator {
1658 FieldSeparator(
const char *Sep =
", ") : Sep(Sep) {}
1666 return OS <<
FS.Sep;
1669struct MDFieldPrinter {
1672 AsmWriterContext &WriterCtx;
1675 : Out(Out), WriterCtx(AsmWriterContext::getEmpty()) {}
1676 MDFieldPrinter(
raw_ostream &Out, AsmWriterContext &Ctx)
1677 : Out(Out), WriterCtx(Ctx) {}
1679 void printTag(
const DINode *
N);
1683 bool ShouldSkipEmpty =
true);
1685 bool ShouldSkipNull =
true);
1686 template <
class IntTy>
1689 bool ShouldSkipZero);
1691 std::optional<bool>
Default = std::nullopt);
1694 template <
class IntTy,
class Stringifier>
1696 bool ShouldSkipZero =
true);
1704void MDFieldPrinter::printTag(
const DINode *
N) {
1705 Out <<
FS <<
"tag: ";
1713void MDFieldPrinter::printMacinfoType(
const DIMacroNode *
N) {
1714 Out <<
FS <<
"type: ";
1719 Out <<
N->getMacinfoType();
1722void MDFieldPrinter::printChecksum(
1725 printString(
"checksum", Checksum.
Value,
false);
1729 bool ShouldSkipEmpty) {
1730 if (ShouldSkipEmpty &&
Value.empty())
1733 Out <<
FS <<
Name <<
": \"";
1734 printEscapedString(
Value, Out);
1739 AsmWriterContext &WriterCtx) {
1745 WriterCtx.onWriteMetadataAsOperand(MD);
1749 bool ShouldSkipNull) {
1750 if (ShouldSkipNull && !MD)
1753 Out <<
FS <<
Name <<
": ";
1757template <
class IntTy>
1758void MDFieldPrinter::printInt(
StringRef Name, IntTy
Int,
bool ShouldSkipZero) {
1759 if (ShouldSkipZero && !
Int)
1766 bool IsUnsigned,
bool ShouldSkipZero) {
1767 if (ShouldSkipZero &&
Int.isZero())
1770 Out <<
FS <<
Name <<
": ";
1771 Int.print(Out, !IsUnsigned);
1775 std::optional<bool>
Default) {
1778 Out <<
FS <<
Name <<
": " << (
Value ?
"true" :
"false");
1785 Out <<
FS <<
Name <<
": ";
1790 FieldSeparator FlagsFS(
" | ");
1791 for (
auto F : SplitFlags) {
1793 assert(!StringF.empty() &&
"Expected valid flag");
1794 Out << FlagsFS << StringF;
1796 if (Extra || SplitFlags.empty())
1797 Out << FlagsFS << Extra;
1804 Out <<
FS <<
Name <<
": ";
1814 FieldSeparator FlagsFS(
" | ");
1815 for (
auto F : SplitFlags) {
1817 assert(!StringF.empty() &&
"Expected valid flag");
1818 Out << FlagsFS << StringF;
1820 if (Extra || SplitFlags.empty())
1821 Out << FlagsFS << Extra;
1836template <
class IntTy,
class Stringifier>
1838 Stringifier
toString,
bool ShouldSkipZero) {
1842 Out <<
FS <<
Name <<
": ";
1851 AsmWriterContext &WriterCtx) {
1852 Out <<
"!GenericDINode(";
1853 MDFieldPrinter
Printer(Out, WriterCtx);
1855 Printer.printString(
"header",
N->getHeader());
1856 if (
N->getNumDwarfOperands()) {
1857 Out <<
Printer.FS <<
"operands: {";
1859 for (
auto &
I :
N->dwarf_operands()) {
1869 AsmWriterContext &WriterCtx) {
1870 Out <<
"!DILocation(";
1871 MDFieldPrinter
Printer(Out, WriterCtx);
1873 Printer.printInt(
"line",
DL->getLine(),
false);
1874 Printer.printInt(
"column",
DL->getColumn());
1875 Printer.printMetadata(
"scope",
DL->getRawScope(),
false);
1876 Printer.printMetadata(
"inlinedAt",
DL->getRawInlinedAt());
1877 Printer.printBool(
"isImplicitCode",
DL->isImplicitCode(),
1883 AsmWriterContext &WriterCtx) {
1884 Out <<
"!DIAssignID()";
1885 MDFieldPrinter
Printer(Out, WriterCtx);
1889 AsmWriterContext &WriterCtx) {
1890 Out <<
"!DISubrange(";
1891 MDFieldPrinter
Printer(Out, WriterCtx);
1893 auto *Count =
N->getRawCountNode();
1894 if (
auto *CE = dyn_cast_or_null<ConstantAsMetadata>(Count)) {
1895 auto *CV = cast<ConstantInt>(CE->getValue());
1896 Printer.printInt(
"count", CV->getSExtValue(),
1899 Printer.printMetadata(
"count", Count,
true);
1903 auto *LBound =
N->getRawLowerBound();
1904 if (
auto *LE = dyn_cast_or_null<ConstantAsMetadata>(LBound)) {
1905 auto *LV = cast<ConstantInt>(LE->getValue());
1906 Printer.printInt(
"lowerBound", LV->getSExtValue(),
1909 Printer.printMetadata(
"lowerBound", LBound,
true);
1911 auto *UBound =
N->getRawUpperBound();
1912 if (
auto *UE = dyn_cast_or_null<ConstantAsMetadata>(UBound)) {
1913 auto *UV = cast<ConstantInt>(UE->getValue());
1914 Printer.printInt(
"upperBound", UV->getSExtValue(),
1917 Printer.printMetadata(
"upperBound", UBound,
true);
1919 auto *Stride =
N->getRawStride();
1920 if (
auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Stride)) {
1921 auto *SV = cast<ConstantInt>(SE->getValue());
1922 Printer.printInt(
"stride", SV->getSExtValue(),
false);
1924 Printer.printMetadata(
"stride", Stride,
true);
1930 AsmWriterContext &WriterCtx) {
1931 Out <<
"!DIGenericSubrange(";
1932 MDFieldPrinter
Printer(Out, WriterCtx);
1934 auto IsConstant = [&](
Metadata *Bound) ->
bool {
1935 if (
auto *BE = dyn_cast_or_null<DIExpression>(Bound)) {
1936 return BE->isConstant() &&
1943 auto GetConstant = [&](
Metadata *Bound) -> int64_t {
1944 assert(IsConstant(Bound) &&
"Expected constant");
1945 auto *BE = dyn_cast_or_null<DIExpression>(Bound);
1946 return static_cast<int64_t
>(BE->getElement(1));
1949 auto *Count =
N->getRawCountNode();
1950 if (IsConstant(Count))
1951 Printer.printInt(
"count", GetConstant(Count),
1954 Printer.printMetadata(
"count", Count,
true);
1956 auto *LBound =
N->getRawLowerBound();
1957 if (IsConstant(LBound))
1958 Printer.printInt(
"lowerBound", GetConstant(LBound),
1961 Printer.printMetadata(
"lowerBound", LBound,
true);
1963 auto *UBound =
N->getRawUpperBound();
1964 if (IsConstant(UBound))
1965 Printer.printInt(
"upperBound", GetConstant(UBound),
1968 Printer.printMetadata(
"upperBound", UBound,
true);
1970 auto *Stride =
N->getRawStride();
1971 if (IsConstant(Stride))
1972 Printer.printInt(
"stride", GetConstant(Stride),
1975 Printer.printMetadata(
"stride", Stride,
true);
1981 AsmWriterContext &) {
1982 Out <<
"!DIEnumerator(";
1984 Printer.printString(
"name",
N->getName(),
false);
1985 Printer.printAPInt(
"value",
N->getValue(),
N->isUnsigned(),
1987 if (
N->isUnsigned())
1988 Printer.printBool(
"isUnsigned",
true);
1993 AsmWriterContext &) {
1994 Out <<
"!DIBasicType(";
1996 if (
N->getTag() != dwarf::DW_TAG_base_type)
1998 Printer.printString(
"name",
N->getName());
1999 Printer.printInt(
"size",
N->getSizeInBits());
2000 Printer.printInt(
"align",
N->getAlignInBits());
2001 Printer.printDwarfEnum(
"encoding",
N->getEncoding(),
2003 Printer.printDIFlags(
"flags",
N->getFlags());
2008 AsmWriterContext &WriterCtx) {
2009 Out <<
"!DIStringType(";
2010 MDFieldPrinter
Printer(Out, WriterCtx);
2011 if (
N->getTag() != dwarf::DW_TAG_string_type)
2013 Printer.printString(
"name",
N->getName());
2014 Printer.printMetadata(
"stringLength",
N->getRawStringLength());
2015 Printer.printMetadata(
"stringLengthExpression",
N->getRawStringLengthExp());
2016 Printer.printMetadata(
"stringLocationExpression",
2017 N->getRawStringLocationExp());
2018 Printer.printInt(
"size",
N->getSizeInBits());
2019 Printer.printInt(
"align",
N->getAlignInBits());
2020 Printer.printDwarfEnum(
"encoding",
N->getEncoding(),
2026 AsmWriterContext &WriterCtx) {
2027 Out <<
"!DIDerivedType(";
2028 MDFieldPrinter
Printer(Out, WriterCtx);
2030 Printer.printString(
"name",
N->getName());
2031 Printer.printMetadata(
"scope",
N->getRawScope());
2032 Printer.printMetadata(
"file",
N->getRawFile());
2033 Printer.printInt(
"line",
N->getLine());
2034 Printer.printMetadata(
"baseType",
N->getRawBaseType(),
2036 Printer.printInt(
"size",
N->getSizeInBits());
2037 Printer.printInt(
"align",
N->getAlignInBits());
2038 Printer.printInt(
"offset",
N->getOffsetInBits());
2039 Printer.printDIFlags(
"flags",
N->getFlags());
2040 Printer.printMetadata(
"extraData",
N->getRawExtraData());
2041 if (
const auto &DWARFAddressSpace =
N->getDWARFAddressSpace())
2042 Printer.printInt(
"dwarfAddressSpace", *DWARFAddressSpace,
2044 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2049 AsmWriterContext &WriterCtx) {
2050 Out <<
"!DICompositeType(";
2051 MDFieldPrinter
Printer(Out, WriterCtx);
2053 Printer.printString(
"name",
N->getName());
2054 Printer.printMetadata(
"scope",
N->getRawScope());
2055 Printer.printMetadata(
"file",
N->getRawFile());
2056 Printer.printInt(
"line",
N->getLine());
2057 Printer.printMetadata(
"baseType",
N->getRawBaseType());
2058 Printer.printInt(
"size",
N->getSizeInBits());
2059 Printer.printInt(
"align",
N->getAlignInBits());
2060 Printer.printInt(
"offset",
N->getOffsetInBits());
2061 Printer.printDIFlags(
"flags",
N->getFlags());
2062 Printer.printMetadata(
"elements",
N->getRawElements());
2063 Printer.printDwarfEnum(
"runtimeLang",
N->getRuntimeLang(),
2065 Printer.printMetadata(
"vtableHolder",
N->getRawVTableHolder());
2066 Printer.printMetadata(
"templateParams",
N->getRawTemplateParams());
2067 Printer.printString(
"identifier",
N->getIdentifier());
2068 Printer.printMetadata(
"discriminator",
N->getRawDiscriminator());
2069 Printer.printMetadata(
"dataLocation",
N->getRawDataLocation());
2070 Printer.printMetadata(
"associated",
N->getRawAssociated());
2071 Printer.printMetadata(
"allocated",
N->getRawAllocated());
2072 if (
auto *RankConst =
N->getRankConst())
2073 Printer.printInt(
"rank", RankConst->getSExtValue(),
2076 Printer.printMetadata(
"rank",
N->getRawRank(),
true);
2077 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2082 AsmWriterContext &WriterCtx) {
2083 Out <<
"!DISubroutineType(";
2084 MDFieldPrinter
Printer(Out, WriterCtx);
2085 Printer.printDIFlags(
"flags",
N->getFlags());
2087 Printer.printMetadata(
"types",
N->getRawTypeArray(),
2095 Printer.printString(
"filename",
N->getFilename(),
2097 Printer.printString(
"directory",
N->getDirectory(),
2100 if (
N->getChecksum())
2101 Printer.printChecksum(*
N->getChecksum());
2108 AsmWriterContext &WriterCtx) {
2109 Out <<
"!DICompileUnit(";
2110 MDFieldPrinter
Printer(Out, WriterCtx);
2111 Printer.printDwarfEnum(
"language",
N->getSourceLanguage(),
2113 Printer.printMetadata(
"file",
N->getRawFile(),
false);
2114 Printer.printString(
"producer",
N->getProducer());
2115 Printer.printBool(
"isOptimized",
N->isOptimized());
2116 Printer.printString(
"flags",
N->getFlags());
2117 Printer.printInt(
"runtimeVersion",
N->getRuntimeVersion(),
2119 Printer.printString(
"splitDebugFilename",
N->getSplitDebugFilename());
2120 Printer.printEmissionKind(
"emissionKind",
N->getEmissionKind());
2121 Printer.printMetadata(
"enums",
N->getRawEnumTypes());
2122 Printer.printMetadata(
"retainedTypes",
N->getRawRetainedTypes());
2123 Printer.printMetadata(
"globals",
N->getRawGlobalVariables());
2124 Printer.printMetadata(
"imports",
N->getRawImportedEntities());
2125 Printer.printMetadata(
"macros",
N->getRawMacros());
2126 Printer.printInt(
"dwoId",
N->getDWOId());
2127 Printer.printBool(
"splitDebugInlining",
N->getSplitDebugInlining(),
true);
2128 Printer.printBool(
"debugInfoForProfiling",
N->getDebugInfoForProfiling(),
2130 Printer.printNameTableKind(
"nameTableKind",
N->getNameTableKind());
2131 Printer.printBool(
"rangesBaseAddress",
N->getRangesBaseAddress(),
false);
2132 Printer.printString(
"sysroot",
N->getSysRoot());
2133 Printer.printString(
"sdk",
N->getSDK());
2138 AsmWriterContext &WriterCtx) {
2139 Out <<
"!DISubprogram(";
2140 MDFieldPrinter
Printer(Out, WriterCtx);
2141 Printer.printString(
"name",
N->getName());
2142 Printer.printString(
"linkageName",
N->getLinkageName());
2143 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2144 Printer.printMetadata(
"file",
N->getRawFile());
2145 Printer.printInt(
"line",
N->getLine());
2146 Printer.printMetadata(
"type",
N->getRawType());
2147 Printer.printInt(
"scopeLine",
N->getScopeLine());
2148 Printer.printMetadata(
"containingType",
N->getRawContainingType());
2149 if (
N->getVirtuality() != dwarf::DW_VIRTUALITY_none ||
2150 N->getVirtualIndex() != 0)
2151 Printer.printInt(
"virtualIndex",
N->getVirtualIndex(),
false);
2152 Printer.printInt(
"thisAdjustment",
N->getThisAdjustment());
2153 Printer.printDIFlags(
"flags",
N->getFlags());
2154 Printer.printDISPFlags(
"spFlags",
N->getSPFlags());
2155 Printer.printMetadata(
"unit",
N->getRawUnit());
2156 Printer.printMetadata(
"templateParams",
N->getRawTemplateParams());
2157 Printer.printMetadata(
"declaration",
N->getRawDeclaration());
2158 Printer.printMetadata(
"retainedNodes",
N->getRawRetainedNodes());
2159 Printer.printMetadata(
"thrownTypes",
N->getRawThrownTypes());
2160 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2161 Printer.printString(
"targetFuncName",
N->getTargetFuncName());
2166 AsmWriterContext &WriterCtx) {
2167 Out <<
"!DILexicalBlock(";
2168 MDFieldPrinter
Printer(Out, WriterCtx);
2169 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2170 Printer.printMetadata(
"file",
N->getRawFile());
2171 Printer.printInt(
"line",
N->getLine());
2172 Printer.printInt(
"column",
N->getColumn());
2178 AsmWriterContext &WriterCtx) {
2179 Out <<
"!DILexicalBlockFile(";
2180 MDFieldPrinter
Printer(Out, WriterCtx);
2181 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2182 Printer.printMetadata(
"file",
N->getRawFile());
2183 Printer.printInt(
"discriminator",
N->getDiscriminator(),
2189 AsmWriterContext &WriterCtx) {
2190 Out <<
"!DINamespace(";
2191 MDFieldPrinter
Printer(Out, WriterCtx);
2192 Printer.printString(
"name",
N->getName());
2193 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2194 Printer.printBool(
"exportSymbols",
N->getExportSymbols(),
false);
2199 AsmWriterContext &WriterCtx) {
2200 Out <<
"!DICommonBlock(";
2201 MDFieldPrinter
Printer(Out, WriterCtx);
2202 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2203 Printer.printMetadata(
"declaration",
N->getRawDecl(),
false);
2204 Printer.printString(
"name",
N->getName());
2205 Printer.printMetadata(
"file",
N->getRawFile());
2206 Printer.printInt(
"line",
N->getLineNo());
2211 AsmWriterContext &WriterCtx) {
2213 MDFieldPrinter
Printer(Out, WriterCtx);
2215 Printer.printInt(
"line",
N->getLine());
2216 Printer.printString(
"name",
N->getName());
2217 Printer.printString(
"value",
N->getValue());
2222 AsmWriterContext &WriterCtx) {
2223 Out <<
"!DIMacroFile(";
2224 MDFieldPrinter
Printer(Out, WriterCtx);
2225 Printer.printInt(
"line",
N->getLine());
2226 Printer.printMetadata(
"file",
N->getRawFile(),
false);
2227 Printer.printMetadata(
"nodes",
N->getRawElements());
2232 AsmWriterContext &WriterCtx) {
2233 Out <<
"!DIModule(";
2234 MDFieldPrinter
Printer(Out, WriterCtx);
2235 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2236 Printer.printString(
"name",
N->getName());
2237 Printer.printString(
"configMacros",
N->getConfigurationMacros());
2238 Printer.printString(
"includePath",
N->getIncludePath());
2239 Printer.printString(
"apinotes",
N->getAPINotesFile());
2240 Printer.printMetadata(
"file",
N->getRawFile());
2241 Printer.printInt(
"line",
N->getLineNo());
2242 Printer.printBool(
"isDecl",
N->getIsDecl(),
false);
2248 AsmWriterContext &WriterCtx) {
2249 Out <<
"!DITemplateTypeParameter(";
2250 MDFieldPrinter
Printer(Out, WriterCtx);
2251 Printer.printString(
"name",
N->getName());
2252 Printer.printMetadata(
"type",
N->getRawType(),
false);
2253 Printer.printBool(
"defaulted",
N->isDefault(),
false);
2259 AsmWriterContext &WriterCtx) {
2260 Out <<
"!DITemplateValueParameter(";
2261 MDFieldPrinter
Printer(Out, WriterCtx);
2262 if (
N->getTag() != dwarf::DW_TAG_template_value_parameter)
2264 Printer.printString(
"name",
N->getName());
2265 Printer.printMetadata(
"type",
N->getRawType());
2266 Printer.printBool(
"defaulted",
N->isDefault(),
false);
2267 Printer.printMetadata(
"value",
N->getValue(),
false);
2272 AsmWriterContext &WriterCtx) {
2273 Out <<
"!DIGlobalVariable(";
2274 MDFieldPrinter
Printer(Out, WriterCtx);
2275 Printer.printString(
"name",
N->getName());
2276 Printer.printString(
"linkageName",
N->getLinkageName());
2277 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2278 Printer.printMetadata(
"file",
N->getRawFile());
2279 Printer.printInt(
"line",
N->getLine());
2280 Printer.printMetadata(
"type",
N->getRawType());
2281 Printer.printBool(
"isLocal",
N->isLocalToUnit());
2282 Printer.printBool(
"isDefinition",
N->isDefinition());
2283 Printer.printMetadata(
"declaration",
N->getRawStaticDataMemberDeclaration());
2284 Printer.printMetadata(
"templateParams",
N->getRawTemplateParams());
2285 Printer.printInt(
"align",
N->getAlignInBits());
2286 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2291 AsmWriterContext &WriterCtx) {
2292 Out <<
"!DILocalVariable(";
2293 MDFieldPrinter
Printer(Out, WriterCtx);
2294 Printer.printString(
"name",
N->getName());
2295 Printer.printInt(
"arg",
N->getArg());
2296 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2297 Printer.printMetadata(
"file",
N->getRawFile());
2298 Printer.printInt(
"line",
N->getLine());
2299 Printer.printMetadata(
"type",
N->getRawType());
2300 Printer.printDIFlags(
"flags",
N->getFlags());
2301 Printer.printInt(
"align",
N->getAlignInBits());
2302 Printer.printMetadata(
"annotations",
N->getRawAnnotations());
2307 AsmWriterContext &WriterCtx) {
2309 MDFieldPrinter
Printer(Out, WriterCtx);
2310 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2311 Printer.printString(
"name",
N->getName());
2312 Printer.printMetadata(
"file",
N->getRawFile());
2313 Printer.printInt(
"line",
N->getLine());
2318 AsmWriterContext &WriterCtx) {
2319 Out <<
"!DIExpression(";
2324 assert(!OpStr.empty() &&
"Expected valid opcode");
2328 Out << FS <<
Op.getArg(0);
2331 for (
unsigned A = 0, AE =
Op.getNumArgs();
A != AE; ++
A)
2332 Out << FS <<
Op.getArg(
A);
2336 for (
const auto &
I :
N->getElements())
2343 AsmWriterContext &WriterCtx,
2344 bool FromValue =
false) {
2346 "Unexpected DIArgList metadata outside of value argument");
2347 Out <<
"!DIArgList(";
2349 MDFieldPrinter
Printer(Out, WriterCtx);
2359 AsmWriterContext &WriterCtx) {
2360 Out <<
"!DIGlobalVariableExpression(";
2361 MDFieldPrinter
Printer(Out, WriterCtx);
2362 Printer.printMetadata(
"var",
N->getVariable());
2363 Printer.printMetadata(
"expr",
N->getExpression());
2368 AsmWriterContext &WriterCtx) {
2369 Out <<
"!DIObjCProperty(";
2370 MDFieldPrinter
Printer(Out, WriterCtx);
2371 Printer.printString(
"name",
N->getName());
2372 Printer.printMetadata(
"file",
N->getRawFile());
2373 Printer.printInt(
"line",
N->getLine());
2374 Printer.printString(
"setter",
N->getSetterName());
2375 Printer.printString(
"getter",
N->getGetterName());
2376 Printer.printInt(
"attributes",
N->getAttributes());
2377 Printer.printMetadata(
"type",
N->getRawType());
2382 AsmWriterContext &WriterCtx) {
2383 Out <<
"!DIImportedEntity(";
2384 MDFieldPrinter
Printer(Out, WriterCtx);
2386 Printer.printString(
"name",
N->getName());
2387 Printer.printMetadata(
"scope",
N->getRawScope(),
false);
2388 Printer.printMetadata(
"entity",
N->getRawEntity());
2389 Printer.printMetadata(
"file",
N->getRawFile());
2390 Printer.printInt(
"line",
N->getLine());
2391 Printer.printMetadata(
"elements",
N->getRawElements());
2396 AsmWriterContext &Ctx) {
2397 if (
Node->isDistinct())
2399 else if (
Node->isTemporary())
2400 Out <<
"<temporary!> ";
2402 switch (
Node->getMetadataID()) {
2405#define HANDLE_MDNODE_LEAF(CLASS) \
2406 case Metadata::CLASS##Kind: \
2407 write##CLASS(Out, cast<CLASS>(Node), Ctx); \
2409#include "llvm/IR/Metadata.def"
2416 AsmWriterContext &WriterCtx) {
2422 const Constant *CV = dyn_cast<Constant>(V);
2423 if (CV && !isa<GlobalValue>(CV)) {
2424 assert(WriterCtx.TypePrinter &&
"Constants require TypePrinting!");
2429 if (
const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
2431 if (IA->hasSideEffects())
2432 Out <<
"sideeffect ";
2433 if (IA->isAlignStack())
2434 Out <<
"alignstack ";
2437 Out <<
"inteldialect ";
2441 printEscapedString(IA->getAsmString(), Out);
2443 printEscapedString(IA->getConstraintString(), Out);
2448 if (
auto *MD = dyn_cast<MetadataAsValue>(V)) {
2456 auto *Machine = WriterCtx.Machine;
2459 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
2460 Slot = Machine->getGlobalSlot(GV);
2463 Slot = Machine->getLocalSlot(V);
2470 Slot = Machine->getLocalSlot(V);
2476 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
2477 Slot = Machine->getGlobalSlot(GV);
2480 Slot = Machine->getLocalSlot(V);
2489 Out << Prefix << Slot;
2495 AsmWriterContext &WriterCtx,
2499 if (
const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
2503 if (
const DIArgList *ArgList = dyn_cast<DIArgList>(MD)) {
2508 if (
const MDNode *
N = dyn_cast<MDNode>(MD)) {
2509 std::unique_ptr<SlotTracker> MachineStorage;
2511 if (!WriterCtx.Machine) {
2512 MachineStorage = std::make_unique<SlotTracker>(WriterCtx.Context);
2513 WriterCtx.Machine = MachineStorage.get();
2515 int Slot = WriterCtx.Machine->getMetadataSlot(
N);
2517 if (
const DILocation *Loc = dyn_cast<DILocation>(
N)) {
2523 Out <<
"<" <<
N <<
">";
2529 if (
const MDString *MDS = dyn_cast<MDString>(MD)) {
2531 printEscapedString(MDS->getString(), Out);
2536 auto *V = cast<ValueAsMetadata>(MD);
2537 assert(WriterCtx.TypePrinter &&
"TypePrinter required for metadata values");
2538 assert((FromValue || !isa<LocalAsMetadata>(V)) &&
2539 "Unexpected function-local metadata outside of value argument");
2541 WriterCtx.TypePrinter->print(V->getValue()->getType(), Out);
2548class AssemblyWriter {
2550 const Module *TheModule =
nullptr;
2552 std::unique_ptr<SlotTracker> SlotTrackerStorage;
2554 TypePrinting TypePrinter;
2558 bool ShouldPreserveUseListOrder;
2569 bool ShouldPreserveUseListOrder =
false);
2574 AsmWriterContext getContext() {
2575 return AsmWriterContext(&TypePrinter, &Machine, TheModule);
2578 void printMDNodeBody(
const MDNode *MD);
2581 void printModule(
const Module *M);
2583 void writeOperand(
const Value *
Op,
bool PrintType);
2585 void writeOperandBundles(
const CallBase *Call);
2591 void writeAtomicCmpXchg(
const LLVMContext &Context,
2596 void writeAllMDNodes();
2597 void writeMDNode(
unsigned Slot,
const MDNode *
Node);
2598 void writeAttribute(
const Attribute &Attr,
bool InAttrGroup =
false);
2599 void writeAttributeSet(
const AttributeSet &AttrSet,
bool InAttrGroup =
false);
2600 void writeAllAttributeGroups();
2602 void printTypeIdentities();
2606 void printComdat(
const Comdat *
C);
2613 void printUseListOrder(
const Value *V,
const std::vector<unsigned> &Shuffle);
2616 void printModuleSummaryIndex();
2617 void printSummaryInfo(
unsigned Slot,
const ValueInfo &VI);
2625 void printArgs(
const std::vector<uint64_t> &Args);
2630 printNonConstVCalls(
const std::vector<FunctionSummary::VFuncId> &VCallList,
2633 printConstVCalls(
const std::vector<FunctionSummary::ConstVCall> &VCallList,
2638 void printMetadataAttachments(
2644 void printInfoComment(
const Value &V);
2655 bool IsForDebug,
bool ShouldPreserveUseListOrder)
2656 : Out(
o), TheModule(
M), Machine(Mac), TypePrinter(
M), AnnotationWriter(AAW),
2657 IsForDebug(IsForDebug),
2658 ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
2661 for (
const GlobalObject &GO : TheModule->global_objects())
2668 : Out(
o), TheIndex(
Index), Machine(Mac), TypePrinter(nullptr),
2669 IsForDebug(IsForDebug), ShouldPreserveUseListOrder(
false) {}
2671void AssemblyWriter::writeOperand(
const Value *Operand,
bool PrintType) {
2673 Out <<
"<null operand!>";
2677 TypePrinter.print(Operand->
getType(), Out);
2680 auto WriterCtx = getContext();
2684void AssemblyWriter::writeSyncScope(
const LLVMContext &Context,
2694 Out <<
" syncscope(\"";
2695 printEscapedString(SSNs[SSID], Out);
2702void AssemblyWriter::writeAtomic(
const LLVMContext &Context,
2705 if (Ordering == AtomicOrdering::NotAtomic)
2708 writeSyncScope(Context, SSID);
2712void AssemblyWriter::writeAtomicCmpXchg(
const LLVMContext &Context,
2716 assert(SuccessOrdering != AtomicOrdering::NotAtomic &&
2717 FailureOrdering != AtomicOrdering::NotAtomic);
2719 writeSyncScope(Context, SSID);
2724void AssemblyWriter::writeParamOperand(
const Value *Operand,
2727 Out <<
"<null operand!>";
2732 TypePrinter.print(Operand->
getType(), Out);
2734 if (
Attrs.hasAttributes()) {
2736 writeAttributeSet(Attrs);
2740 auto WriterCtx = getContext();
2744void AssemblyWriter::writeOperandBundles(
const CallBase *Call) {
2745 if (!
Call->hasOperandBundles())
2750 bool FirstBundle =
true;
2751 for (
unsigned i = 0, e =
Call->getNumOperandBundles(); i != e; ++i) {
2756 FirstBundle =
false;
2764 bool FirstInput =
true;
2765 auto WriterCtx = getContext();
2766 for (
const auto &Input : BU.
Inputs) {
2771 if (Input ==
nullptr)
2772 Out <<
"<null operand bundle!>";
2774 TypePrinter.print(Input->getType(), Out);
2786void AssemblyWriter::printModule(
const Module *M) {
2787 Machine.initializeIfNeeded();
2789 if (ShouldPreserveUseListOrder)
2792 if (!
M->getModuleIdentifier().empty() &&
2795 M->getModuleIdentifier().find(
'\n') == std::string::npos)
2796 Out <<
"; ModuleID = '" <<
M->getModuleIdentifier() <<
"'\n";
2798 if (!
M->getSourceFileName().empty()) {
2799 Out <<
"source_filename = \"";
2800 printEscapedString(
M->getSourceFileName(), Out);
2804 const std::string &
DL =
M->getDataLayoutStr();
2806 Out <<
"target datalayout = \"" <<
DL <<
"\"\n";
2807 if (!
M->getTargetTriple().empty())
2808 Out <<
"target triple = \"" <<
M->getTargetTriple() <<
"\"\n";
2810 if (!
M->getModuleInlineAsm().empty()) {
2817 std::tie(Front, Asm) =
Asm.split(
'\n');
2821 Out <<
"module asm \"";
2822 printEscapedString(Front, Out);
2824 }
while (!
Asm.empty());
2827 printTypeIdentities();
2830 if (!Comdats.empty())
2832 for (
const Comdat *
C : Comdats) {
2834 if (
C != Comdats.back())
2839 if (!
M->global_empty()) Out <<
'\n';
2841 printGlobal(&GV); Out <<
'\n';
2845 if (!
M->alias_empty()) Out <<
"\n";
2850 if (!
M->ifunc_empty()) Out <<
"\n";
2861 printUseLists(
nullptr);
2864 if (!Machine.as_empty()) {
2866 writeAllAttributeGroups();
2870 if (!
M->named_metadata_empty()) Out <<
'\n';
2873 printNamedMDNode(&
Node);
2876 if (!Machine.mdn_empty()) {
2882void AssemblyWriter::printModuleSummaryIndex() {
2884 int NumSlots = Machine.initializeIndexIfNeeded();
2890 std::vector<std::pair<std::string, ModuleHash>> moduleVec;
2891 std::string RegularLTOModuleName =
2893 moduleVec.resize(TheIndex->modulePaths().size());
2894 for (
auto &[ModPath, ModHash] : TheIndex->modulePaths())
2895 moduleVec[Machine.getModulePathSlot(ModPath)] = std::make_pair(
2898 ModPath.empty() ? RegularLTOModuleName : std::string(ModPath), ModHash);
2901 for (
auto &ModPair : moduleVec) {
2902 Out <<
"^" << i++ <<
" = module: (";
2904 printEscapedString(ModPair.first, Out);
2905 Out <<
"\", hash: (";
2907 for (
auto Hash : ModPair.second)
2914 for (
auto &GlobalList : *TheIndex) {
2915 auto GUID = GlobalList.first;
2916 for (
auto &Summary : GlobalList.second.SummaryList)
2917 SummaryToGUIDMap[
Summary.get()] = GUID;
2921 for (
auto &GlobalList : *TheIndex) {
2922 auto GUID = GlobalList.first;
2923 auto VI = TheIndex->getValueInfo(GlobalList);
2924 printSummaryInfo(Machine.getGUIDSlot(GUID), VI);
2928 for (
const auto &TID : TheIndex->typeIds()) {
2929 Out <<
"^" << Machine.getTypeIdSlot(TID.second.first)
2930 <<
" = typeid: (name: \"" << TID.second.first <<
"\"";
2931 printTypeIdSummary(TID.second.second);
2932 Out <<
") ; guid = " << TID.first <<
"\n";
2936 for (
auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
2938 Out <<
"^" << Machine.getGUIDSlot(GUID)
2939 <<
" = typeidCompatibleVTable: (name: \"" << TId.first <<
"\"";
2940 printTypeIdCompatibleVtableSummary(TId.second);
2941 Out <<
") ; guid = " << GUID <<
"\n";
2945 if (TheIndex->getFlags()) {
2946 Out <<
"^" << NumSlots <<
" = flags: " << TheIndex->getFlags() <<
"\n";
2950 Out <<
"^" << NumSlots <<
" = blockcount: " << TheIndex->getBlockCount()
2960 return "singleImpl";
2962 return "branchFunnel";
2973 return "uniformRetVal";
2975 return "uniqueRetVal";
2977 return "virtualConstProp";
3007 Out <<
", alignLog2: " << TTRes.
AlignLog2;
3009 Out <<
", sizeM1: " << TTRes.
SizeM1;
3019void AssemblyWriter::printTypeIdSummary(
const TypeIdSummary &TIS) {
3020 Out <<
", summary: (";
3021 printTypeTestResolution(TIS.
TTRes);
3022 if (!TIS.
WPDRes.empty()) {
3023 Out <<
", wpdResolutions: (";
3025 for (
auto &WPDRes : TIS.
WPDRes) {
3027 Out <<
"(offset: " << WPDRes.first <<
", ";
3028 printWPDRes(WPDRes.second);
3036void AssemblyWriter::printTypeIdCompatibleVtableSummary(
3038 Out <<
", summary: (";
3040 for (
auto &
P : TI) {
3042 Out <<
"(offset: " <<
P.AddressPointOffset <<
", ";
3043 Out <<
"^" << Machine.getGUIDSlot(
P.VTableVI.getGUID());
3049void AssemblyWriter::printArgs(
const std::vector<uint64_t> &Args) {
3052 for (
auto arg : Args) {
3060 Out <<
"wpdRes: (kind: ";
3067 Out <<
", resByArg: (";
3069 for (
auto &ResByArg : WPDRes.
ResByArg) {
3071 printArgs(ResByArg.first);
3072 Out <<
", byArg: (kind: ";
3074 if (ResByArg.second.TheKind ==
3076 ResByArg.second.TheKind ==
3078 Out <<
", info: " << ResByArg.second.Info;
3082 if (ResByArg.second.Byte || ResByArg.second.Bit)
3083 Out <<
", byte: " << ResByArg.second.Byte
3084 <<
", bit: " << ResByArg.second.Bit;
3105void AssemblyWriter::printAliasSummary(
const AliasSummary *AS) {
3106 Out <<
", aliasee: ";
3111 Out <<
"^" << Machine.getGUIDSlot(SummaryToGUIDMap[&AS->
getAliasee()]);
3117 auto VTableFuncs =
GS->vTableFuncs();
3118 Out <<
", varFlags: (readonly: " <<
GS->VarFlags.MaybeReadOnly <<
", "
3119 <<
"writeonly: " <<
GS->VarFlags.MaybeWriteOnly <<
", "
3120 <<
"constant: " <<
GS->VarFlags.Constant;
3121 if (!VTableFuncs.empty())
3123 <<
"vcall_visibility: " <<
GS->VarFlags.VCallVisibility;
3126 if (!VTableFuncs.empty()) {
3127 Out <<
", vTableFuncs: (";
3129 for (
auto &
P : VTableFuncs) {
3131 Out <<
"(virtFunc: ^" << Machine.getGUIDSlot(
P.FuncVI.getGUID())
3132 <<
", offset: " <<
P.VTableOffset;
3150 return "linkonce_odr";
3160 return "extern_weak";
3162 return "available_externally";
3189 Out <<
", insts: " <<
FS->instCount();
3190 if (
FS->fflags().anyFlagSet())
3191 Out <<
", " <<
FS->fflags();
3193 if (!
FS->calls().empty()) {
3194 Out <<
", calls: (";
3196 for (
auto &Call :
FS->calls()) {
3198 Out <<
"(callee: ^" << Machine.getGUIDSlot(
Call.first.getGUID());
3199 if (
Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
3201 else if (
Call.second.RelBlockFreq)
3202 Out <<
", relbf: " <<
Call.second.RelBlockFreq;
3208 if (
const auto *TIdInfo =
FS->getTypeIdInfo())
3209 printTypeIdInfo(*TIdInfo);
3213 auto AllocTypeName = [](uint8_t
Type) ->
const char * {
3215 case (uint8_t)AllocationType::None:
3217 case (uint8_t)AllocationType::NotCold:
3219 case (uint8_t)AllocationType::Cold:
3221 case (uint8_t)AllocationType::Hot:
3227 if (!
FS->allocs().empty()) {
3228 Out <<
", allocs: (";
3230 for (
auto &AI :
FS->allocs()) {
3232 Out <<
"(versions: (";
3234 for (
auto V : AI.Versions) {
3236 Out << AllocTypeName(V);
3238 Out <<
"), memProf: (";
3239 FieldSeparator MIBFS;
3240 for (
auto &MIB : AI.MIBs) {
3242 Out <<
"(type: " << AllocTypeName((uint8_t)MIB.AllocType);
3243 Out <<
", stackIds: (";
3244 FieldSeparator SIDFS;
3245 for (
auto Id : MIB.StackIdIndices) {
3247 Out << TheIndex->getStackIdAtIndex(Id);
3256 if (!
FS->callsites().empty()) {
3257 Out <<
", callsites: (";
3258 FieldSeparator SNFS;
3259 for (
auto &CI :
FS->callsites()) {
3262 Out <<
"(callee: ^" << Machine.getGUIDSlot(CI.Callee.getGUID());
3264 Out <<
"(callee: null";
3265 Out <<
", clones: (";
3267 for (
auto V : CI.Clones) {
3271 Out <<
"), stackIds: (";
3272 FieldSeparator SIDFS;
3273 for (
auto Id : CI.StackIdIndices) {
3275 Out << TheIndex->getStackIdAtIndex(Id);
3283 Out <<
"[" <<
Range.getSignedMin() <<
", " <<
Range.getSignedMax() <<
"]";
3286 if (!
FS->paramAccesses().empty()) {
3287 Out <<
", params: (";
3289 for (
auto &PS :
FS->paramAccesses()) {
3291 Out <<
"(param: " << PS.ParamNo;
3292 Out <<
", offset: ";
3294 if (!PS.Calls.empty()) {
3295 Out <<
", calls: (";
3297 for (
auto &Call : PS.Calls) {
3299 Out <<
"(callee: ^" << Machine.getGUIDSlot(
Call.Callee.getGUID());
3300 Out <<
", param: " <<
Call.ParamNo;
3301 Out <<
", offset: ";
3302 PrintRange(
Call.Offsets);
3313void AssemblyWriter::printTypeIdInfo(
3315 Out <<
", typeIdInfo: (";
3316 FieldSeparator TIDFS;
3319 Out <<
"typeTests: (";
3322 auto TidIter = TheIndex->typeIds().equal_range(GUID);
3323 if (TidIter.first == TidIter.second) {
3329 for (
auto It = TidIter.first; It != TidIter.second; ++It) {
3331 auto Slot = Machine.getTypeIdSlot(It->second.first);
3349 "typeTestAssumeConstVCalls");
3354 "typeCheckedLoadConstVCalls");
3360 auto TidIter = TheIndex->typeIds().equal_range(VFId.
GUID);
3361 if (TidIter.first == TidIter.second) {
3362 Out <<
"vFuncId: (";
3363 Out <<
"guid: " << VFId.
GUID;
3364 Out <<
", offset: " << VFId.
Offset;
3370 for (
auto It = TidIter.first; It != TidIter.second; ++It) {
3372 Out <<
"vFuncId: (";
3373 auto Slot = Machine.getTypeIdSlot(It->second.first);
3376 Out <<
", offset: " << VFId.
Offset;
3381void AssemblyWriter::printNonConstVCalls(
3382 const std::vector<FunctionSummary::VFuncId> &VCallList,
const char *
Tag) {
3383 Out <<
Tag <<
": (";
3385 for (
auto &VFuncId : VCallList) {
3387 printVFuncId(VFuncId);
3392void AssemblyWriter::printConstVCalls(
3393 const std::vector<FunctionSummary::ConstVCall> &VCallList,
3395 Out <<
Tag <<
": (";
3397 for (
auto &ConstVCall : VCallList) {
3400 printVFuncId(ConstVCall.VFunc);
3401 if (!ConstVCall.Args.empty()) {
3403 printArgs(ConstVCall.Args);
3414 Out <<
"(module: ^" << Machine.getModulePathSlot(
Summary.modulePath())
3417 Out <<
", visibility: "
3420 Out <<
", live: " << GVFlags.
Live;
3421 Out <<
", dsoLocal: " << GVFlags.
DSOLocal;
3426 printAliasSummary(cast<AliasSummary>(&Summary));
3428 printFunctionSummary(cast<FunctionSummary>(&Summary));
3430 printGlobalVarSummary(cast<GlobalVarSummary>(&Summary));
3432 auto RefList =
Summary.refs();
3433 if (!RefList.empty()) {
3436 for (
auto &
Ref : RefList) {
3438 if (
Ref.isReadOnly())
3440 else if (
Ref.isWriteOnly())
3441 Out <<
"writeonly ";
3442 Out <<
"^" << Machine.getGUIDSlot(
Ref.getGUID());
3450void AssemblyWriter::printSummaryInfo(
unsigned Slot,
const ValueInfo &VI) {
3451 Out <<
"^" <<
Slot <<
" = gv: (";
3452 if (!
VI.name().empty())
3453 Out <<
"name: \"" <<
VI.name() <<
"\"";
3455 Out <<
"guid: " <<
VI.getGUID();
3456 if (!
VI.getSummaryList().empty()) {
3457 Out <<
", summaries: (";
3459 for (
auto &Summary :
VI.getSummaryList()) {
3461 printSummary(*Summary);
3466 if (!
VI.name().empty())
3467 Out <<
" ; guid = " <<
VI.getGUID();
3474 Out <<
"<empty name> ";
3476 if (isalpha(
static_cast<unsigned char>(
Name[0])) ||
Name[0] ==
'-' ||
3480 Out <<
'\\' << hexdigit(
Name[0] >> 4) << hexdigit(
Name[0] & 0x0F);
3481 for (
unsigned i = 1, e =
Name.size(); i != e; ++i) {
3482 unsigned char C =
Name[i];
3483 if (isalnum(
static_cast<unsigned char>(
C)) ||
C ==
'-' ||
C ==
'$' ||
3484 C ==
'.' ||
C ==
'_')
3487 Out <<
'\\' << hexdigit(
C >> 4) << hexdigit(
C & 0x0F);
3492void AssemblyWriter::printNamedMDNode(
const NamedMDNode *NMD) {
3504 "DIArgLists should not appear in NamedMDNodes");
3505 if (
auto *Expr = dyn_cast<DIExpression>(
Op)) {
3510 int Slot = Machine.getMetadataSlot(
Op);
3531 Out <<
"dso_local ";
3546 case GlobalVariable::NotThreadLocal:
3548 case GlobalVariable::GeneralDynamicTLSModel:
3549 Out <<
"thread_local ";
3551 case GlobalVariable::LocalDynamicTLSModel:
3552 Out <<
"thread_local(localdynamic) ";
3554 case GlobalVariable::InitialExecTLSModel:
3555 Out <<
"thread_local(initialexec) ";
3557 case GlobalVariable::LocalExecTLSModel:
3558 Out <<
"thread_local(localexec) ";
3565 case GlobalVariable::UnnamedAddr::None:
3567 case GlobalVariable::UnnamedAddr::Local:
3568 return "local_unnamed_addr";
3569 case GlobalVariable::UnnamedAddr::Global:
3570 return "unnamed_addr";
3581 if (isa<GlobalVariable>(GO))
3595 Out <<
"; Materializable\n";
3597 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GV->
getParent());
3616 Out << (GV->
isConstant() ?
"constant " :
"global ");
3625 Out <<
", section \"";
3630 Out <<
", partition \"";
3639 Out <<
", no_sanitize_address";
3641 Out <<
", no_sanitize_hwaddress";
3643 Out <<
", sanitize_memtag";
3645 Out <<
", sanitize_address_dyninit";
3650 Out <<
", align " <<
A->value();
3654 printMetadataAttachments(MDs,
", ");
3657 if (
Attrs.hasAttributes())
3658 Out <<
" #" << Machine.getAttributeGroupSlot(Attrs);
3660 printInfoComment(*GV);
3663void AssemblyWriter::printAlias(
const GlobalAlias *GA) {
3665 Out <<
"; Materializable\n";
3667 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GA->
getParent());
3686 writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
3688 TypePrinter.print(GA->
getType(), Out);
3689 Out <<
" <<NULL ALIASEE>>";
3693 Out <<
", partition \"";
3698 printInfoComment(*GA);
3702void AssemblyWriter::printIFunc(
const GlobalIFunc *GI) {
3704 Out <<
"; Materializable\n";
3706 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GI->
getParent());
3722 TypePrinter.print(GI->
getType(), Out);
3723 Out <<
" <<NULL RESOLVER>>";
3727 Out <<
", partition \"";
3732 printInfoComment(*GI);
3736void AssemblyWriter::printComdat(
const Comdat *
C) {
3740void AssemblyWriter::printTypeIdentities() {
3741 if (TypePrinter.empty())
3747 auto &NumberedTypes = TypePrinter.getNumberedTypes();
3748 for (
unsigned I = 0,
E = NumberedTypes.size();
I !=
E; ++
I) {
3749 Out <<
'%' <<
I <<
" = type ";
3753 TypePrinter.printStructBody(NumberedTypes[
I], Out);
3757 auto &NamedTypes = TypePrinter.getNamedTypes();
3764 TypePrinter.printStructBody(NamedType, Out);
3770void AssemblyWriter::printFunction(
const Function *
F) {
3771 if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(
F, Out);
3773 if (
F->isMaterializable())
3774 Out <<
"; Materializable\n";
3777 if (
Attrs.hasFnAttrs()) {
3779 std::string AttrStr;
3782 if (!Attr.isStringAttribute()) {
3783 if (!AttrStr.empty()) AttrStr +=
' ';
3784 AttrStr += Attr.getAsString();
3788 if (!AttrStr.empty())
3789 Out <<
"; Function Attrs: " << AttrStr <<
'\n';
3792 Machine.incorporateFunction(
F);
3794 if (
F->isDeclaration()) {
3797 F->getAllMetadata(MDs);
3798 printMetadataAttachments(MDs,
" ");
3815 if (
Attrs.hasRetAttrs())
3817 TypePrinter.print(
F->getReturnType(), Out);
3818 AsmWriterContext WriterCtx(&TypePrinter, &Machine,
F->getParent());
3824 if (
F->isDeclaration() && !IsForDebug) {
3826 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
3831 TypePrinter.print(FT->getParamType(
I), Out);
3836 writeAttributeSet(ArgAttrs);
3843 if (Arg.getArgNo() != 0)
3845 printArgument(&Arg,
Attrs.getParamAttrs(Arg.getArgNo()));
3850 if (FT->isVarArg()) {
3851 if (FT->getNumParams()) Out <<
", ";
3862 if (
F->getAddressSpace() != 0 || !
Mod ||
3864 Out <<
" addrspace(" <<
F->getAddressSpace() <<
")";
3865 if (
Attrs.hasFnAttrs())
3866 Out <<
" #" << Machine.getAttributeGroupSlot(
Attrs.getFnAttrs());
3867 if (
F->hasSection()) {
3868 Out <<
" section \"";
3869 printEscapedString(
F->getSection(), Out);
3872 if (
F->hasPartition()) {
3873 Out <<
" partition \"";
3874 printEscapedString(
F->getPartition(), Out);
3879 Out <<
" align " <<
A->value();
3881 Out <<
" gc \"" <<
F->getGC() <<
'"';
3882 if (
F->hasPrefixData()) {
3884 writeOperand(
F->getPrefixData(),
true);
3886 if (
F->hasPrologueData()) {
3887 Out <<
" prologue ";
3888 writeOperand(
F->getPrologueData(),
true);
3890 if (
F->hasPersonalityFn()) {
3891 Out <<
" personality ";
3892 writeOperand(
F->getPersonalityFn(),
true);
3895 if (
F->isDeclaration()) {
3899 F->getAllMetadata(MDs);
3900 printMetadataAttachments(MDs,
" ");
3905 printBasicBlock(&BB);
3913 Machine.purgeFunction();
3920 TypePrinter.print(Arg->
getType(), Out);
3923 if (
Attrs.hasAttributes()) {
3925 writeAttributeSet(Attrs);
3933 int Slot = Machine.getLocalSlot(Arg);
3934 assert(Slot != -1 &&
"expect argument in function here");
3935 Out <<
" %" <<
Slot;
3940void AssemblyWriter::printBasicBlock(
const BasicBlock *BB) {
3946 }
else if (!IsEntryBlock) {
3948 int Slot = Machine.getLocalSlot(BB);
3955 if (!IsEntryBlock) {
3957 Out.PadToColumn(50);
3962 Out <<
" No predecessors!";
3965 writeOperand(*PI,
false);
3966 for (++PI; PI != PE; ++PI) {
3968 writeOperand(*PI,
false);
3975 if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
3979 printInstructionLine(
I);
3982 if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
3986void AssemblyWriter::printInstructionLine(
const Instruction &
I) {
3987 printInstruction(
I);
3993void AssemblyWriter::printGCRelocateComment(
const GCRelocateInst &Relocate) {
4003void AssemblyWriter::printInfoComment(
const Value &V) {
4004 if (
const auto *Relocate = dyn_cast<GCRelocateInst>(&V))
4005 printGCRelocateComment(*Relocate);
4007 if (AnnotationWriter)
4008 AnnotationWriter->printInfoComment(V, Out);
4014 if (Operand ==
nullptr) {
4015 Out <<
" <cannot get addrspace!>";
4019 bool PrintAddrSpace = CallAddrSpace != 0;
4020 if (!PrintAddrSpace) {
4026 PrintAddrSpace =
true;
4029 Out <<
" addrspace(" << CallAddrSpace <<
")";
4033void AssemblyWriter::printInstruction(
const Instruction &
I) {
4034 if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&
I, Out);
4043 }
else if (!
I.getType()->isVoidTy()) {
4045 int SlotNum = Machine.getLocalSlot(&
I);
4047 Out <<
"<badref> = ";
4049 Out <<
'%' << SlotNum <<
" = ";
4052 if (
const CallInst *CI = dyn_cast<CallInst>(&
I)) {
4053 if (CI->isMustTailCall())
4055 else if (CI->isTailCall())
4057 else if (CI->isNoTailCall())
4062 Out <<
I.getOpcodeName();
4065 if ((isa<LoadInst>(
I) && cast<LoadInst>(
I).isAtomic()) ||
4066 (isa<StoreInst>(
I) && cast<StoreInst>(
I).isAtomic()))
4069 if (isa<AtomicCmpXchgInst>(
I) && cast<AtomicCmpXchgInst>(
I).isWeak())
4073 if ((isa<LoadInst>(
I) && cast<LoadInst>(
I).isVolatile()) ||
4074 (isa<StoreInst>(
I) && cast<StoreInst>(
I).isVolatile()) ||
4075 (isa<AtomicCmpXchgInst>(
I) && cast<AtomicCmpXchgInst>(
I).isVolatile()) ||
4076 (isa<AtomicRMWInst>(
I) && cast<AtomicRMWInst>(
I).isVolatile()))
4083 if (
const CmpInst *CI = dyn_cast<CmpInst>(&
I))
4084 Out <<
' ' << CI->getPredicate();
4091 const Value *Operand =
I.getNumOperands() ?
I.getOperand(0) :
nullptr;
4094 if (isa<BranchInst>(
I) && cast<BranchInst>(
I).isConditional()) {
4097 writeOperand(BI.getCondition(),
true);
4099 writeOperand(BI.getSuccessor(0),
true);
4101 writeOperand(BI.getSuccessor(1),
true);
4103 }
else if (isa<SwitchInst>(
I)) {
4107 writeOperand(
SI.getCondition(),
true);
4109 writeOperand(
SI.getDefaultDest(),
true);
4111 for (
auto Case :
SI.cases()) {
4113 writeOperand(Case.getCaseValue(),
true);
4115 writeOperand(Case.getCaseSuccessor(),
true);
4118 }
else if (isa<IndirectBrInst>(
I)) {
4121 writeOperand(Operand,
true);
4124 for (
unsigned i = 1, e =
I.getNumOperands(); i != e; ++i) {
4127 writeOperand(
I.getOperand(i),
true);
4130 }
else if (
const PHINode *PN = dyn_cast<PHINode>(&
I)) {
4132 TypePrinter.print(
I.getType(), Out);
4135 for (
unsigned op = 0, Eop = PN->getNumIncomingValues();
op < Eop; ++
op) {
4136 if (
op) Out <<
", ";
4138 writeOperand(PN->getIncomingValue(
op),
false); Out <<
", ";
4139 writeOperand(PN->getIncomingBlock(
op),
false); Out <<
" ]";
4143 writeOperand(
I.getOperand(0),
true);
4144 for (
unsigned i : EVI->indices())
4148 writeOperand(
I.getOperand(0),
true); Out <<
", ";
4149 writeOperand(
I.getOperand(1),
true);
4150 for (
unsigned i : IVI->indices())
4152 }
else if (
const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&
I)) {
4154 TypePrinter.print(
I.getType(), Out);
4155 if (LPI->isCleanup() || LPI->getNumClauses() != 0)
4158 if (LPI->isCleanup())
4161 for (
unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
4162 if (i != 0 || LPI->isCleanup()) Out <<
"\n";
4163 if (LPI->isCatch(i))
4168 writeOperand(LPI->getClause(i),
true);
4170 }
else if (
const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&
I)) {
4172 writeOperand(CatchSwitch->getParentPad(),
false);
4175 for (
const BasicBlock *PadBB : CatchSwitch->handlers()) {
4178 writeOperand(PadBB,
true);
4182 if (
const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
4183 writeOperand(UnwindDest,
true);
4186 }
else if (
const auto *FPI = dyn_cast<FuncletPadInst>(&
I)) {
4188 writeOperand(FPI->getParentPad(),
false);
4190 for (
unsigned Op = 0, NumOps = FPI->arg_size();
Op < NumOps; ++
Op) {
4193 writeOperand(FPI->getArgOperand(
Op),
true);
4196 }
else if (isa<ReturnInst>(
I) && !Operand) {
4198 }
else if (
const auto *CRI = dyn_cast<CatchReturnInst>(&
I)) {
4200 writeOperand(CRI->getOperand(0),
false);
4203 writeOperand(CRI->getOperand(1),
true);
4204 }
else if (
const auto *CRI = dyn_cast<CleanupReturnInst>(&
I)) {
4206 writeOperand(CRI->getOperand(0),
false);
4209 if (CRI->hasUnwindDest())
4210 writeOperand(CRI->getOperand(1),
true);
4213 }
else if (
const CallInst *CI = dyn_cast<CallInst>(&
I)) {
4220 Operand = CI->getCalledOperand();
4235 TypePrinter.print(FTy->isVarArg() ? FTy :
RetTy, Out);
4237 writeOperand(Operand,
false);
4239 for (
unsigned op = 0, Eop = CI->arg_size();
op < Eop; ++
op) {
4247 if (CI->isMustTailCall() && CI->getParent() &&
4248 CI->getParent()->getParent() &&
4249 CI->getParent()->getParent()->isVarArg()) {
4250 if (CI->arg_size() > 0)
4257 Out <<
" #" << Machine.getAttributeGroupSlot(PAL.
getFnAttrs());
4259 writeOperandBundles(CI);
4260 }
else if (
const InvokeInst *II = dyn_cast<InvokeInst>(&
I)) {
4261 Operand = II->getCalledOperand();
4283 TypePrinter.print(FTy->isVarArg() ? FTy :
RetTy, Out);
4285 writeOperand(Operand,
false);
4287 for (
unsigned op = 0, Eop = II->arg_size();
op < Eop; ++
op) {
4295 Out <<
" #" << Machine.getAttributeGroupSlot(PAL.
getFnAttrs());
4297 writeOperandBundles(II);
4300 writeOperand(II->getNormalDest(),
true);
4302 writeOperand(II->getUnwindDest(),
true);
4303 }
else if (
const CallBrInst *CBI = dyn_cast<CallBrInst>(&
I)) {
4304 Operand = CBI->getCalledOperand();
4323 TypePrinter.print(FTy->isVarArg() ? FTy :
RetTy, Out);
4325 writeOperand(Operand,
false);
4327 for (
unsigned op = 0, Eop = CBI->arg_size();
op < Eop; ++
op) {
4335 Out <<
" #" << Machine.getAttributeGroupSlot(PAL.
getFnAttrs());
4337 writeOperandBundles(CBI);
4340 writeOperand(CBI->getDefaultDest(),
true);
4342 for (
unsigned i = 0, e = CBI->getNumIndirectDests(); i != e; ++i) {
4345 writeOperand(CBI->getIndirectDest(i),
true);
4348 }
else if (
const AllocaInst *AI = dyn_cast<AllocaInst>(&
I)) {
4350 if (AI->isUsedWithInAlloca())
4352 if (AI->isSwiftError())
4353 Out <<
"swifterror ";
4354 TypePrinter.print(AI->getAllocatedType(), Out);
4360 if (!AI->getArraySize() || AI->isArrayAllocation() ||
4361 !AI->getArraySize()->getType()->isIntegerTy(32)) {
4363 writeOperand(AI->getArraySize(),
true);
4366 Out <<
", align " <<
A->value();
4369 unsigned AddrSpace = AI->getAddressSpace();
4370 if (AddrSpace != 0) {
4371 Out <<
", addrspace(" << AddrSpace <<
')';
4373 }
else if (isa<CastInst>(
I)) {
4376 writeOperand(Operand,
true);
4379 TypePrinter.print(
I.getType(), Out);
4380 }
else if (isa<VAArgInst>(
I)) {
4383 writeOperand(Operand,
true);
4386 TypePrinter.print(
I.getType(), Out);
4387 }
else if (Operand) {
4388 if (
const auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
4390 TypePrinter.print(
GEP->getSourceElementType(), Out);
4392 }
else if (
const auto *LI = dyn_cast<LoadInst>(&
I)) {
4394 TypePrinter.print(LI->getType(), Out);
4401 bool PrintAllTypes =
false;
4406 if (isa<SelectInst>(
I) || isa<StoreInst>(
I) || isa<ShuffleVectorInst>(
I) ||
4407 isa<ReturnInst>(
I) || isa<AtomicCmpXchgInst>(
I) ||
4408 isa<AtomicRMWInst>(
I)) {
4409 PrintAllTypes =
true;
4411 for (
unsigned i = 1,
E =
I.getNumOperands(); i !=
E; ++i) {
4412 Operand =
I.getOperand(i);
4415 if (Operand && Operand->
getType() != TheType) {
4416 PrintAllTypes =
true;
4422 if (!PrintAllTypes) {
4424 TypePrinter.print(TheType, Out);
4428 for (
unsigned i = 0,
E =
I.getNumOperands(); i !=
E; ++i) {
4430 writeOperand(
I.getOperand(i), PrintAllTypes);
4435 if (
const LoadInst *LI = dyn_cast<LoadInst>(&
I)) {
4437 writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID());
4439 Out <<
", align " <<
A->value();
4440 }
else if (
const StoreInst *SI = dyn_cast<StoreInst>(&
I)) {
4442 writeAtomic(
SI->getContext(),
SI->getOrdering(),
SI->getSyncScopeID());
4444 Out <<
", align " <<
A->value();
4446 writeAtomicCmpXchg(CXI->getContext(), CXI->getSuccessOrdering(),
4447 CXI->getFailureOrdering(), CXI->getSyncScopeID());
4448 Out <<
", align " << CXI->getAlign().value();
4449 }
else if (
const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&
I)) {
4450 writeAtomic(RMWI->getContext(), RMWI->getOrdering(),
4451 RMWI->getSyncScopeID());
4452 Out <<
", align " << RMWI->getAlign().value();
4453 }
else if (
const FenceInst *FI = dyn_cast<FenceInst>(&
I)) {
4454 writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
4461 I.getAllMetadata(InstMD);
4462 printMetadataAttachments(InstMD,
", ");
4465 printInfoComment(
I);
4468void AssemblyWriter::printMetadataAttachments(
4474 if (MDNames.empty())
4475 MDs[0].second->getContext().getMDKindNames(MDNames);
4477 auto WriterCtx = getContext();
4478 for (
const auto &
I : MDs) {
4479 unsigned Kind =
I.first;
4481 if (Kind < MDNames.size()) {
4485 Out <<
"!<unknown kind #" <<
Kind <<
">";
4491void AssemblyWriter::writeMDNode(
unsigned Slot,
const MDNode *
Node) {
4492 Out <<
'!' <<
Slot <<
" = ";
4493 printMDNodeBody(
Node);
4497void AssemblyWriter::writeAllMDNodes() {
4499 Nodes.
resize(Machine.mdn_size());
4501 Nodes[
I.second] = cast<MDNode>(
I.first);
4503 for (
unsigned i = 0, e = Nodes.
size(); i != e; ++i) {
4504 writeMDNode(i, Nodes[i]);
4508void AssemblyWriter::printMDNodeBody(
const MDNode *
Node) {
4509 auto WriterCtx = getContext();
4513void AssemblyWriter::writeAttribute(
const Attribute &Attr,
bool InAttrGroup) {
4522 TypePrinter.print(Ty, Out);
4527void AssemblyWriter::writeAttributeSet(
const AttributeSet &AttrSet,
4529 bool FirstAttr =
true;
4530 for (
const auto &Attr : AttrSet) {
4533 writeAttribute(Attr, InAttrGroup);
4538void AssemblyWriter::writeAllAttributeGroups() {
4539 std::vector<std::pair<AttributeSet, unsigned>> asVec;
4540 asVec.resize(Machine.as_size());
4543 asVec[
I.second] =
I;
4545 for (
const auto &
I : asVec)
4546 Out <<
"attributes #" <<
I.second <<
" = { "
4547 <<
I.first.getAsString(
true) <<
" }\n";
4550void AssemblyWriter::printUseListOrder(
const Value *V,
4551 const std::vector<unsigned> &Shuffle) {
4552 bool IsInFunction = Machine.getFunction();
4556 Out <<
"uselistorder";
4557 if (
const BasicBlock *BB = IsInFunction ?
nullptr : dyn_cast<BasicBlock>(V)) {
4559 writeOperand(BB->getParent(),
false);
4561 writeOperand(BB,
false);
4564 writeOperand(V,
true);
4568 assert(Shuffle.size() >= 2 &&
"Shuffle too small");
4570 for (
unsigned I = 1,
E = Shuffle.size();
I !=
E; ++
I)
4571 Out <<
", " << Shuffle[
I];
4575void AssemblyWriter::printUseLists(
const Function *
F) {
4576 auto It = UseListOrders.find(
F);
4577 if (It == UseListOrders.end())
4580 Out <<
"\n; uselistorder directives\n";
4581 for (
const auto &Pair : It->second)
4582 printUseListOrder(Pair.first, Pair.second);
4590 bool ShouldPreserveUseListOrder,
4591 bool IsForDebug)
const {
4594 AssemblyWriter W(
OS, SlotTable, this->
getParent(), AAW,
4596 ShouldPreserveUseListOrder);
4597 W.printFunction(
this);
4601 bool ShouldPreserveUseListOrder,
4602 bool IsForDebug)
const {
4605 AssemblyWriter W(
OS, SlotTable, this->
getModule(), AAW,
4607 ShouldPreserveUseListOrder);
4608 W.printBasicBlock(
this);
4612 bool ShouldPreserveUseListOrder,
bool IsForDebug)
const {
4615 AssemblyWriter W(
OS, SlotTable,
this, AAW, IsForDebug,
4616 ShouldPreserveUseListOrder);
4617 W.printModule(
this);
4623 AssemblyWriter W(
OS, SlotTable,
getParent(),
nullptr, IsForDebug);
4624 W.printNamedMDNode(
this);
4628 bool IsForDebug)
const {
4629 std::optional<SlotTracker> LocalST;
4635 SlotTable = &*LocalST;
4639 AssemblyWriter W(
OS, *SlotTable,
getParent(),
nullptr, IsForDebug);
4640 W.printNamedMDNode(
this);
4645 ROS <<
" = comdat ";
4652 ROS <<
"exactmatch";
4658 ROS <<
"nodeduplicate";
4670 TP.print(
const_cast<Type*
>(
this),
OS);
4676 if (
StructType *STy = dyn_cast<StructType>(
const_cast<Type*
>(
this)))
4679 TP.printStructBody(STy,
OS);
4684 if (
const auto *CI = dyn_cast<CallInst>(&
I))
4685 if (
Function *
F = CI->getCalledFunction())
4686 if (
F->isIntrinsic())
4687 for (
auto &
Op :
I.operands())
4688 if (
auto *V = dyn_cast_or_null<MetadataAsValue>(
Op))
4689 if (isa<MDNode>(V->getMetadata()))
4695 bool ShouldInitializeAllMetadata =
false;
4696 if (
auto *
I = dyn_cast<Instruction>(
this))
4698 else if (isa<Function>(
this) || isa<MetadataAsValue>(
this))
4699 ShouldInitializeAllMetadata =
true;
4702 print(ROS, MST, IsForDebug);
4706 bool IsForDebug)
const {
4711 auto incorporateFunction = [&](
const Function *
F) {
4716 if (
const Instruction *
I = dyn_cast<Instruction>(
this)) {
4717 incorporateFunction(
I->getParent() ?
I->getParent()->getParent() :
nullptr);
4719 W.printInstruction(*
I);
4720 }
else if (
const BasicBlock *BB = dyn_cast<BasicBlock>(
this)) {
4721 incorporateFunction(BB->getParent());
4723 W.printBasicBlock(BB);
4724 }
else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
this)) {
4725 AssemblyWriter W(
OS, SlotTable, GV->
getParent(),
nullptr, IsForDebug);
4728 else if (
const Function *
F = dyn_cast<Function>(GV))
4730 else if (
const GlobalAlias *
A = dyn_cast<GlobalAlias>(GV))
4732 else if (
const GlobalIFunc *
I = dyn_cast<GlobalIFunc>(GV))
4736 }
else if (
const MetadataAsValue *V = dyn_cast<MetadataAsValue>(
this)) {
4738 }
else if (
const Constant *
C = dyn_cast<Constant>(
this)) {
4739 TypePrinting TypePrinter;
4740 TypePrinter.print(
C->getType(),
OS);
4742 AsmWriterContext WriterCtx(&TypePrinter, MST.
getMachine());
4744 }
else if (isa<InlineAsm>(
this) || isa<Argument>(
this)) {
4756 if (V.hasName() || isa<GlobalValue>(V) ||
4757 (!isa<Constant>(V) && !isa<MetadataAsValue>(V))) {
4758 AsmWriterContext WriterCtx(
nullptr, Machine, M);
4767 TypePrinting TypePrinter(MST.
getModule());
4769 TypePrinter.print(V.getType(), O);
4787 M, isa<MetadataAsValue>(
this));
4803 AsmWriterContext &WriterCtx) {
4807 auto *
N = dyn_cast<MDNode>(&MD);
4808 if (!
N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
4816struct MDTreeAsmWriterContext :
public AsmWriterContext {
4819 using EntryTy = std::pair<unsigned, std::string>;
4829 : AsmWriterContext(TP,
ST,
M), Level(0
U), Visited({InitMD}), MainOS(
OS) {}
4831 void onWriteMetadataAsOperand(
const Metadata *MD)
override {
4832 if (!Visited.
insert(MD).second)
4841 unsigned InsertIdx = Buffer.
size() - 1;
4844 Buffer[InsertIdx].second = std::move(
SS.str());
4848 ~MDTreeAsmWriterContext() {
4849 for (
const auto &Entry : Buffer) {
4851 unsigned NumIndent = Entry.first * 2U;
4852 MainOS.
indent(NumIndent) << Entry.second;
4860 bool OnlyAsOperand,
bool PrintAsTree =
false) {
4863 TypePrinting TypePrinter(M);
4865 std::unique_ptr<AsmWriterContext> WriterCtx;
4866 if (PrintAsTree && !OnlyAsOperand)
4867 WriterCtx = std::make_unique<MDTreeAsmWriterContext>(
4871 std::make_unique<AsmWriterContext>(&TypePrinter, MST.
getMachine(), M);
4875 auto *
N = dyn_cast<MDNode>(&MD);
4876 if (OnlyAsOperand || !
N || isa<DIExpression>(MD) || isa<DIArgList>(MD))