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/Error.h" 8 #include "llvm/Support/Path.h" 9 #include "llvm/Support/TargetSelect.h" 10 11 using namespace llvm; 12 using namespace bolt; 13 14 namespace opts { 15 16 static cl::OptionCategory *HeatmapCategories[] = {&HeatmapCategory, 17 &BoltOutputCategory}; 18 19 static cl::opt<std::string> InputFilename(cl::Positional, 20 cl::desc("<executable>"), 21 cl::Required, 22 cl::cat(HeatmapCategory)); 23 24 } // namespace opts 25 26 static StringRef ToolName; 27 28 static void report_error(StringRef Message, std::error_code EC) { 29 assert(EC); 30 errs() << ToolName << ": '" << Message << "': " << EC.message() << ".\n"; 31 exit(1); 32 } 33 34 static void report_error(StringRef Message, Error E) { 35 assert(E); 36 errs() << ToolName << ": '" << Message << "': " << toString(std::move(E)) 37 << ".\n"; 38 exit(1); 39 } 40 41 static std::string GetExecutablePath(const char *Argv0) { 42 SmallString<256> ExecutablePath(Argv0); 43 // Do a PATH lookup if Argv0 isn't a valid path. 44 if (!llvm::sys::fs::exists(ExecutablePath)) 45 if (llvm::ErrorOr<std::string> P = 46 llvm::sys::findProgramByName(ExecutablePath)) 47 ExecutablePath = *P; 48 return std::string(ExecutablePath.str()); 49 } 50 51 int main(int argc, char **argv) { 52 cl::HideUnrelatedOptions(makeArrayRef(opts::HeatmapCategories)); 53 cl::ParseCommandLineOptions(argc, argv, ""); 54 55 if (opts::PerfData.empty()) { 56 errs() << ToolName << ": expected -perfdata=<filename> option.\n"; 57 exit(1); 58 } 59 60 opts::HeatmapMode = true; 61 opts::AggregateOnly = true; 62 if (!sys::fs::exists(opts::InputFilename)) 63 report_error(opts::InputFilename, errc::no_such_file_or_directory); 64 65 // Output to stdout by default 66 if (opts::OutputFilename.empty()) 67 opts::OutputFilename = "-"; 68 69 // Initialize targets and assembly printers/parsers. 70 llvm::InitializeAllTargetInfos(); 71 llvm::InitializeAllTargetMCs(); 72 llvm::InitializeAllAsmParsers(); 73 llvm::InitializeAllDisassemblers(); 74 75 llvm::InitializeAllTargets(); 76 llvm::InitializeAllAsmPrinters(); 77 78 ToolName = argv[0]; 79 std::string ToolPath = GetExecutablePath(argv[0]); 80 Expected<OwningBinary<Binary>> BinaryOrErr = 81 createBinary(opts::InputFilename); 82 if (Error E = BinaryOrErr.takeError()) 83 report_error(opts::InputFilename, std::move(E)); 84 Binary &Binary = *BinaryOrErr.get().getBinary(); 85 86 if (auto *e = dyn_cast<ELFObjectFileBase>(&Binary)) { 87 RewriteInstance RI(e, argc, argv, ToolPath); 88 if (Error E = RI.setProfile(opts::PerfData)) 89 report_error(opts::PerfData, std::move(E)); 90 91 RI.run(); 92 } else { 93 report_error(opts::InputFilename, object_error::invalid_file_type); 94 } 95 96 return EXIT_SUCCESS; 97 } 98