Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:08

0001 //===-- llvm/ModuleSummaryIndexYAML.h - YAML I/O for summary ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_IR_MODULESUMMARYINDEXYAML_H
0010 #define LLVM_IR_MODULESUMMARYINDEXYAML_H
0011 
0012 #include "llvm/IR/ModuleSummaryIndex.h"
0013 #include "llvm/Support/YAMLTraits.h"
0014 
0015 namespace llvm {
0016 namespace yaml {
0017 
0018 template <> struct ScalarEnumerationTraits<TypeTestResolution::Kind> {
0019   static void enumeration(IO &io, TypeTestResolution::Kind &value) {
0020     io.enumCase(value, "Unknown", TypeTestResolution::Unknown);
0021     io.enumCase(value, "Unsat", TypeTestResolution::Unsat);
0022     io.enumCase(value, "ByteArray", TypeTestResolution::ByteArray);
0023     io.enumCase(value, "Inline", TypeTestResolution::Inline);
0024     io.enumCase(value, "Single", TypeTestResolution::Single);
0025     io.enumCase(value, "AllOnes", TypeTestResolution::AllOnes);
0026   }
0027 };
0028 
0029 template <> struct MappingTraits<TypeTestResolution> {
0030   static void mapping(IO &io, TypeTestResolution &res) {
0031     io.mapOptional("Kind", res.TheKind);
0032     io.mapOptional("SizeM1BitWidth", res.SizeM1BitWidth);
0033     io.mapOptional("AlignLog2", res.AlignLog2);
0034     io.mapOptional("SizeM1", res.SizeM1);
0035     io.mapOptional("BitMask", res.BitMask);
0036     io.mapOptional("InlineBits", res.InlineBits);
0037   }
0038 };
0039 
0040 template <>
0041 struct ScalarEnumerationTraits<WholeProgramDevirtResolution::ByArg::Kind> {
0042   static void enumeration(IO &io,
0043                           WholeProgramDevirtResolution::ByArg::Kind &value) {
0044     io.enumCase(value, "Indir", WholeProgramDevirtResolution::ByArg::Indir);
0045     io.enumCase(value, "UniformRetVal",
0046                 WholeProgramDevirtResolution::ByArg::UniformRetVal);
0047     io.enumCase(value, "UniqueRetVal",
0048                 WholeProgramDevirtResolution::ByArg::UniqueRetVal);
0049     io.enumCase(value, "VirtualConstProp",
0050                 WholeProgramDevirtResolution::ByArg::VirtualConstProp);
0051   }
0052 };
0053 
0054 template <> struct MappingTraits<WholeProgramDevirtResolution::ByArg> {
0055   static void mapping(IO &io, WholeProgramDevirtResolution::ByArg &res) {
0056     io.mapOptional("Kind", res.TheKind);
0057     io.mapOptional("Info", res.Info);
0058     io.mapOptional("Byte", res.Byte);
0059     io.mapOptional("Bit", res.Bit);
0060   }
0061 };
0062 
0063 template <>
0064 struct CustomMappingTraits<
0065     std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg>> {
0066   static void inputOne(
0067       IO &io, StringRef Key,
0068       std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) {
0069     std::vector<uint64_t> Args;
0070     std::pair<StringRef, StringRef> P = {"", Key};
0071     while (!P.second.empty()) {
0072       P = P.second.split(',');
0073       uint64_t Arg;
0074       if (P.first.getAsInteger(0, Arg)) {
0075         io.setError("key not an integer");
0076         return;
0077       }
0078       Args.push_back(Arg);
0079     }
0080     io.mapRequired(Key.str().c_str(), V[Args]);
0081   }
0082   static void output(
0083       IO &io,
0084       std::map<std::vector<uint64_t>, WholeProgramDevirtResolution::ByArg> &V) {
0085     for (auto &P : V) {
0086       std::string Key;
0087       for (uint64_t Arg : P.first) {
0088         if (!Key.empty())
0089           Key += ',';
0090         Key += llvm::utostr(Arg);
0091       }
0092       io.mapRequired(Key.c_str(), P.second);
0093     }
0094   }
0095 };
0096 
0097 template <> struct ScalarEnumerationTraits<WholeProgramDevirtResolution::Kind> {
0098   static void enumeration(IO &io, WholeProgramDevirtResolution::Kind &value) {
0099     io.enumCase(value, "Indir", WholeProgramDevirtResolution::Indir);
0100     io.enumCase(value, "SingleImpl", WholeProgramDevirtResolution::SingleImpl);
0101     io.enumCase(value, "BranchFunnel",
0102                 WholeProgramDevirtResolution::BranchFunnel);
0103   }
0104 };
0105 
0106 template <> struct MappingTraits<WholeProgramDevirtResolution> {
0107   static void mapping(IO &io, WholeProgramDevirtResolution &res) {
0108     io.mapOptional("Kind", res.TheKind);
0109     io.mapOptional("SingleImplName", res.SingleImplName);
0110     io.mapOptional("ResByArg", res.ResByArg);
0111   }
0112 };
0113 
0114 template <>
0115 struct CustomMappingTraits<std::map<uint64_t, WholeProgramDevirtResolution>> {
0116   static void inputOne(IO &io, StringRef Key,
0117                        std::map<uint64_t, WholeProgramDevirtResolution> &V) {
0118     uint64_t KeyInt;
0119     if (Key.getAsInteger(0, KeyInt)) {
0120       io.setError("key not an integer");
0121       return;
0122     }
0123     io.mapRequired(Key.str().c_str(), V[KeyInt]);
0124   }
0125   static void output(IO &io, std::map<uint64_t, WholeProgramDevirtResolution> &V) {
0126     for (auto &P : V)
0127       io.mapRequired(llvm::utostr(P.first).c_str(), P.second);
0128   }
0129 };
0130 
0131 template <> struct MappingTraits<TypeIdSummary> {
0132   static void mapping(IO &io, TypeIdSummary& summary) {
0133     io.mapOptional("TTRes", summary.TTRes);
0134     io.mapOptional("WPDRes", summary.WPDRes);
0135   }
0136 };
0137 
0138 struct GlobalValueSummaryYaml {
0139   // Commonly used fields
0140   unsigned Linkage, Visibility;
0141   bool NotEligibleToImport, Live, IsLocal, CanAutoHide;
0142   unsigned ImportType;
0143   // Fields for AliasSummary
0144   std::optional<uint64_t> Aliasee;
0145   // Fields for FunctionSummary
0146   std::vector<uint64_t> Refs = {};
0147   std::vector<uint64_t> TypeTests = {};
0148   std::vector<FunctionSummary::VFuncId> TypeTestAssumeVCalls = {};
0149   std::vector<FunctionSummary::VFuncId> TypeCheckedLoadVCalls = {};
0150   std::vector<FunctionSummary::ConstVCall> TypeTestAssumeConstVCalls = {};
0151   std::vector<FunctionSummary::ConstVCall> TypeCheckedLoadConstVCalls = {};
0152 };
0153 
0154 } // End yaml namespace
0155 } // End llvm namespace
0156 
0157 namespace llvm {
0158 namespace yaml {
0159 
0160 template <> struct MappingTraits<FunctionSummary::VFuncId> {
0161   static void mapping(IO &io, FunctionSummary::VFuncId& id) {
0162     io.mapOptional("GUID", id.GUID);
0163     io.mapOptional("Offset", id.Offset);
0164   }
0165 };
0166 
0167 template <> struct MappingTraits<FunctionSummary::ConstVCall> {
0168   static void mapping(IO &io, FunctionSummary::ConstVCall& id) {
0169     io.mapOptional("VFunc", id.VFunc);
0170     io.mapOptional("Args", id.Args);
0171   }
0172 };
0173 
0174 } // End yaml namespace
0175 } // End llvm namespace
0176 
0177 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::VFuncId)
0178 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummary::ConstVCall)
0179 
0180 namespace llvm {
0181 namespace yaml {
0182 
0183 template <> struct MappingTraits<GlobalValueSummaryYaml> {
0184   static void mapping(IO &io, GlobalValueSummaryYaml &summary) {
0185     io.mapOptional("Linkage", summary.Linkage);
0186     io.mapOptional("Visibility", summary.Visibility);
0187     io.mapOptional("NotEligibleToImport", summary.NotEligibleToImport);
0188     io.mapOptional("Live", summary.Live);
0189     io.mapOptional("Local", summary.IsLocal);
0190     io.mapOptional("CanAutoHide", summary.CanAutoHide);
0191     io.mapOptional("ImportType", summary.ImportType);
0192     io.mapOptional("Aliasee", summary.Aliasee);
0193     io.mapOptional("Refs", summary.Refs);
0194     io.mapOptional("TypeTests", summary.TypeTests);
0195     io.mapOptional("TypeTestAssumeVCalls", summary.TypeTestAssumeVCalls);
0196     io.mapOptional("TypeCheckedLoadVCalls", summary.TypeCheckedLoadVCalls);
0197     io.mapOptional("TypeTestAssumeConstVCalls",
0198                    summary.TypeTestAssumeConstVCalls);
0199     io.mapOptional("TypeCheckedLoadConstVCalls",
0200                    summary.TypeCheckedLoadConstVCalls);
0201   }
0202 };
0203 
0204 } // End yaml namespace
0205 } // End llvm namespace
0206 
0207 LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalValueSummaryYaml)
0208 
0209 namespace llvm {
0210 namespace yaml {
0211 
0212 // FIXME: Add YAML mappings for the rest of the module summary.
0213 template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
0214   static void inputOne(IO &io, StringRef Key, GlobalValueSummaryMapTy &V) {
0215     std::vector<GlobalValueSummaryYaml> GVSums;
0216     io.mapRequired(Key.str().c_str(), GVSums);
0217     uint64_t KeyInt;
0218     if (Key.getAsInteger(0, KeyInt)) {
0219       io.setError("key not an integer");
0220       return;
0221     }
0222     auto &Elem = V.try_emplace(KeyInt, /*IsAnalysis=*/false).first->second;
0223     for (auto &GVSum : GVSums) {
0224       GlobalValueSummary::GVFlags GVFlags(
0225           static_cast<GlobalValue::LinkageTypes>(GVSum.Linkage),
0226           static_cast<GlobalValue::VisibilityTypes>(GVSum.Visibility),
0227           GVSum.NotEligibleToImport, GVSum.Live, GVSum.IsLocal,
0228           GVSum.CanAutoHide,
0229           static_cast<GlobalValueSummary::ImportKind>(GVSum.ImportType));
0230       if (GVSum.Aliasee) {
0231         auto ASum = std::make_unique<AliasSummary>(GVFlags);
0232         if (!V.count(*GVSum.Aliasee))
0233           V.emplace(*GVSum.Aliasee, /*IsAnalysis=*/false);
0234         ValueInfo AliaseeVI(/*IsAnalysis=*/false, &*V.find(*GVSum.Aliasee));
0235         // Note: Aliasee cannot be filled until all summaries are loaded.
0236         // This is done in fixAliaseeLinks() which is called in
0237         // MappingTraits<ModuleSummaryIndex>::mapping().
0238         ASum->setAliasee(AliaseeVI, /*Aliasee=*/nullptr);
0239         Elem.SummaryList.push_back(std::move(ASum));
0240         continue;
0241       }
0242       SmallVector<ValueInfo, 0> Refs;
0243       Refs.reserve(GVSum.Refs.size());
0244       for (auto &RefGUID : GVSum.Refs) {
0245         auto It = V.try_emplace(RefGUID, /*IsAnalysis=*/false).first;
0246         Refs.push_back(ValueInfo(/*IsAnalysis=*/false, &*It));
0247       }
0248       Elem.SummaryList.push_back(std::make_unique<FunctionSummary>(
0249           GVFlags, /*NumInsts=*/0, FunctionSummary::FFlags{}, std::move(Refs),
0250           SmallVector<FunctionSummary::EdgeTy, 0>{}, std::move(GVSum.TypeTests),
0251           std::move(GVSum.TypeTestAssumeVCalls),
0252           std::move(GVSum.TypeCheckedLoadVCalls),
0253           std::move(GVSum.TypeTestAssumeConstVCalls),
0254           std::move(GVSum.TypeCheckedLoadConstVCalls),
0255           ArrayRef<FunctionSummary::ParamAccess>{}, ArrayRef<CallsiteInfo>{},
0256           ArrayRef<AllocInfo>{}));
0257     }
0258   }
0259   static void output(IO &io, GlobalValueSummaryMapTy &V) {
0260     for (auto &P : V) {
0261       std::vector<GlobalValueSummaryYaml> GVSums;
0262       for (auto &Sum : P.second.SummaryList) {
0263         if (auto *FSum = dyn_cast<FunctionSummary>(Sum.get())) {
0264           std::vector<uint64_t> Refs;
0265           Refs.reserve(FSum->refs().size());
0266           for (auto &VI : FSum->refs())
0267             Refs.push_back(VI.getGUID());
0268           GVSums.push_back(GlobalValueSummaryYaml{
0269               FSum->flags().Linkage, FSum->flags().Visibility,
0270               static_cast<bool>(FSum->flags().NotEligibleToImport),
0271               static_cast<bool>(FSum->flags().Live),
0272               static_cast<bool>(FSum->flags().DSOLocal),
0273               static_cast<bool>(FSum->flags().CanAutoHide),
0274               FSum->flags().ImportType, /*Aliasee=*/std::nullopt, Refs,
0275               FSum->type_tests(), FSum->type_test_assume_vcalls(),
0276               FSum->type_checked_load_vcalls(),
0277               FSum->type_test_assume_const_vcalls(),
0278               FSum->type_checked_load_const_vcalls()});
0279         } else if (auto *ASum = dyn_cast<AliasSummary>(Sum.get());
0280                    ASum && ASum->hasAliasee()) {
0281           GVSums.push_back(GlobalValueSummaryYaml{
0282               ASum->flags().Linkage, ASum->flags().Visibility,
0283               static_cast<bool>(ASum->flags().NotEligibleToImport),
0284               static_cast<bool>(ASum->flags().Live),
0285               static_cast<bool>(ASum->flags().DSOLocal),
0286               static_cast<bool>(ASum->flags().CanAutoHide),
0287               ASum->flags().ImportType,
0288               /*Aliasee=*/ASum->getAliaseeGUID()});
0289         }
0290       }
0291       if (!GVSums.empty())
0292         io.mapRequired(llvm::utostr(P.first).c_str(), GVSums);
0293     }
0294   }
0295   static void fixAliaseeLinks(GlobalValueSummaryMapTy &V) {
0296     for (auto &P : V) {
0297       for (auto &Sum : P.second.SummaryList) {
0298         if (auto *Alias = dyn_cast<AliasSummary>(Sum.get())) {
0299           ValueInfo AliaseeVI = Alias->getAliaseeVI();
0300           auto AliaseeSL = AliaseeVI.getSummaryList();
0301           if (AliaseeSL.empty()) {
0302             ValueInfo EmptyVI;
0303             Alias->setAliasee(EmptyVI, nullptr);
0304           } else
0305             Alias->setAliasee(AliaseeVI, AliaseeSL[0].get());
0306         }
0307       }
0308     }
0309   }
0310 };
0311 
0312 template <> struct CustomMappingTraits<TypeIdSummaryMapTy> {
0313   static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V) {
0314     TypeIdSummary TId;
0315     io.mapRequired(Key.str().c_str(), TId);
0316     V.insert({GlobalValue::getGUID(Key), {Key, TId}});
0317   }
0318   static void output(IO &io, TypeIdSummaryMapTy &V) {
0319     for (auto &TidIter : V)
0320       io.mapRequired(TidIter.second.first.str().c_str(), TidIter.second.second);
0321   }
0322 };
0323 
0324 template <> struct MappingTraits<ModuleSummaryIndex> {
0325   static void mapping(IO &io, ModuleSummaryIndex& index) {
0326     io.mapOptional("GlobalValueMap", index.GlobalValueMap);
0327     if (!io.outputting())
0328       CustomMappingTraits<GlobalValueSummaryMapTy>::fixAliaseeLinks(
0329           index.GlobalValueMap);
0330 
0331     if (io.outputting()) {
0332       io.mapOptional("TypeIdMap", index.TypeIdMap);
0333     } else {
0334       TypeIdSummaryMapTy TypeIdMap;
0335       io.mapOptional("TypeIdMap", TypeIdMap);
0336       for (auto &[TypeGUID, TypeIdSummaryMap] : TypeIdMap) {
0337         // Save type id references in index and point TypeIdMap to use the
0338         // references owned by index.
0339         StringRef KeyRef = index.TypeIdSaver.save(TypeIdSummaryMap.first);
0340         index.TypeIdMap.insert(
0341             {TypeGUID, {KeyRef, std::move(TypeIdSummaryMap.second)}});
0342       }
0343     }
0344 
0345     io.mapOptional("WithGlobalValueDeadStripping",
0346                    index.WithGlobalValueDeadStripping);
0347 
0348     if (io.outputting()) {
0349       std::vector<std::string> CfiFunctionDefs(index.CfiFunctionDefs.begin(),
0350                                                index.CfiFunctionDefs.end());
0351       io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
0352       std::vector<std::string> CfiFunctionDecls(index.CfiFunctionDecls.begin(),
0353                                                 index.CfiFunctionDecls.end());
0354       io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
0355     } else {
0356       std::vector<std::string> CfiFunctionDefs;
0357       io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
0358       index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()};
0359       std::vector<std::string> CfiFunctionDecls;
0360       io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
0361       index.CfiFunctionDecls = {CfiFunctionDecls.begin(),
0362                                 CfiFunctionDecls.end()};
0363     }
0364   }
0365 };
0366 
0367 } // End yaml namespace
0368 } // End llvm namespace
0369 
0370 #endif