diff options
Diffstat (limited to 'lib/IR/AsmWriter.cpp')
| -rw-r--r-- | lib/IR/AsmWriter.cpp | 228 |
1 files changed, 155 insertions, 73 deletions
diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 99a25a723b4a..a5dc623e1a30 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -36,7 +36,6 @@ #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" @@ -199,7 +198,7 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F, !isa<GlobalVariable>(V) && !isa<Function>(V) && !isa<BasicBlock>(V); if (auto *BA = dyn_cast<BlockAddress>(V)) ID = OM.lookup(BA->getBasicBlock()).first; - llvm::sort(List.begin(), List.end(), [&](const Entry &L, const Entry &R) { + llvm::sort(List, [&](const Entry &L, const Entry &R) { const Use *LU = L.first; const Use *RU = R.first; if (LU == RU) @@ -363,6 +362,7 @@ static void PrintCallingConv(unsigned cc, raw_ostream &Out) { case CallingConv::ARM_APCS: Out << "arm_apcscc"; break; case CallingConv::ARM_AAPCS: Out << "arm_aapcscc"; break; case CallingConv::ARM_AAPCS_VFP: Out << "arm_aapcs_vfpcc"; break; + case CallingConv::AArch64_VectorCall: Out << "aarch64_vector_pcs"; break; case CallingConv::MSP430_INTR: Out << "msp430_intrcc"; break; case CallingConv::AVR_INTR: Out << "avr_intrcc "; break; case CallingConv::AVR_SIGNAL: Out << "avr_signalcc "; break; @@ -704,6 +704,10 @@ private: DenseMap<GlobalValue::GUID, unsigned> GUIDMap; unsigned GUIDNext = 0; + /// TypeIdMap - The slot map for type ids used in the summary index. + StringMap<unsigned> TypeIdMap; + unsigned TypeIdNext = 0; + public: /// Construct from a module. /// @@ -735,6 +739,7 @@ public: int getAttributeGroupSlot(AttributeSet AS); int getModulePathSlot(StringRef Path); int getGUIDSlot(GlobalValue::GUID GUID); + int getTypeIdSlot(StringRef Id); /// If you'd like to deal with a function instead of just a module, use /// this method to get its data into the SlotTracker. @@ -789,6 +794,7 @@ private: inline void CreateModulePathSlot(StringRef Path); void CreateGUIDSlot(GlobalValue::GUID GUID); + void CreateTypeIdSlot(StringRef Id); /// Add all of the module level global variables (and their initializers) /// and function declarations, but not the contents of those functions. @@ -991,9 +997,9 @@ void SlotTracker::processFunction() { // We allow direct calls to any llvm.foo function here, because the // target may not be linked into the optimizer. - if (auto CS = ImmutableCallSite(&I)) { + if (const auto *Call = dyn_cast<CallBase>(&I)) { // Add all the call attributes to the table. - AttributeSet Attrs = CS.getAttributes().getFnAttributes(); + AttributeSet Attrs = Call->getAttributes().getFnAttributes(); if (Attrs.hasAttributes()) CreateAttributeSetSlot(Attrs); } @@ -1025,8 +1031,12 @@ void SlotTracker::processIndex() { for (auto &GlobalList : *TheIndex) CreateGUIDSlot(GlobalList.first); - for (auto &TId : TheIndex->typeIds()) - CreateGUIDSlot(GlobalValue::getGUID(TId.first)); + // Start numbering the TypeIds after the GUIDs. + TypeIdNext = GUIDNext; + + for (auto TidIter = TheIndex->typeIds().begin(); + TidIter != TheIndex->typeIds().end(); TidIter++) + CreateTypeIdSlot(TidIter->second.first); ST_DEBUG("end processIndex!\n"); } @@ -1132,6 +1142,15 @@ int SlotTracker::getGUIDSlot(GlobalValue::GUID GUID) { return I == GUIDMap.end() ? -1 : (int)I->second; } +int SlotTracker::getTypeIdSlot(StringRef Id) { + // Check for uninitialized state and do lazy initialization. + initializeIndexIfNeeded(); + + // Find the TypeId string in the map + auto I = TypeIdMap.find(Id); + return I == TypeIdMap.end() ? -1 : (int)I->second; +} + /// CreateModuleSlot - Insert the specified GlobalValue* into the slot table. void SlotTracker::CreateModuleSlot(const GlobalValue *V) { assert(V && "Can't insert a null Value into SlotTracker!"); @@ -1202,6 +1221,11 @@ void SlotTracker::CreateGUIDSlot(GlobalValue::GUID GUID) { GUIDMap[GUID] = GUIDNext++; } +/// Create a new slot for the specified Id +void SlotTracker::CreateTypeIdSlot(StringRef Id) { + TypeIdMap[Id] = TypeIdNext++; +} + //===----------------------------------------------------------------------===// // AsmWriter Implementation //===----------------------------------------------------------------------===// @@ -1216,24 +1240,6 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, SlotTracker *Machine, const Module *Context, bool FromValue = false); -static void writeAtomicRMWOperation(raw_ostream &Out, - AtomicRMWInst::BinOp Op) { - switch (Op) { - default: Out << " <unknown operation " << Op << ">"; break; - case AtomicRMWInst::Xchg: Out << " xchg"; break; - case AtomicRMWInst::Add: Out << " add"; break; - case AtomicRMWInst::Sub: Out << " sub"; break; - case AtomicRMWInst::And: Out << " and"; break; - case AtomicRMWInst::Nand: Out << " nand"; break; - case AtomicRMWInst::Or: Out << " or"; break; - case AtomicRMWInst::Xor: Out << " xor"; break; - case AtomicRMWInst::Max: Out << " max"; break; - case AtomicRMWInst::Min: Out << " min"; break; - case AtomicRMWInst::UMax: Out << " umax"; break; - case AtomicRMWInst::UMin: Out << " umin"; break; - } -} - static void WriteOptimizationInfo(raw_ostream &Out, const User *U) { if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U)) { // 'Fast' is an abbreviation for all fast-math-flags. @@ -1600,10 +1606,13 @@ struct MDFieldPrinter { void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true); void printBool(StringRef Name, bool Value, Optional<bool> Default = None); void printDIFlags(StringRef Name, DINode::DIFlags Flags); + void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags); template <class IntTy, class Stringifier> void printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString, bool ShouldSkipZero = true); void printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK); + void printNameTableKind(StringRef Name, + DICompileUnit::DebugNameTableKind NTK); }; } // end anonymous namespace @@ -1696,11 +1705,42 @@ void MDFieldPrinter::printDIFlags(StringRef Name, DINode::DIFlags Flags) { Out << FlagsFS << Extra; } +void MDFieldPrinter::printDISPFlags(StringRef Name, + DISubprogram::DISPFlags Flags) { + // Always print this field, because no flags in the IR at all will be + // interpreted as old-style isDefinition: true. + Out << FS << Name << ": "; + + if (!Flags) { + Out << 0; + return; + } + + SmallVector<DISubprogram::DISPFlags, 8> SplitFlags; + auto Extra = DISubprogram::splitFlags(Flags, SplitFlags); + + FieldSeparator FlagsFS(" | "); + for (auto F : SplitFlags) { + auto StringF = DISubprogram::getFlagString(F); + assert(!StringF.empty() && "Expected valid flag"); + Out << FlagsFS << StringF; + } + if (Extra || SplitFlags.empty()) + Out << FlagsFS << Extra; +} + void MDFieldPrinter::printEmissionKind(StringRef Name, DICompileUnit::DebugEmissionKind EK) { Out << FS << Name << ": " << DICompileUnit::emissionKindString(EK); } +void MDFieldPrinter::printNameTableKind(StringRef Name, + DICompileUnit::DebugNameTableKind NTK) { + if (NTK == DICompileUnit::DebugNameTableKind::Default) + return; + Out << FS << Name << ": " << DICompileUnit::nameTableKindString(NTK); +} + template <class IntTy, class Stringifier> void MDFieldPrinter::printDwarfEnum(StringRef Name, IntTy Value, Stringifier toString, bool ShouldSkipZero) { @@ -1744,6 +1784,8 @@ static void writeDILocation(raw_ostream &Out, const DILocation *DL, Printer.printInt("column", DL->getColumn()); Printer.printMetadata("scope", DL->getRawScope(), /* ShouldSkipNull */ false); Printer.printMetadata("inlinedAt", DL->getRawInlinedAt()); + Printer.printBool("isImplicitCode", DL->isImplicitCode(), + /* Default */ false); Out << ")"; } @@ -1787,6 +1829,7 @@ static void writeDIBasicType(raw_ostream &Out, const DIBasicType *N, Printer.printInt("align", N->getAlignInBits()); Printer.printDwarfEnum("encoding", N->getEncoding(), dwarf::AttributeEncodingString); + Printer.printDIFlags("flags", N->getFlags()); Out << ")"; } @@ -1890,7 +1933,8 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, Printer.printBool("splitDebugInlining", N->getSplitDebugInlining(), true); Printer.printBool("debugInfoForProfiling", N->getDebugInfoForProfiling(), false); - Printer.printBool("gnuPubnames", N->getGnuPubnames(), false); + Printer.printNameTableKind("nameTableKind", N->getNameTableKind()); + Printer.printBool("rangesBaseAddress", N->getRangesBaseAddress(), false); Out << ")"; } @@ -1905,18 +1949,14 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, Printer.printMetadata("file", N->getRawFile()); Printer.printInt("line", N->getLine()); Printer.printMetadata("type", N->getRawType()); - Printer.printBool("isLocal", N->isLocalToUnit()); - Printer.printBool("isDefinition", N->isDefinition()); Printer.printInt("scopeLine", N->getScopeLine()); Printer.printMetadata("containingType", N->getRawContainingType()); - Printer.printDwarfEnum("virtuality", N->getVirtuality(), - dwarf::VirtualityString); if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none || N->getVirtualIndex() != 0) Printer.printInt("virtualIndex", N->getVirtualIndex(), false); Printer.printInt("thisAdjustment", N->getThisAdjustment()); Printer.printDIFlags("flags", N->getFlags()); - Printer.printBool("isOptimized", N->isOptimized()); + Printer.printDISPFlags("spFlags", N->getSPFlags()); Printer.printMetadata("unit", N->getRawUnit()); Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printMetadata("declaration", N->getRawDeclaration()); @@ -2040,6 +2080,7 @@ static void writeDIGlobalVariable(raw_ostream &Out, const DIGlobalVariable *N, Printer.printBool("isLocal", N->isLocalToUnit()); Printer.printBool("isDefinition", N->isDefinition()); Printer.printMetadata("declaration", N->getRawStaticDataMemberDeclaration()); + Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printInt("align", N->getAlignInBits()); Out << ")"; } @@ -2252,11 +2293,15 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD, Machine = MachineStorage.get(); } int Slot = Machine->getMetadataSlot(N); - if (Slot == -1) + if (Slot == -1) { + if (const DILocation *Loc = dyn_cast<DILocation>(N)) { + writeDILocation(Out, Loc, TypePrinter, Machine, Context); + return; + } // Give the pointer value instead of "badref", since this comes up all // the time when debugging. Out << "<" << N << ">"; - else + } else Out << '!' << Slot; return; } @@ -2313,7 +2358,7 @@ public: void writeOperand(const Value *Op, bool PrintType); void writeParamOperand(const Value *Operand, AttributeSet Attrs); - void writeOperandBundles(ImmutableCallSite CS); + void writeOperandBundles(const CallBase *Call); void writeSyncScope(const LLVMContext &Context, SyncScope::ID SSID); void writeAtomic(const LLVMContext &Context, @@ -2464,15 +2509,15 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule); } -void AssemblyWriter::writeOperandBundles(ImmutableCallSite CS) { - if (!CS.hasOperandBundles()) +void AssemblyWriter::writeOperandBundles(const CallBase *Call) { + if (!Call->hasOperandBundles()) return; Out << " [ "; bool FirstBundle = true; - for (unsigned i = 0, e = CS.getNumOperandBundles(); i != e; ++i) { - OperandBundleUse BU = CS.getOperandBundleAt(i); + for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i) { + OperandBundleUse BU = Call->getOperandBundleAt(i); if (!FirstBundle) Out << ", "; @@ -2643,12 +2688,12 @@ void AssemblyWriter::printModuleSummaryIndex() { } // Print the TypeIdMap entries. - for (auto &TId : TheIndex->typeIds()) { - auto GUID = GlobalValue::getGUID(TId.first); - Out << "^" << Machine.getGUIDSlot(GUID) << " = typeid: (name: \"" - << TId.first << "\""; - printTypeIdSummary(TId.second); - Out << ") ; guid = " << GUID << "\n"; + for (auto TidIter = TheIndex->typeIds().begin(); + TidIter != TheIndex->typeIds().end(); TidIter++) { + Out << "^" << Machine.getTypeIdSlot(TidIter->second.first) + << " = typeid: (name: \"" << TidIter->second.first << "\""; + printTypeIdSummary(TidIter->second.second); + Out << ") ; guid = " << TidIter->first << "\n"; } } @@ -2800,7 +2845,7 @@ void AssemblyWriter::printAliasSummary(const AliasSummary *AS) { } void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) { - // Nothing for now + Out << ", varFlags: (readonly: " << GS->VarFlags.ReadOnly << ")"; } static std::string getLinkageName(GlobalValue::LinkageTypes LT) { @@ -2840,22 +2885,6 @@ static std::string getLinkageNameWithSpace(GlobalValue::LinkageTypes LT) { return getLinkageName(LT) + " "; } -static const char *getHotnessName(CalleeInfo::HotnessType HT) { - switch (HT) { - case CalleeInfo::HotnessType::Unknown: - return "unknown"; - case CalleeInfo::HotnessType::Cold: - return "cold"; - case CalleeInfo::HotnessType::None: - return "none"; - case CalleeInfo::HotnessType::Hot: - return "hot"; - case CalleeInfo::HotnessType::Critical: - return "critical"; - } - llvm_unreachable("invalid hotness"); -} - void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) { Out << ", insts: " << FS->instCount(); @@ -2867,6 +2896,7 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) { Out << ", readOnly: " << FFlags.ReadOnly; Out << ", noRecurse: " << FFlags.NoRecurse; Out << ", returnDoesNotAlias: " << FFlags.ReturnDoesNotAlias; + Out << ", noInline: " << FFlags.NoInline; Out << ")"; } if (!FS->calls().empty()) { @@ -2897,12 +2927,19 @@ void AssemblyWriter::printTypeIdInfo( Out << "typeTests: ("; FieldSeparator FS; for (auto &GUID : TIDInfo.TypeTests) { - Out << FS; - auto Slot = Machine.getGUIDSlot(GUID); - if (Slot != -1) - Out << "^" << Slot; - else + auto TidIter = TheIndex->typeIds().equal_range(GUID); + if (TidIter.first == TidIter.second) { + Out << FS; Out << GUID; + continue; + } + // Print all type id that correspond to this GUID. + for (auto It = TidIter.first; It != TidIter.second; ++It) { + Out << FS; + auto Slot = Machine.getTypeIdSlot(It->second.first); + assert(Slot != -1); + Out << "^" << Slot; + } } Out << ")"; } @@ -2928,14 +2965,25 @@ void AssemblyWriter::printTypeIdInfo( } void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) { - Out << "vFuncId: ("; - auto Slot = Machine.getGUIDSlot(VFId.GUID); - if (Slot != -1) - Out << "^" << Slot; - else + auto TidIter = TheIndex->typeIds().equal_range(VFId.GUID); + if (TidIter.first == TidIter.second) { + Out << "vFuncId: ("; Out << "guid: " << VFId.GUID; - Out << ", offset: " << VFId.Offset; - Out << ")"; + Out << ", offset: " << VFId.Offset; + Out << ")"; + return; + } + // Print all type id that correspond to this GUID. + FieldSeparator FS; + for (auto It = TidIter.first; It != TidIter.second; ++It) { + Out << FS; + Out << "vFuncId: ("; + auto Slot = Machine.getTypeIdSlot(It->second.first); + assert(Slot != -1); + Out << "^" << Slot; + Out << ", offset: " << VFId.Offset; + Out << ")"; + } } void AssemblyWriter::printNonConstVCalls( @@ -2955,11 +3003,13 @@ void AssemblyWriter::printConstVCalls( FieldSeparator FS; for (auto &ConstVCall : VCallList) { Out << FS; + Out << "("; printVFuncId(ConstVCall.VFunc); if (!ConstVCall.Args.empty()) { Out << ", "; printArgs(ConstVCall.Args); } + Out << ")"; } Out << ")"; } @@ -2989,6 +3039,8 @@ void AssemblyWriter::printSummary(const GlobalValueSummary &Summary) { FieldSeparator FS; for (auto &Ref : RefList) { Out << FS; + if (Ref.isReadOnly()) + Out << "readonly "; Out << "^" << Machine.getGUIDSlot(Ref.getGUID()); } Out << ")"; @@ -3354,6 +3406,13 @@ void AssemblyWriter::printFunction(const Function *F) { StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr()); if (!UA.empty()) Out << ' ' << UA; + // We print the function address space if it is non-zero or if we are writing + // a module with a non-zero program address space or if there is no valid + // Module* so that the file can be parsed without the datalayout string. + const Module *Mod = F->getParent(); + if (F->getAddressSpace() != 0 || !Mod || + Mod->getDataLayout().getProgramAddressSpace() != 0) + Out << " addrspace(" << F->getAddressSpace() << ")"; if (Attrs.hasAttributes(AttributeList::FunctionIndex)) Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes()); if (F->hasSection()) { @@ -3491,6 +3550,23 @@ void AssemblyWriter::printInfoComment(const Value &V) { AnnotationWriter->printInfoComment(V, Out); } +static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I, + raw_ostream &Out) { + // We print the address space of the call if it is non-zero. + unsigned CallAddrSpace = Operand->getType()->getPointerAddressSpace(); + bool PrintAddrSpace = CallAddrSpace != 0; + if (!PrintAddrSpace) { + const Module *Mod = getModuleFromVal(I); + // We also print it if it is zero but not equal to the program address space + // or if we can't find a valid Module* to make it possible to parse + // the resulting file even without a datalayout string. + if (!Mod || Mod->getDataLayout().getProgramAddressSpace() != 0) + PrintAddrSpace = true; + } + if (PrintAddrSpace) + Out << " addrspace(" << CallAddrSpace << ")"; +} + // This member is called for each Instruction in a function.. void AssemblyWriter::printInstruction(const Instruction &I) { if (AnnotationWriter) AnnotationWriter->emitInstructionAnnot(&I, Out); @@ -3547,7 +3623,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { // Print out the atomicrmw operation if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(&I)) - writeAtomicRMWOperation(Out, RMWI->getOperation()); + Out << ' ' << AtomicRMWInst::getOperationName(RMWI->getOperation()); // Print out the type of the operands... const Value *Operand = I.getNumOperands() ? I.getOperand(0) : nullptr; @@ -3688,6 +3764,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.hasAttributes(AttributeList::ReturnIndex)) Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex); + // Only print addrspace(N) if necessary: + maybePrintCallAddrSpace(Operand, &I, Out); + // If possible, print out the short form of the call instruction. We can // only do this if the first argument is a pointer to a nonvararg function, // and if the return type is not a pointer to a function. @@ -3730,6 +3809,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) { if (PAL.hasAttributes(AttributeList::ReturnIndex)) Out << ' ' << PAL.getAsString(AttributeList::ReturnIndex); + // Only print addrspace(N) if necessary: + maybePrintCallAddrSpace(Operand, &I, Out); + // If possible, print out the short form of the invoke instruction. We can // only do this if the first argument is a pointer to a nonvararg function, // and if the return type is not a pointer to a function. |
