aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR/AsmWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/AsmWriter.cpp')
-rw-r--r--lib/IR/AsmWriter.cpp975
1 files changed, 488 insertions, 487 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp
index de0e614..ae0beba 100644
--- a/lib/IR/AsmWriter.cpp
+++ b/lib/IR/AsmWriter.cpp
@@ -14,9 +14,9 @@
//
//===----------------------------------------------------------------------===//
-#include "AsmWriter.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/AssemblyAnnotationWriter.h"
@@ -32,12 +32,14 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/TypeFinder.h"
+#include "llvm/IR/UseListOrder.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cctype>
using namespace llvm;
@@ -275,6 +277,15 @@ static const Module *getModuleFromVal(const Value *V) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return GV->getParent();
+
+ if (const auto *MAV = dyn_cast<MetadataAsValue>(V)) {
+ for (const User *U : MAV->users())
+ if (isa<Instruction>(U))
+ if (const Module *M = getModuleFromVal(U))
+ return M;
+ return nullptr;
+ }
+
return nullptr;
}
@@ -378,7 +389,29 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) {
}
-namespace llvm {
+namespace {
+class TypePrinting {
+ TypePrinting(const TypePrinting &) = delete;
+ void operator=(const TypePrinting&) = delete;
+public:
+
+ /// NamedTypes - The named types that are used by the current module.
+ TypeFinder NamedTypes;
+
+ /// NumberedTypes - The numbered types, along with their value.
+ DenseMap<StructType*, unsigned> NumberedTypes;
+
+
+ TypePrinting() {}
+ ~TypePrinting() {}
+
+ void incorporateTypes(const Module &M);
+
+ void print(Type *Ty, raw_ostream &OS);
+
+ void printStructBody(StructType *Ty, raw_ostream &OS);
+};
+} // namespace
void TypePrinting::incorporateTypes(const Module &M) {
NamedTypes.run(M, false);
@@ -508,6 +541,7 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {
OS << '>';
}
+namespace {
//===----------------------------------------------------------------------===//
// SlotTracker Class: Enumerate slot numbers for unnamed values
//===----------------------------------------------------------------------===//
@@ -525,6 +559,7 @@ private:
/// TheFunction - The function for which we are holding slot numbers.
const Function* TheFunction;
bool FunctionProcessed;
+ bool ShouldInitializeAllMetadata;
/// mMap - The slot map for the module level data.
ValueMap mMap;
@@ -542,10 +577,20 @@ private:
DenseMap<AttributeSet, unsigned> asMap;
unsigned asNext;
public:
- /// Construct from a module
- explicit SlotTracker(const Module *M);
+ /// Construct from a module.
+ ///
+ /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
+ /// functions, giving correct numbering for metadata referenced only from
+ /// within a function (even if no functions have been initialized).
+ explicit SlotTracker(const Module *M,
+ bool ShouldInitializeAllMetadata = false);
/// Construct from a function, starting out in incorp state.
- explicit SlotTracker(const Function *F);
+ ///
+ /// If \c ShouldInitializeAllMetadata, initializes all metadata in all
+ /// functions, giving correct numbering for metadata referenced only from
+ /// within a function (even if no functions have been initialized).
+ explicit SlotTracker(const Function *F,
+ bool ShouldInitializeAllMetadata = false);
/// Return the slot number of the specified value in it's type
/// plane. If something is not in the SlotTracker, return -1.
@@ -606,11 +651,18 @@ private:
/// Add all of the functions arguments, basic blocks, and instructions.
void processFunction();
+ /// Add all of the metadata from a function.
+ void processFunctionMetadata(const Function &F);
+
+ /// Add all of the metadata from an instruction.
+ void processInstructionMetadata(const Instruction &I);
+
SlotTracker(const SlotTracker &) = delete;
void operator=(const SlotTracker &) = delete;
};
+} // namespace
-SlotTracker *createSlotTracker(const Module *M) {
+static SlotTracker *createSlotTracker(const Module *M) {
return new SlotTracker(M);
}
@@ -645,15 +697,18 @@ static SlotTracker *createSlotTracker(const Value *V) {
// Module level constructor. Causes the contents of the Module (sans functions)
// to be added to the slot table.
-SlotTracker::SlotTracker(const Module *M)
- : TheModule(M), TheFunction(nullptr), FunctionProcessed(false), mNext(0),
+SlotTracker::SlotTracker(const Module *M, bool ShouldInitializeAllMetadata)
+ : TheModule(M), TheFunction(nullptr), FunctionProcessed(false),
+ ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), mNext(0),
fNext(0), mdnNext(0), asNext(0) {}
// Function level constructor. Causes the contents of the Module and the one
// function provided to be added to the slot table.
-SlotTracker::SlotTracker(const Function *F)
+SlotTracker::SlotTracker(const Function *F, bool ShouldInitializeAllMetadata)
: TheModule(F ? F->getParent() : nullptr), TheFunction(F),
- FunctionProcessed(false), mNext(0), fNext(0), mdnNext(0), asNext(0) {}
+ FunctionProcessed(false),
+ ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), mNext(0),
+ fNext(0), mdnNext(0), asNext(0) {}
inline void SlotTracker::initialize() {
if (TheModule) {
@@ -692,6 +747,9 @@ void SlotTracker::processModule() {
// Add all the unnamed functions to the table.
CreateModuleSlot(I);
+ if (ShouldInitializeAllMetadata)
+ processFunctionMetadata(*I);
+
// Add all the function attributes to the table.
// FIXME: Add attributes of other objects?
AttributeSet FnAttrs = I->getAttributes().getFnAttributes();
@@ -715,46 +773,30 @@ void SlotTracker::processFunction() {
ST_DEBUG("Inserting Instructions:\n");
- SmallVector<std::pair<unsigned, MDNode *>, 4> MDForInst;
-
// Add all of the basic blocks and instructions with no names.
- for (Function::const_iterator BB = TheFunction->begin(),
- E = TheFunction->end(); BB != E; ++BB) {
- if (!BB->hasName())
- CreateFunctionSlot(BB);
-
- for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
- ++I) {
- if (!I->getType()->isVoidTy() && !I->hasName())
- CreateFunctionSlot(I);
-
- // Intrinsics can directly use metadata. We allow direct calls to any
- // llvm.foo function here, because the target may not be linked into the
- // optimizer.
- if (const CallInst *CI = dyn_cast<CallInst>(I)) {
- if (Function *F = CI->getCalledFunction())
- if (F->isIntrinsic())
- for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
- if (auto *V = dyn_cast_or_null<MetadataAsValue>(I->getOperand(i)))
- if (MDNode *N = dyn_cast<MDNode>(V->getMetadata()))
- CreateMetadataSlot(N);
+ for (auto &BB : *TheFunction) {
+ if (!BB.hasName())
+ CreateFunctionSlot(&BB);
+
+ for (auto &I : BB) {
+ if (!I.getType()->isVoidTy() && !I.hasName())
+ CreateFunctionSlot(&I);
+
+ processInstructionMetadata(I);
+ // We allow direct calls to any llvm.foo function here, because the
+ // target may not be linked into the optimizer.
+ if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
// Add all the call attributes to the table.
AttributeSet Attrs = CI->getAttributes().getFnAttributes();
if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
CreateAttributeSetSlot(Attrs);
- } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) {
+ } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
// Add all the call attributes to the table.
AttributeSet Attrs = II->getAttributes().getFnAttributes();
if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
CreateAttributeSetSlot(Attrs);
}
-
- // Process metadata attached with this instruction.
- I->getAllMetadata(MDForInst);
- for (unsigned i = 0, e = MDForInst.size(); i != e; ++i)
- CreateMetadataSlot(MDForInst[i].second);
- MDForInst.clear();
}
}
@@ -763,6 +805,29 @@ void SlotTracker::processFunction() {
ST_DEBUG("end processFunction!\n");
}
+void SlotTracker::processFunctionMetadata(const Function &F) {
+ for (auto &BB : F)
+ for (auto &I : BB)
+ processInstructionMetadata(I);
+}
+
+void SlotTracker::processInstructionMetadata(const Instruction &I) {
+ // Process metadata used directly by intrinsics.
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
+ if (Function *F = CI->getCalledFunction())
+ if (F->isIntrinsic())
+ for (auto &Op : I.operands())
+ if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
+ if (MDNode *N = dyn_cast<MDNode>(V->getMetadata()))
+ CreateMetadataSlot(N);
+
+ // Process metadata attached to this instruction.
+ SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
+ I.getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ CreateMetadataSlot(MD.second);
+}
+
/// Clean up after incorporating a function. This is the only way to get out of
/// the function incorporation state that affects get*Slot/Create*Slot. Function
/// incorporation state is indicated by TheFunction != 0.
@@ -1010,7 +1075,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
(StrVal[1] >= '0' && StrVal[1] <= '9'))) {
// Reparse stringized version!
if (APFloat(APFloat::IEEEdouble, StrVal).convertToDouble() == Val) {
- Out << StrVal.str();
+ Out << StrVal;
return;
}
}
@@ -1223,6 +1288,14 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,
Out << ' ' << getPredicateText(CE->getPredicate());
Out << " (";
+ if (const GEPOperator *GEP = dyn_cast<GEPOperator>(CE)) {
+ TypePrinter.print(
+ cast<PointerType>(GEP->getPointerOperandType()->getScalarType())
+ ->getElementType(),
+ Out);
+ Out << ", ";
+ }
+
for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
TypePrinter.print((*OI)->getType(), Out);
Out << ' ';
@@ -1285,8 +1358,52 @@ raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
}
return OS << FS.Sep;
}
+struct MDFieldPrinter {
+ raw_ostream &Out;
+ FieldSeparator FS;
+ TypePrinting *TypePrinter;
+ SlotTracker *Machine;
+ const Module *Context;
+
+ explicit MDFieldPrinter(raw_ostream &Out)
+ : Out(Out), TypePrinter(nullptr), Machine(nullptr), Context(nullptr) {}
+ MDFieldPrinter(raw_ostream &Out, TypePrinting *TypePrinter,
+ SlotTracker *Machine, const Module *Context)
+ : Out(Out), TypePrinter(TypePrinter), Machine(Machine), Context(Context) {
+ }
+ void printTag(const DebugNode *N);
+ void printString(StringRef Name, StringRef Value,
+ bool ShouldSkipEmpty = true);
+ void printMetadata(StringRef Name, const Metadata *MD,
+ bool ShouldSkipNull = true);
+ template <class IntTy>
+ void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true);
+ void printBool(StringRef Name, bool Value);
+ void printDIFlags(StringRef Name, unsigned Flags);
+ template <class IntTy, class Stringifier>
+ void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString,
+ bool ShouldSkipZero = true);
+};
} // end namespace
+void MDFieldPrinter::printTag(const DebugNode *N) {
+ Out << FS << "tag: ";
+ if (const char *Tag = dwarf::TagString(N->getTag()))
+ Out << Tag;
+ else
+ Out << N->getTag();
+}
+
+void MDFieldPrinter::printString(StringRef Name, StringRef Value,
+ bool ShouldSkipEmpty) {
+ if (ShouldSkipEmpty && Value.empty())
+ return;
+
+ Out << FS << Name << ": \"";
+ PrintEscapedString(Value, Out);
+ Out << "\"";
+}
+
static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
TypePrinting *TypePrinter,
SlotTracker *Machine,
@@ -1298,27 +1415,68 @@ static void writeMetadataAsOperand(raw_ostream &Out, const Metadata *MD,
WriteAsOperandInternal(Out, MD, TypePrinter, Machine, Context);
}
-static void writeTag(raw_ostream &Out, FieldSeparator &FS, const DebugNode *N) {
- Out << FS << "tag: ";
- if (const char *Tag = dwarf::TagString(N->getTag()))
- Out << Tag;
+void MDFieldPrinter::printMetadata(StringRef Name, const Metadata *MD,
+ bool ShouldSkipNull) {
+ if (ShouldSkipNull && !MD)
+ return;
+
+ Out << FS << Name << ": ";
+ writeMetadataAsOperand(Out, MD, TypePrinter, Machine, Context);
+}
+
+template <class IntTy>
+void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) {
+ if (ShouldSkipZero && !Int)
+ return;
+
+ Out << FS << Name << ": " << Int;
+}
+
+void MDFieldPrinter::printBool(StringRef Name, bool Value) {
+ Out << FS << Name << ": " << (Value ? "true" : "false");
+}
+
+void MDFieldPrinter::printDIFlags(StringRef Name, unsigned Flags) {
+ if (!Flags)
+ return;
+
+ Out << FS << Name << ": ";
+
+ SmallVector<unsigned, 8> SplitFlags;
+ unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
+
+ FieldSeparator FlagsFS(" | ");
+ for (unsigned F : SplitFlags) {
+ const char *StringF = DIDescriptor::getFlagString(F);
+ assert(StringF && "Expected valid flag");
+ Out << FlagsFS << StringF;
+ }
+ if (Extra || SplitFlags.empty())
+ Out << FlagsFS << Extra;
+}
+
+template <class IntTy, class Stringifier>
+void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,
+ Stringifier toString, bool ShouldSkipZero) {
+ if (!Value)
+ return;
+
+ Out << FS << Name << ": ";
+ if (const char *S = toString(Value))
+ Out << S;
else
- Out << N->getTag();
+ Out << Value;
}
static void writeGenericDebugNode(raw_ostream &Out, const GenericDebugNode *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
Out << "!GenericDebugNode(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- if (!N->getHeader().empty()) {
- Out << FS << "header: \"";
- PrintEscapedString(N->getHeader(), Out);
- Out << "\"";
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("header", N->getHeader());
if (N->getNumDwarfOperands()) {
- Out << FS << "operands: {";
+ Out << Printer.FS << "operands: {";
FieldSeparator IFS;
for (auto &I : N->dwarf_operands()) {
Out << IFS;
@@ -1333,111 +1491,64 @@ static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDLocation(";
- FieldSeparator FS;
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
// Always output the line, since 0 is a relevant and important value for it.
- Out << FS << "line: " << DL->getLine();
- if (DL->getColumn())
- Out << FS << "column: " << DL->getColumn();
- Out << FS << "scope: ";
- WriteAsOperandInternal(Out, DL->getScope(), TypePrinter, Machine, Context);
- if (DL->getInlinedAt()) {
- Out << FS << "inlinedAt: ";
- WriteAsOperandInternal(Out, DL->getInlinedAt(), TypePrinter, Machine,
- Context);
- }
+ Printer.printInt("line", DL->getLine(), /* ShouldSkipZero */ false);
+ Printer.printInt("column", DL->getColumn());
+ Printer.printMetadata("scope", DL->getRawScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("inlinedAt", DL->getRawInlinedAt());
Out << ")";
}
static void writeMDSubrange(raw_ostream &Out, const MDSubrange *N,
TypePrinting *, SlotTracker *, const Module *) {
Out << "!MDSubrange(";
- FieldSeparator FS;
- Out << FS << "count: " << N->getCount();
- if (N->getLo())
- Out << FS << "lowerBound: " << N->getLo();
+ MDFieldPrinter Printer(Out);
+ Printer.printInt("count", N->getCount(), /* ShouldSkipZero */ false);
+ Printer.printInt("lowerBound", N->getLo());
Out << ")";
}
static void writeMDEnumerator(raw_ostream &Out, const MDEnumerator *N,
TypePrinting *, SlotTracker *, const Module *) {
Out << "!MDEnumerator(";
- FieldSeparator FS;
- Out << FS << "name: \"" << N->getName() << "\"";
- Out << FS << "value: " << N->getValue();
+ MDFieldPrinter Printer(Out);
+ Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
+ Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
Out << ")";
}
static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
TypePrinting *, SlotTracker *, const Module *) {
Out << "!MDBasicType(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- if (!N->getName().empty())
- Out << FS << "name: \"" << N->getName() << "\"";
- if (N->getSizeInBits())
- Out << FS << "size: " << N->getSizeInBits();
- if (N->getAlignInBits())
- Out << FS << "align: " << N->getAlignInBits();
- if (unsigned Encoding = N->getEncoding()) {
- Out << FS << "encoding: ";
- if (const char *S = dwarf::AttributeEncodingString(Encoding))
- Out << S;
- else
- Out << Encoding;
- }
+ MDFieldPrinter Printer(Out);
+ if (N->getTag() != dwarf::DW_TAG_base_type)
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printDwarfEnum("encoding", N->getEncoding(),
+ dwarf::AttributeEncodingString);
Out << ")";
}
-static void writeDIFlags(raw_ostream &Out, unsigned Flags) {
- SmallVector<unsigned, 8> SplitFlags;
- unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
-
- FieldSeparator FS(" | ");
- for (unsigned F : SplitFlags) {
- const char *StringF = DIDescriptor::getFlagString(F);
- assert(StringF && "Expected valid flag");
- Out << FS << StringF;
- }
- if (Extra || SplitFlags.empty())
- Out << FS << Extra;
-}
-
static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDDerivedType(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- if (!N->getName().empty())
- Out << FS << "name: \"" << N->getName() << "\"";
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (N->getScope()) {
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- }
- Out << FS << "baseType: ";
- writeMetadataAsOperand(Out, N->getBaseType(), TypePrinter, Machine, Context);
- if (N->getSizeInBits())
- Out << FS << "size: " << N->getSizeInBits();
- if (N->getAlignInBits())
- Out << FS << "align: " << N->getAlignInBits();
- if (N->getOffsetInBits())
- Out << FS << "offset: " << N->getOffsetInBits();
- if (auto Flags = N->getFlags()) {
- Out << FS << "flags: ";
- writeDIFlags(Out, Flags);
- }
- if (N->getExtraData()) {
- Out << FS << "extraData: ";
- writeMetadataAsOperand(Out, N->getExtraData(), TypePrinter, Machine,
- Context);
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getScope());
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("baseType", N->getBaseType(),
+ /* ShouldSkipNull */ false);
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printInt("offset", N->getOffsetInBits());
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("extraData", N->getExtraData());
Out << ")";
}
@@ -1445,61 +1556,23 @@ static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
Out << "!MDCompositeType(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- if (!N->getName().empty())
- Out << FS << "name: \"" << N->getName() << "\"";
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (N->getScope()) {
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- }
- if (N->getBaseType()) {
- Out << FS << "baseType: ";
- writeMetadataAsOperand(Out, N->getBaseType(), TypePrinter, Machine,
- Context);
- }
- if (N->getSizeInBits())
- Out << FS << "size: " << N->getSizeInBits();
- if (N->getAlignInBits())
- Out << FS << "align: " << N->getAlignInBits();
- if (N->getOffsetInBits())
- Out << FS << "offset: " << N->getOffsetInBits();
- if (auto Flags = N->getFlags()) {
- Out << FS << "flags: ";
- writeDIFlags(Out, Flags);
- }
- if (N->getElements()) {
- Out << FS << "elements: ";
- writeMetadataAsOperand(Out, N->getElements(), TypePrinter, Machine,
- Context);
- }
- if (unsigned Lang = N->getRuntimeLang()) {
- Out << FS << "runtimeLang: ";
- if (const char *S = dwarf::LanguageString(Lang))
- Out << S;
- else
- Out << Lang;
- }
-
- if (N->getVTableHolder()) {
- Out << FS << "vtableHolder: ";
- writeMetadataAsOperand(Out, N->getVTableHolder(), TypePrinter, Machine,
- Context);
- }
- if (N->getTemplateParams()) {
- Out << FS << "templateParams: ";
- writeMetadataAsOperand(Out, N->getTemplateParams(), TypePrinter, Machine,
- Context);
- }
- if (!N->getIdentifier().empty())
- Out << FS << "identifier: \"" << N->getIdentifier() << "\"";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getScope());
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("baseType", N->getBaseType());
+ Printer.printInt("size", N->getSizeInBits());
+ Printer.printInt("align", N->getAlignInBits());
+ Printer.printInt("offset", N->getOffsetInBits());
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("elements", N->getElements());
+ Printer.printDwarfEnum("runtimeLang", N->getRuntimeLang(),
+ dwarf::LanguageString);
+ Printer.printMetadata("vtableHolder", N->getVTableHolder());
+ Printer.printMetadata("templateParams", N->getTemplateParams());
+ Printer.printString("identifier", N->getIdentifier());
Out << ")";
}
@@ -1507,22 +1580,20 @@ static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
Out << "!MDSubroutineType(";
- FieldSeparator FS;
- if (auto Flags = N->getFlags()) {
- Out << FS << "flags: ";
- writeDIFlags(Out, Flags);
- }
- Out << FS << "types: ";
- writeMetadataAsOperand(Out, N->getTypeArray(), TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("types", N->getTypeArray(), /* ShouldSkipNull */ false);
Out << ")";
}
static void writeMDFile(raw_ostream &Out, const MDFile *N, TypePrinting *,
SlotTracker *, const Module *) {
Out << "!MDFile(";
- FieldSeparator FS;
- Out << FS << "filename: \"" << N->getFilename() << "\"";
- Out << FS << "directory: \"" << N->getDirectory() << "\"";
+ MDFieldPrinter Printer(Out);
+ Printer.printString("filename", N->getFilename(),
+ /* ShouldSkipEmpty */ false);
+ Printer.printString("directory", N->getDirectory(),
+ /* ShouldSkipEmpty */ false);
Out << ")";
}
@@ -1530,48 +1601,23 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDCompileUnit(";
- FieldSeparator FS;
- Out << FS << "language: ";
- if (const char *Lang = dwarf::LanguageString(N->getSourceLanguage()))
- Out << Lang;
- else
- Out << N->getSourceLanguage();
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
- if (!N->getProducer().empty())
- Out << FS << "producer: \"" << N->getProducer() << "\"";
- Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
- if (!N->getFlags().empty())
- Out << FS << "flags: \"" << N->getFlags() << "\"";
- Out << FS << "runtimeVersion: " << N->getRuntimeVersion();
- if (!N->getSplitDebugFilename().empty())
- Out << FS << "splitDebugFilename: \"" << N->getSplitDebugFilename() << "\"";
- Out << FS << "emissionKind: " << N->getEmissionKind();
- if (N->getEnumTypes()) {
- Out << FS << "enums: ";
- writeMetadataAsOperand(Out, N->getEnumTypes(), TypePrinter, Machine,
- Context);
- }
- if (N->getRetainedTypes()) {
- Out << FS << "retainedTypes: ";
- writeMetadataAsOperand(Out, N->getRetainedTypes(), TypePrinter, Machine,
- Context);
- }
- if (N->getSubprograms()) {
- Out << FS << "subprograms: ";
- writeMetadataAsOperand(Out, N->getSubprograms(), TypePrinter, Machine,
- Context);
- }
- if (N->getGlobalVariables()) {
- Out << FS << "globals: ";
- writeMetadataAsOperand(Out, N->getGlobalVariables(), TypePrinter, Machine,
- Context);
- }
- if (N->getImportedEntities()) {
- Out << FS << "imports: ";
- writeMetadataAsOperand(Out, N->getImportedEntities(), TypePrinter, Machine,
- Context);
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printDwarfEnum("language", N->getSourceLanguage(),
+ dwarf::LanguageString, /* ShouldSkipZero */ false);
+ Printer.printMetadata("file", N->getFile(), /* ShouldSkipNull */ false);
+ Printer.printString("producer", N->getProducer());
+ Printer.printBool("isOptimized", N->isOptimized());
+ Printer.printString("flags", N->getFlags());
+ Printer.printInt("runtimeVersion", N->getRuntimeVersion(),
+ /* ShouldSkipZero */ false);
+ Printer.printString("splitDebugFilename", N->getSplitDebugFilename());
+ Printer.printInt("emissionKind", N->getEmissionKind(),
+ /* ShouldSkipZero */ false);
+ Printer.printMetadata("enums", N->getEnumTypes());
+ Printer.printMetadata("retainedTypes", N->getRetainedTypes());
+ Printer.printMetadata("subprograms", N->getSubprograms());
+ Printer.printMetadata("globals", N->getGlobalVariables());
+ Printer.printMetadata("imports", N->getImportedEntities());
Out << ")";
}
@@ -1579,67 +1625,26 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDSubprogram(";
- FieldSeparator FS;
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- Out << FS << "name: \"" << N->getName() << "\"";
- if (!N->getLinkageName().empty())
- Out << FS << "linkageName: \"" << N->getLinkageName() << "\"";
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (N->getType()) {
- Out << FS << "type: ";
- writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
- Context);
- }
- Out << FS << "isLocal: " << (N->isLocalToUnit() ? "true" : "false");
- Out << FS << "isDefinition: " << (N->isDefinition() ? "true" : "false");
- if (N->getScopeLine())
- Out << FS << "scopeLine: " << N->getScopeLine();
- if (N->getContainingType()) {
- Out << FS << "containingType: ";
- writeMetadataAsOperand(Out, N->getContainingType(), TypePrinter, Machine,
- Context);
- }
- if (unsigned V = N->getVirtuality()) {
- Out << FS << "virtuality: ";
- if (const char *S = dwarf::VirtualityString(V))
- Out << S;
- else
- Out << V;
- }
- if (N->getVirtualIndex())
- Out << FS << "virtualIndex: " << N->getVirtualIndex();
- if (auto Flags = N->getFlags()) {
- Out << FS << "flags: ";
- writeDIFlags(Out, Flags);
- }
- Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
- if (N->getFunction()) {
- Out << FS << "function: ";
- writeMetadataAsOperand(Out, N->getFunction(), TypePrinter, Machine,
- Context);
- }
- if (N->getTemplateParams()) {
- Out << FS << "templateParams: ";
- writeMetadataAsOperand(Out, N->getTemplateParams(), TypePrinter, Machine,
- Context);
- }
- if (N->getDeclaration()) {
- Out << FS << "declaration: ";
- writeMetadataAsOperand(Out, N->getDeclaration(), TypePrinter, Machine,
- Context);
- }
- if (N->getVariables()) {
- Out << FS << "variables: ";
- writeMetadataAsOperand(Out, N->getVariables(), TypePrinter, Machine,
- Context);
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printString("linkageName", N->getLinkageName());
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("type", N->getType());
+ Printer.printBool("isLocal", N->isLocalToUnit());
+ Printer.printBool("isDefinition", N->isDefinition());
+ Printer.printInt("scopeLine", N->getScopeLine());
+ Printer.printMetadata("containingType", N->getContainingType());
+ Printer.printDwarfEnum("virtuality", N->getVirtuality(),
+ dwarf::VirtualityString);
+ Printer.printInt("virtualIndex", N->getVirtualIndex());
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printBool("isOptimized", N->isOptimized());
+ Printer.printMetadata("function", N->getFunction());
+ Printer.printMetadata("templateParams", N->getTemplateParams());
+ Printer.printMetadata("declaration", N->getDeclaration());
+ Printer.printMetadata("variables", N->getVariables());
Out << ")";
}
@@ -1647,18 +1652,11 @@ static void writeMDLexicalBlock(raw_ostream &Out, const MDLexicalBlock *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDLexicalBlock(";
- FieldSeparator FS;
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (N->getColumn())
- Out << FS << "column: " << N->getColumn();
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printInt("column", N->getColumn());
Out << ")";
}
@@ -1668,15 +1666,11 @@ static void writeMDLexicalBlockFile(raw_ostream &Out,
SlotTracker *Machine,
const Module *Context) {
Out << "!MDLexicalBlockFile(";
- FieldSeparator FS;
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- Out << FS << "discriminator: " << N->getDiscriminator();
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("discriminator", N->getDiscriminator(),
+ /* ShouldSkipZero */ false);
Out << ")";
}
@@ -1684,17 +1678,11 @@ static void writeMDNamespace(raw_ostream &Out, const MDNamespace *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDNamespace(";
- FieldSeparator FS;
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
- }
- if (!N->getName().empty())
- Out << FS << "name: \"" << N->getName() << "\"";
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
Out << ")";
}
@@ -1704,10 +1692,9 @@ static void writeMDTemplateTypeParameter(raw_ostream &Out,
SlotTracker *Machine,
const Module *Context) {
Out << "!MDTemplateTypeParameter(";
- FieldSeparator FS;
- Out << FS << "name: \"" << N->getName() << "\"";
- Out << FS << "type: ";
- writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("type", N->getType(), /* ShouldSkipNull */ false);
Out << ")";
}
@@ -1717,13 +1704,12 @@ static void writeMDTemplateValueParameter(raw_ostream &Out,
SlotTracker *Machine,
const Module *Context) {
Out << "!MDTemplateValueParameter(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- Out << FS << "name: \"" << N->getName() << "\"";
- Out << FS << "type: ";
- writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
- Out << FS << "value: ";
- writeMetadataAsOperand(Out, N->getValue(), TypePrinter, Machine, Context);
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ if (N->getTag() != dwarf::DW_TAG_template_value_parameter)
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("type", N->getType());
+ Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
Out << ")";
}
@@ -1731,36 +1717,17 @@ static void writeMDGlobalVariable(raw_ostream &Out, const MDGlobalVariable *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
Out << "!MDGlobalVariable(";
- FieldSeparator FS;
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- Out << FS << "name: \"" << N->getName() << "\"";
- if (!N->getLinkageName().empty())
- Out << FS << "linkageName: \"" << N->getLinkageName() << "\"";
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (N->getType()) {
- Out << FS << "type: ";
- writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
- Context);
- }
- Out << FS << "isLocal: " << (N->isLocalToUnit() ? "true" : "false");
- Out << FS << "isDefinition: " << (N->isDefinition() ? "true" : "false");
- if (N->getVariable()) {
- Out << FS << "variable: ";
- writeMetadataAsOperand(Out, N->getVariable(), TypePrinter, Machine,
- Context);
- }
- if (N->getStaticDataMemberDeclaration()) {
- Out << FS << "declaration: ";
- writeMetadataAsOperand(Out, N->getStaticDataMemberDeclaration(),
- TypePrinter, Machine, Context);
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printString("linkageName", N->getLinkageName());
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("type", N->getType());
+ Printer.printBool("isLocal", N->isLocalToUnit());
+ Printer.printBool("isDefinition", N->isDefinition());
+ Printer.printMetadata("variable", N->getVariable());
+ Printer.printMetadata("declaration", N->getStaticDataMemberDeclaration());
Out << ")";
}
@@ -1768,34 +1735,18 @@ static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
Out << "!MDLocalVariable(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- Out << FS << "name: \"" << N->getName() << "\"";
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
- Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (N->getType()) {
- Out << FS << "type: ";
- writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine,
- Context);
- }
- if (N->getTag() == dwarf::DW_TAG_arg_variable || N->getArg())
- Out << FS << "arg: " << N->getArg();
- if (auto Flags = N->getFlags()) {
- Out << FS << "flags: ";
- writeDIFlags(Out, Flags);
- }
- if (N->getInlinedAt()) {
- Out << FS << "inlinedAt: ";
- writeMetadataAsOperand(Out, N->getInlinedAt(), TypePrinter, Machine,
- Context);
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printInt("arg", N->getArg(),
+ /* ShouldSkipZero */
+ N->getTag() == dwarf::DW_TAG_auto_variable);
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printMetadata("type", N->getType());
+ Printer.printDIFlags("flags", N->getFlags());
+ Printer.printMetadata("inlinedAt", N->getInlinedAt());
Out << ")";
}
@@ -1824,24 +1775,14 @@ static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
TypePrinting *TypePrinter, SlotTracker *Machine,
const Module *Context) {
Out << "!MDObjCProperty(";
- FieldSeparator FS;
- Out << FS << "name: \"" << N->getName() << "\"";
- if (N->getFile()) {
- Out << FS << "file: ";
- writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- if (!N->getSetterName().empty())
- Out << FS << "setter: \"" << N->getSetterName() << "\"";
- if (!N->getGetterName().empty())
- Out << FS << "getter: \"" << N->getGetterName() << "\"";
- if (N->getAttributes())
- Out << FS << "attributes: " << N->getAttributes();
- if (N->getType()) {
- Out << FS << "type: ";
- writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
- }
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("file", N->getFile());
+ Printer.printInt("line", N->getLine());
+ Printer.printString("setter", N->getSetterName());
+ Printer.printString("getter", N->getGetterName());
+ Printer.printInt("attributes", N->getAttributes());
+ Printer.printMetadata("type", N->getType());
Out << ")";
}
@@ -1849,17 +1790,12 @@ static void writeMDImportedEntity(raw_ostream &Out, const MDImportedEntity *N,
TypePrinting *TypePrinter,
SlotTracker *Machine, const Module *Context) {
Out << "!MDImportedEntity(";
- FieldSeparator FS;
- writeTag(Out, FS, N);
- Out << FS << "scope: ";
- writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
- if (N->getEntity()) {
- Out << FS << "entity: ";
- writeMetadataAsOperand(Out, N->getEntity(), TypePrinter, Machine, Context);
- }
- if (N->getLine())
- Out << FS << "line: " << N->getLine();
- Out << FS << "name: \"" << N->getName() << "\"";
+ MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
+ Printer.printTag(N);
+ Printer.printString("name", N->getName());
+ Printer.printMetadata("scope", N->getScope(), /* ShouldSkipNull */ false);
+ Printer.printMetadata("entity", N->getEntity());
+ Printer.printInt("line", N->getLine());
Out << ")";
}
@@ -1868,10 +1804,10 @@ static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
TypePrinting *TypePrinter,
SlotTracker *Machine,
const Module *Context) {
- assert(!Node->isTemporary() && "Unexpected forward declaration");
-
if (Node->isDistinct())
Out << "distinct ";
+ else if (Node->isTemporary())
+ Out << "<temporary!> "; // Handle broken code.
switch (Node->getMetadataID()) {
default:
@@ -1998,6 +1934,64 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
WriteAsOperandInternal(Out, V->getValue(), TypePrinter, Machine, Context);
}
+namespace {
+class AssemblyWriter {
+ formatted_raw_ostream &Out;
+ const Module *TheModule;
+ std::unique_ptr<SlotTracker> ModuleSlotTracker;
+ SlotTracker &Machine;
+ TypePrinting TypePrinter;
+ AssemblyAnnotationWriter *AnnotationWriter;
+ SetVector<const Comdat *> Comdats;
+ UseListOrderStack UseListOrders;
+
+public:
+ /// Construct an AssemblyWriter with an external SlotTracker
+ AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,
+ const Module *M, AssemblyAnnotationWriter *AAW);
+
+ /// Construct an AssemblyWriter with an internally allocated SlotTracker
+ AssemblyWriter(formatted_raw_ostream &o, const Module *M,
+ AssemblyAnnotationWriter *AAW);
+
+ void printMDNodeBody(const MDNode *MD);
+ void printNamedMDNode(const NamedMDNode *NMD);
+
+ void printModule(const Module *M);
+
+ void writeOperand(const Value *Op, bool PrintType);
+ void writeParamOperand(const Value *Operand, AttributeSet Attrs,unsigned Idx);
+ void writeAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope);
+ void writeAtomicCmpXchg(AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering,
+ SynchronizationScope SynchScope);
+
+ void writeAllMDNodes();
+ void writeMDNode(unsigned Slot, const MDNode *Node);
+ void writeAllAttributeGroups();
+
+ void printTypeIdentities();
+ void printGlobal(const GlobalVariable *GV);
+ void printAlias(const GlobalAlias *GV);
+ void printComdat(const Comdat *C);
+ void printFunction(const Function *F);
+ void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx);
+ void printBasicBlock(const BasicBlock *BB);
+ void printInstructionLine(const Instruction &I);
+ void printInstruction(const Instruction &I);
+
+ void printUseListOrder(const UseListOrder &Order);
+ void printUseLists(const Function *F);
+
+private:
+ void init();
+
+ // printInfoComment - Print a little comment after the instruction indicating
+ // which slot it occupies.
+ void printInfoComment(const Value &V);
+};
+} // namespace
+
void AssemblyWriter::init() {
if (!TheModule)
return;
@@ -2025,8 +2019,6 @@ AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, const Module *M,
init();
}
-AssemblyWriter::~AssemblyWriter() { }
-
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType) {
if (!Operand) {
Out << "<null operand!>";
@@ -2876,7 +2868,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
if (AI->isUsedWithInAlloca())
Out << "inalloca ";
TypePrinter.print(AI->getAllocatedType(), Out);
- if (!AI->getArraySize() || AI->isArrayAllocation()) {
+
+ // Explicitly write the array size if the code is broken, if it's an array
+ // allocation, or if the type is not canonical for scalar allocations. The
+ // latter case prevents the type from mutating when round-tripping through
+ // assembly.
+ if (!AI->getArraySize() || AI->isArrayAllocation() ||
+ !AI->getArraySize()->getType()->isIntegerTy(32)) {
Out << ", ";
writeOperand(AI->getArraySize(), true);
}
@@ -2898,6 +2896,15 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << ", ";
TypePrinter.print(I.getType(), Out);
} else if (Operand) { // Print the normal way.
+ if (const auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
+ Out << ' ';
+ TypePrinter.print(GEP->getSourceElementType(), Out);
+ Out << ',';
+ } else if (const auto *LI = dyn_cast<LoadInst>(&I)) {
+ Out << ' ';
+ TypePrinter.print(LI->getType(), Out);
+ Out << ',';
+ }
// PrintAllTypes - Instructions who have operands of all the same type
// omit the type from all but the first operand. If the instruction has
@@ -2974,29 +2981,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
printInfoComment(I);
}
-static void WriteMDNodeComment(const MDNode *Node,
- formatted_raw_ostream &Out) {
- if (Node->getNumOperands() < 1)
- return;
-
- Metadata *Op = Node->getOperand(0);
- if (!Op || !isa<MDString>(Op))
- return;
-
- DIDescriptor Desc(Node);
- if (!Desc.Verify())
- return;
-
- unsigned Tag = Desc.getTag();
- Out.PadToColumn(50);
- if (dwarf::TagString(Tag)) {
- Out << "; ";
- Desc.print(Out);
- } else if (Tag == dwarf::DW_TAG_user_base) {
- Out << "; [ DW_TAG_user_base ]";
- }
-}
-
void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
Out << '!' << Slot << " = ";
printMDNodeBody(Node);
@@ -3017,7 +3001,6 @@ void AssemblyWriter::writeAllMDNodes() {
void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
- WriteMDNodeComment(Node, Out);
}
void AssemblyWriter::writeAllAttributeGroups() {
@@ -3034,8 +3017,6 @@ void AssemblyWriter::writeAllAttributeGroups() {
<< I->first.getAsString(AttributeSet::FunctionIndex, true) << " }\n";
}
-} // namespace llvm
-
void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
bool IsInFunction = Machine.getFunction();
if (IsInFunction)
@@ -3130,11 +3111,24 @@ void Type::print(raw_ostream &OS) const {
}
}
+static bool isReferencingMDNode(const Instruction &I) {
+ if (const auto *CI = dyn_cast<CallInst>(&I))
+ if (Function *F = CI->getCalledFunction())
+ if (F->isIntrinsic())
+ for (auto &Op : I.operands())
+ if (auto *V = dyn_cast_or_null<MetadataAsValue>(Op))
+ if (isa<MDNode>(V->getMetadata()))
+ return true;
+ return false;
+}
+
void Value::print(raw_ostream &ROS) const {
formatted_raw_ostream OS(ROS);
if (const Instruction *I = dyn_cast<Instruction>(this)) {
const Function *F = I->getParent() ? I->getParent()->getParent() : nullptr;
- SlotTracker SlotTable(F);
+ SlotTracker SlotTable(
+ F,
+ /* ShouldInitializeAllMetadata */ isReferencingMDNode(*I));
AssemblyWriter W(OS, SlotTable, getModuleFromVal(I), nullptr);
W.printInstruction(*I);
} else if (const BasicBlock *BB = dyn_cast<BasicBlock>(this)) {
@@ -3142,7 +3136,8 @@ void Value::print(raw_ostream &ROS) const {
AssemblyWriter W(OS, SlotTable, getModuleFromVal(BB), nullptr);
W.printBasicBlock(BB);
} else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
- SlotTracker SlotTable(GV->getParent());
+ SlotTracker SlotTable(GV->getParent(),
+ /* ShouldInitializeAllMetadata */ isa<Function>(GV));
AssemblyWriter W(OS, SlotTable, GV->getParent(), nullptr);
if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
W.printGlobal(V);
@@ -3151,7 +3146,7 @@ void Value::print(raw_ostream &ROS) const {
else
W.printAlias(cast<GlobalAlias>(GV));
} else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
- V->getMetadata()->print(ROS);
+ V->getMetadata()->print(ROS, getModuleFromVal(V));
} else if (const Constant *C = dyn_cast<Constant>(this)) {
TypePrinting TypePrinter;
TypePrinter.print(C->getType(), OS);
@@ -3167,8 +3162,9 @@ void Value::print(raw_ostream &ROS) const {
void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) const {
// Fast path: Don't construct and populate a TypePrinting object if we
// won't be needing any types printed.
- if (!PrintType && ((!isa<Constant>(this) && !isa<MetadataAsValue>(this)) ||
- hasName() || isa<GlobalValue>(this))) {
+ bool IsMetadata = isa<MetadataAsValue>(this);
+ if (!PrintType && ((!isa<Constant>(this) && !IsMetadata) || hasName() ||
+ isa<GlobalValue>(this))) {
WriteAsOperandInternal(O, this, nullptr, nullptr, M);
return;
}
@@ -3184,33 +3180,35 @@ void Value::printAsOperand(raw_ostream &O, bool PrintType, const Module *M) cons
O << ' ';
}
- WriteAsOperandInternal(O, this, &TypePrinter, nullptr, M);
+ SlotTracker Machine(M, /* ShouldInitializeAllMetadata */ IsMetadata);
+ WriteAsOperandInternal(O, this, &TypePrinter, &Machine, M);
}
-void Metadata::print(raw_ostream &ROS) const {
+static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
+ const Module *M, bool OnlyAsOperand) {
formatted_raw_ostream OS(ROS);
- if (auto *N = dyn_cast<MDNode>(this)) {
- SlotTracker SlotTable(static_cast<Function *>(nullptr));
- AssemblyWriter W(OS, SlotTable, nullptr, nullptr);
- W.printMDNodeBody(N);
+ auto *N = dyn_cast<MDNode>(&MD);
+ TypePrinting TypePrinter;
+ SlotTracker Machine(M, /* ShouldInitializeAllMetadata */ N);
+ if (M)
+ TypePrinter.incorporateTypes(*M);
+
+ WriteAsOperandInternal(OS, &MD, &TypePrinter, &Machine, M,
+ /* FromValue */ true);
+ if (OnlyAsOperand || !N)
return;
- }
- printAsOperand(OS);
+
+ OS << " = ";
+ WriteMDNodeBodyInternal(OS, N, &TypePrinter, &Machine, M);
}
-void Metadata::printAsOperand(raw_ostream &ROS, bool PrintType,
- const Module *M) const {
- formatted_raw_ostream OS(ROS);
+void Metadata::printAsOperand(raw_ostream &OS, const Module *M) const {
+ printMetadataImpl(OS, *this, M, /* OnlyAsOperand */ true);
+}
- std::unique_ptr<TypePrinting> TypePrinter;
- if (PrintType) {
- TypePrinter.reset(new TypePrinting);
- if (M)
- TypePrinter->incorporateTypes(*M);
- }
- WriteAsOperandInternal(OS, this, TypePrinter.get(), nullptr, M,
- /* FromValue */ true);
+void Metadata::print(raw_ostream &OS, const Module *M) const {
+ printMetadataImpl(OS, *this, M, /* OnlyAsOperand */ false);
}
// Value::dump - allow easy printing of Values from the debugger.
@@ -3234,7 +3232,10 @@ LLVM_DUMP_METHOD
void NamedMDNode::dump() const { print(dbgs()); }
LLVM_DUMP_METHOD
-void Metadata::dump() const {
- print(dbgs());
+void Metadata::dump() const { dump(nullptr); }
+
+LLVM_DUMP_METHOD
+void Metadata::dump(const Module *M) const {
+ print(dbgs(), M);
dbgs() << '\n';
}