diff --git a/bolt/include/bolt/Profile/ProfileYAMLMapping.h b/bolt/include/bolt/Profile/ProfileYAMLMapping.h --- a/bolt/include/bolt/Profile/ProfileYAMLMapping.h +++ b/bolt/include/bolt/Profile/ProfileYAMLMapping.h @@ -187,6 +187,7 @@ // Type of the profile. std::string Origin; // How the profile was obtained. std::string EventNames; // Events used for sample profile. + bool IsDFSOrder{true}; // Whether using DFS block order in function profile }; } // end namespace bolt @@ -198,6 +199,7 @@ YamlIO.mapRequired("profile-flags", Header.Flags); YamlIO.mapOptional("profile-origin", Header.Origin); YamlIO.mapOptional("profile-events", Header.EventNames); + YamlIO.mapOptional("dfs-order", Header.IsDFSOrder); } }; diff --git a/bolt/lib/Profile/YAMLProfileReader.cpp b/bolt/lib/Profile/YAMLProfileReader.cpp --- a/bolt/lib/Profile/YAMLProfileReader.cpp +++ b/bolt/lib/Profile/YAMLProfileReader.cpp @@ -79,6 +79,7 @@ BinaryFunction &BF, const yaml::bolt::BinaryFunctionProfile &YamlBF) { BinaryContext &BC = BF.getBinaryContext(); + const bool IsDFSOrder = YamlBP.Header.IsDFSOrder; bool ProfileMatched = true; uint64_t MismatchedBlocks = 0; uint64_t MismatchedCalls = 0; @@ -94,7 +95,7 @@ FuncRawBranchCount += YamlSI.Count; BF.setRawBranchCount(FuncRawBranchCount); - if (!opts::IgnoreHash && YamlBF.Hash != BF.computeHash(opts::ProfileUseDFS)) { + if (!opts::IgnoreHash && YamlBF.Hash != BF.computeHash(IsDFSOrder)) { if (opts::Verbosity >= 1) errs() << "BOLT-WARNING: function hash mismatch\n"; ProfileMatched = false; @@ -107,7 +108,7 @@ } BinaryFunction::BasicBlockOrderType Order; - if (opts::ProfileUseDFS) + if (IsDFSOrder) llvm::copy(BF.dfs(), std::back_inserter(Order)); else llvm::copy(BF.getLayout().blocks(), std::back_inserter(Order)); @@ -346,7 +347,7 @@ // Recompute hash once per function. if (!opts::IgnoreHash) - Function.computeHash(opts::ProfileUseDFS); + Function.computeHash(YamlBP.Header.IsDFSOrder); for (StringRef FunctionName : Function.getNames()) { auto PI = ProfileNameToProfile.find(FunctionName); diff --git a/bolt/lib/Profile/YAMLProfileWriter.cpp b/bolt/lib/Profile/YAMLProfileWriter.cpp --- a/bolt/lib/Profile/YAMLProfileWriter.cpp +++ b/bolt/lib/Profile/YAMLProfileWriter.cpp @@ -188,6 +188,7 @@ std::optional BuildID = BC.getFileBuildID(); BP.Header.Id = BuildID ? std::string(*BuildID) : ""; BP.Header.Origin = std::string(RI.getProfileReader()->getReaderName()); + BP.Header.IsDFSOrder = opts::ProfileUseDFS; StringSet<> EventNames = RI.getProfileReader()->getEventNames(); if (!EventNames.empty()) { diff --git a/bolt/test/yaml-profile-kind.s b/bolt/test/yaml-profile-kind.s new file mode 100644 --- /dev/null +++ b/bolt/test/yaml-profile-kind.s @@ -0,0 +1,18 @@ +# This test checks the handling of YAML profile with different block orders. +# RUN: %clang %cflags -Wl,-q %s -o %t.exe +# RUN: link_fdata %s %t.exe %t.fdata +# RUN: llvm-bolt %t.exe -o /dev/null -data %t.fdata -w %t.yaml +# RUN: FileCheck %s --input-file %t.yaml --check-prefix=CHECK-BINARY +# CHECK-BINARY: dfs-order: false +# RUN: llvm-bolt %t.exe -o /dev/null -data %t.fdata -w %t.yaml --profile-use-dfs +# RUN: FileCheck %s --input-file %t.yaml --check-prefix=CHECK-DFS +# CHECK-DFS: dfs-order: true + + .globl main + .type main, %function +main: +# FDATA: 0 [unknown] 0 1 main 0 0 0 + .cfi_startproc + .long 0 + .cfi_endproc +.size main, .-main