diff options
Diffstat (limited to 'llvm/lib/IR/AsmWriter.cpp')
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 244 |
1 files changed, 195 insertions, 49 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index acf0e4afef27..fd08310316b3 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -228,9 +228,9 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F, return LU->getOperandNo() > RU->getOperandNo(); }); - if (std::is_sorted( - List.begin(), List.end(), - [](const Entry &L, const Entry &R) { return L.second < R.second; })) + if (llvm::is_sorted(List, [](const Entry &L, const Entry &R) { + return L.second < R.second; + })) // Order is already correct. return; @@ -462,6 +462,33 @@ static void PrintLLVMName(raw_ostream &OS, const Value *V) { isa<GlobalValue>(V) ? GlobalPrefix : LocalPrefix); } +static void PrintShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef<int> Mask) { + Out << ", <"; + if (isa<ScalableVectorType>(Ty)) + Out << "vscale x "; + Out << Mask.size() << " x i32> "; + bool FirstElt = true; + if (all_of(Mask, [](int Elt) { return Elt == 0; })) { + Out << "zeroinitializer"; + } else if (all_of(Mask, [](int Elt) { return Elt == UndefMaskElem; })) { + Out << "undef"; + } else { + Out << "<"; + for (int Elt : Mask) { + if (FirstElt) + FirstElt = false; + else + Out << ", "; + Out << "i32 "; + if (Elt == UndefMaskElem) + Out << "undef"; + else + Out << Elt; + } + Out << ">"; + } +} + namespace { class TypePrinting { @@ -561,6 +588,7 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { switch (Ty->getTypeID()) { case Type::VoidTyID: OS << "void"; return; case Type::HalfTyID: OS << "half"; return; + case Type::BFloatTyID: OS << "bfloat"; return; case Type::FloatTyID: OS << "float"; return; case Type::DoubleTyID: OS << "double"; return; case Type::X86_FP80TyID: OS << "x86_fp80"; return; @@ -623,12 +651,14 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { OS << ']'; return; } - case Type::VectorTyID: { + case Type::FixedVectorTyID: + case Type::ScalableVectorTyID: { VectorType *PTy = cast<VectorType>(Ty); + ElementCount EC = PTy->getElementCount(); OS << "<"; - if (PTy->isScalable()) + if (EC.Scalable) OS << "vscale x "; - OS << PTy->getNumElements() << " x "; + OS << EC.Min << " x "; print(PTy->getElementType(), OS); OS << '>'; return; @@ -783,7 +813,7 @@ public: /// These functions do the actual initialization. inline void initializeIfNeeded(); - void initializeIndexIfNeeded(); + int initializeIndexIfNeeded(); // Implementation Details private: @@ -806,7 +836,8 @@ private: /// Add all of the module level global variables (and their initializers) /// and function declarations, but not the contents of those functions. void processModule(); - void processIndex(); + // Returns number of allocated slots + int processIndex(); /// Add all of the functions arguments, basic blocks, and instructions. void processFunction(); @@ -920,11 +951,12 @@ inline void SlotTracker::initializeIfNeeded() { processFunction(); } -void SlotTracker::initializeIndexIfNeeded() { +int SlotTracker::initializeIndexIfNeeded() { if (!TheIndex) - return; - processIndex(); + return 0; + int NumSlots = processIndex(); TheIndex = nullptr; ///< Prevent re-processing next time we're called. + return NumSlots; } // Iterate through all the global variables, functions, and global @@ -1019,7 +1051,7 @@ void SlotTracker::processFunction() { } // Iterate through all the GUID in the index and create slots for them. -void SlotTracker::processIndex() { +int SlotTracker::processIndex() { ST_DEBUG("begin processIndex!\n"); assert(TheIndex); @@ -1038,17 +1070,17 @@ void SlotTracker::processIndex() { for (auto &GlobalList : *TheIndex) CreateGUIDSlot(GlobalList.first); + for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) + 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); - for (auto &TId : TheIndex->typeIdCompatibleVtableMap()) - CreateGUIDSlot(GlobalValue::getGUID(TId.first)); - ST_DEBUG("end processIndex!\n"); + return TypeIdNext; } void SlotTracker::processGlobalObjectMetadata(const GlobalObject &GO) { @@ -1348,7 +1380,7 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, return; } - // Either half, or some form of long double. + // Either half, bfloat or some form of long double. // These appear as a magic letter identifying the type, then a // fixed number of hex digits. Out << "0x"; @@ -1376,6 +1408,10 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, Out << 'H'; Out << format_hex_no_prefix(API.getZExtValue(), 4, /*Upper=*/true); + } else if (&APF.getSemantics() == &APFloat::BFloat()) { + Out << 'R'; + Out << format_hex_no_prefix(API.getZExtValue(), 4, + /*Upper=*/true); } else llvm_unreachable("Unsupported floating point type"); return; @@ -1475,13 +1511,14 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, } if (isa<ConstantVector>(CV) || isa<ConstantDataVector>(CV)) { - Type *ETy = CV->getType()->getVectorElementType(); + auto *CVVTy = cast<VectorType>(CV->getType()); + Type *ETy = CVVTy->getElementType(); Out << '<'; TypePrinter.print(ETy, Out); Out << ' '; WriteAsOperandInternal(Out, CV->getAggregateElement(0U), &TypePrinter, Machine, Context); - for (unsigned i = 1, e = CV->getType()->getVectorNumElements(); i != e;++i){ + for (unsigned i = 1, e = CVVTy->getNumElements(); i != e; ++i) { Out << ", "; TypePrinter.print(ETy, Out); Out << ' '; @@ -1545,6 +1582,9 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, TypePrinter.print(CE->getType(), Out); } + if (CE->getOpcode() == Instruction::ShuffleVector) + PrintShuffleMask(Out, CE->getType(), CE->getShuffleMask()); + Out << ')'; return; } @@ -1614,6 +1654,8 @@ struct MDFieldPrinter { bool ShouldSkipNull = true); template <class IntTy> void printInt(StringRef Name, IntTy Int, bool ShouldSkipZero = true); + void printAPInt(StringRef Name, const APInt &Int, bool IsUnsigned, + bool ShouldSkipZero); void printBool(StringRef Name, bool Value, Optional<bool> Default = None); void printDIFlags(StringRef Name, DINode::DIFlags Flags); void printDISPFlags(StringRef Name, DISubprogram::DISPFlags Flags); @@ -1689,6 +1731,15 @@ void MDFieldPrinter::printInt(StringRef Name, IntTy Int, bool ShouldSkipZero) { Out << FS << Name << ": " << Int; } +void MDFieldPrinter::printAPInt(StringRef Name, const APInt &Int, + bool IsUnsigned, bool ShouldSkipZero) { + if (ShouldSkipZero && Int.isNullValue()) + return; + + Out << FS << Name << ": "; + Int.print(Out, !IsUnsigned); +} + void MDFieldPrinter::printBool(StringRef Name, bool Value, Optional<bool> Default) { if (Default && Value == *Default) @@ -1807,9 +1858,34 @@ static void writeDISubrange(raw_ostream &Out, const DISubrange *N, if (auto *CE = N->getCount().dyn_cast<ConstantInt*>()) Printer.printInt("count", CE->getSExtValue(), /* ShouldSkipZero */ false); else - Printer.printMetadata("count", N->getCount().dyn_cast<DIVariable*>(), - /*ShouldSkipNull */ false); - Printer.printInt("lowerBound", N->getLowerBound()); + Printer.printMetadata("count", N->getCount().dyn_cast<DIVariable *>(), + /*ShouldSkipNull */ true); + + // A lowerBound of constant 0 should not be skipped, since it is different + // from an unspecified lower bound (= nullptr). + auto *LBound = N->getRawLowerBound(); + if (auto *LE = dyn_cast_or_null<ConstantAsMetadata>(LBound)) { + auto *LV = cast<ConstantInt>(LE->getValue()); + Printer.printInt("lowerBound", LV->getSExtValue(), + /* ShouldSkipZero */ false); + } else + Printer.printMetadata("lowerBound", LBound, /*ShouldSkipNull */ true); + + auto *UBound = N->getRawUpperBound(); + if (auto *UE = dyn_cast_or_null<ConstantAsMetadata>(UBound)) { + auto *UV = cast<ConstantInt>(UE->getValue()); + Printer.printInt("upperBound", UV->getSExtValue(), + /* ShouldSkipZero */ false); + } else + Printer.printMetadata("upperBound", UBound, /*ShouldSkipNull */ true); + + auto *Stride = N->getRawStride(); + if (auto *SE = dyn_cast_or_null<ConstantAsMetadata>(Stride)) { + auto *SV = cast<ConstantInt>(SE->getValue()); + Printer.printInt("stride", SV->getSExtValue(), /* ShouldSkipZero */ false); + } else + Printer.printMetadata("stride", Stride, /*ShouldSkipNull */ true); + Out << ")"; } @@ -1818,13 +1894,10 @@ static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N, Out << "!DIEnumerator("; MDFieldPrinter Printer(Out); Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false); - if (N->isUnsigned()) { - auto Value = static_cast<uint64_t>(N->getValue()); - Printer.printInt("value", Value, /* ShouldSkipZero */ false); + Printer.printAPInt("value", N->getValue(), N->isUnsigned(), + /*ShouldSkipZero=*/false); + if (N->isUnsigned()) Printer.printBool("isUnsigned", true); - } else { - Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false); - } Out << ")"; } @@ -1888,6 +1961,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N, Printer.printMetadata("templateParams", N->getRawTemplateParams()); Printer.printString("identifier", N->getIdentifier()); Printer.printMetadata("discriminator", N->getRawDiscriminator()); + Printer.printMetadata("dataLocation", N->getRawDataLocation()); Out << ")"; } @@ -1945,6 +2019,8 @@ static void writeDICompileUnit(raw_ostream &Out, const DICompileUnit *N, false); Printer.printNameTableKind("nameTableKind", N->getNameTableKind()); Printer.printBool("rangesBaseAddress", N->getRangesBaseAddress(), false); + Printer.printString("sysroot", N->getSysRoot()); + Printer.printString("sdk", N->getSDK()); Out << ")"; } @@ -2057,7 +2133,9 @@ static void writeDIModule(raw_ostream &Out, const DIModule *N, Printer.printString("name", N->getName()); Printer.printString("configMacros", N->getConfigurationMacros()); Printer.printString("includePath", N->getIncludePath()); - Printer.printString("sysroot", N->getSysRoot()); + Printer.printString("apinotes", N->getAPINotesFile()); + Printer.printMetadata("file", N->getRawFile()); + Printer.printInt("line", N->getLineNo()); Out << ")"; } @@ -2071,6 +2149,7 @@ static void writeDITemplateTypeParameter(raw_ostream &Out, MDFieldPrinter Printer(Out, TypePrinter, Machine, Context); Printer.printString("name", N->getName()); Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false); + Printer.printBool("defaulted", N->isDefault(), /* Default= */ false); Out << ")"; } @@ -2085,6 +2164,7 @@ static void writeDITemplateValueParameter(raw_ostream &Out, Printer.printTag(N); Printer.printString("name", N->getName()); Printer.printMetadata("type", N->getRawType()); + Printer.printBool("defaulted", N->isDefault(), /* Default= */ false); Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false); Out << ")"; } @@ -2430,10 +2510,10 @@ public: void printTypeIdInfo(const FunctionSummary::TypeIdInfo &TIDInfo); void printVFuncId(const FunctionSummary::VFuncId VFId); void - printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> VCallList, + printNonConstVCalls(const std::vector<FunctionSummary::VFuncId> &VCallList, const char *Tag); void - printConstVCalls(const std::vector<FunctionSummary::ConstVCall> VCallList, + printConstVCalls(const std::vector<FunctionSummary::ConstVCall> &VCallList, const char *Tag); private: @@ -2651,8 +2731,10 @@ void AssemblyWriter::printModule(const Module *M) { printUseLists(nullptr); // Output all of the functions. - for (const Function &F : *M) + for (const Function &F : *M) { + Out << '\n'; printFunction(&F); + } assert(UseListOrders.empty() && "All use-lists should have been consumed"); // Output all attribute groups. @@ -2676,21 +2758,22 @@ void AssemblyWriter::printModule(const Module *M) { void AssemblyWriter::printModuleSummaryIndex() { assert(TheIndex); - Machine.initializeIndexIfNeeded(); + int NumSlots = Machine.initializeIndexIfNeeded(); Out << "\n"; // Print module path entries. To print in order, add paths to a vector // indexed by module slot. std::vector<std::pair<std::string, ModuleHash>> moduleVec; - std::string RegularLTOModuleName = "[Regular LTO]"; + std::string RegularLTOModuleName = + ModuleSummaryIndex::getRegularLTOModuleName(); moduleVec.resize(TheIndex->modulePaths().size()); for (auto &ModPath : TheIndex->modulePaths()) moduleVec[Machine.getModulePathSlot(ModPath.first())] = std::make_pair( // A module id of -1 is a special entry for a regular LTO module created // during the thin link. ModPath.second.first == -1u ? RegularLTOModuleName - : (std::string)ModPath.first(), + : (std::string)std::string(ModPath.first()), ModPath.second.second); unsigned i = 0; @@ -2737,6 +2820,15 @@ void AssemblyWriter::printModuleSummaryIndex() { printTypeIdCompatibleVtableSummary(TId.second); Out << ") ; guid = " << GUID << "\n"; } + + // Don't emit flags when it's not really needed (value is zero by default). + if (TheIndex->getFlags()) { + Out << "^" << NumSlots << " = flags: " << TheIndex->getFlags() << "\n"; + ++NumSlots; + } + + Out << "^" << NumSlots << " = blockcount: " << TheIndex->getBlockCount() + << "\n"; } static const char * @@ -2769,6 +2861,8 @@ static const char *getWholeProgDevirtResByArgKindName( static const char *getTTResKindName(TypeTestResolution::Kind K) { switch (K) { + case TypeTestResolution::Unknown: + return "unknown"; case TypeTestResolution::Unsat: return "unsat"; case TypeTestResolution::ByteArray: @@ -2900,10 +2994,15 @@ void AssemblyWriter::printAliasSummary(const AliasSummary *AS) { } void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) { + auto VTableFuncs = GS->vTableFuncs(); Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", " - << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ")"; + << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", " + << "constant: " << GS->VarFlags.Constant; + if (!VTableFuncs.empty()) + Out << ", " + << "vcall_visibility: " << GS->VarFlags.VCallVisibility; + Out << ")"; - auto VTableFuncs = GS->vTableFuncs(); if (!VTableFuncs.empty()) { Out << ", vTableFuncs: ("; FieldSeparator FS; @@ -2986,6 +3085,36 @@ void AssemblyWriter::printFunctionSummary(const FunctionSummary *FS) { if (const auto *TIdInfo = FS->getTypeIdInfo()) printTypeIdInfo(*TIdInfo); + + auto PrintRange = [&](const ConstantRange &Range) { + Out << "[" << Range.getLower() << ", " << Range.getSignedMax() << "]"; + }; + + if (!FS->paramAccesses().empty()) { + Out << ", params: ("; + FieldSeparator IFS; + for (auto &PS : FS->paramAccesses()) { + Out << IFS; + Out << "(param: " << PS.ParamNo; + Out << ", offset: "; + PrintRange(PS.Use); + if (!PS.Calls.empty()) { + Out << ", calls: ("; + FieldSeparator IFS; + for (auto &Call : PS.Calls) { + Out << IFS; + Out << "(callee: ^" << Machine.getGUIDSlot(Call.Callee); + Out << ", param: " << Call.ParamNo; + Out << ", offset: "; + PrintRange(Call.Offsets); + Out << ")"; + } + Out << ")"; + } + Out << ")"; + } + Out << ")"; + } } void AssemblyWriter::printTypeIdInfo( @@ -3057,7 +3186,7 @@ void AssemblyWriter::printVFuncId(const FunctionSummary::VFuncId VFId) { } void AssemblyWriter::printNonConstVCalls( - const std::vector<FunctionSummary::VFuncId> VCallList, const char *Tag) { + const std::vector<FunctionSummary::VFuncId> &VCallList, const char *Tag) { Out << Tag << ": ("; FieldSeparator FS; for (auto &VFuncId : VCallList) { @@ -3068,7 +3197,8 @@ void AssemblyWriter::printNonConstVCalls( } void AssemblyWriter::printConstVCalls( - const std::vector<FunctionSummary::ConstVCall> VCallList, const char *Tag) { + const std::vector<FunctionSummary::ConstVCall> &VCallList, + const char *Tag) { Out << Tag << ": ("; FieldSeparator FS; for (auto &ConstVCall : VCallList) { @@ -3200,11 +3330,7 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis, static void PrintDSOLocation(const GlobalValue &GV, formatted_raw_ostream &Out) { - // GVs with local linkage or non default visibility are implicitly dso_local, - // so we don't print it. - bool Implicit = GV.hasLocalLinkage() || - (!GV.hasExternalWeakLinkage() && !GV.hasDefaultVisibility()); - if (GV.isDSOLocal() && !Implicit) + if (GV.isDSOLocal() && !GV.isImplicitDSOLocal()) Out << "dso_local "; } @@ -3850,7 +3976,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { PrintCallingConv(CI->getCallingConv(), Out); } - Operand = CI->getCalledValue(); + Operand = CI->getCalledOperand(); FunctionType *FTy = CI->getFunctionType(); Type *RetTy = FTy->getReturnType(); const AttributeList &PAL = CI->getAttributes(); @@ -3889,7 +4015,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperandBundles(CI); } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { - Operand = II->getCalledValue(); + Operand = II->getCalledOperand(); FunctionType *FTy = II->getFunctionType(); Type *RetTy = FTy->getReturnType(); const AttributeList &PAL = II->getAttributes(); @@ -3932,7 +4058,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { Out << " unwind "; writeOperand(II->getUnwindDest(), true); } else if (const CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) { - Operand = CBI->getCalledValue(); + Operand = CBI->getCalledOperand(); FunctionType *FTy = CBI->getFunctionType(); Type *RetTy = FTy->getReturnType(); const AttributeList &PAL = CBI->getAttributes(); @@ -4079,6 +4205,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { RMWI->getSyncScopeID()); } else if (const FenceInst *FI = dyn_cast<FenceInst>(&I)) { writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID()); + } else if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(&I)) { + PrintShuffleMask(Out, SVI->getType(), SVI->getShuffleMask()); } // Print Metadata info. @@ -4140,9 +4268,16 @@ void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) { return; } - assert(Attr.hasAttribute(Attribute::ByVal) && "unexpected type attr"); + assert((Attr.hasAttribute(Attribute::ByVal) || + Attr.hasAttribute(Attribute::Preallocated)) && + "unexpected type attr"); + + if (Attr.hasAttribute(Attribute::ByVal)) { + Out << "byval"; + } else { + Out << "preallocated"; + } - Out << "byval"; if (Type *Ty = Attr.getValueAsType()) { Out << '('; TypePrinter.print(Ty, Out); @@ -4228,6 +4363,17 @@ void Function::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW, W.printFunction(this); } +void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW, + bool ShouldPreserveUseListOrder, + bool IsForDebug) const { + SlotTracker SlotTable(this->getModule()); + formatted_raw_ostream OS(ROS); + AssemblyWriter W(OS, SlotTable, this->getModule(), AAW, + IsForDebug, + ShouldPreserveUseListOrder); + W.printBasicBlock(this); +} + void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW, bool ShouldPreserveUseListOrder, bool IsForDebug) const { SlotTracker SlotTable(this); |