diff options
Diffstat (limited to 'lib/IR/AsmWriter.cpp')
| -rw-r--r-- | lib/IR/AsmWriter.cpp | 147 | 
1 files changed, 93 insertions, 54 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 556e122ff82f..c7f112887a30 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -1,5 +1,4 @@ - -//===-- AsmWriter.cpp - Printing LLVM as an assembly file -----------------===// +//===- AsmWriter.cpp - Printing LLVM as an assembly file ------------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -15,63 +14,105 @@  //  //===----------------------------------------------------------------------===// +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/SetVector.h"  #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h"  #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/IR/Argument.h"  #include "llvm/IR/AssemblyAnnotationWriter.h"  #include "llvm/IR/Attributes.h" +#include "llvm/IR/BasicBlock.h"  #include "llvm/IR/CFG.h" +#include "llvm/IR/CallSite.h"  #include "llvm/IR/CallingConv.h" +#include "llvm/IR/Comdat.h" +#include "llvm/IR/Constant.h"  #include "llvm/IR/Constants.h" -#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h"  #include "llvm/IR/DerivedTypes.h" +#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"  #include "llvm/IR/IRPrintingPasses.h"  #include "llvm/IR/InlineAsm.h" -#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h"  #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h"  #include "llvm/IR/Module.h"  #include "llvm/IR/ModuleSlotTracker.h"  #include "llvm/IR/Operator.h"  #include "llvm/IR/Statepoint.h" +#include "llvm/IR/Type.h"  #include "llvm/IR/TypeFinder.h" +#include "llvm/IR/Use.h"  #include "llvm/IR/UseListOrder.h" -#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/IR/User.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/AtomicOrdering.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/Format.h"  #include "llvm/Support/FormattedStream.h" -#include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h"  #include <algorithm> +#include <cassert>  #include <cctype> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <memory> +#include <string> +#include <tuple> +#include <utility> +#include <vector> +  using namespace llvm;  // Make virtual table appear in this compilation unit. -AssemblyAnnotationWriter::~AssemblyAnnotationWriter() {} +AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default;  //===----------------------------------------------------------------------===//  // Helper Functions  //===----------------------------------------------------------------------===//  namespace { +  struct OrderMap {    DenseMap<const Value *, std::pair<unsigned, bool>> IDs;    unsigned size() const { return IDs.size(); }    std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; } +    std::pair<unsigned, bool> lookup(const Value *V) const {      return IDs.lookup(V);    } +    void index(const Value *V) {      // Explicitly sequence get-size and insert-value operations to avoid UB.      unsigned ID = IDs.size() + 1;      IDs[V].first = ID;    }  }; -} + +} // end anonymous namespace  static void orderValue(const Value *V, OrderMap &OM) {    if (OM.lookup(V).first) @@ -139,7 +180,7 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,                                           unsigned ID, const OrderMap &OM,                                           UseListOrderStack &Stack) {    // Predict use-list order for this one. -  typedef std::pair<const Use *, unsigned> Entry; +  using Entry = std::pair<const Use *, unsigned>;    SmallVector<Entry, 64> List;    for (const Use &U : V->uses())      // Check if this user will be serialized. @@ -421,13 +462,10 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) {                  isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix);  } -  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; @@ -435,6 +473,8 @@ public:    DenseMap<StructType*, unsigned> NumberedTypes;    TypePrinting() = default; +  TypePrinting(const TypePrinting &) = delete; +  TypePrinting &operator=(const TypePrinting &) = delete;    void incorporateTypes(const Module &M); @@ -442,7 +482,8 @@ public:    void printStructBody(StructType *Ty, raw_ostream &OS);  }; -} // namespace + +} // end anonymous namespace  void TypePrinting::incorporateTypes(const Module &M) {    NamedTypes.run(M, false); @@ -574,6 +615,7 @@ void TypePrinting::printStructBody(StructType *STy, raw_ostream &OS) {  }  namespace llvm { +  //===----------------------------------------------------------------------===//  // SlotTracker Class: Enumerate slot numbers for unnamed values  //===----------------------------------------------------------------------===// @@ -582,32 +624,33 @@ namespace llvm {  class SlotTracker {  public:    /// ValueMap - A mapping of Values to slot numbers. -  typedef DenseMap<const Value*, unsigned> ValueMap; +  using ValueMap = DenseMap<const Value *, unsigned>;  private:    /// TheModule - The module for which we are holding slot numbers.    const Module* TheModule;    /// TheFunction - The function for which we are holding slot numbers. -  const Function* TheFunction; -  bool FunctionProcessed; +  const Function* TheFunction = nullptr; +  bool FunctionProcessed = false;    bool ShouldInitializeAllMetadata;    /// mMap - The slot map for the module level data.    ValueMap mMap; -  unsigned mNext; +  unsigned mNext = 0;    /// fMap - The slot map for the function level data.    ValueMap fMap; -  unsigned fNext; +  unsigned fNext = 0;    /// mdnMap - Map for MDNodes.    DenseMap<const MDNode*, unsigned> mdnMap; -  unsigned mdnNext; +  unsigned mdnNext = 0;    /// asMap - The slot map for attribute sets.    DenseMap<AttributeSet, unsigned> asMap; -  unsigned asNext; +  unsigned asNext = 0; +  public:    /// Construct from a module.    /// @@ -616,6 +659,7 @@ public:    /// 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.    ///    /// If \c ShouldInitializeAllMetadata, initializes all metadata in all @@ -624,6 +668,9 @@ public:    explicit SlotTracker(const Function *F,                         bool ShouldInitializeAllMetadata = false); +  SlotTracker(const SlotTracker &) = delete; +  SlotTracker &operator=(const SlotTracker &) = delete; +    /// Return the slot number of the specified value in it's type    /// plane.  If something is not in the SlotTracker, return -1.    int getLocalSlot(const Value *V); @@ -646,14 +693,16 @@ public:    void purgeFunction();    /// MDNode map iterators. -  typedef DenseMap<const MDNode*, unsigned>::iterator mdn_iterator; +  using mdn_iterator = DenseMap<const MDNode*, unsigned>::iterator; +    mdn_iterator mdn_begin() { return mdnMap.begin(); }    mdn_iterator mdn_end() { return mdnMap.end(); }    unsigned mdn_size() const { return mdnMap.size(); }    bool mdn_empty() const { return mdnMap.empty(); }    /// AttributeSet map iterators. -  typedef DenseMap<AttributeSet, unsigned>::iterator as_iterator; +  using as_iterator = DenseMap<AttributeSet, unsigned>::iterator; +    as_iterator as_begin()   { return asMap.begin(); }    as_iterator as_end()     { return asMap.end(); }    unsigned as_size() const { return asMap.size(); } @@ -691,11 +740,9 @@ private:    /// Add all of the metadata from an instruction.    void processInstructionMetadata(const Instruction &I); - -  SlotTracker(const SlotTracker &) = delete; -  void operator=(const SlotTracker &) = delete;  }; -} // namespace llvm + +} // end namespace llvm  ModuleSlotTracker::ModuleSlotTracker(SlotTracker &Machine, const Module *M,                                       const Function *F) @@ -706,7 +753,7 @@ ModuleSlotTracker::ModuleSlotTracker(const Module *M,      : ShouldCreateStorage(M),        ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), M(M) {} -ModuleSlotTracker::~ModuleSlotTracker() {} +ModuleSlotTracker::~ModuleSlotTracker() = default;  SlotTracker *ModuleSlotTracker::getMachine() {    if (!ShouldCreateStorage) @@ -773,17 +820,13 @@ 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, bool ShouldInitializeAllMetadata) -    : TheModule(M), TheFunction(nullptr), FunctionProcessed(false), -      ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), mNext(0), -      fNext(0), mdnNext(0), asNext(0) {} +    : TheModule(M), ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}  // 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, bool ShouldInitializeAllMetadata)      : TheModule(F ? F->getParent() : nullptr), TheFunction(F), -      FunctionProcessed(false), -      ShouldInitializeAllMetadata(ShouldInitializeAllMetadata), mNext(0), -      fNext(0), mdnNext(0), asNext(0) {} +      ShouldInitializeAllMetadata(ShouldInitializeAllMetadata) {}  inline void SlotTracker::initialize() {    if (TheModule) { @@ -949,7 +992,6 @@ int SlotTracker::getMetadataSlot(const MDNode *N) {    return MI == mdnMap.end() ? -1 : (int)MI->second;  } -  /// getLocalSlot - Get the slot number for a value that is local to a function.  int SlotTracker::getLocalSlot(const Value *V) {    assert(!isa<Constant>(V) && "Can't get a constant or global slot with this!"); @@ -1248,7 +1290,6 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV,      return;    } -    if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {      if (CS->getType()->isPacked())        Out << '<'; @@ -1381,11 +1422,14 @@ static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,  }  namespace { +  struct FieldSeparator { -  bool Skip; +  bool Skip = true;    const char *Sep; -  FieldSeparator(const char *Sep = ", ") : Skip(true), Sep(Sep) {} + +  FieldSeparator(const char *Sep = ", ") : Sep(Sep) {}  }; +  raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {    if (FS.Skip) {      FS.Skip = false; @@ -1393,19 +1437,20 @@ 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; +  TypePrinting *TypePrinter = nullptr; +  SlotTracker *Machine = nullptr; +  const Module *Context = nullptr; -  explicit MDFieldPrinter(raw_ostream &Out) -      : Out(Out), TypePrinter(nullptr), Machine(nullptr), Context(nullptr) {} +  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) {    } +    void printTag(const DINode *N);    void printMacinfoType(const DIMacroNode *N);    void printChecksumKind(const DIFile *N); @@ -1422,7 +1467,8 @@ struct MDFieldPrinter {                        bool ShouldSkipZero = true);    void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK);  }; -} // end namespace + +} // end anonymous namespace  void MDFieldPrinter::printTag(const DINode *N) {    Out << FS << "tag: "; @@ -1518,7 +1564,6 @@ void MDFieldPrinter::printEmissionKind(StringRef Name,    Out << FS << Name << ": " << DICompileUnit::EmissionKindString(EK);  } -  template <class IntTy, class Stringifier>  void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value,                                      Stringifier toString, bool ShouldSkipZero) { @@ -1923,7 +1968,6 @@ static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,    Out << ")";  } -  static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,                                      TypePrinting *TypePrinter,                                      SlotTracker *Machine, @@ -2062,6 +2106,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,  }  namespace { +  class AssemblyWriter {    formatted_raw_ostream &Out;    const Module *TheModule; @@ -2125,7 +2170,8 @@ private:    // intrinsic indicating base and derived pointer names.    void printGCRelocateComment(const GCRelocateInst &Relocate);  }; -} // namespace + +} // end anonymous namespace  AssemblyWriter::AssemblyWriter(formatted_raw_ostream &o, SlotTracker &Mac,                                 const Module *M, AssemblyAnnotationWriter *AAW, @@ -2594,7 +2640,6 @@ void AssemblyWriter::printTypeIdentities() {  }  /// printFunction - Print all aspects of a function. -///  void AssemblyWriter::printFunction(const Function *F) {    // Print out the return type and name.    Out << '\n'; @@ -2730,7 +2775,6 @@ void AssemblyWriter::printFunction(const Function *F) {  /// printArgument - This member is called for every argument that is passed into  /// the function.  Simply print it out -///  void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {    // Output type...    TypePrinter.print(Arg->getType(), Out); @@ -2747,7 +2791,6 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {  }  /// printBasicBlock - This member is called for each basic block in a method. -///  void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {    if (BB->hasName()) {              // Print out the label if it exists...      Out << "\n"; @@ -2813,7 +2856,6 @@ void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) {  /// printInfoComment - Print a little comment after the instruction indicating  /// which slot it occupies. -///  void AssemblyWriter::printInfoComment(const Value &V) {    if (const auto *Relocate = dyn_cast<GCRelocateInst>(&V))      printGCRelocateComment(*Relocate); @@ -3046,7 +3088,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {        Out << " #" << Machine.getAttributeGroupSlot(PAL.getFnAttributes());      writeOperandBundles(CI); -    } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {      Operand = II->getCalledValue();      FunctionType *FTy = II->getFunctionType(); @@ -3087,7 +3128,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {      writeOperand(II->getNormalDest(), true);      Out << " unwind ";      writeOperand(II->getUnwindDest(), true); -    } else if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) {      Out << ' ';      if (AI->isUsedWithInAlloca()) @@ -3113,7 +3153,6 @@ void AssemblyWriter::printInstruction(const Instruction &I) {      if (AddrSpace != 0) {        Out << ", addrspace(" << AddrSpace << ')';      } -    } else if (isa<CastInst>(I)) {      if (Operand) {        Out << ' ';  | 
