llvm.org GIT mirror llvm / dcf592e
[bugpoint] Find 'opt', etc., in bugpoint directory Summary: When bugpoint attempts to find the other executables it needs to run, such as `opt` or `clang`, it tries searching the user's PATH. However, in many cases, the 'bugpoint' executable is part of an LLVM build, and the 'opt' executable it's looking for is in that same directory. Many LLVM tools handle this case by using the `Paths` parameter of `llvm::sys::findProgramByName`, passing the parent path of the currently running executable. Do this same thing for bugpoint. However, to preserve the current behavior exactly, first search the user's PATH, and then search for 'opt' in the directory containing 'bugpoint'. Test Plan: `check-llvm`. Many of the existing bugpoint tests no longer need to use the `--opt-command` option as a result of these changes. Reviewers: MatzeB, silvas, davide Reviewed By: MatzeB, davide Subscribers: davide, llvm-commits Differential Revision: https://reviews.llvm.org/D54884 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348734 91177308-0d34-0410-b5e6-96231b3b80d8 Brian Gesiak 8 months ago
11 changed file(s) with 74 addition(s) and 77 deletion(s). Raw diff Collapse all Expand all
None ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext --compile-custom --compile-command="%python %/s.py arg1 arg2" --opt-command opt --output-prefix %t %s | FileCheck %s
0 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext --compile-custom --compile-command="%python %/s.py arg1 arg2" --output-prefix %t %s | FileCheck %s
11 ; REQUIRES: loadable_module
22
33 ; Test that arguments are correctly passed in --compile-command. The output
0 ; Test that bugpoint can narrow down the testcase to the important function
11 ;
2 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls --opt-command opt -silence-passes > /dev/null
2 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes > /dev/null
33 ; REQUIRES: loadable_module
44
55 define i32 @foo() { ret i32 1 }
None ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes --opt-command opt 2>&1 | FileCheck %s
0 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes 2>&1 | FileCheck %s
11 ; REQUIRES: loadable_module
22 ; CHECK: DICompileUnit not listed in llvm.dbg.cu
33
0 ; REQUIRES: loadable_module
1 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes -disable-namedmd-remove -disable-strip-debuginfo -disable-strip-debug-types --opt-command opt > /dev/null
1 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes -disable-namedmd-remove -disable-strip-debuginfo -disable-strip-debug-types > /dev/null
22 ; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
33 ;
4 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-nodebug -bugpoint-crashcalls -silence-passes -disable-namedmd-remove --opt-command opt > /dev/null
4 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-nodebug -bugpoint-crashcalls -silence-passes -disable-namedmd-remove > /dev/null
55 ; RUN: llvm-dis %t-nodebug-reduced-simplified.bc -o - | FileCheck %s --check-prefix=NODEBUG
66 ;
7 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-notype -bugpoint-crashcalls -silence-passes -disable-namedmd-remove -disable-strip-debuginfo --opt-command opt > /dev/null
7 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-notype -bugpoint-crashcalls -silence-passes -disable-namedmd-remove -disable-strip-debuginfo > /dev/null
88 ; RUN: llvm-dis %t-notype-reduced-simplified.bc -o - | FileCheck %s --check-prefix=NOTYPE
99 ;
1010 ; Bugpoint should keep the call's metadata attached to the call.
None ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes -disable-strip-debuginfo --opt-command opt > /dev/null
0 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes -disable-strip-debuginfo > /dev/null
11 ; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
22 ; RUN-DISABLE: bugpoint -disable-namedmd-remove -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes > /dev/null
33 ; RUN-DISABLE: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
None ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes --opt-command opt
0 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes
11 ; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
22 ; REQUIRES: loadable_module
33
0 ; Test that bugpoint can reduce the set of functions by replacing them with null.
11 ;
2 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -replace-funcs-with-null -bugpoint-crash-decl-funcs -silence-passes -safe-run-llc --opt-command opt
2 ; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -replace-funcs-with-null -bugpoint-crash-decl-funcs -silence-passes -safe-run-llc
33 ; REQUIRES: loadable_module
44
55 @foo2 = alias i32 (), i32 ()* @foo
147147 std::string Message;
148148
149149 if (CCBinary.empty()) {
150 if (sys::findProgramByName("clang"))
151 CCBinary = "clang";
150 if (ErrorOr ClangPath =
151 FindProgramByName("clang", getToolName(), &AbsTolerance))
152 CCBinary = *ClangPath;
152153 else
153154 CCBinary = "gcc";
154155 }
192193 break;
193194 case CompileCustom:
194195 Interpreter = AbstractInterpreter::createCustomCompiler(
195 Message, CustomCompileCommand);
196 getToolName(), Message, CustomCompileCommand);
196197 break;
197198 case Custom:
198 Interpreter =
199 AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
199 Interpreter = AbstractInterpreter::createCustomExecutor(
200 getToolName(), Message, CustomExecCommand);
200201 break;
201202 }
202203 if (!Interpreter)
238239 SafeInterpreterSel == RunLLCIA);
239240 break;
240241 case Custom:
241 SafeInterpreter =
242 AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
242 SafeInterpreter = AbstractInterpreter::createCustomExecutor(
243 getToolName(), Message, CustomExecCommand);
243244 break;
244245 default:
245246 Message = "Sorry, this back-end is not supported by bugpoint as the "
251252 exit(1);
252253 }
253254
254 cc = CC::create(Message, CCBinary, &CCToolArgv);
255 cc = CC::create(getToolName(), Message, CCBinary, &CCToolArgv);
255256 if (!cc) {
256257 outs() << Message << "\nExiting.\n";
257258 exit(1);
1515 //===----------------------------------------------------------------------===//
1616
1717 #include "BugDriver.h"
18 #include "ToolRunner.h"
1819 #include "llvm/Bitcode/BitcodeWriter.h"
1920 #include "llvm/IR/DataLayout.h"
2021 #include "llvm/IR/Module.h"
165166
166167 std::string tool = OptCmd;
167168 if (OptCmd.empty()) {
168 if (ErrorOr Path = sys::findProgramByName("opt"))
169 if (ErrorOr Path =
170 FindProgramByName("opt", getToolName(), &OutputPrefix))
169171 tool = *Path;
170172 else
171173 errs() << Path.getError().message() << "\n";
201201
202202 void AbstractInterpreter::anchor() {}
203203
204 #if defined(LLVM_ON_UNIX)
205 const char EXESuffix[] = "";
206 #elif defined(_WIN32)
207 const char EXESuffix[] = "exe";
208 #endif
209
210 /// Prepend the path to the program being executed
211 /// to \p ExeName, given the value of argv[0] and the address of main()
212 /// itself. This allows us to find another LLVM tool if it is built in the same
213 /// directory. An empty string is returned on error; note that this function
214 /// just mainpulates the path and doesn't check for executability.
215 /// Find a named executable.
216 static std::string PrependMainExecutablePath(const std::string &ExeName,
204 ErrorOr llvm::FindProgramByName(const std::string &ExeName,
217205 const char *Argv0,
218206 void *MainAddr) {
219207 // Check the directory that the calling program is in. We can do
221209 // is a relative path to the executable itself.
222210 std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr);
223211 StringRef Result = sys::path::parent_path(Main);
224
225 if (!Result.empty()) {
226 SmallString<128> Storage = Result;
227 sys::path::append(Storage, ExeName);
228 sys::path::replace_extension(Storage, EXESuffix);
229 return Storage.str();
230 }
231
232 return Result.str();
212 if (ErrorOr Path = sys::findProgramByName(ExeName, Result))
213 return *Path;
214
215 // Check the user PATH.
216 return sys::findProgramByName(ExeName);
233217 }
234218
235219 // LLI create method - Try to find the LLI executable
236220 AbstractInterpreter *
237221 AbstractInterpreter::createLLI(const char *Argv0, std::string &Message,
238222 const std::vector *ToolArgs) {
239 std::string LLIPath =
240 PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI);
241 if (!LLIPath.empty()) {
242 Message = "Found lli: " + LLIPath + "\n";
243 return new LLI(LLIPath, ToolArgs);
244 }
245
246 Message = "Cannot find `lli' in executable directory!\n";
247 return nullptr;
223 if (ErrorOr LLIPath =
224 FindProgramByName("lli", Argv0, (void *)(intptr_t)&createLLI)) {
225 Message = "Found lli: " + *LLIPath + "\n";
226 return new LLI(*LLIPath, ToolArgs);
227 } else {
228 Message = LLIPath.getError().message() + "\n";
229 return nullptr;
230 }
248231 }
249232
250233 //===---------------------------------------------------------------------===//
367350 // '\ ' -> ' '
368351 // 'exa\mple' -> 'example'
369352 //
370 static void lexCommand(std::string &Message, const std::string &CommandLine,
371 std::string &CmdPath, std::vector &Args) {
353 static void lexCommand(const char *Argv0, std::string &Message,
354 const std::string &CommandLine, std::string &CmdPath,
355 std::vector &Args) {
372356
373357 std::string Token;
374358 std::string Command;
401385 Token.push_back(CommandLine[Pos]);
402386 }
403387
404 auto Path = sys::findProgramByName(Command);
388 auto Path = FindProgramByName(Command, Argv0, (void *)(intptr_t)&lexCommand);
405389 if (!Path) {
406390 Message = std::string("Cannot find '") + Command +
407391 "' in PATH: " + Path.getError().message() + "\n";
415399 // Custom execution environment create method, takes the execution command
416400 // as arguments
417401 AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
418 std::string &Message, const std::string &CompileCommandLine) {
402 const char *Argv0, std::string &Message,
403 const std::string &CompileCommandLine) {
419404
420405 std::string CmdPath;
421406 std::vector Args;
422 lexCommand(Message, CompileCommandLine, CmdPath, Args);
407 lexCommand(Argv0, Message, CompileCommandLine, CmdPath, Args);
423408 if (CmdPath.empty())
424409 return nullptr;
425410
429414 // Custom execution environment create method, takes the execution command
430415 // as arguments
431416 AbstractInterpreter *
432 AbstractInterpreter::createCustomExecutor(std::string &Message,
417 AbstractInterpreter::createCustomExecutor(const char *Argv0,
418 std::string &Message,
433419 const std::string &ExecCommandLine) {
434420
435421 std::string CmdPath;
436422 std::vector Args;
437 lexCommand(Message, ExecCommandLine, CmdPath, Args);
423 lexCommand(Argv0, Message, ExecCommandLine, CmdPath, Args);
438424 if (CmdPath.empty())
439425 return nullptr;
440426
523509 const std::vector *Args,
524510 const std::vector *CCArgs,
525511 bool UseIntegratedAssembler) {
526 std::string LLCPath =
527 PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC);
528 if (LLCPath.empty()) {
529 Message = "Cannot find `llc' in executable directory!\n";
512 ErrorOr LLCPath =
513 FindProgramByName("llc", Argv0, (void *)(intptr_t)&createLLC);
514 if (!LLCPath) {
515 Message = LLCPath.getError().message() + "\n";
530516 return nullptr;
531517 }
532518
533 CC *cc = CC::create(Message, CCBinary, CCArgs);
519 CC *cc = CC::create(Argv0, Message, CCBinary, CCArgs);
534520 if (!cc) {
535521 errs() << Message << "\n";
536522 exit(1);
537523 }
538 Message = "Found llc: " + LLCPath + "\n";
539 return new LLC(LLCPath, cc, Args, UseIntegratedAssembler);
524 Message = "Found llc: " + *LLCPath + "\n";
525 return new LLC(*LLCPath, cc, Args, UseIntegratedAssembler);
540526 }
541527
542528 //===---------------------------------------------------------------------===//
605591 AbstractInterpreter *
606592 AbstractInterpreter::createJIT(const char *Argv0, std::string &Message,
607593 const std::vector *Args) {
608 std::string LLIPath =
609 PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT);
610 if (!LLIPath.empty()) {
611 Message = "Found lli: " + LLIPath + "\n";
612 return new JIT(LLIPath, Args);
613 }
614
615 Message = "Cannot find `lli' in executable directory!\n";
616 return nullptr;
594 if (ErrorOr LLIPath =
595 FindProgramByName("lli", Argv0, (void *)(intptr_t)&createJIT)) {
596 Message = "Found lli: " + *LLIPath + "\n";
597 return new JIT(*LLIPath, Args);
598 } else {
599 Message = LLIPath.getError().message() + "\n";
600 return nullptr;
601 }
617602 }
618603
619604 //===---------------------------------------------------------------------===//
854839
855840 /// create - Try to find the CC executable
856841 ///
857 CC *CC::create(std::string &Message, const std::string &CCBinary,
842 CC *CC::create(const char *Argv0, std::string &Message,
843 const std::string &CCBinary,
858844 const std::vector *Args) {
859 auto CCPath = sys::findProgramByName(CCBinary);
845 auto CCPath = FindProgramByName(CCBinary, Argv0, (void *)(intptr_t)&create);
860846 if (!CCPath) {
861847 Message = "Cannot find `" + CCBinary + "' in PATH: " +
862848 CCPath.getError().message() + "\n";
4848 public:
4949 enum FileType { AsmFile, ObjectFile, CFile };
5050
51 static CC *create(std::string &Message, const std::string &CCBinary,
51 static CC *create(const char *Argv0, std::string &Message,
52 const std::string &CCBinary,
5253 const std::vector *Args);
5354
5455 /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
9798 const std::vector *Args = nullptr);
9899
99100 static AbstractInterpreter *
100 createCustomCompiler(std::string &Message,
101 createCustomCompiler(const char *Argv0, std::string &Message,
101102 const std::string &CompileCommandLine);
102103
103104 static AbstractInterpreter *
104 createCustomExecutor(std::string &Message,
105 createCustomExecutor(const char *Argv0, std::string &Message,
105106 const std::string &ExecCommandLine);
106107
107108 virtual ~AbstractInterpreter() {}
177178 unsigned MemoryLimit = 0) override;
178179 };
179180
181 /// Find the first executable file \ExeName, either in the user's PATH or,
182 /// failing that, in the same directory as argv[0]. This allows us to find
183 /// another LLVM tool if it is built in the same directory. If no executable is
184 /// found, an error is returned.
185 ErrorOr FindProgramByName(const std::string &ExeName,
186 const char *Argv0, void *MainAddr);
187
180188 } // End llvm namespace
181189
182190 #endif