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 @@ -26,6 +26,10 @@ IgnoreHash("profile-ignore-hash", cl::desc("ignore hash while reading function profile"), cl::Hidden, cl::cat(BoltOptCategory)); + +llvm::cl::opt ProfileUseDFS("profile-use-dfs", + cl::desc("use DFS order for YAML profile"), + cl::Hidden, cl::cat(BoltOptCategory)); } namespace llvm { @@ -90,7 +94,7 @@ FuncRawBranchCount += YamlSI.Count; BF.setRawBranchCount(FuncRawBranchCount); - if (!opts::IgnoreHash && YamlBF.Hash != BF.computeHash(/*UseDFS=*/true)) { + if (!opts::IgnoreHash && YamlBF.Hash != BF.computeHash(opts::ProfileUseDFS)) { if (opts::Verbosity >= 1) errs() << "BOLT-WARNING: function hash mismatch\n"; ProfileMatched = false; @@ -102,10 +106,14 @@ ProfileMatched = false; } - BinaryFunction::BasicBlockOrderType DFSOrder = BF.dfs(); + BinaryFunction::BasicBlockOrderType Order; + if (opts::ProfileUseDFS) + llvm::copy(BF.dfs(), std::back_inserter(Order)); + else + llvm::copy(BF.getLayout().blocks(), std::back_inserter(Order)); for (const yaml::bolt::BinaryBasicBlockProfile &YamlBB : YamlBF.Blocks) { - if (YamlBB.Index >= DFSOrder.size()) { + if (YamlBB.Index >= Order.size()) { if (opts::Verbosity >= 2) errs() << "BOLT-WARNING: index " << YamlBB.Index << " is out of bounds\n"; @@ -113,7 +121,7 @@ continue; } - BinaryBasicBlock &BB = *DFSOrder[YamlBB.Index]; + BinaryBasicBlock &BB = *Order[YamlBB.Index]; // Basic samples profile (without LBR) does not have branches information // and needs a special processing. @@ -197,14 +205,14 @@ } for (const yaml::bolt::SuccessorInfo &YamlSI : YamlBB.Successors) { - if (YamlSI.Index >= DFSOrder.size()) { + if (YamlSI.Index >= Order.size()) { if (opts::Verbosity >= 1) errs() << "BOLT-WARNING: index out of bounds for profiled block\n"; ++MismatchedEdges; continue; } - BinaryBasicBlock &SuccessorBB = *DFSOrder[YamlSI.Index]; + BinaryBasicBlock &SuccessorBB = *Order[YamlSI.Index]; if (!BB.getSuccessor(SuccessorBB.getLabel())) { if (opts::Verbosity >= 1) errs() << "BOLT-WARNING: no successor for block " << BB.getName() @@ -338,7 +346,7 @@ // Recompute hash once per function. if (!opts::IgnoreHash) - Function.computeHash(/*UseDFS=*/true); + Function.computeHash(opts::ProfileUseDFS); 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 @@ -12,12 +12,17 @@ #include "bolt/Profile/ProfileReaderBase.h" #include "bolt/Profile/ProfileYAMLMapping.h" #include "bolt/Rewrite/RewriteInstance.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" #undef DEBUG_TYPE #define DEBUG_TYPE "bolt-prof" +namespace opts { +extern llvm::cl::opt ProfileUseDFS; +} // namespace opts + namespace llvm { namespace bolt { @@ -29,7 +34,7 @@ const uint16_t LBRProfile = BF.getProfileFlags() & BinaryFunction::PF_LBR; // Prepare function and block hashes - BF.computeHash(/*UseDFS=*/true); + BF.computeHash(opts::ProfileUseDFS); BF.computeBlockHashes(); YamlBF.Name = BF.getPrintName(); @@ -38,7 +43,11 @@ YamlBF.NumBasicBlocks = BF.size(); YamlBF.ExecCount = BF.getKnownExecutionCount(); - for (const BinaryBasicBlock *BB : BF.dfs()) { + BinaryFunction::BasicBlockOrderType Order; + llvm::copy(opts::ProfileUseDFS ? BF.dfs() : BF.getLayout().blocks(), + std::back_inserter(Order)); + + for (const BinaryBasicBlock *BB : Order) { yaml::bolt::BinaryBasicBlockProfile YamlBB; YamlBB.Index = BB->getLayoutIndex(); YamlBB.NumInstructions = BB->getNumNonPseudos(); diff --git a/bolt/test/X86/pre-aggregated-perf.test b/bolt/test/X86/pre-aggregated-perf.test --- a/bolt/test/X86/pre-aggregated-perf.test +++ b/bolt/test/X86/pre-aggregated-perf.test @@ -10,7 +10,8 @@ REQUIRES: system-linux RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe -RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new +RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \ +RUN: --profile-use-dfs RUN: cat %t | sort | FileCheck %s -check-prefix=PERF2BOLT RUN: cat %t.new | FileCheck %s -check-prefix=NEWFORMAT @@ -20,7 +21,7 @@ RUN: cat %t.fdata | sort | FileCheck %s -check-prefix=PERF2BOLT RUN: perf2bolt %t.exe -o %t.yaml --pa -p %p/Inputs/pre-aggregated.txt \ -RUN: --profile-format=yaml +RUN: --profile-format=yaml --profile-use-dfs RUN: cat %t.yaml | FileCheck %s -check-prefix=NEWFORMAT # Test --profile-format option with llvm-bolt --aggregate-only @@ -29,7 +30,7 @@ RUN: cat %t.bolt.fdata | sort | FileCheck %s -check-prefix=PERF2BOLT RUN: llvm-bolt %t.exe -o %t.bolt.yaml --pa -p %p/Inputs/pre-aggregated.txt \ -RUN: --aggregate-only --profile-format=yaml +RUN: --aggregate-only --profile-format=yaml --profile-use-dfs RUN: cat %t.bolt.yaml | FileCheck %s -check-prefix=NEWFORMAT PERF2BOLT: 0 [unknown] 7f36d18d60c0 1 main 53c 0 2 diff --git a/bolt/test/X86/reader-stale-yaml.test b/bolt/test/X86/reader-stale-yaml.test --- a/bolt/test/X86/reader-stale-yaml.test +++ b/bolt/test/X86/reader-stale-yaml.test @@ -2,8 +2,9 @@ # correctly and stale data is corrected. RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe -RUN: llvm-bolt %t.exe -o /dev/null --b %p/Inputs/blarge_profile_stale.yaml --print-cfg --print-only=usqrt --infer-stale-profile=1 --profile-ignore-hash=1 \ -RUN: 2>&1 | FileCheck %s -check-prefix=CHECK +RUN: llvm-bolt %t.exe -o /dev/null --b %p/Inputs/blarge_profile_stale.yaml \ +RUN: --print-cfg --print-only=usqrt --infer-stale-profile=1 \ +RUN: --profile-ignore-hash=1 --profile-use-dfs 2>&1 | FileCheck %s # Verify that yaml reader works as expected. CHECK: pre-processing profile using YAML profile reader