Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / bolt / tools / heatmap / heatmap.cpp
blobf5204fa8ec60b3020e3276a6ddd22a1ad691d12c
1 #include "bolt/Profile/DataAggregator.h"
2 #include "bolt/Rewrite/RewriteInstance.h"
3 #include "bolt/Utils/CommandLineOpts.h"
4 #include "llvm/MC/TargetRegistry.h"
5 #include "llvm/Object/Binary.h"
6 #include "llvm/Support/CommandLine.h"
7 #include "llvm/Support/Errc.h"
8 #include "llvm/Support/Error.h"
9 #include "llvm/Support/Path.h"
10 #include "llvm/Support/TargetSelect.h"
12 using namespace llvm;
13 using namespace bolt;
15 namespace opts {
17 static cl::OptionCategory *HeatmapCategories[] = {&HeatmapCategory,
18 &BoltOutputCategory};
20 static cl::opt<std::string> InputFilename(cl::Positional,
21 cl::desc("<executable>"),
22 cl::Required,
23 cl::cat(HeatmapCategory));
25 } // namespace opts
27 static StringRef ToolName;
29 static void report_error(StringRef Message, std::error_code EC) {
30 assert(EC);
31 errs() << ToolName << ": '" << Message << "': " << EC.message() << ".\n";
32 exit(1);
35 static void report_error(StringRef Message, Error E) {
36 assert(E);
37 errs() << ToolName << ": '" << Message << "': " << toString(std::move(E))
38 << ".\n";
39 exit(1);
42 static std::string GetExecutablePath(const char *Argv0) {
43 SmallString<256> ExecutablePath(Argv0);
44 // Do a PATH lookup if Argv0 isn't a valid path.
45 if (!llvm::sys::fs::exists(ExecutablePath))
46 if (llvm::ErrorOr<std::string> P =
47 llvm::sys::findProgramByName(ExecutablePath))
48 ExecutablePath = *P;
49 return std::string(ExecutablePath.str());
52 int main(int argc, char **argv) {
53 cl::HideUnrelatedOptions(ArrayRef(opts::HeatmapCategories));
54 cl::ParseCommandLineOptions(argc, argv, "");
56 if (opts::PerfData.empty()) {
57 errs() << ToolName << ": expected -perfdata=<filename> option.\n";
58 exit(1);
61 opts::HeatmapMode = true;
62 opts::AggregateOnly = true;
63 if (!sys::fs::exists(opts::InputFilename))
64 report_error(opts::InputFilename, errc::no_such_file_or_directory);
66 // Output to stdout by default
67 if (opts::OutputFilename.empty())
68 opts::OutputFilename = "-";
70 // Initialize targets and assembly printers/parsers.
71 llvm::InitializeAllTargetInfos();
72 llvm::InitializeAllTargetMCs();
73 llvm::InitializeAllAsmParsers();
74 llvm::InitializeAllDisassemblers();
76 llvm::InitializeAllTargets();
77 llvm::InitializeAllAsmPrinters();
79 ToolName = argv[0];
80 std::string ToolPath = GetExecutablePath(argv[0]);
81 Expected<OwningBinary<Binary>> BinaryOrErr =
82 createBinary(opts::InputFilename);
83 if (Error E = BinaryOrErr.takeError())
84 report_error(opts::InputFilename, std::move(E));
85 Binary &Binary = *BinaryOrErr.get().getBinary();
87 if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) {
88 auto RIOrErr = RewriteInstance::create(e, argc, argv, ToolPath);
89 if (Error E = RIOrErr.takeError())
90 report_error("RewriteInstance", std::move(E));
92 RewriteInstance &RI = *RIOrErr.get();
93 if (Error E = RI.setProfile(opts::PerfData))
94 report_error(opts::PerfData, std::move(E));
96 if (Error E = RI.run())
97 report_error(opts::InputFilename, std::move(E));
98 } else {
99 report_error(opts::InputFilename, object_error::invalid_file_type);
102 return EXIT_SUCCESS;