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";
359 assert(!
Name.empty() &&
"Cannot get empty name!");
362 bool NeedsQuotes = isdigit(
static_cast<unsigned char>(
Name[0]));
364 for (
unsigned char C :
Name) {
369 if (!isalnum(
static_cast<unsigned char>(
C)) &&
C !=
'-' &&
C !=
'.' &&
386 printEscapedString(
Name,
OS);
422 if (isa<ScalableVectorType>(Ty))
424 Out << Mask.size() <<
" x i32> ";
425 bool FirstElt =
true;
426 if (
all_of(Mask, [](
int Elt) {
return Elt == 0; })) {
427 Out <<
"zeroinitializer";
432 for (
int Elt : Mask) {
451 TypePrinting(
const Module *M =
nullptr) : DeferredM(
M) {}
453 TypePrinting(
const TypePrinting &) =
delete;
454 TypePrinting &operator=(
const TypePrinting &) =
delete;
460 std::vector<StructType *> &getNumberedTypes();
469 void incorporateTypes();
479 std::vector<StructType *> NumberedTypes;
489std::vector<StructType *> &TypePrinting::getNumberedTypes() {
495 if (NumberedTypes.size() == Type2Number.size())
496 return NumberedTypes;
498 NumberedTypes.resize(Type2Number.size());
499 for (
const auto &
P : Type2Number) {
500 assert(
P.second < NumberedTypes.size() &&
"Didn't get a dense numbering?");
501 assert(!NumberedTypes[
P.second] &&
"Didn't get a unique numbering?");
502 NumberedTypes[
P.second] =
P.first;
504 return NumberedTypes;
507bool TypePrinting::empty() {
509 return NamedTypes.empty() && Type2Number.empty();
512void TypePrinting::incorporateTypes() {
516 NamedTypes.run(*DeferredM,
false);
521 unsigned NextNumber = 0;
523 std::vector<StructType *>::iterator NextToUse = NamedTypes.begin();
526 if (STy->isLiteral())
529 if (STy->getName().empty())
530 Type2Number[STy] = NextNumber++;
535 NamedTypes.erase(NextToUse, NamedTypes.end());
556 OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
561 print(FTy->getReturnType(),
OS);
564 for (
Type *Ty : FTy->params()) {
577 return printStructBody(STy,
OS);
583 const auto I = Type2Number.find(STy);
584 if (
I != Type2Number.end())
585 OS <<
'%' <<
I->second;
587 OS <<
"%\"type " << STy <<
'\"';
592 if (PTy->isOpaque()) {
598 print(PTy->getNonOpaquePointerElementType(),
OS);
606 OS <<
'[' << ATy->getNumElements() <<
" x ";
607 print(ATy->getElementType(),
OS);
618 OS <<
EC.getKnownMinValue() <<
" x ";
619 print(PTy->getElementType(),
OS);
635 OS <<
", " << *Inner;
637 OS <<
", " << IntParam;
688 const Function* TheFunction =
nullptr;
689 bool FunctionProcessed =
false;
690 bool ShouldInitializeAllMetadata;
695 ProcessFunctionHookFn;
710 unsigned mdnNext = 0;
718 unsigned ModulePathNext = 0;
722 unsigned GUIDNext = 0;
726 unsigned TypeIdNext = 0;
735 bool ShouldInitializeAllMetadata =
false);
743 bool ShouldInitializeAllMetadata =
false);
776 FunctionProcessed =
false;
815 void CreateMetadataSlot(
const MDNode *
N);
818 void CreateFunctionSlot(
const Value *V);
823 inline void CreateModulePathSlot(
StringRef Path);
829 void processModule();
834 void processFunction();
837 void processGlobalObjectMetadata(
const GlobalObject &GO);
840 void processFunctionMetadata(
const Function &
F);
850 : M(M),
F(
F), Machine(&Machine) {}
853 bool ShouldInitializeAllMetadata)
854 : ShouldCreateStorage(M),
855 ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {}
860 if (!ShouldCreateStorage)
863 ShouldCreateStorage =
false;
865 std::make_unique<SlotTracker>(M, ShouldInitializeAllMetadata);
866 Machine = MachineStorage.get();
867 if (ProcessModuleHookFn)
869 if (ProcessFunctionHookFn)
889 assert(F &&
"No function incorporated");
896 ProcessModuleHookFn = Fn;
902 ProcessFunctionHookFn = Fn;
906 if (
const Argument *FA = dyn_cast<Argument>(V))
913 if (
const BasicBlock *BB = dyn_cast<BasicBlock>(V))
919 if (
const GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
922 if (
const GlobalIFunc *GIF = dyn_cast<GlobalIFunc>(V))
925 if (
const Function *Func = dyn_cast<Function>(V))
932#define ST_DEBUG(X) dbgs() << X
940 : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
945 : TheModule(
F ?
F->
getParent() : nullptr), TheFunction(
F),
946 ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}
949 : TheModule(nullptr), ShouldInitializeAllMetadata(
false), TheIndex(
Index) {}
957 if (TheFunction && !FunctionProcessed)
964 int NumSlots = processIndex();
971void SlotTracker::processModule() {
977 CreateModuleSlot(&Var);
978 processGlobalObjectMetadata(Var);
979 auto Attrs = Var.getAttributes();
980 if (Attrs.hasAttributes())
981 CreateAttributeSetSlot(Attrs);
986 CreateModuleSlot(&
A);
991 CreateModuleSlot(&
I);
996 for (
unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
997 CreateMetadataSlot(NMD.getOperand(i));
1003 CreateModuleSlot(&
F);
1005 if (ShouldInitializeAllMetadata)
1006 processFunctionMetadata(
F);
1012 CreateAttributeSetSlot(FnAttrs);
1015 if (ProcessModuleHookFn)
1016 ProcessModuleHookFn(
this, TheModule, ShouldInitializeAllMetadata);
1022void SlotTracker::processFunction() {
1023 ST_DEBUG(
"begin processFunction!\n");
1027 if (!ShouldInitializeAllMetadata)
1028 processFunctionMetadata(*TheFunction);
1032 AE = TheFunction->
arg_end(); AI != AE; ++AI)
1034 CreateFunctionSlot(&*AI);
1036 ST_DEBUG(
"Inserting Instructions:\n");
1039 for (
auto &BB : *TheFunction) {
1041 CreateFunctionSlot(&BB);
1043 for (
auto &
I : BB) {
1044 if (!
I.getType()->isVoidTy() && !
I.hasName())
1045 CreateFunctionSlot(&
I);
1049 if (
const auto *Call = dyn_cast<CallBase>(&
I)) {
1052 if (
Attrs.hasAttributes())
1053 CreateAttributeSetSlot(Attrs);
1058 if (ProcessFunctionHookFn)
1059 ProcessFunctionHookFn(
this, TheFunction, ShouldInitializeAllMetadata);
1061 FunctionProcessed =
true;
1063 ST_DEBUG(
"end processFunction!\n");
1067int SlotTracker::processIndex() {
1074 std::map<uint64_t, StringRef> ModuleIdToPathMap;
1075 for (
auto &[ModPath, ModId] : TheIndex->
modulePaths())
1076 ModuleIdToPathMap[ModId.first] = ModPath;
1077 for (
auto &ModPair : ModuleIdToPathMap)
1078 CreateModulePathSlot(ModPair.second);
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, ModId] : TheIndex->modulePaths())
2895 moduleVec[Machine.getModulePathSlot(ModPath)] = std::make_pair(
2898 ModId.first == -1u ? RegularLTOModuleName : std::string(ModPath),
2902 for (
auto &ModPair : moduleVec) {
2903 Out <<
"^" << i++ <<
" = module: (";
2905 printEscapedString(ModPair.first, Out);
2906 Out <<
"\", hash: (";
2908 for (
auto Hash : ModPair.second)
2915 for (
auto &GlobalList : *TheIndex) {
2916 auto GUID = GlobalList.first;
2917 for (
auto &Summary : GlobalList.second.SummaryList)
2918 SummaryToGUIDMap[
Summary.get()] = GUID;
2922 for (
auto &GlobalList : *TheIndex) {
2923 auto GUID = GlobalList.first;
2924 auto VI = TheIndex->getValueInfo(GlobalList);
2925 printSummaryInfo(Machine.getGUIDSlot(GUID), VI);
2929 for (
const auto &TID : TheIndex->typeIds()) {
2930 Out <<
"^" << Machine.getTypeIdSlot(TID.second.first)
2931 <<
" = typeid: (name: \"" << TID.second.first <<
"\"";
2932 printTypeIdSummary(TID.second.second);
2933 Out <<
") ; guid = " << TID.first <<
"\n";
2937 for (
auto &TId : TheIndex->typeIdCompatibleVtableMap()) {
2939 Out <<
"^" << Machine.getGUIDSlot(GUID)
2940 <<
" = typeidCompatibleVTable: (name: \"" << TId.first <<
"\"";
2941 printTypeIdCompatibleVtableSummary(TId.second);
2942 Out <<
") ; guid = " << GUID <<
"\n";
2946 if (TheIndex->getFlags()) {
2947 Out <<
"^" << NumSlots <<
" = flags: " << TheIndex->getFlags() <<
"\n";
2951 Out <<
"^" << NumSlots <<
" = blockcount: " << TheIndex->getBlockCount()
2961 return "singleImpl";
2963 return "branchFunnel";
2974 return "uniformRetVal";
2976 return "uniqueRetVal";
2978 return "virtualConstProp";
3008 Out <<
", alignLog2: " << TTRes.
AlignLog2;
3010 Out <<
", sizeM1: " << TTRes.
SizeM1;
3020void AssemblyWriter::printTypeIdSummary(
const TypeIdSummary &TIS) {
3021 Out <<
", summary: (";
3022 printTypeTestResolution(TIS.
TTRes);
3023 if (!TIS.
WPDRes.empty()) {
3024 Out <<
", wpdResolutions: (";
3026 for (
auto &WPDRes : TIS.
WPDRes) {
3028 Out <<
"(offset: " << WPDRes.first <<
", ";
3029 printWPDRes(WPDRes.second);
3037void AssemblyWriter::printTypeIdCompatibleVtableSummary(
3039 Out <<
", summary: (";
3041 for (
auto &
P : TI) {
3043 Out <<
"(offset: " <<
P.AddressPointOffset <<
", ";
3044 Out <<
"^" << Machine.getGUIDSlot(
P.VTableVI.getGUID());
3050void AssemblyWriter::printArgs(
const std::vector<uint64_t> &Args) {
3053 for (
auto arg : Args) {
3061 Out <<
"wpdRes: (kind: ";
3068 Out <<
", resByArg: (";
3070 for (
auto &ResByArg : WPDRes.
ResByArg) {
3072 printArgs(ResByArg.first);
3073 Out <<
", byArg: (kind: ";
3075 if (ResByArg.second.TheKind ==
3077 ResByArg.second.TheKind ==
3079 Out <<
", info: " << ResByArg.second.Info;
3083 if (ResByArg.second.Byte || ResByArg.second.Bit)
3084 Out <<
", byte: " << ResByArg.second.Byte
3085 <<
", bit: " << ResByArg.second.Bit;
3106void AssemblyWriter::printAliasSummary(
const AliasSummary *AS) {
3107 Out <<
", aliasee: ";
3112 Out <<
"^" << Machine.getGUIDSlot(SummaryToGUIDMap[&AS->
getAliasee()]);
3118 auto VTableFuncs =
GS->vTableFuncs();
3119 Out <<
", varFlags: (readonly: " <<
GS->VarFlags.MaybeReadOnly <<
", "
3120 <<
"writeonly: " <<
GS->VarFlags.MaybeWriteOnly <<
", "
3121 <<
"constant: " <<
GS->VarFlags.Constant;
3122 if (!VTableFuncs.empty())
3124 <<
"vcall_visibility: " <<
GS->VarFlags.VCallVisibility;
3127 if (!VTableFuncs.empty()) {
3128 Out <<
", vTableFuncs: (";
3130 for (
auto &
P : VTableFuncs) {
3132 Out <<
"(virtFunc: ^" << Machine.getGUIDSlot(
P.FuncVI.getGUID())
3133 <<
", offset: " <<
P.VTableOffset;
3151 return "linkonce_odr";
3161 return "extern_weak";
3163 return "available_externally";
3190 Out <<
", insts: " <<
FS->instCount();
3191 if (
FS->fflags().anyFlagSet())
3192 Out <<
", " <<
FS->fflags();
3194 if (!
FS->calls().empty()) {
3195 Out <<
", calls: (";
3197 for (
auto &Call :
FS->calls()) {
3199 Out <<
"(callee: ^" << Machine.getGUIDSlot(
Call.first.getGUID());
3200 if (
Call.second.getHotness() != CalleeInfo::HotnessType::Unknown)
3202 else if (
Call.second.RelBlockFreq)
3203 Out <<
", relbf: " <<
Call.second.RelBlockFreq;
3209 if (
const auto *TIdInfo =
FS->getTypeIdInfo())
3210 printTypeIdInfo(*TIdInfo);
3214 auto AllocTypeName = [](uint8_t
Type) ->
const char * {
3216 case (uint8_t)AllocationType::None:
3218 case (uint8_t)AllocationType::NotCold:
3220 case (uint8_t)AllocationType::Cold:
3222 case (uint8_t)AllocationType::Hot:
3228 if (!
FS->allocs().empty()) {
3229 Out <<
", allocs: (";
3231 for (
auto &AI :
FS->allocs()) {
3233 Out <<
"(versions: (";
3235 for (
auto V : AI.Versions) {
3237 Out << AllocTypeName(V);
3239 Out <<
"), memProf: (";
3240 FieldSeparator MIBFS;
3241 for (
auto &MIB : AI.MIBs) {
3243 Out <<
"(type: " << AllocTypeName((uint8_t)MIB.AllocType);
3244 Out <<
", stackIds: (";
3245 FieldSeparator SIDFS;
3246 for (
auto Id : MIB.StackIdIndices) {
3248 Out << TheIndex->getStackIdAtIndex(Id);
3257 if (!
FS->callsites().empty()) {
3258 Out <<
", callsites: (";
3259 FieldSeparator SNFS;
3260 for (
auto &CI :
FS->callsites()) {
3263 Out <<
"(callee: ^" << Machine.getGUIDSlot(CI.Callee.getGUID());
3265 Out <<
"(callee: null";
3266 Out <<
", clones: (";
3268 for (
auto V : CI.Clones) {
3272 Out <<
"), stackIds: (";
3273 FieldSeparator SIDFS;
3274 for (
auto Id : CI.StackIdIndices) {
3276 Out << TheIndex->getStackIdAtIndex(Id);
3284 Out <<
"[" <<
Range.getSignedMin() <<
", " <<
Range.getSignedMax() <<
"]";
3287 if (!
FS->paramAccesses().empty()) {
3288 Out <<
", params: (";
3290 for (
auto &PS :
FS->paramAccesses()) {
3292 Out <<
"(param: " << PS.ParamNo;
3293 Out <<
", offset: ";
3295 if (!PS.Calls.empty()) {
3296 Out <<
", calls: (";
3298 for (
auto &Call : PS.Calls) {
3300 Out <<
"(callee: ^" << Machine.getGUIDSlot(
Call.Callee.getGUID());
3301 Out <<
", param: " <<
Call.ParamNo;
3302 Out <<
", offset: ";
3303 PrintRange(
Call.Offsets);
3314void AssemblyWriter::printTypeIdInfo(
3316 Out <<
", typeIdInfo: (";
3317 FieldSeparator TIDFS;
3320 Out <<
"typeTests: (";
3323 auto TidIter = TheIndex->typeIds().equal_range(GUID);
3324 if (TidIter.first == TidIter.second) {
3330 for (
auto It = TidIter.first; It != TidIter.second; ++It) {
3332 auto Slot = Machine.getTypeIdSlot(It->second.first);
3350 "typeTestAssumeConstVCalls");
3355 "typeCheckedLoadConstVCalls");
3361 auto TidIter = TheIndex->typeIds().equal_range(VFId.
GUID);
3362 if (TidIter.first == TidIter.second) {
3363 Out <<
"vFuncId: (";
3364 Out <<
"guid: " << VFId.
GUID;
3365 Out <<
", offset: " << VFId.
Offset;
3371 for (
auto It = TidIter.first; It != TidIter.second; ++It) {
3373 Out <<
"vFuncId: (";
3374 auto Slot = Machine.getTypeIdSlot(It->second.first);
3377 Out <<
", offset: " << VFId.
Offset;
3382void AssemblyWriter::printNonConstVCalls(
3383 const std::vector<FunctionSummary::VFuncId> &VCallList,
const char *
Tag) {
3384 Out <<
Tag <<
": (";
3386 for (
auto &VFuncId : VCallList) {
3388 printVFuncId(VFuncId);
3393void AssemblyWriter::printConstVCalls(
3394 const std::vector<FunctionSummary::ConstVCall> &VCallList,
3396 Out <<
Tag <<
": (";
3398 for (
auto &ConstVCall : VCallList) {
3401 printVFuncId(ConstVCall.VFunc);
3402 if (!ConstVCall.Args.empty()) {
3404 printArgs(ConstVCall.Args);
3415 Out <<
"(module: ^" << Machine.getModulePathSlot(
Summary.modulePath())
3418 Out <<
", visibility: "
3421 Out <<
", live: " << GVFlags.
Live;
3422 Out <<
", dsoLocal: " << GVFlags.
DSOLocal;
3427 printAliasSummary(cast<AliasSummary>(&Summary));
3429 printFunctionSummary(cast<FunctionSummary>(&Summary));
3431 printGlobalVarSummary(cast<GlobalVarSummary>(&Summary));
3433 auto RefList =
Summary.refs();
3434 if (!RefList.empty()) {
3437 for (
auto &
Ref : RefList) {
3439 if (
Ref.isReadOnly())
3441 else if (
Ref.isWriteOnly())
3442 Out <<
"writeonly ";
3443 Out <<
"^" << Machine.getGUIDSlot(
Ref.getGUID());
3451void AssemblyWriter::printSummaryInfo(
unsigned Slot,
const ValueInfo &VI) {
3452 Out <<
"^" <<
Slot <<
" = gv: (";
3453 if (!
VI.name().empty())
3454 Out <<
"name: \"" <<
VI.name() <<
"\"";
3456 Out <<
"guid: " <<
VI.getGUID();
3457 if (!
VI.getSummaryList().empty()) {
3458 Out <<
", summaries: (";
3460 for (
auto &Summary :
VI.getSummaryList()) {
3462 printSummary(*Summary);
3467 if (!
VI.name().empty())
3468 Out <<
" ; guid = " <<
VI.getGUID();
3475 Out <<
"<empty name> ";
3477 if (isalpha(
static_cast<unsigned char>(
Name[0])) ||
Name[0] ==
'-' ||
3481 Out <<
'\\' << hexdigit(
Name[0] >> 4) << hexdigit(
Name[0] & 0x0F);
3482 for (
unsigned i = 1, e =
Name.size(); i != e; ++i) {
3483 unsigned char C =
Name[i];
3484 if (isalnum(
static_cast<unsigned char>(
C)) ||
C ==
'-' ||
C ==
'$' ||
3485 C ==
'.' ||
C ==
'_')
3488 Out <<
'\\' << hexdigit(
C >> 4) << hexdigit(
C & 0x0F);
3493void AssemblyWriter::printNamedMDNode(
const NamedMDNode *NMD) {
3504 assert(!isa<DIArgList>(Op) &&
3505 "DIArgLists should not appear in NamedMDNodes");
3506 if (
auto *Expr = dyn_cast<DIExpression>(Op)) {
3511 int Slot = Machine.getMetadataSlot(Op);
3532 Out <<
"dso_local ";
3547 case GlobalVariable::NotThreadLocal:
3549 case GlobalVariable::GeneralDynamicTLSModel:
3550 Out <<
"thread_local ";
3552 case GlobalVariable::LocalDynamicTLSModel:
3553 Out <<
"thread_local(localdynamic) ";
3555 case GlobalVariable::InitialExecTLSModel:
3556 Out <<
"thread_local(initialexec) ";
3558 case GlobalVariable::LocalExecTLSModel:
3559 Out <<
"thread_local(localexec) ";
3566 case GlobalVariable::UnnamedAddr::None:
3568 case GlobalVariable::UnnamedAddr::Local:
3569 return "local_unnamed_addr";
3570 case GlobalVariable::UnnamedAddr::Global:
3571 return "unnamed_addr";
3582 if (isa<GlobalVariable>(GO))
3596 Out <<
"; Materializable\n";
3598 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GV->
getParent());
3617 Out << (GV->
isConstant() ?
"constant " :
"global ");
3626 Out <<
", section \"";
3631 Out <<
", partition \"";
3640 Out <<
", no_sanitize_address";
3642 Out <<
", no_sanitize_hwaddress";
3644 Out <<
", sanitize_memtag";
3646 Out <<
", sanitize_address_dyninit";
3651 Out <<
", align " <<
A->value();
3655 printMetadataAttachments(MDs,
", ");
3658 if (
Attrs.hasAttributes())
3659 Out <<
" #" << Machine.getAttributeGroupSlot(Attrs);
3661 printInfoComment(*GV);
3664void AssemblyWriter::printAlias(
const GlobalAlias *GA) {
3666 Out <<
"; Materializable\n";
3668 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GA->
getParent());
3687 writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
3689 TypePrinter.print(GA->
getType(), Out);
3690 Out <<
" <<NULL ALIASEE>>";
3694 Out <<
", partition \"";
3699 printInfoComment(*GA);
3703void AssemblyWriter::printIFunc(
const GlobalIFunc *GI) {
3705 Out <<
"; Materializable\n";
3707 AsmWriterContext WriterCtx(&TypePrinter, &Machine, GI->
getParent());
3723 TypePrinter.print(GI->
getType(), Out);
3724 Out <<
" <<NULL RESOLVER>>";
3728 Out <<
", partition \"";
3733 printInfoComment(*GI);
3737void AssemblyWriter::printComdat(
const Comdat *
C) {
3741void AssemblyWriter::printTypeIdentities() {
3742 if (TypePrinter.empty())
3748 auto &NumberedTypes = TypePrinter.getNumberedTypes();
3749 for (
unsigned I = 0,
E = NumberedTypes.size();
I !=
E; ++
I) {
3750 Out <<
'%' <<
I <<
" = type ";
3754 TypePrinter.printStructBody(NumberedTypes[
I], Out);
3758 auto &NamedTypes = TypePrinter.getNamedTypes();
3765 TypePrinter.printStructBody(NamedType, Out);
3771void AssemblyWriter::printFunction(
const Function *
F) {
3772 if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(
F, Out);
3774 if (
F->isMaterializable())
3775 Out <<
"; Materializable\n";
3778 if (
Attrs.hasFnAttrs()) {
3780 std::string AttrStr;
3783 if (!Attr.isStringAttribute()) {
3784 if (!AttrStr.empty()) AttrStr +=
' ';
3785 AttrStr += Attr.getAsString();
3789 if (!AttrStr.empty())
3790 Out <<
"; Function Attrs: " << AttrStr <<
'\n';
3793 Machine.incorporateFunction(
F);
3795 if (
F->isDeclaration()) {
3798 F->getAllMetadata(MDs);
3799 printMetadataAttachments(MDs,
" ");
3816 if (
Attrs.hasRetAttrs())
3818 TypePrinter.print(
F->getReturnType(), Out);
3819 AsmWriterContext WriterCtx(&TypePrinter, &Machine,
F->getParent());
3825 if (
F->isDeclaration() && !IsForDebug) {
3827 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
3832 TypePrinter.print(FT->getParamType(
I), Out);
3837 writeAttributeSet(ArgAttrs);
3844 if (
Arg.getArgNo() != 0)
3846 printArgument(&
Arg,
Attrs.getParamAttrs(
Arg.getArgNo()));
3851 if (FT->isVarArg()) {
3852 if (FT->getNumParams()) Out <<
", ";
3863 if (
F->getAddressSpace() != 0 || !
Mod ||
3865 Out <<
" addrspace(" <<
F->getAddressSpace() <<
")";
3866 if (
Attrs.hasFnAttrs())
3867 Out <<
" #" << Machine.getAttributeGroupSlot(
Attrs.getFnAttrs());
3868 if (
F->hasSection()) {
3869 Out <<
" section \"";
3870 printEscapedString(
F->getSection(), Out);
3873 if (
F->hasPartition()) {
3874 Out <<
" partition \"";
3875 printEscapedString(
F->getPartition(), Out);
3880 Out <<
" align " <<
A->value();
3882 Out <<
" gc \"" <<
F->getGC() <<
'"';
3883 if (
F->hasPrefixData()) {
3885 writeOperand(
F->getPrefixData(),
true);
3887 if (
F->hasPrologueData()) {
3888 Out <<
" prologue ";
3889 writeOperand(
F->getPrologueData(),
true);
3891 if (
F->hasPersonalityFn()) {
3892 Out <<
" personality ";
3893 writeOperand(
F->getPersonalityFn(),
true);
3896 if (
F->isDeclaration()) {
3900 F->getAllMetadata(MDs);
3901 printMetadataAttachments(MDs,
" ");
3906 printBasicBlock(&BB);
3914 Machine.purgeFunction();
3921 TypePrinter.print(
Arg->getType(), Out);
3924 if (
Attrs.hasAttributes()) {
3926 writeAttributeSet(Attrs);
3930 if (
Arg->hasName()) {
3934 int Slot = Machine.getLocalSlot(
Arg);
3935 assert(Slot != -1 &&
"expect argument in function here");
3936 Out <<
" %" <<
Slot;
3941void AssemblyWriter::printBasicBlock(
const BasicBlock *BB) {
3947 }
else if (!IsEntryBlock) {
3949 int Slot = Machine.getLocalSlot(BB);
3956 if (!IsEntryBlock) {
3958 Out.PadToColumn(50);
3963 Out <<
" No predecessors!";
3966 writeOperand(*PI,
false);
3967 for (++PI; PI != PE; ++PI) {
3969 writeOperand(*PI,
false);
3976 if (AnnotationWriter) AnnotationWriter->emitBasicBlockStartAnnot(BB, Out);
3980 printInstructionLine(
I);
3983 if (AnnotationWriter) AnnotationWriter->emitBasicBlockEndAnnot(BB, Out);
3987void AssemblyWriter::printInstructionLine(
const Instruction &
I) {
3988 printInstruction(
I);
3994void AssemblyWriter::printGCRelocateComment(
const GCRelocateInst &Relocate) {
4004void AssemblyWriter::printInfoComment(
const Value &V) {
4005 if (
const auto *Relocate = dyn_cast<GCRelocateInst>(&V))
4006 printGCRelocateComment(*Relocate);
4008 if (AnnotationWriter)
4009 AnnotationWriter->printInfoComment(V, Out);
4015 if (Operand ==
nullptr) {
4016 Out <<
" <cannot get addrspace!>";
4020 bool PrintAddrSpace = CallAddrSpace != 0;
4021 if (!PrintAddrSpace) {
4027 PrintAddrSpace =
true;
4030 Out <<
" addrspace(" << CallAddrSpace <<
")";
4034void AssemblyWriter::printInstruction(
const Instruction &
I) {
4035 if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&
I, Out);
4044 }
else if (!
I.getType()->isVoidTy()) {
4046 int SlotNum = Machine.getLocalSlot(&
I);
4048 Out <<
"<badref> = ";
4050 Out <<
'%' << SlotNum <<
" = ";
4053 if (
const CallInst *CI = dyn_cast<CallInst>(&
I)) {
4054 if (CI->isMustTailCall())
4056 else if (CI->isTailCall())
4058 else if (CI->isNoTailCall())
4063 Out <<
I.getOpcodeName();
4066 if ((isa<LoadInst>(
I) && cast<LoadInst>(
I).isAtomic()) ||
4067 (isa<StoreInst>(
I) && cast<StoreInst>(
I).isAtomic()))
4070 if (isa<AtomicCmpXchgInst>(
I) && cast<AtomicCmpXchgInst>(
I).isWeak())
4074 if ((isa<LoadInst>(
I) && cast<LoadInst>(
I).isVolatile()) ||
4075 (isa<StoreInst>(
I) && cast<StoreInst>(
I).isVolatile()) ||
4076 (isa<AtomicCmpXchgInst>(
I) && cast<AtomicCmpXchgInst>(
I).isVolatile()) ||
4077 (isa<AtomicRMWInst>(
I) && cast<AtomicRMWInst>(
I).isVolatile()))
4084 if (
const CmpInst *CI = dyn_cast<CmpInst>(&
I))
4085 Out <<
' ' << CI->getPredicate();
4092 const Value *Operand =
I.getNumOperands() ?
I.getOperand(0) :
nullptr;
4095 if (isa<BranchInst>(
I) && cast<BranchInst>(
I).isConditional()) {
4098 writeOperand(BI.getCondition(),
true);
4100 writeOperand(BI.getSuccessor(0),
true);
4102 writeOperand(BI.getSuccessor(1),
true);
4104 }
else if (isa<SwitchInst>(
I)) {
4108 writeOperand(
SI.getCondition(),
true);
4110 writeOperand(
SI.getDefaultDest(),
true);
4112 for (
auto Case :
SI.cases()) {
4114 writeOperand(Case.getCaseValue(),
true);
4116 writeOperand(Case.getCaseSuccessor(),
true);
4119 }
else if (isa<IndirectBrInst>(
I)) {
4122 writeOperand(Operand,
true);
4125 for (
unsigned i = 1, e =
I.getNumOperands(); i != e; ++i) {
4128 writeOperand(
I.getOperand(i),
true);
4131 }
else if (
const PHINode *PN = dyn_cast<PHINode>(&
I)) {
4133 TypePrinter.print(
I.getType(), Out);
4136 for (
unsigned op = 0, Eop = PN->getNumIncomingValues();
op < Eop; ++
op) {
4137 if (
op) Out <<
", ";
4139 writeOperand(PN->getIncomingValue(
op),
false); Out <<
", ";
4140 writeOperand(PN->getIncomingBlock(
op),
false); Out <<
" ]";
4144 writeOperand(
I.getOperand(0),
true);
4145 for (
unsigned i : EVI->indices())
4149 writeOperand(
I.getOperand(0),
true); Out <<
", ";
4150 writeOperand(
I.getOperand(1),
true);
4151 for (
unsigned i : IVI->indices())
4153 }
else if (
const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&
I)) {
4155 TypePrinter.print(
I.getType(), Out);
4156 if (LPI->isCleanup() || LPI->getNumClauses() != 0)
4159 if (LPI->isCleanup())
4162 for (
unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) {
4163 if (i != 0 || LPI->isCleanup()) Out <<
"\n";
4164 if (LPI->isCatch(i))
4169 writeOperand(LPI->getClause(i),
true);
4171 }
else if (
const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(&
I)) {
4173 writeOperand(CatchSwitch->getParentPad(),
false);
4176 for (
const BasicBlock *PadBB : CatchSwitch->handlers()) {
4179 writeOperand(PadBB,
true);
4183 if (
const BasicBlock *UnwindDest = CatchSwitch->getUnwindDest())
4184 writeOperand(UnwindDest,
true);
4187 }
else if (
const auto *FPI = dyn_cast<FuncletPadInst>(&
I)) {
4189 writeOperand(FPI->getParentPad(),
false);
4191 for (
unsigned Op = 0, NumOps = FPI->arg_size(); Op < NumOps; ++Op) {
4194 writeOperand(FPI->getArgOperand(Op),
true);
4197 }
else if (isa<ReturnInst>(
I) && !Operand) {
4199 }
else if (
const auto *CRI = dyn_cast<CatchReturnInst>(&
I)) {
4201 writeOperand(CRI->getOperand(0),
false);
4204 writeOperand(CRI->getOperand(1),
true);
4205 }
else if (
const auto *CRI = dyn_cast<CleanupReturnInst>(&
I)) {
4207 writeOperand(CRI->getOperand(0),
false);
4210 if (CRI->hasUnwindDest())
4211 writeOperand(CRI->getOperand(1),
true);
4214 }
else if (
const CallInst *CI = dyn_cast<CallInst>(&
I)) {
4221 Operand = CI->getCalledOperand();
4236 TypePrinter.print(FTy->isVarArg() ? FTy :
RetTy, Out);
4238 writeOperand(Operand,
false);
4240 for (
unsigned op = 0, Eop = CI->arg_size();
op < Eop; ++
op) {
4248 if (CI->isMustTailCall() && CI->getParent() &&
4249 CI->getParent()->getParent() &&
4250 CI->getParent()->getParent()->isVarArg()) {
4251 if (CI->arg_size() > 0)
4258 Out <<
" #" << Machine.getAttributeGroupSlot(PAL.
getFnAttrs());
4260 writeOperandBundles(CI);
4261 }
else if (
const InvokeInst *II = dyn_cast<InvokeInst>(&
I)) {
4262 Operand = II->getCalledOperand();
4284 TypePrinter.print(FTy->isVarArg() ? FTy :
RetTy, Out);
4286 writeOperand(Operand,
false);
4288 for (
unsigned op = 0, Eop = II->arg_size();
op < Eop; ++
op) {
4296 Out <<
" #" << Machine.getAttributeGroupSlot(PAL.
getFnAttrs());
4298 writeOperandBundles(II);
4301 writeOperand(II->getNormalDest(),
true);
4303 writeOperand(II->getUnwindDest(),
true);
4304 }
else if (
const CallBrInst *CBI = dyn_cast<CallBrInst>(&
I)) {
4305 Operand = CBI->getCalledOperand();
4324 TypePrinter.print(FTy->isVarArg() ? FTy :
RetTy, Out);
4326 writeOperand(Operand,
false);
4328 for (
unsigned op = 0, Eop = CBI->arg_size();
op < Eop; ++
op) {
4336 Out <<
" #" << Machine.getAttributeGroupSlot(PAL.
getFnAttrs());
4338 writeOperandBundles(CBI);
4341 writeOperand(CBI->getDefaultDest(),
true);
4343 for (
unsigned i = 0, e = CBI->getNumIndirectDests(); i != e; ++i) {
4346 writeOperand(CBI->getIndirectDest(i),
true);
4349 }
else if (
const AllocaInst *AI = dyn_cast<AllocaInst>(&
I)) {
4351 if (AI->isUsedWithInAlloca())
4353 if (AI->isSwiftError())
4354 Out <<
"swifterror ";
4355 TypePrinter.print(AI->getAllocatedType(), Out);
4361 if (!AI->getArraySize() || AI->isArrayAllocation() ||
4362 !AI->getArraySize()->getType()->isIntegerTy(32)) {
4364 writeOperand(AI->getArraySize(),
true);
4367 Out <<
", align " <<
A->value();
4370 unsigned AddrSpace = AI->getAddressSpace();
4371 if (AddrSpace != 0) {
4372 Out <<
", addrspace(" << AddrSpace <<
')';
4374 }
else if (isa<CastInst>(
I)) {
4377 writeOperand(Operand,
true);
4380 TypePrinter.print(
I.getType(), Out);
4381 }
else if (isa<VAArgInst>(
I)) {
4384 writeOperand(Operand,
true);
4387 TypePrinter.print(
I.getType(), Out);
4388 }
else if (Operand) {
4389 if (
const auto *
GEP = dyn_cast<GetElementPtrInst>(&
I)) {
4391 TypePrinter.print(
GEP->getSourceElementType(), Out);
4393 }
else if (
const auto *LI = dyn_cast<LoadInst>(&
I)) {
4395 TypePrinter.print(LI->getType(), Out);
4402 bool PrintAllTypes =
false;
4407 if (isa<SelectInst>(
I) || isa<StoreInst>(
I) || isa<ShuffleVectorInst>(
I) ||
4408 isa<ReturnInst>(
I) || isa<AtomicCmpXchgInst>(
I) ||
4409 isa<AtomicRMWInst>(
I)) {
4410 PrintAllTypes =
true;
4412 for (
unsigned i = 1,
E =
I.getNumOperands(); i !=
E; ++i) {
4413 Operand =
I.getOperand(i);
4416 if (Operand && Operand->
getType() != TheType) {
4417 PrintAllTypes =
true;
4423 if (!PrintAllTypes) {
4425 TypePrinter.print(TheType, Out);
4429 for (
unsigned i = 0,
E =
I.getNumOperands(); i !=
E; ++i) {
4431 writeOperand(
I.getOperand(i), PrintAllTypes);
4436 if (
const LoadInst *LI = dyn_cast<LoadInst>(&
I)) {
4438 writeAtomic(LI->getContext(), LI->getOrdering(), LI->getSyncScopeID());
4440 Out <<
", align " <<
A->value();
4441 }
else if (
const StoreInst *SI = dyn_cast<StoreInst>(&
I)) {
4443 writeAtomic(
SI->getContext(),
SI->getOrdering(),
SI->getSyncScopeID());
4445 Out <<
", align " <<
A->value();
4447 writeAtomicCmpXchg(CXI->getContext(), CXI->getSuccessOrdering(),
4448 CXI->getFailureOrdering(), CXI->getSyncScopeID());
4449 Out <<
", align " << CXI->getAlign().value();
4450 }
else if (
const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&
I)) {
4451 writeAtomic(RMWI->getContext(), RMWI->getOrdering(),
4452 RMWI->getSyncScopeID());
4453 Out <<
", align " << RMWI->getAlign().value();
4454 }
else if (
const FenceInst *FI = dyn_cast<FenceInst>(&
I)) {
4455 writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID());
4462 I.getAllMetadata(InstMD);
4463 printMetadataAttachments(InstMD,
", ");
4466 printInfoComment(
I);
4469void AssemblyWriter::printMetadataAttachments(
4475 if (MDNames.empty())
4476 MDs[0].second->getContext().getMDKindNames(MDNames);
4478 auto WriterCtx = getContext();
4479 for (
const auto &
I : MDs) {
4480 unsigned Kind =
I.first;
4482 if (Kind < MDNames.size()) {
4486 Out <<
"!<unknown kind #" <<
Kind <<
">";
4492void AssemblyWriter::writeMDNode(
unsigned Slot,
const MDNode *
Node) {
4493 Out <<
'!' <<
Slot <<
" = ";
4494 printMDNodeBody(
Node);
4498void AssemblyWriter::writeAllMDNodes() {
4500 Nodes.
resize(Machine.mdn_size());
4502 Nodes[
I.second] = cast<MDNode>(
I.first);
4504 for (
unsigned i = 0, e = Nodes.
size(); i != e; ++i) {
4505 writeMDNode(i, Nodes[i]);
4509void AssemblyWriter::printMDNodeBody(
const MDNode *
Node) {
4510 auto WriterCtx = getContext();
4514void AssemblyWriter::writeAttribute(
const Attribute &Attr,
bool InAttrGroup) {
4523 TypePrinter.print(Ty, Out);
4528void AssemblyWriter::writeAttributeSet(
const AttributeSet &AttrSet,
4530 bool FirstAttr =
true;
4531 for (
const auto &Attr : AttrSet) {
4534 writeAttribute(Attr, InAttrGroup);
4539void AssemblyWriter::writeAllAttributeGroups() {
4540 std::vector<std::pair<AttributeSet, unsigned>> asVec;
4541 asVec.resize(Machine.as_size());
4544 asVec[
I.second] =
I;
4546 for (
const auto &
I : asVec)
4547 Out <<
"attributes #" <<
I.second <<
" = { "
4548 <<
I.first.getAsString(
true) <<
" }\n";
4551void AssemblyWriter::printUseListOrder(
const Value *V,
4552 const std::vector<unsigned> &Shuffle) {
4553 bool IsInFunction = Machine.getFunction();
4557 Out <<
"uselistorder";
4558 if (
const BasicBlock *BB = IsInFunction ?
nullptr : dyn_cast<BasicBlock>(V)) {
4560 writeOperand(BB->getParent(),
false);
4562 writeOperand(BB,
false);
4565 writeOperand(V,
true);
4569 assert(Shuffle.size() >= 2 &&
"Shuffle too small");
4571 for (
unsigned I = 1,
E = Shuffle.size();
I !=
E; ++
I)
4572 Out <<
", " << Shuffle[
I];
4576void AssemblyWriter::printUseLists(
const Function *
F) {
4577 auto It = UseListOrders.find(
F);
4578 if (It == UseListOrders.end())
4581 Out <<
"\n; uselistorder directives\n";
4582 for (
const auto &Pair : It->second)
4583 printUseListOrder(Pair.first, Pair.second);
4591 bool ShouldPreserveUseListOrder,
4592 bool IsForDebug)
const {
4595 AssemblyWriter W(
OS, SlotTable, this->
getParent(), AAW,
4597 ShouldPreserveUseListOrder);
4598 W.printFunction(
this);
4602 bool ShouldPreserveUseListOrder,
4603 bool IsForDebug)
const {
4606 AssemblyWriter W(
OS, SlotTable, this->
getModule(), AAW,
4608 ShouldPreserveUseListOrder);
4609 W.printBasicBlock(
this);
4613 bool ShouldPreserveUseListOrder,
bool IsForDebug)
const {
4616 AssemblyWriter W(
OS, SlotTable,
this, AAW, IsForDebug,
4617 ShouldPreserveUseListOrder);
4618 W.printModule(
this);
4624 AssemblyWriter W(
OS, SlotTable,
getParent(),
nullptr, IsForDebug);
4625 W.printNamedMDNode(
this);
4629 bool IsForDebug)
const {
4630 std::optional<SlotTracker> LocalST;
4636 SlotTable = &*LocalST;
4640 AssemblyWriter W(
OS, *SlotTable,
getParent(),
nullptr, IsForDebug);
4641 W.printNamedMDNode(
this);
4646 ROS <<
" = comdat ";
4653 ROS <<
"exactmatch";
4659 ROS <<
"nodeduplicate";
4671 TP.print(
const_cast<Type*
>(
this),
OS);
4677 if (
StructType *STy = dyn_cast<StructType>(
const_cast<Type*
>(
this)))
4680 TP.printStructBody(STy,
OS);
4685 if (
const auto *CI = dyn_cast<CallInst>(&
I))
4686 if (
Function *
F = CI->getCalledFunction())
4687 if (
F->isIntrinsic())
4688 for (
auto &Op :
I.operands())
4689 if (
auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
4690 if (isa<MDNode>(V->getMetadata()))
4696 bool ShouldInitializeAllMetadata =
false;
4697 if (
auto *
I = dyn_cast<Instruction>(
this))
4699 else if (isa<Function>(
this) || isa<MetadataAsValue>(
this))
4700 ShouldInitializeAllMetadata =
true;
4703 print(ROS, MST, IsForDebug);
4707 bool IsForDebug)
const {
4712 auto incorporateFunction = [&](
const Function *
F) {
4717 if (
const Instruction *
I = dyn_cast<Instruction>(
this)) {
4718 incorporateFunction(
I->getParent() ?
I->getParent()->getParent() :
nullptr);
4720 W.printInstruction(*
I);
4721 }
else if (
const BasicBlock *BB = dyn_cast<BasicBlock>(
this)) {
4722 incorporateFunction(BB->getParent());
4724 W.printBasicBlock(BB);
4725 }
else if (
const GlobalValue *GV = dyn_cast<GlobalValue>(
this)) {
4726 AssemblyWriter W(
OS, SlotTable, GV->
getParent(),
nullptr, IsForDebug);
4729 else if (
const Function *
F = dyn_cast<Function>(GV))
4731 else if (
const GlobalAlias *
A = dyn_cast<GlobalAlias>(GV))
4733 else if (
const GlobalIFunc *
I = dyn_cast<GlobalIFunc>(GV))
4737 }
else if (
const MetadataAsValue *V = dyn_cast<MetadataAsValue>(
this)) {
4739 }
else if (
const Constant *
C = dyn_cast<Constant>(
this)) {
4740 TypePrinting TypePrinter;
4741 TypePrinter.print(
C->getType(),
OS);
4743 AsmWriterContext WriterCtx(&TypePrinter, MST.
getMachine());
4745 }
else if (isa<InlineAsm>(
this) || isa<Argument>(
this)) {
4757 if (V.hasName() || isa<GlobalValue>(V) ||
4758 (!isa<Constant>(V) && !isa<MetadataAsValue>(V))) {
4759 AsmWriterContext WriterCtx(
nullptr, Machine, M);
4768 TypePrinting TypePrinter(MST.
getModule());
4770 TypePrinter.print(V.getType(), O);
4788 M, isa<MetadataAsValue>(
this));
4804 AsmWriterContext &WriterCtx) {
4808 auto *
N = dyn_cast<MDNode>(&MD);
4809 if (!
N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
4817struct MDTreeAsmWriterContext :
public AsmWriterContext {
4820 using EntryTy = std::pair<unsigned, std::string>;
4830 : AsmWriterContext(TP,
ST,
M),
Level(0
U), Visited({InitMD}), MainOS(
OS) {}
4832 void onWriteMetadataAsOperand(
const Metadata *MD)
override {
4833 if (!Visited.
insert(MD).second)
4842 unsigned InsertIdx = Buffer.
size() - 1;
4845 Buffer[InsertIdx].second = std::move(
SS.str());
4849 ~MDTreeAsmWriterContext() {
4850 for (
const auto &Entry : Buffer) {
4852 unsigned NumIndent = Entry.first * 2U;
4853 MainOS.
indent(NumIndent) << Entry.second;
4861 bool OnlyAsOperand,
bool PrintAsTree =
false) {
4864 TypePrinting TypePrinter(M);
4866 std::unique_ptr<AsmWriterContext> WriterCtx;
4867 if (PrintAsTree && !OnlyAsOperand)
4868 WriterCtx = std::make_unique<MDTreeAsmWriterContext>(
4872 std::make_unique<AsmWriterContext>(&TypePrinter, MST.
getMachine(), M);
4876 auto *
N = dyn_cast<MDNode>(&MD);
4877 if (OnlyAsOperand || !
N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
4901 const Module *M,
bool )
const {