Skip to content

Commit 5cc8920

Browse files
committed
[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 llvm-svn: 348734
1 parent dd5341f commit 5cc8920

11 files changed

+71
-74
lines changed

llvm/test/BugPoint/compile-custom.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext --compile-custom --compile-command="%python %/s.py arg1 arg2" --opt-command opt --output-prefix %t %s | FileCheck %s
1+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext --compile-custom --compile-command="%python %/s.py arg1 arg2" --output-prefix %t %s | FileCheck %s
22
; REQUIRES: loadable_module
33

44
; Test that arguments are correctly passed in --compile-command. The output

llvm/test/BugPoint/crash-narrowfunctiontest.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; Test that bugpoint can narrow down the testcase to the important function
22
;
3-
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls --opt-command opt -silence-passes > /dev/null
3+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes > /dev/null
44
; REQUIRES: loadable_module
55

66
define i32 @foo() { ret i32 1 }

llvm/test/BugPoint/invalid-debuginfo.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes --opt-command opt 2>&1 | FileCheck %s
1+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes 2>&1 | FileCheck %s
22
; REQUIRES: loadable_module
33
; CHECK: DICompileUnit not listed in llvm.dbg.cu
44

llvm/test/BugPoint/metadata.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
; REQUIRES: loadable_module
2-
; 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
2+
; 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
33
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
44
;
5-
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-nodebug -bugpoint-crashcalls -silence-passes -disable-namedmd-remove --opt-command opt > /dev/null
5+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-nodebug -bugpoint-crashcalls -silence-passes -disable-namedmd-remove > /dev/null
66
; RUN: llvm-dis %t-nodebug-reduced-simplified.bc -o - | FileCheck %s --check-prefix=NODEBUG
77
;
8-
; 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
8+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t-notype -bugpoint-crashcalls -silence-passes -disable-namedmd-remove -disable-strip-debuginfo > /dev/null
99
; RUN: llvm-dis %t-notype-reduced-simplified.bc -o - | FileCheck %s --check-prefix=NOTYPE
1010
;
1111
; Bugpoint should keep the call's metadata attached to the call.

llvm/test/BugPoint/named-md.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; 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
1+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes -disable-strip-debuginfo > /dev/null
22
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
33
; RUN-DISABLE: bugpoint -disable-namedmd-remove -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crash-too-many-cus -silence-passes > /dev/null
44
; RUN-DISABLE: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s

llvm/test/BugPoint/remove_arguments_test.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes --opt-command opt
1+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashcalls -silence-passes
22
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
33
; REQUIRES: loadable_module
44

llvm/test/BugPoint/replace-funcs-with-null.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
; Test that bugpoint can reduce the set of functions by replacing them with null.
22
;
3-
; 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
3+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -replace-funcs-with-null -bugpoint-crash-decl-funcs -silence-passes -safe-run-llc
44
; REQUIRES: loadable_module
55

66
@foo2 = alias i32 (), i32 ()* @foo

llvm/tools/bugpoint/ExecutionDriver.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ Error BugDriver::initializeExecutionEnvironment() {
148148
std::string Message;
149149

150150
if (CCBinary.empty()) {
151-
if (sys::findProgramByName("clang"))
152-
CCBinary = "clang";
151+
if (ErrorOr<std::string> ClangPath =
152+
FindProgramByName("clang", getToolName(), &AbsTolerance))
153+
CCBinary = *ClangPath;
153154
else
154155
CCBinary = "gcc";
155156
}
@@ -193,11 +194,11 @@ Error BugDriver::initializeExecutionEnvironment() {
193194
break;
194195
case CompileCustom:
195196
Interpreter = AbstractInterpreter::createCustomCompiler(
196-
Message, CustomCompileCommand);
197+
getToolName(), Message, CustomCompileCommand);
197198
break;
198199
case Custom:
199-
Interpreter =
200-
AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
200+
Interpreter = AbstractInterpreter::createCustomExecutor(
201+
getToolName(), Message, CustomExecCommand);
201202
break;
202203
}
203204
if (!Interpreter)
@@ -239,8 +240,8 @@ Error BugDriver::initializeExecutionEnvironment() {
239240
SafeInterpreterSel == RunLLCIA);
240241
break;
241242
case Custom:
242-
SafeInterpreter =
243-
AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
243+
SafeInterpreter = AbstractInterpreter::createCustomExecutor(
244+
getToolName(), Message, CustomExecCommand);
244245
break;
245246
default:
246247
Message = "Sorry, this back-end is not supported by bugpoint as the "
@@ -252,7 +253,7 @@ Error BugDriver::initializeExecutionEnvironment() {
252253
exit(1);
253254
}
254255

255-
cc = CC::create(Message, CCBinary, &CCToolArgv);
256+
cc = CC::create(getToolName(), Message, CCBinary, &CCToolArgv);
256257
if (!cc) {
257258
outs() << Message << "\nExiting.\n";
258259
exit(1);

llvm/tools/bugpoint/OptimizerDriver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//===----------------------------------------------------------------------===//
1717

1818
#include "BugDriver.h"
19+
#include "ToolRunner.h"
1920
#include "llvm/Bitcode/BitcodeWriter.h"
2021
#include "llvm/IR/DataLayout.h"
2122
#include "llvm/IR/Module.h"
@@ -166,7 +167,8 @@ bool BugDriver::runPasses(Module &Program,
166167

167168
std::string tool = OptCmd;
168169
if (OptCmd.empty()) {
169-
if (ErrorOr<std::string> Path = sys::findProgramByName("opt"))
170+
if (ErrorOr<std::string> Path =
171+
FindProgramByName("opt", getToolName(), &OutputPrefix))
170172
tool = *Path;
171173
else
172174
errs() << Path.getError().message() << "\n";

llvm/tools/bugpoint/ToolRunner.cpp

Lines changed: 39 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -202,50 +202,33 @@ Expected<int> LLI::ExecuteProgram(const std::string &Bitcode,
202202

203203
void AbstractInterpreter::anchor() {}
204204

205-
#if defined(LLVM_ON_UNIX)
206-
const char EXESuffix[] = "";
207-
#elif defined(_WIN32)
208-
const char EXESuffix[] = "exe";
209-
#endif
210-
211-
/// Prepend the path to the program being executed
212-
/// to \p ExeName, given the value of argv[0] and the address of main()
213-
/// itself. This allows us to find another LLVM tool if it is built in the same
214-
/// directory. An empty string is returned on error; note that this function
215-
/// just mainpulates the path and doesn't check for executability.
216-
/// Find a named executable.
217-
static std::string PrependMainExecutablePath(const std::string &ExeName,
205+
ErrorOr<std::string> llvm::FindProgramByName(const std::string &ExeName,
218206
const char *Argv0,
219207
void *MainAddr) {
220208
// Check the directory that the calling program is in. We can do
221209
// this if ProgramPath contains at least one / character, indicating that it
222210
// is a relative path to the executable itself.
223211
std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr);
224212
StringRef Result = sys::path::parent_path(Main);
213+
if (ErrorOr<std::string> Path = sys::findProgramByName(ExeName, Result))
214+
return *Path;
225215

226-
if (!Result.empty()) {
227-
SmallString<128> Storage = Result;
228-
sys::path::append(Storage, ExeName);
229-
sys::path::replace_extension(Storage, EXESuffix);
230-
return Storage.str();
231-
}
232-
233-
return Result.str();
216+
// Check the user PATH.
217+
return sys::findProgramByName(ExeName);
234218
}
235219

236220
// LLI create method - Try to find the LLI executable
237221
AbstractInterpreter *
238222
AbstractInterpreter::createLLI(const char *Argv0, std::string &Message,
239223
const std::vector<std::string> *ToolArgs) {
240-
std::string LLIPath =
241-
PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI);
242-
if (!LLIPath.empty()) {
243-
Message = "Found lli: " + LLIPath + "\n";
244-
return new LLI(LLIPath, ToolArgs);
224+
if (ErrorOr<std::string> LLIPath =
225+
FindProgramByName("lli", Argv0, (void *)(intptr_t)&createLLI)) {
226+
Message = "Found lli: " + *LLIPath + "\n";
227+
return new LLI(*LLIPath, ToolArgs);
228+
} else {
229+
Message = LLIPath.getError().message() + "\n";
230+
return nullptr;
245231
}
246-
247-
Message = "Cannot find `lli' in executable directory!\n";
248-
return nullptr;
249232
}
250233

251234
//===---------------------------------------------------------------------===//
@@ -368,8 +351,9 @@ Expected<int> CustomExecutor::ExecuteProgram(
368351
// '\ ' -> ' '
369352
// 'exa\mple' -> 'example'
370353
//
371-
static void lexCommand(std::string &Message, const std::string &CommandLine,
372-
std::string &CmdPath, std::vector<std::string> &Args) {
354+
static void lexCommand(const char *Argv0, std::string &Message,
355+
const std::string &CommandLine, std::string &CmdPath,
356+
std::vector<std::string> &Args) {
373357

374358
std::string Token;
375359
std::string Command;
@@ -402,7 +386,7 @@ static void lexCommand(std::string &Message, const std::string &CommandLine,
402386
Token.push_back(CommandLine[Pos]);
403387
}
404388

405-
auto Path = sys::findProgramByName(Command);
389+
auto Path = FindProgramByName(Command, Argv0, (void *)(intptr_t)&lexCommand);
406390
if (!Path) {
407391
Message = std::string("Cannot find '") + Command +
408392
"' in PATH: " + Path.getError().message() + "\n";
@@ -416,11 +400,12 @@ static void lexCommand(std::string &Message, const std::string &CommandLine,
416400
// Custom execution environment create method, takes the execution command
417401
// as arguments
418402
AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
419-
std::string &Message, const std::string &CompileCommandLine) {
403+
const char *Argv0, std::string &Message,
404+
const std::string &CompileCommandLine) {
420405

421406
std::string CmdPath;
422407
std::vector<std::string> Args;
423-
lexCommand(Message, CompileCommandLine, CmdPath, Args);
408+
lexCommand(Argv0, Message, CompileCommandLine, CmdPath, Args);
424409
if (CmdPath.empty())
425410
return nullptr;
426411

@@ -430,12 +415,13 @@ AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
430415
// Custom execution environment create method, takes the execution command
431416
// as arguments
432417
AbstractInterpreter *
433-
AbstractInterpreter::createCustomExecutor(std::string &Message,
418+
AbstractInterpreter::createCustomExecutor(const char *Argv0,
419+
std::string &Message,
434420
const std::string &ExecCommandLine) {
435421

436422
std::string CmdPath;
437423
std::vector<std::string> Args;
438-
lexCommand(Message, ExecCommandLine, CmdPath, Args);
424+
lexCommand(Argv0, Message, ExecCommandLine, CmdPath, Args);
439425
if (CmdPath.empty())
440426
return nullptr;
441427

@@ -524,20 +510,20 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message,
524510
const std::vector<std::string> *Args,
525511
const std::vector<std::string> *CCArgs,
526512
bool UseIntegratedAssembler) {
527-
std::string LLCPath =
528-
PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC);
529-
if (LLCPath.empty()) {
530-
Message = "Cannot find `llc' in executable directory!\n";
513+
ErrorOr<std::string> LLCPath =
514+
FindProgramByName("llc", Argv0, (void *)(intptr_t)&createLLC);
515+
if (!LLCPath) {
516+
Message = LLCPath.getError().message() + "\n";
531517
return nullptr;
532518
}
533519

534-
CC *cc = CC::create(Message, CCBinary, CCArgs);
520+
CC *cc = CC::create(Argv0, Message, CCBinary, CCArgs);
535521
if (!cc) {
536522
errs() << Message << "\n";
537523
exit(1);
538524
}
539-
Message = "Found llc: " + LLCPath + "\n";
540-
return new LLC(LLCPath, cc, Args, UseIntegratedAssembler);
525+
Message = "Found llc: " + *LLCPath + "\n";
526+
return new LLC(*LLCPath, cc, Args, UseIntegratedAssembler);
541527
}
542528

543529
//===---------------------------------------------------------------------===//
@@ -606,15 +592,14 @@ Expected<int> JIT::ExecuteProgram(const std::string &Bitcode,
606592
AbstractInterpreter *
607593
AbstractInterpreter::createJIT(const char *Argv0, std::string &Message,
608594
const std::vector<std::string> *Args) {
609-
std::string LLIPath =
610-
PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT);
611-
if (!LLIPath.empty()) {
612-
Message = "Found lli: " + LLIPath + "\n";
613-
return new JIT(LLIPath, Args);
595+
if (ErrorOr<std::string> LLIPath =
596+
FindProgramByName("lli", Argv0, (void *)(intptr_t)&createJIT)) {
597+
Message = "Found lli: " + *LLIPath + "\n";
598+
return new JIT(*LLIPath, Args);
599+
} else {
600+
Message = LLIPath.getError().message() + "\n";
601+
return nullptr;
614602
}
615-
616-
Message = "Cannot find `lli' in executable directory!\n";
617-
return nullptr;
618603
}
619604

620605
//===---------------------------------------------------------------------===//
@@ -855,9 +840,10 @@ Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
855840

856841
/// create - Try to find the CC executable
857842
///
858-
CC *CC::create(std::string &Message, const std::string &CCBinary,
843+
CC *CC::create(const char *Argv0, std::string &Message,
844+
const std::string &CCBinary,
859845
const std::vector<std::string> *Args) {
860-
auto CCPath = sys::findProgramByName(CCBinary);
846+
auto CCPath = FindProgramByName(CCBinary, Argv0, (void *)(intptr_t)&create);
861847
if (!CCPath) {
862848
Message = "Cannot find `" + CCBinary + "' in PATH: " +
863849
CCPath.getError().message() + "\n";

llvm/tools/bugpoint/ToolRunner.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class CC {
4949
public:
5050
enum FileType { AsmFile, ObjectFile, CFile };
5151

52-
static CC *create(std::string &Message, const std::string &CCBinary,
52+
static CC *create(const char *Argv0, std::string &Message,
53+
const std::string &CCBinary,
5354
const std::vector<std::string> *Args);
5455

5556
/// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
@@ -98,11 +99,11 @@ class AbstractInterpreter {
9899
const std::vector<std::string> *Args = nullptr);
99100

100101
static AbstractInterpreter *
101-
createCustomCompiler(std::string &Message,
102+
createCustomCompiler(const char *Argv0, std::string &Message,
102103
const std::string &CompileCommandLine);
103104

104105
static AbstractInterpreter *
105-
createCustomExecutor(std::string &Message,
106+
createCustomExecutor(const char *Argv0, std::string &Message,
106107
const std::string &ExecCommandLine);
107108

108109
virtual ~AbstractInterpreter() {}
@@ -178,6 +179,13 @@ class LLC : public AbstractInterpreter {
178179
unsigned MemoryLimit = 0) override;
179180
};
180181

182+
/// Find the first executable file \ExeName, either in the user's PATH or,
183+
/// failing that, in the same directory as argv[0]. This allows us to find
184+
/// another LLVM tool if it is built in the same directory. If no executable is
185+
/// found, an error is returned.
186+
ErrorOr<std::string> FindProgramByName(const std::string &ExeName,
187+
const char *Argv0, void *MainAddr);
188+
181189
} // End llvm namespace
182190

183191
#endif

0 commit comments

Comments
 (0)