diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -642,7 +642,8 @@ ? llvm::DICompileUnit::DebugNameTableKind::None : static_cast( CGOpts.DebugNameTable), - CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK); + CGOpts.DebugRangesBaseAddress, remapDIPath(Sysroot), SDK, + CGOpts.hasProfileIRUse()); } llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h --- a/llvm/include/llvm/IR/DIBuilder.h +++ b/llvm/include/llvm/IR/DIBuilder.h @@ -138,6 +138,8 @@ /// \param SysRoot The clang system root (value of -isysroot). /// \param SDK The SDK name. On Darwin, this is the last component /// of the sysroot. + /// \param HasPGO A boolean flag which indicates whether PGO data + /// is available or not DICompileUnit * createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, @@ -149,7 +151,7 @@ DICompileUnit::DebugNameTableKind NameTableKind = DICompileUnit::DebugNameTableKind::Default, bool RangesBaseAddress = false, StringRef SysRoot = {}, - StringRef SDK = {}); + StringRef SDK = {}, bool HasPGO = false); /// Create a file descriptor to hold debugging information for a file. /// \param Filename File name. diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1333,6 +1333,7 @@ private: unsigned SourceLanguage; bool IsOptimized; + bool HasPGO; unsigned RuntimeVersion; unsigned EmissionKind; uint64_t DWOId; @@ -1345,13 +1346,14 @@ bool IsOptimized, unsigned RuntimeVersion, unsigned EmissionKind, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, unsigned NameTableKind, - bool RangesBaseAddress, ArrayRef Ops) + bool RangesBaseAddress, bool HasPGO, ArrayRef Ops) : DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops), SourceLanguage(SourceLanguage), IsOptimized(IsOptimized), RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), DWOId(DWOId), SplitDebugInlining(SplitDebugInlining), DebugInfoForProfiling(DebugInfoForProfiling), - NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) { + NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress), + HasPGO(HasPGO) { assert(Storage != Uniqued); } ~DICompileUnit() = default; @@ -1366,7 +1368,8 @@ DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot, - StringRef SDK, StorageType Storage, bool ShouldCreate = true) { + StringRef SDK, bool HasPGO, StorageType Storage, + bool ShouldCreate = true) { return getImpl( Context, SourceLanguage, File, getCanonicalMDString(Context, Producer), IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion, @@ -1375,7 +1378,7 @@ ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining, DebugInfoForProfiling, NameTableKind, RangesBaseAddress, getCanonicalMDString(Context, SysRoot), - getCanonicalMDString(Context, SDK), Storage, ShouldCreate); + getCanonicalMDString(Context, SDK), HasPGO, Storage, ShouldCreate); } static DICompileUnit * getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File, @@ -1385,7 +1388,7 @@ Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, unsigned NameTableKind, - bool RangesBaseAddress, MDString *SysRoot, MDString *SDK, + bool RangesBaseAddress, MDString *SysRoot, MDString *SDK, bool HasPGO, StorageType Storage, bool ShouldCreate = true); TempDICompileUnit cloneImpl() const { @@ -1395,7 +1398,7 @@ getEmissionKind(), getEnumTypes(), getRetainedTypes(), getGlobalVariables(), getImportedEntities(), getMacros(), DWOId, getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(), - getRangesBaseAddress(), getSysRoot(), getSDK()); + getRangesBaseAddress(), getSysRoot(), getSDK(), hasPGO()); } public: @@ -1412,12 +1415,12 @@ DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, DebugNameTableKind NameTableKind, bool RangesBaseAddress, - StringRef SysRoot, StringRef SDK), + StringRef SysRoot, StringRef SDK, bool HasPGO), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress, - SysRoot, SDK)) + SysRoot, SDK, HasPGO)) DEFINE_MDNODE_GET_DISTINCT_TEMPORARY( DICompileUnit, (unsigned SourceLanguage, Metadata *File, MDString *Producer, @@ -1427,16 +1430,18 @@ Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot, - MDString *SDK), + MDString *SDK, bool HasPGO), (SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining, - DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK)) + DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK, + HasPGO)) TempDICompileUnit clone() const { return cloneImpl(); } unsigned getSourceLanguage() const { return SourceLanguage; } bool isOptimized() const { return IsOptimized; } + bool hasPGO() const { return HasPGO; } unsigned getRuntimeVersion() const { return RuntimeVersion; } DebugEmissionKind getEmissionKind() const { return (DebugEmissionKind)EmissionKind; diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -5001,7 +5001,8 @@ OPTIONAL(nameTableKind, NameTableKindField, ); \ OPTIONAL(rangesBaseAddress, MDBoolField, = false); \ OPTIONAL(sysroot, MDStringField, ); \ - OPTIONAL(sdk, MDStringField, ); + OPTIONAL(sdk, MDStringField, ); \ + OPTIONAL(hasPGO, MDBoolField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -5010,7 +5011,7 @@ runtimeVersion.Val, splitDebugFilename.Val, emissionKind.Val, enums.Val, retainedTypes.Val, globals.Val, imports.Val, macros.Val, dwoId.Val, splitDebugInlining.Val, debugInfoForProfiling.Val, nameTableKind.Val, - rangesBaseAddress.Val, sysroot.Val, sdk.Val); + rangesBaseAddress.Val, sysroot.Val, sdk.Val, hasPGO.Val); return false; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -1608,7 +1608,7 @@ break; } case bitc::METADATA_COMPILE_UNIT: { - if (Record.size() < 14 || Record.size() > 22) + if (Record.size() < 14 || Record.size() > 23) return error("Invalid record"); // Ignore Record[0], which indicates whether this compile unit is @@ -1626,7 +1626,8 @@ Record.size() <= 18 ? 0 : Record[18], Record.size() <= 19 ? 0 : Record[19], Record.size() <= 20 ? nullptr : getMDString(Record[20]), - Record.size() <= 21 ? nullptr : getMDString(Record[21])); + Record.size() <= 21 ? nullptr : getMDString(Record[21]), + Record.size() <= 22 ? false : Record[22]); MetadataList.assignValue(CU, NextMetadataNo); NextMetadataNo++; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1762,6 +1762,7 @@ Record.push_back(N->getRangesBaseAddress()); Record.push_back(VE.getMetadataOrNullID(N->getRawSysRoot())); Record.push_back(VE.getMetadataOrNullID(N->getRawSDK())); + Record.push_back(N->hasPGO()); Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -804,6 +804,9 @@ // The low byte of the flags indicates the source language. Flags = MapDWLangToCVLang(CU->getSourceLanguage()); // TODO: Figure out which other flags need to be set. + if (CU->hasPGO()) { + Flags |= static_cast(CompileSym3Flags::PGO); + } OS.AddComment("Flags and language"); OS.emitInt32(Flags); @@ -1428,6 +1431,10 @@ if (Asm->TM.getOptLevel() != CodeGenOpt::None && !GV.hasOptSize() && !GV.hasOptNone()) FPO |= FrameProcedureOptions::OptimizedForSpeed; + if (GV.getEntryCount().hasValue()) { + FPO |= FrameProcedureOptions::ValidProfileCounts; + FPO |= FrameProcedureOptions::ProfileGuidedOptimization; + } // FIXME: Set GuardCfg when it is implemented. CurFn->FrameProcOpts = FPO; diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -141,7 +141,7 @@ DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, DICompileUnit::DebugNameTableKind NameTableKind, bool RangesBaseAddress, - StringRef SysRoot, StringRef SDK) { + StringRef SysRoot, StringRef SDK, bool HasPGO) { assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) || (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && @@ -152,7 +152,7 @@ VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer, SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId, SplitDebugInlining, DebugInfoForProfiling, NameTableKind, - RangesBaseAddress, SysRoot, SDK); + RangesBaseAddress, SysRoot, SDK, HasPGO); // Create a named metadata so that it is easier to find cu in a module. NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -491,7 +491,8 @@ RetainedTypes, GlobalVariables, ImportedEntities, CU->getMacros(), CU->getDWOId(), CU->getSplitDebugInlining(), CU->getDebugInfoForProfiling(), CU->getNameTableKind(), - CU->getRangesBaseAddress(), CU->getSysRoot(), CU->getSDK()); + CU->getRangesBaseAddress(), CU->getSysRoot(), CU->getSDK(), + CU->hasPGO()); } DILocation *getReplacementMDLocation(DILocation *MLD) { diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -736,7 +736,7 @@ Metadata *GlobalVariables, Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling, unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot, - MDString *SDK, StorageType Storage, bool ShouldCreate) { + MDString *SDK, bool HasPGO, StorageType Storage, bool ShouldCreate) { assert(Storage != Uniqued && "Cannot unique DICompileUnit"); assert(isCanonical(Producer) && "Expected canonical MDString"); assert(isCanonical(Flags) && "Expected canonical MDString"); @@ -757,7 +757,7 @@ Context, Storage, SourceLanguage, IsOptimized, RuntimeVersion, EmissionKind, DWOId, SplitDebugInlining, DebugInfoForProfiling, NameTableKind, RangesBaseAddress, - Ops), + HasPGO, Ops), Storage); } diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp --- a/llvm/unittests/IR/MetadataTest.cpp +++ b/llvm/unittests/IR/MetadataTest.cpp @@ -97,7 +97,7 @@ Context, 1, getFile(), "clang", false, "-g", 2, "", DICompileUnit::FullDebug, getTuple(), getTuple(), getTuple(), getTuple(), getTuple(), 0, true, false, - DICompileUnit::DebugNameTableKind::Default, false, "/", ""); + DICompileUnit::DebugNameTableKind::Default, false, "/", "", false); } DIType *getBasicType(StringRef Name) { return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name); @@ -2110,11 +2110,13 @@ MDTuple *Macros = getTuple(); StringRef SysRoot = "/"; StringRef SDK = "MacOSX.sdk"; + bool HasPGO = false; auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, GlobalVariables, ImportedEntities, Macros, DWOId, true, - false, DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK); + false, DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK, + HasPGO); EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag()); EXPECT_EQ(SourceLanguage, N->getSourceLanguage()); @@ -2133,6 +2135,7 @@ EXPECT_EQ(DWOId, N->getDWOId()); EXPECT_EQ(SysRoot, N->getSysRoot()); EXPECT_EQ(SDK, N->getSDK()); + EXPECT_EQ(HasPGO, N->hasPGO()); TempDICompileUnit Temp = N->clone(); EXPECT_EQ(dwarf::DW_TAG_compile_unit, Temp->getTag()); @@ -2151,6 +2154,7 @@ EXPECT_EQ(Macros, Temp->getMacros().get()); EXPECT_EQ(SysRoot, Temp->getSysRoot()); EXPECT_EQ(SDK, Temp->getSDK()); + EXPECT_EQ(HasPGO, Temp->hasPGO()); auto *TempAddress = Temp.get(); auto *Clone = MDNode::replaceWithPermanent(std::move(Temp)); @@ -2173,11 +2177,12 @@ uint64_t DWOId = 0xc0ffee; StringRef SysRoot = "/"; StringRef SDK = "MacOSX.sdk"; + bool HasPGO = false; auto *N = DICompileUnit::getDistinct( Context, SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId, true, false, - DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK); + DICompileUnit::DebugNameTableKind::Default, false, SysRoot, SDK, HasPGO); auto *GlobalVariables = MDTuple::getDistinct(Context, None); EXPECT_EQ(nullptr, N->getGlobalVariables().get());