File indexing completed on 2026-05-10 08:44:08
0001
0002
0003
0004
0005
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
0140 unsigned Linkage, Visibility;
0141 bool NotEligibleToImport, Live, IsLocal, CanAutoHide;
0142 unsigned ImportType;
0143
0144 std::optional<uint64_t> Aliasee;
0145
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 }
0155 }
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 }
0175 }
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 }
0205 }
0206
0207 LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalValueSummaryYaml)
0208
0209 namespace llvm {
0210 namespace yaml {
0211
0212
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, 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, false);
0234 ValueInfo AliaseeVI(false, &*V.find(*GVSum.Aliasee));
0235
0236
0237
0238 ASum->setAliasee(AliaseeVI, 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, false).first;
0246 Refs.push_back(ValueInfo(false, &*It));
0247 }
0248 Elem.SummaryList.push_back(std::make_unique<FunctionSummary>(
0249 GVFlags, 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, 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 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
0338
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 }
0368 }
0369
0370 #endif