summaryrefslogtreecommitdiff
path: root/llvm/lib/IR/AsmWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/AsmWriter.cpp')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp644
1 files changed, 366 insertions, 278 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 69e2d85e58fe..7734c0a8de58 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -44,7 +45,6 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
@@ -72,6 +72,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
@@ -554,16 +555,13 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
FunctionType *FTy = cast<FunctionType>(Ty);
print(FTy->getReturnType(), OS);
OS << " (";
- for (FunctionType::param_iterator I = FTy->param_begin(),
- E = FTy->param_end(); I != E; ++I) {
- if (I != FTy->param_begin())
- OS << ", ";
- print(*I, OS);
- }
- if (FTy->isVarArg()) {
- if (FTy->getNumParams()) OS << ", ";
- OS << "...";
+ ListSeparator LS;
+ for (Type *Ty : FTy->params()) {
+ OS << LS;
+ print(Ty, OS);
}
+ if (FTy->isVarArg())
+ OS << LS << "...";
OS << ')';
return;
}
@@ -633,12 +631,11 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
if (STy->getNumElements() == 0) {
OS << "{}";
} else {
- StructType::element_iterator I = STy->element_begin();
OS << "{ ";
- print(*I++, OS);
- for (StructType::element_iterator E = STy->element_end(); I != E; ++I) {
- OS << ", ";
- print(*I, OS);
+ ListSeparator LS;
+ for (Type *Ty : STy->elements()) {
+ OS << LS;
+ print(Ty, OS);
}
OS << " }";
@@ -988,7 +985,7 @@ void SlotTracker::processModule() {
// Add all the function attributes to the table.
// FIXME: Add attributes of other objects?
- AttributeSet FnAttrs = F.getAttributes().getFnAttributes();
+ AttributeSet FnAttrs = F.getAttributes().getFnAttrs();
if (FnAttrs.hasAttributes())
CreateAttributeSetSlot(FnAttrs);
}
@@ -1029,7 +1026,7 @@ void SlotTracker::processFunction() {
// target may not be linked into the optimizer.
if (const auto *Call = dyn_cast<CallBase>(&I)) {
// Add all the call attributes to the table.
- AttributeSet Attrs = Call->getAttributes().getFnAttributes();
+ AttributeSet Attrs = Call->getAttributes().getFnAttrs();
if (Attrs.hasAttributes())
CreateAttributeSetSlot(Attrs);
}
@@ -1277,18 +1274,38 @@ void SlotTracker::CreateTypeIdSlot(StringRef Id) {
TypeIdMap[Id] = TypeIdNext++;
}
+namespace {
+/// Common instances used by most of the printer functions.
+struct AsmWriterContext {
+ TypePrinting *TypePrinter = nullptr;
+ SlotTracker *Machine = nullptr;
+ const Module *Context = nullptr;
+
+ AsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M = nullptr)
+ : TypePrinter(TP), Machine(ST), Context(M) {}
+
+ static AsmWriterContext &getEmpty() {
+ static AsmWriterContext EmptyCtx(nullptr, nullptr);
+ return EmptyCtx;
+ }
+
+ /// A callback that will be triggered when the underlying printer
+ /// prints a Metadata as operand.
+ virtual void onWriteMetadataAsOperand(const Metadata *) {}
+
+ virtual ~AsmWriterContext() {}
+};
+} // end anonymous namespace
+
//===----------------------------------------------------------------------===//
// AsmWriter Implementation
//===----------------------------------------------------------------------===//
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context);
+ AsmWriterContext &WriterCtx);
static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context,
+ AsmWriterContext &WriterCtx,
bool FromValue = false);
static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
@@ -1331,9 +1348,7 @@ static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
}
static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
- TypePrinting &TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
if (CI->getType()->isIntegerTy(1)) {
Out << (CI->getZExtValue() ? "true" : "false");
@@ -1442,36 +1457,30 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
Out << "blockaddress(";
- WriteAsOperandInternal(Out, BA->getFunction(), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, BA->getFunction(), WriterCtx);
Out << ", ";
- WriteAsOperandInternal(Out, BA->getBasicBlock(), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, BA->getBasicBlock(), WriterCtx);
Out << ")";
return;
}
if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV)) {
Out << "dso_local_equivalent ";
- WriteAsOperandInternal(Out, Equiv->getGlobalValue(), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, Equiv->getGlobalValue(), WriterCtx);
return;
}
if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
Type *ETy = CA->getType()->getElementType();
Out << '[';
- TypePrinter.print(ETy, Out);
+ WriterCtx.TypePrinter->print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CA->getOperand(0),
- &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, CA->getOperand(0), WriterCtx);
for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
Out << ", ";
- TypePrinter.print(ETy, Out);
+ WriterCtx.TypePrinter->print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, CA->getOperand(i), WriterCtx);
}
Out << ']';
return;
@@ -1489,17 +1498,14 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
Type *ETy = CA->getType()->getElementType();
Out << '[';
- TypePrinter.print(ETy, Out);
+ WriterCtx.TypePrinter->print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CA->getElementAsConstant(0),
- &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, CA->getElementAsConstant(0), WriterCtx);
for (unsigned i = 1, e = CA->getNumElements(); i != e; ++i) {
Out << ", ";
- TypePrinter.print(ETy, Out);
+ WriterCtx.TypePrinter->print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CA->getElementAsConstant(i), &TypePrinter,
- Machine, Context);
+ WriteAsOperandInternal(Out, CA->getElementAsConstant(i), WriterCtx);
}
Out << ']';
return;
@@ -1512,19 +1518,17 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
unsigned N = CS->getNumOperands();
if (N) {
Out << ' ';
- TypePrinter.print(CS->getOperand(0)->getType(), Out);
+ WriterCtx.TypePrinter->print(CS->getOperand(0)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, CS->getOperand(0), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, CS->getOperand(0), WriterCtx);
for (unsigned i = 1; i < N; i++) {
Out << ", ";
- TypePrinter.print(CS->getOperand(i)->getType(), Out);
+ WriterCtx.TypePrinter->print(CS->getOperand(i)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, CS->getOperand(i), &TypePrinter, Machine,
- Context);
+ WriteAsOperandInternal(Out, CS->getOperand(i), WriterCtx);
}
Out << ' ';
}
@@ -1539,16 +1543,14 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
auto *CVVTy = cast<FixedVectorType>(CV->getType());
Type *ETy = CVVTy->getElementType();
Out << '<';
- TypePrinter.print(ETy, Out);
+ WriterCtx.TypePrinter->print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter,
- Machine, Context);
+ WriteAsOperandInternal(Out, CV->getAggregateElement(0U), WriterCtx);
for (unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) {
Out << ", ";
- TypePrinter.print(ETy, Out);
+ WriterCtx.TypePrinter->print(ETy, Out);
Out << ' ';
- WriteAsOperandInternal(Out, CV->getAggregateElement(i), &TypePrinter,
- Machine, Context);
+ WriteAsOperandInternal(Out, CV->getAggregateElement(i), WriterCtx);
}
Out << '>';
return;
@@ -1584,7 +1586,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
Optional<unsigned> InRangeOp;
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
- TypePrinter.print(GEP->getSourceElementType(), Out);
+ WriterCtx.TypePrinter->print(GEP->getSourceElementType(), Out);
Out << ", ";
InRangeOp = GEP->getInRangeIndex();
if (InRangeOp)
@@ -1594,9 +1596,9 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
if (InRangeOp && unsigned(OI - CE->op_begin()) == *InRangeOp)
Out << "inrange ";
- TypePrinter.print((*OI)->getType(), Out);
+ WriterCtx.TypePrinter->print((*OI)->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, *OI, &TypePrinter, Machine, Context);
+ WriteAsOperandInternal(Out, *OI, WriterCtx);
if (OI+1 != CE->op_end())
Out << ", ";
}
@@ -1609,7 +1611,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
if (CE->isCast()) {
Out << " to ";
- TypePrinter.print(CE->getType(), Out);
+ WriterCtx.TypePrinter->print(CE->getType(), Out);
}
if (CE->getOpcode() == Instruction::ShuffleVector)
@@ -1623,8 +1625,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
}
static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!{";
for (unsigned mi = 0, me = Node->getNumOperands(); mi != me; ++mi) {
const Metadata *MD = Node->getOperand(mi);
@@ -1632,11 +1633,12 @@ static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
Out << "null";
else if (auto *MDV = dyn_cast<ValueAsMetadata>(MD)) {
Value *V = MDV->getValue();
- TypePrinter->print(V->getType(), Out);
+ WriterCtx.TypePrinter->print(V->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, V, TypePrinter, Machine, Context);
+ WriteAsOperandInternal(Out, V, WriterCtx);
} else {
- WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
+ WriteAsOperandInternal(Out, MD, WriterCtx);
+ WriterCtx.onWriteMetadataAsOperand(MD);
}
if (mi + 1 != me)
Out << ", ";
@@ -1665,15 +1667,12 @@ raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
struct MDFieldPrinter {
raw_ostream &Out;
FieldSeparator FS;
- TypePrinting *TypePrinter = nullptr;
- SlotTracker *Machine = nullptr;
- const Module *Context = nullptr;
+ AsmWriterContext &WriterCtx;
- explicit MDFieldPrinter(raw_ostream &Out) : Out(Out) {}
- MDFieldPrinter(raw_ostream &Out, TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context)
- : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
- }
+ explicit MDFieldPrinter(raw_ostream &Out)
+ : Out(Out), WriterCtx(AsmWriterContext::getEmpty()) {}
+ MDFieldPrinter(raw_ostream &Out, AsmWriterContext &Ctx)
+ : Out(Out), WriterCtx(Ctx) {}
void printTag(const DINode *N);
void printMacinfoType(const DIMacroNode *N);
@@ -1734,14 +1733,13 @@ void MDFieldPrinter::printString(StringRef Name, StringRef Value,
}
static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
if (!MD) {
Out << "null";
return;
}
- WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
+ WriteAsOperandInternal(Out, MD, WriterCtx);
+ WriterCtx.onWriteMetadataAsOperand(MD);
}
void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
@@ -1750,7 +1748,7 @@ void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
return;
Out << FS << Name << ": ";
- writeMetadataAsOperand(Out, MD, TypePrinter, Machine, Context);
+ writeMetadataAsOperand(Out, MD, WriterCtx);
}
template <class IntTy>
@@ -1763,7 +1761,7 @@ void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int,
bool IsUnsigned, bool ShouldSkipZero) {
- if (ShouldSkipZero && Int.isNullValue())
+ if (ShouldSkipZero && Int.isZero())
return;
Out << FS << Name << ": ";
@@ -1847,10 +1845,9 @@ void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
}
static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!GenericDINode(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printTag(N);
Printer.printString("header", N->getHeader());
if (N->getNumDwarfOperands()) {
@@ -1858,7 +1855,7 @@ static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
FieldSeparator IFS;
for (auto &I : N->dwarf_operands()) {
Out << IFS;
- writeMetadataAsOperand(Out, I, TypePrinter, Machine, Context);
+ writeMetadataAsOperand(Out, I, WriterCtx);
}
Out << "}";
}
@@ -1866,10 +1863,9 @@ static void writeGenericDINode(raw_ostream &Out, const GenericDINode *N,
}
static void writeDILocation(raw_ostream &Out, const DILocation *DL,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DILocation(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
// Always output the line, since 0 is a relevant and important value for it.
Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
Printer.printInt("column", DL->getColumn());
@@ -1881,10 +1877,9 @@ static void writeDILocation(raw_ostream &Out, const DILocation *DL,
}
static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DISubrange(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
auto *Count = N->getRawCountNode();
if (auto *CE = dyn_cast_or_null<ConstantAsMetadata>(Count)) {
@@ -1923,18 +1918,15 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N,
}
static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIGenericSubrange(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
auto IsConstant = [&](Metadata *Bound) -> bool {
if (auto *BE = dyn_cast_or_null<DIExpression>(Bound)) {
- return BE->isConstant()
- ? DIExpression::SignedOrUnsignedConstant::SignedConstant ==
- *BE->isConstant()
- : false;
+ return BE->isConstant() &&
+ DIExpression::SignedOrUnsignedConstant::SignedConstant ==
+ *BE->isConstant();
}
return false;
};
@@ -1977,7 +1969,7 @@ static void writeDIGenericSubrange(raw_ostream &Out, const DIGenericSubrange *N,
}
static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
- TypePrinting *, SlotTracker *, const Module *) {
+ AsmWriterContext &) {
Out << "!DIEnumerator(";
MDFieldPrinter Printer(Out);
Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
@@ -1989,7 +1981,7 @@ static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
}
static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
- TypePrinting *, SlotTracker *, const Module *) {
+ AsmWriterContext &) {
Out << "!DIBasicType(";
MDFieldPrinter Printer(Out);
if (N->getTag() != dwarf::DW_TAG_base_type)
@@ -2004,10 +1996,9 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N,
}
static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIStringType(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
if (N->getTag() != dwarf::DW_TAG_string_type)
Printer.printTag(N);
Printer.printString("name", N->getName());
@@ -2021,10 +2012,9 @@ static void writeDIStringType(raw_ostream &Out, const DIStringType *N,
}
static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIDerivedType(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printTag(N);
Printer.printString("name", N->getName());
Printer.printMetadata("scope", N->getRawScope());
@@ -2040,14 +2030,14 @@ static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace,
/* ShouldSkipZero */ false);
+ Printer.printMetadata("annotations", N->getRawAnnotations());
Out << ")";
}
static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DICompositeType(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printTag(N);
Printer.printString("name", N->getName());
Printer.printMetadata("scope", N->getRawScope());
@@ -2073,14 +2063,14 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
/* ShouldSkipZero */ false);
else
Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
+ Printer.printMetadata("annotations", N->getRawAnnotations());
Out << ")";
}
static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DISubroutineType(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printDIFlags("flags", N->getFlags());
Printer.printDwarfEnum("cc", N->getCC(), dwarf::ConventionString);
Printer.printMetadata("types", N->getRawTypeArray(),
@@ -2088,8 +2078,7 @@ static void writeDISubroutineType(raw_ostream &Out, const DISubroutineType *N,
Out << ")";
}
-static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *,
- SlotTracker *, const Module *) {
+static void writeDIFile(raw_ostream &Out, const DIFile *N, AsmWriterContext &) {
Out << "!DIFile(";
MDFieldPrinter Printer(Out);
Printer.printString("filename", N->getFilename(),
@@ -2105,10 +2094,9 @@ static void writeDIFile(raw_ostream &Out, const DIFile *N, TypePrinting *,
}
static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DICompileUnit(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printDwarfEnum("language", N->getSourceLanguage(),
dwarf::LanguageString, /* ShouldSkipZero */ false);
Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
@@ -2136,10 +2124,9 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N,
}
static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DISubprogram(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printString("name", N->getName());
Printer.printString("linkageName", N->getLinkageName());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
@@ -2159,14 +2146,14 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
Printer.printMetadata("declaration", N->getRawDeclaration());
Printer.printMetadata("retainedNodes", N->getRawRetainedNodes());
Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
+ Printer.printMetadata("annotations", N->getRawAnnotations());
Out << ")";
}
static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DILexicalBlock(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
@@ -2176,11 +2163,9 @@ static void writeDILexicalBlock(raw_ostream &Out, const DILexicalBlock *N,
static void writeDILexicalBlockFile(raw_ostream &Out,
const DILexicalBlockFile *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DILexicalBlockFile(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("discriminator", N->getDiscriminator(),
@@ -2189,10 +2174,9 @@ static void writeDILexicalBlockFile(raw_ostream &Out,
}
static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DINamespace(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printString("name", N->getName());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printBool("exportSymbols", N->getExportSymbols(), false);
@@ -2200,10 +2184,9 @@ static void writeDINamespace(raw_ostream &Out, const DINamespace *N,
}
static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DICommonBlock(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMetadata("scope", N->getRawScope(), false);
Printer.printMetadata("declaration", N->getRawDecl(), false);
Printer.printString("name", N->getName());
@@ -2213,10 +2196,9 @@ static void writeDICommonBlock(raw_ostream &Out, const DICommonBlock *N,
}
static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIMacro(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMacinfoType(N);
Printer.printInt("line", N->getLine());
Printer.printString("name", N->getName());
@@ -2225,10 +2207,9 @@ static void writeDIMacro(raw_ostream &Out, const DIMacro *N,
}
static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIMacroFile(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printInt("line", N->getLine());
Printer.printMetadata("file", N->getRawFile(), /* ShouldSkipNull */ false);
Printer.printMetadata("nodes", N->getRawElements());
@@ -2236,10 +2217,9 @@ static void writeDIMacroFile(raw_ostream &Out, const DIMacroFile *N,
}
static void writeDIModule(raw_ostream &Out, const DIModule *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIModule(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printString("name", N->getName());
Printer.printString("configMacros", N->getConfigurationMacros());
@@ -2251,14 +2231,11 @@ static void writeDIModule(raw_ostream &Out, const DIModule *N,
Out << ")";
}
-
static void writeDITemplateTypeParameter(raw_ostream &Out,
const DITemplateTypeParameter *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DITemplateTypeParameter(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printString("name", N->getName());
Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
@@ -2267,11 +2244,9 @@ static void writeDITemplateTypeParameter(raw_ostream &Out,
static void writeDITemplateValueParameter(raw_ostream &Out,
const DITemplateValueParameter *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DITemplateValueParameter(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
Printer.printTag(N);
Printer.printString("name", N->getName());
@@ -2282,10 +2257,9 @@ static void writeDITemplateValueParameter(raw_ostream &Out,
}
static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIGlobalVariable(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printString("name", N->getName());
Printer.printString("linkageName", N->getLinkageName());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
@@ -2297,14 +2271,14 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N,
Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printInt("align", N->getAlignInBits());
+ Printer.printMetadata("annotations", N->getRawAnnotations());
Out << ")";
}
static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DILocalVariable(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printString("name", N->getName());
Printer.printInt("arg", N->getArg());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
@@ -2313,14 +2287,14 @@ static void writeDILocalVariable(raw_ostream &Out, const DILocalVariable *N,
Printer.printMetadata("type", N->getRawType());
Printer.printDIFlags("flags", N->getFlags());
Printer.printInt("align", N->getAlignInBits());
+ Printer.printMetadata("annotations", N->getRawAnnotations());
Out << ")";
}
static void writeDILabel(raw_ostream &Out, const DILabel *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DILabel(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printString("name", N->getName());
Printer.printMetadata("file", N->getRawFile());
@@ -2329,8 +2303,7 @@ static void writeDILabel(raw_ostream &Out, const DILabel *N,
}
static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIExpression(";
FieldSeparator FS;
if (N->isValid()) {
@@ -2355,37 +2328,34 @@ static void writeDIExpression(raw_ostream &Out, const DIExpression *N,
}
static void writeDIArgList(raw_ostream &Out, const DIArgList *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context, bool FromValue = false) {
+ AsmWriterContext &WriterCtx,
+ bool FromValue = false) {
assert(FromValue &&
"Unexpected DIArgList metadata outside of value argument");
Out << "!DIArgList(";
FieldSeparator FS;
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
for (Metadata *Arg : N->getArgs()) {
Out << FS;
- WriteAsOperandInternal(Out, Arg, TypePrinter, Machine, Context, true);
+ WriteAsOperandInternal(Out, Arg, WriterCtx, true);
}
Out << ")";
}
static void writeDIGlobalVariableExpression(raw_ostream &Out,
const DIGlobalVariableExpression *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIGlobalVariableExpression(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printMetadata("var", N->getVariable());
Printer.printMetadata("expr", N->getExpression());
Out << ")";
}
static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
- TypePrinting *TypePrinter, SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIObjCProperty(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printString("name", N->getName());
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
@@ -2397,23 +2367,21 @@ static void writeDIObjCProperty(raw_ostream &Out, const DIObjCProperty *N,
}
static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context) {
+ AsmWriterContext &WriterCtx) {
Out << "!DIImportedEntity(";
- MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, WriterCtx);
Printer.printTag(N);
Printer.printString("name", N->getName());
Printer.printMetadata("scope", N->getRawScope(), /* ShouldSkipNull */ false);
Printer.printMetadata("entity", N->getRawEntity());
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
+ Printer.printMetadata("elements", N->getRawElements());
Out << ")";
}
static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &Ctx) {
if (Node->isDistinct())
Out << "distinct ";
else if (Node->isTemporary())
@@ -2424,7 +2392,7 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
llvm_unreachable("Expected uniquable MDNode");
#define HANDLE_MDNODE_LEAF(CLASS) \
case Metadata::CLASS##Kind: \
- write##CLASS(Out, cast<CLASS>(Node), TypePrinter, Machine, Context); \
+ write##CLASS(Out, cast<CLASS>(Node), Ctx); \
break;
#include "llvm/IR/Metadata.def"
}
@@ -2433,9 +2401,7 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
// Full implementation of printing a Value as an operand with support for
// TypePrinting, etc.
static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
- TypePrinting *TypePrinter,
- SlotTracker *Machine,
- const Module *Context) {
+ AsmWriterContext &WriterCtx) {
if (V->hasName()) {
PrintLLVMName(Out, V);
return;
@@ -2443,8 +2409,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
const Constant *CV = dyn_cast<Constant>(V);
if (CV && !isa<GlobalValue>(CV)) {
- assert(TypePrinter && "Constants require TypePrinting!");
- WriteConstantInternal(Out, CV, *TypePrinter, Machine, Context);
+ assert(WriterCtx.TypePrinter && "Constants require TypePrinting!");
+ WriteConstantInternal(Out, CV, WriterCtx);
return;
}
@@ -2468,13 +2434,14 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
}
if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
- WriteAsOperandInternal(Out, MD->getMetadata(), TypePrinter, Machine,
- Context, /* FromValue */ true);
+ WriteAsOperandInternal(Out, MD->getMetadata(), WriterCtx,
+ /* FromValue */ true);
return;
}
char Prefix = '%';
int Slot;
+ auto *Machine = WriterCtx.Machine;
// If we have a SlotTracker, use it.
if (Machine) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
@@ -2513,30 +2480,30 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
}
static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
- TypePrinting *TypePrinter,
- SlotTracker *Machine, const Module *Context,
+ AsmWriterContext &WriterCtx,
bool FromValue) {
// Write DIExpressions and DIArgLists inline when used as a value. Improves
// readability of debug info intrinsics.
if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
- writeDIExpression(Out, Expr, TypePrinter, Machine, Context);
+ writeDIExpression(Out, Expr, WriterCtx);
return;
}
if (const DIArgList *ArgList = dyn_cast<DIArgList>(MD)) {
- writeDIArgList(Out, ArgList, TypePrinter, Machine, Context, FromValue);
+ writeDIArgList(Out, ArgList, WriterCtx, FromValue);
return;
}
if (const MDNode *N = dyn_cast<MDNode>(MD)) {
std::unique_ptr<SlotTracker> MachineStorage;
- if (!Machine) {
- MachineStorage = std::make_unique<SlotTracker>(Context);
- Machine = MachineStorage.get();
+ SaveAndRestore<SlotTracker *> SARMachine(WriterCtx.Machine);
+ if (!WriterCtx.Machine) {
+ MachineStorage = std::make_unique<SlotTracker>(WriterCtx.Context);
+ WriterCtx.Machine = MachineStorage.get();
}
- int Slot = Machine->getMetadataSlot(N);
+ int Slot = WriterCtx.Machine->getMetadataSlot(N);
if (Slot == -1) {
if (const DILocation *Loc = dyn_cast<DILocation>(N)) {
- writeDILocation(Out, Loc, TypePrinter, Machine, Context);
+ writeDILocation(Out, Loc, WriterCtx);
return;
}
// Give the pointer value instead of "badref", since this comes up all
@@ -2555,13 +2522,13 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
}
auto *V = cast<ValueAsMetadata>(MD);
- assert(TypePrinter && "TypePrinter required for metadata values");
+ assert(WriterCtx.TypePrinter && "TypePrinter required for metadata values");
assert((FromValue || !isa<LocalAsMetadata>(V)) &&
"Unexpected function-local metadata outside of value argument");
- TypePrinter->print(V->getValue()->getType(), Out);
+ WriterCtx.TypePrinter->print(V->getValue()->getType(), Out);
Out << ' ';
- WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
+ WriteAsOperandInternal(Out, V->getValue(), WriterCtx);
}
namespace {
@@ -2592,6 +2559,10 @@ public:
AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
const ModuleSummaryIndex *Index, bool IsForDebug);
+ AsmWriterContext getContext() {
+ return AsmWriterContext(&TypePrinter, &Machine, TheModule);
+ }
+
void printMDNodeBody(const MDNode *MD);
void printNamedMDNode(const NamedMDNode *NMD);
@@ -2618,7 +2589,8 @@ public:
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
- void printIndirectSymbol(const GlobalIndirectSymbol *GIS);
+ void printAlias(const GlobalAlias *GA);
+ void printIFunc(const GlobalIFunc *GI);
void printComdat(const Comdat *C);
void printFunction(const Function *F);
void printArgument(const Argument *FA, AttributeSet Attrs);
@@ -2693,7 +2665,8 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
TypePrinter.print(Operand->getType(), Out);
Out << ' ';
}
- WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
+ auto WriterCtx = getContext();
+ WriteAsOperandInternal(Out, Operand, WriterCtx);
}
void AssemblyWriter::writeSyncScope(const LLVMContext &Context,
@@ -2752,7 +2725,8 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
}
Out << ' ';
// Print the operand
- WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
+ auto WriterCtx = getContext();
+ WriteAsOperandInternal(Out, Operand, WriterCtx);
}
void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
@@ -2776,6 +2750,7 @@ void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
Out << '(';
bool FirstInput = true;
+ auto WriterCtx = getContext();
for (const auto &Input : BU.Inputs) {
if (!FirstInput)
Out << ", ";
@@ -2783,7 +2758,7 @@ void AssemblyWriter::writeOperandBundles(const CallBase *Call) {
TypePrinter.print(Input->getType(), Out);
Out << " ";
- WriteAsOperandInternal(Out, Input, &TypePrinter, &Machine, TheModule);
+ WriteAsOperandInternal(Out, Input, WriterCtx);
}
Out << ')';
@@ -2853,12 +2828,12 @@ void AssemblyWriter::printModule(const Module *M) {
// Output all aliases.
if (!M->alias_empty()) Out << "\n";
for (const GlobalAlias &GA : M->aliases())
- printIndirectSymbol(&GA);
+ printAlias(&GA);
// Output all ifuncs.
if (!M->ifunc_empty()) Out << "\n";
for (const GlobalIFunc &GI : M->ifuncs())
- printIndirectSymbol(&GI);
+ printIFunc(&GI);
// Output all of the functions.
for (const Function &F : *M) {
@@ -3198,19 +3173,9 @@ static const char *getVisibilityName(GlobalValue::VisibilityTypes Vis) {
void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) {
Out << ", insts: " << FS->instCount();
+ if (FS->fflags().anyFlagSet())
+ Out << ", " << FS->fflags();
- FunctionSummary::FFlags FFlags = FS->fflags();
- if (FFlags.ReadNone | FFlags.ReadOnly | FFlags.NoRecurse |
- FFlags.ReturnDoesNotAlias | FFlags.NoInline | FFlags.AlwaysInline) {
- Out << ", funcFlags: (";
- Out << "readNone: " << FFlags.ReadNone;
- Out << ", readOnly: " << FFlags.ReadOnly;
- Out << ", noRecurse: " << FFlags.NoRecurse;
- Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias;
- Out << ", noInline: " << FFlags.NoInline;
- Out << ", alwaysInline: " << FFlags.AlwaysInline;
- Out << ")";
- }
if (!FS->calls().empty()) {
Out << ", calls: (";
FieldSeparator IFS;
@@ -3453,7 +3418,7 @@ void AssemblyWriter::printNamedMDNode(const NamedMDNode *NMD) {
assert(!isa<DIArgList>(Op) &&
"DIArgLists should not appear in NamedMDNodes");
if (auto *Expr = dyn_cast<DIExpression>(Op)) {
- writeDIExpression(Out, Expr, nullptr, nullptr, nullptr);
+ writeDIExpression(Out, Expr, AsmWriterContext::getEmpty());
continue;
}
@@ -3544,7 +3509,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
if (GV->isMaterializable())
Out << "; Materializable\n";
- WriteAsOperandInternal(Out, GV, &TypePrinter, &Machine, GV->getParent());
+ AsmWriterContext WriterCtx(&TypePrinter, &Machine, GV->getParent());
+ WriteAsOperandInternal(Out, GV, WriterCtx);
Out << " = ";
if (!GV->hasInitializer() && GV->hasExternalLinkage())
@@ -3596,49 +3562,76 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
printInfoComment(*GV);
}
-void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
- if (GIS->isMaterializable())
+void AssemblyWriter::printAlias(const GlobalAlias *GA) {
+ if (GA->isMaterializable())
Out << "; Materializable\n";
- WriteAsOperandInternal(Out, GIS, &TypePrinter, &Machine, GIS->getParent());
+ AsmWriterContext WriterCtx(&TypePrinter, &Machine, GA->getParent());
+ WriteAsOperandInternal(Out, GA, WriterCtx);
Out << " = ";
- Out << getLinkageNameWithSpace(GIS->getLinkage());
- PrintDSOLocation(*GIS, Out);
- PrintVisibility(GIS->getVisibility(), Out);
- PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
- PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
- StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
+ Out << getLinkageNameWithSpace(GA->getLinkage());
+ PrintDSOLocation(*GA, Out);
+ PrintVisibility(GA->getVisibility(), Out);
+ PrintDLLStorageClass(GA->getDLLStorageClass(), Out);
+ PrintThreadLocalModel(GA->getThreadLocalMode(), Out);
+ StringRef UA = getUnnamedAddrEncoding(GA->getUnnamedAddr());
if (!UA.empty())
Out << UA << ' ';
- if (isa<GlobalAlias>(GIS))
- Out << "alias ";
- else if (isa<GlobalIFunc>(GIS))
- Out << "ifunc ";
- else
- llvm_unreachable("Not an alias or ifunc!");
-
- TypePrinter.print(GIS->getValueType(), Out);
+ Out << "alias ";
+ TypePrinter.print(GA->getValueType(), Out);
Out << ", ";
- const Constant *IS = GIS->getIndirectSymbol();
-
- if (!IS) {
- TypePrinter.print(GIS->getType(), Out);
+ if (const Constant *Aliasee = GA->getAliasee()) {
+ writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
+ } else {
+ TypePrinter.print(GA->getType(), Out);
Out << " <<NULL ALIASEE>>";
+ }
+
+ if (GA->hasPartition()) {
+ Out << ", partition \"";
+ printEscapedString(GA->getPartition(), Out);
+ Out << '"';
+ }
+
+ printInfoComment(*GA);
+ Out << '\n';
+}
+
+void AssemblyWriter::printIFunc(const GlobalIFunc *GI) {
+ if (GI->isMaterializable())
+ Out << "; Materializable\n";
+
+ AsmWriterContext WriterCtx(&TypePrinter, &Machine, GI->getParent());
+ WriteAsOperandInternal(Out, GI, WriterCtx);
+ Out << " = ";
+
+ Out << getLinkageNameWithSpace(GI->getLinkage());
+ PrintDSOLocation(*GI, Out);
+ PrintVisibility(GI->getVisibility(), Out);
+
+ Out << "ifunc ";
+
+ TypePrinter.print(GI->getValueType(), Out);
+ Out << ", ";
+
+ if (const Constant *Resolver = GI->getResolver()) {
+ writeOperand(Resolver, !isa<ConstantExpr>(Resolver));
} else {
- writeOperand(IS, !isa<ConstantExpr>(IS));
+ TypePrinter.print(GI->getType(), Out);
+ Out << " <<NULL RESOLVER>>";
}
- if (GIS->hasPartition()) {
+ if (GI->hasPartition()) {
Out << ", partition \"";
- printEscapedString(GIS->getPartition(), Out);
+ printEscapedString(GI->getPartition(), Out);
Out << '"';
}
- printInfoComment(*GIS);
+ printInfoComment(*GI);
Out << '\n';
}
@@ -3683,8 +3676,8 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << "; Materializable\n";
const AttributeList &Attrs = F->getAttributes();
- if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
- AttributeSet AS = Attrs.getFnAttributes();
+ if (Attrs.hasFnAttrs()) {
+ AttributeSet AS = Attrs.getFnAttrs();
std::string AttrStr;
for (const Attribute &Attr : AS) {
@@ -3721,11 +3714,12 @@ void AssemblyWriter::printFunction(const Function *F) {
}
FunctionType *FT = F->getFunctionType();
- if (Attrs.hasAttributes(AttributeList::ReturnIndex))
+ if (Attrs.hasRetAttrs())
Out << Attrs.getAsString(AttributeList::ReturnIndex) << ' ';
TypePrinter.print(F->getReturnType(), Out);
+ AsmWriterContext WriterCtx(&TypePrinter, &Machine, F->getParent());
Out << ' ';
- WriteAsOperandInternal(Out, F, &TypePrinter, &Machine, F->getParent());
+ WriteAsOperandInternal(Out, F, WriterCtx);
Out << '(';
// Loop over the arguments, printing them...
@@ -3738,7 +3732,7 @@ void AssemblyWriter::printFunction(const Function *F) {
// Output type...
TypePrinter.print(FT->getParamType(I), Out);
- AttributeSet ArgAttrs = Attrs.getParamAttributes(I);
+ AttributeSet ArgAttrs = Attrs.getParamAttrs(I);
if (ArgAttrs.hasAttributes()) {
Out << ' ';
writeAttributeSet(ArgAttrs);
@@ -3750,7 +3744,7 @@ void AssemblyWriter::printFunction(const Function *F) {
// Insert commas as we go... the first arg doesn't get a comma
if (Arg.getArgNo() != 0)
Out << ", ";
- printArgument(&Arg, Attrs.getParamAttributes(Arg.getArgNo()));
+ printArgument(&Arg, Attrs.getParamAttrs(Arg.getArgNo()));
}
}
@@ -3770,8 +3764,8 @@ void AssemblyWriter::printFunction(const Function *F) {
if (F->getAddressSpace() != 0 || !Mod ||
Mod->getDataLayout().getProgramAddressSpace() != 0)
Out << " addrspace(" << F->getAddressSpace() << ")";
- if (Attrs.hasAttributes(AttributeList::FunctionIndex))
- Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
+ if (Attrs.hasFnAttrs())
+ Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttrs());
if (F->hasSection()) {
Out << " section \"";
printEscapedString(F->getSection(), Out);
@@ -4127,7 +4121,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Type *RetTy = FTy->getReturnType();
const AttributeList &PAL = CI->getAttributes();
- if (PAL.hasAttributes(AttributeList::ReturnIndex))
+ if (PAL.hasRetAttrs())
Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
// Only print addrspace(N) if necessary:
@@ -4142,10 +4136,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ' ';
writeOperand(Operand, false);
Out << '(';
- for (unsigned op = 0, Eop = CI->getNumArgOperands(); op < Eop; ++op) {
+ for (unsigned op = 0, Eop = CI->arg_size(); op < Eop; ++op) {
if (op > 0)
Out << ", ";
- writeParamOperand(CI->getArgOperand(op), PAL.getParamAttributes(op));
+ writeParamOperand(CI->getArgOperand(op), PAL.getParamAttrs(op));
}
// Emit an ellipsis if this is a musttail call in a vararg function. This
@@ -4156,8 +4150,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ", ...";
Out << ')';
- if (PAL.hasAttributes(AttributeList::FunctionIndex))
- Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
+ if (PAL.hasFnAttrs())
+ Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
writeOperandBundles(CI);
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
@@ -4172,7 +4166,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
PrintCallingConv(II->getCallingConv(), Out);
}
- if (PAL.hasAttributes(AttributeList::ReturnIndex))
+ if (PAL.hasRetAttrs())
Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
// Only print addrspace(N) if necessary:
@@ -4187,15 +4181,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ' ';
writeOperand(Operand, false);
Out << '(';
- for (unsigned op = 0, Eop = II->getNumArgOperands(); op < Eop; ++op) {
+ for (unsigned op = 0, Eop = II->arg_size(); op < Eop; ++op) {
if (op)
Out << ", ";
- writeParamOperand(II->getArgOperand(op), PAL.getParamAttributes(op));
+ writeParamOperand(II->getArgOperand(op), PAL.getParamAttrs(op));
}
Out << ')';
- if (PAL.hasAttributes(AttributeList::FunctionIndex))
- Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
+ if (PAL.hasFnAttrs())
+ Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
writeOperandBundles(II);
@@ -4215,7 +4209,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
PrintCallingConv(CBI->getCallingConv(), Out);
}
- if (PAL.hasAttributes(AttributeList::ReturnIndex))
+ if (PAL.hasRetAttrs())
Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex);
// If possible, print out the short form of the callbr instruction. We can
@@ -4227,15 +4221,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ' ';
writeOperand(Operand, false);
Out << '(';
- for (unsigned op = 0, Eop = CBI->getNumArgOperands(); op < Eop; ++op) {
+ for (unsigned op = 0, Eop = CBI->arg_size(); op < Eop; ++op) {
if (op)
Out << ", ";
- writeParamOperand(CBI->getArgOperand(op), PAL.getParamAttributes(op));
+ writeParamOperand(CBI->getArgOperand(op), PAL.getParamAttrs(op));
}
Out << ')';
- if (PAL.hasAttributes(AttributeList::FunctionIndex))
- Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());
+ if (PAL.hasFnAttrs())
+ Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttrs());
writeOperandBundles(CBI);
@@ -4375,6 +4369,7 @@ void AssemblyWriter::printMetadataAttachments(
if (MDNames.empty())
MDs[0].second->getContext().getMDKindNames(MDNames);
+ auto WriterCtx = getContext();
for (const auto &I : MDs) {
unsigned Kind = I.first;
Out << Separator;
@@ -4384,7 +4379,7 @@ void AssemblyWriter::printMetadataAttachments(
} else
Out << "!<unknown kind #" << Kind << ">";
Out << ' ';
- WriteAsOperandInternal(Out, I.second, &TypePrinter, &Machine, TheModule);
+ WriteAsOperandInternal(Out, I.second, WriterCtx);
}
}
@@ -4406,7 +4401,8 @@ void AssemblyWriter::writeAllMDNodes() {
}
void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
- WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
+ auto WriterCtx = getContext();
+ WriteMDNodeBodyInternal(Out, Node, WriterCtx);
}
void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
@@ -4626,15 +4622,20 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
W.printGlobal(V);
else if (const Function *F = dyn_cast<Function>(GV))
W.printFunction(F);
+ else if (const GlobalAlias *A = dyn_cast<GlobalAlias>(GV))
+ W.printAlias(A);
+ else if (const GlobalIFunc *I = dyn_cast<GlobalIFunc>(GV))
+ W.printIFunc(I);
else
- W.printIndirectSymbol(cast<GlobalIndirectSymbol>(GV));
+ llvm_unreachable("Unknown GlobalValue to print out!");
} else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
} else if (const Constant *C = dyn_cast<Constant>(this)) {
TypePrinting TypePrinter;
TypePrinter.print(C->getType(), OS);
OS << ' ';
- WriteConstantInternal(OS, C, TypePrinter, MST.getMachine(), nullptr);
+ AsmWriterContext WriterCtx(&TypePrinter, MST.getMachine());
+ WriteConstantInternal(OS, C, WriterCtx);
} else if (isa<InlineAsm>(this) || isa<Argument>(this)) {
this->printAsOperand(OS, /* PrintType */ true, MST);
} else {
@@ -4649,7 +4650,8 @@ static bool printWithoutType(const Value &V, raw_ostream &O,
SlotTracker *Machine, const Module *M) {
if (V.hasName() || isa<GlobalValue>(V) ||
(!isa<Constant>(V) && !isa<MetadataAsValue>(V))) {
- WriteAsOperandInternal(O, &V, nullptr, Machine, M);
+ AsmWriterContext WriterCtx(nullptr, Machine, M);
+ WriteAsOperandInternal(O, &V, WriterCtx);
return true;
}
return false;
@@ -4663,8 +4665,8 @@ static void printAsOperandImpl(const Value &V, raw_ostream &O, bool PrintType,
O << ' ';
}
- WriteAsOperandInternal(O, &V, &TypePrinter, MST.getMachine(),
- MST.getModule());
+ AsmWriterContext WriterCtx(&TypePrinter, MST.getMachine(), MST.getModule());
+ WriteAsOperandInternal(O, &V, WriterCtx);
}
void Value::printAsOperand(raw_ostream &O, bool PrintType,
@@ -4691,22 +4693,87 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType,
printAsOperandImpl(*this, O, PrintType, MST);
}
+/// Recursive version of printMetadataImpl.
+static void printMetadataImplRec(raw_ostream &ROS, const Metadata &MD,
+ AsmWriterContext &WriterCtx) {
+ formatted_raw_ostream OS(ROS);
+ WriteAsOperandInternal(OS, &MD, WriterCtx, /* FromValue */ true);
+
+ auto *N = dyn_cast<MDNode>(&MD);
+ if (!N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
+ return;
+
+ OS << " = ";
+ WriteMDNodeBodyInternal(OS, N, WriterCtx);
+}
+
+namespace {
+struct MDTreeAsmWriterContext : public AsmWriterContext {
+ unsigned Level;
+ // {Level, Printed string}
+ using EntryTy = std::pair<unsigned, std::string>;
+ SmallVector<EntryTy, 4> Buffer;
+
+ // Used to break the cycle in case there is any.
+ SmallPtrSet<const Metadata *, 4> Visited;
+
+ raw_ostream &MainOS;
+
+ MDTreeAsmWriterContext(TypePrinting *TP, SlotTracker *ST, const Module *M,
+ raw_ostream &OS, const Metadata *InitMD)
+ : AsmWriterContext(TP, ST, M), Level(0U), Visited({InitMD}), MainOS(OS) {}
+
+ void onWriteMetadataAsOperand(const Metadata *MD) override {
+ if (Visited.count(MD))
+ return;
+ Visited.insert(MD);
+
+ std::string Str;
+ raw_string_ostream SS(Str);
+ ++Level;
+ // A placeholder entry to memorize the correct
+ // position in buffer.
+ Buffer.emplace_back(std::make_pair(Level, ""));
+ unsigned InsertIdx = Buffer.size() - 1;
+
+ printMetadataImplRec(SS, *MD, *this);
+ Buffer[InsertIdx].second = std::move(SS.str());
+ --Level;
+ }
+
+ ~MDTreeAsmWriterContext() {
+ for (const auto &Entry : Buffer) {
+ MainOS << "\n";
+ unsigned NumIndent = Entry.first * 2U;
+ MainOS.indent(NumIndent) << Entry.second;
+ }
+ }
+};
+} // end anonymous namespace
+
static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
ModuleSlotTracker &MST, const Module *M,
- bool OnlyAsOperand) {
+ bool OnlyAsOperand, bool PrintAsTree = false) {
formatted_raw_ostream OS(ROS);
TypePrinting TypePrinter(M);
- WriteAsOperandInternal(OS, &MD, &TypePrinter, MST.getMachine(), M,
- /* FromValue */ true);
+ std::unique_ptr<AsmWriterContext> WriterCtx;
+ if (PrintAsTree && !OnlyAsOperand)
+ WriterCtx = std::make_unique<MDTreeAsmWriterContext>(
+ &TypePrinter, MST.getMachine(), M, OS, &MD);
+ else
+ WriterCtx =
+ std::make_unique<AsmWriterContext>(&TypePrinter, MST.getMachine(), M);
+
+ WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true);
auto *N = dyn_cast<MDNode>(&MD);
if (OnlyAsOperand || !N || isa<DIExpression>(MD) || isa<DIArgList>(MD))
return;
OS << " = ";
- WriteMDNodeBodyInternal(OS, N, &TypePrinter, MST.getMachine(), M);
+ WriteMDNodeBodyInternal(OS, N, *WriterCtx);
}
void Metadata::printAsOperand(raw_ostream &OS, const Module *M) const {
@@ -4730,6 +4797,18 @@ void Metadata::print(raw_ostream &OS, ModuleSlotTracker &MST,
printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false);
}
+void MDNode::printTree(raw_ostream &OS, const Module *M) const {
+ ModuleSlotTracker MST(M, true);
+ printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false,
+ /*PrintAsTree=*/true);
+}
+
+void MDNode::printTree(raw_ostream &OS, ModuleSlotTracker &MST,
+ const Module *M) const {
+ printMetadataImpl(OS, *this, MST, M, /* OnlyAsOperand */ false,
+ /*PrintAsTree=*/true);
+}
+
void ModuleSummaryIndex::print(raw_ostream &ROS, bool IsForDebug) const {
SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
@@ -4781,6 +4860,15 @@ void Metadata::dump(const Module *M) const {
dbgs() << '\n';
}
+LLVM_DUMP_METHOD
+void MDNode::dumpTree() const { dumpTree(nullptr); }
+
+LLVM_DUMP_METHOD
+void MDNode::dumpTree(const Module *M) const {
+ printTree(dbgs(), M);
+ dbgs() << '\n';
+}
+
// Allow printing of ModuleSummaryIndex from the debugger.
LLVM_DUMP_METHOD
void ModuleSummaryIndex::dump() const { print(dbgs(), /*IsForDebug=*/true); }