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"
17 static cl::OptionCategory
*HeatmapCategories
[] = {&HeatmapCategory
,
20 static cl::opt
<std::string
> InputFilename(cl::Positional
,
21 cl::desc("<executable>"),
23 cl::cat(HeatmapCategory
));
27 static StringRef ToolName
;
29 static void report_error(StringRef Message
, std::error_code EC
) {
31 errs() << ToolName
<< ": '" << Message
<< "': " << EC
.message() << ".\n";
35 static void report_error(StringRef Message
, Error E
) {
37 errs() << ToolName
<< ": '" << Message
<< "': " << toString(std::move(E
))
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
))
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";
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();
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
));
99 report_error(opts::InputFilename
, object_error::invalid_file_type
);