For PR351:

* Place a try/catch block around the entire tool to Make sure std::string
  exceptions are caught and printed before exiting the tool.
* Make sure we catch unhandled exceptions at the top level so that we don't
  abort with a useless message but indicate than an unhandled exception was
  generated.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19192 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer
2004-12-30 05:36:08 +00:00
parent c18671cdcd
commit 1ef8bdaedb
17 changed files with 960 additions and 852 deletions

View File

@@ -116,58 +116,66 @@ namespace {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
sys::PrintStackTraceOnErrorSignal();
Module *CurMod = 0;
try { try {
cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
sys::PrintStackTraceOnErrorSignal();
Module *CurMod = 0;
try {
#if 0 #if 0
TimeRegion RegionTimer(BytecodeLoadTimer); TimeRegion RegionTimer(BytecodeLoadTimer);
#endif #endif
CurMod = ParseBytecodeFile(InputFilename); CurMod = ParseBytecodeFile(InputFilename);
if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){ if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
std::cerr << argv[0] << ": input file didn't read correctly.\n"; std::cerr << argv[0] << ": input file didn't read correctly.\n";
return 1;
}
} catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1; return 1;
} }
} catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\n"; // Create a PassManager to hold and optimize the collection of passes we are
return 1; // about to build...
//
PassManager Passes;
// Add an appropriate TargetData instance for this module...
Passes.add(new TargetData("analyze", CurMod));
// Make sure the input LLVM is well formed.
if (!NoVerify)
Passes.add(createVerifierPass());
// Create a new optimization pass for each one specified on the command line
for (unsigned i = 0; i < AnalysesList.size(); ++i) {
const PassInfo *Analysis = AnalysesList[i];
if (Analysis->getNormalCtor()) {
Pass *P = Analysis->getNormalCtor()();
Passes.add(P);
if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P))
Passes.add(new BasicBlockPassPrinter(Analysis));
else if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P))
Passes.add(new FunctionPassPrinter(Analysis));
else
Passes.add(new ModulePassPrinter(Analysis));
} else
std::cerr << argv[0] << ": cannot create pass: "
<< Analysis->getPassName() << "\n";
}
Passes.run(*CurMod);
delete CurMod;
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
// Create a PassManager to hold and optimize the collection of passes we are
// about to build...
//
PassManager Passes;
// Add an appropriate TargetData instance for this module...
Passes.add(new TargetData("analyze", CurMod));
// Make sure the input LLVM is well formed.
if (!NoVerify)
Passes.add(createVerifierPass());
// Create a new optimization pass for each one specified on the command line
for (unsigned i = 0; i < AnalysesList.size(); ++i) {
const PassInfo *Analysis = AnalysesList[i];
if (Analysis->getNormalCtor()) {
Pass *P = Analysis->getNormalCtor()();
Passes.add(P);
if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P))
Passes.add(new BasicBlockPassPrinter(Analysis));
else if (FunctionPass *FP = dynamic_cast<FunctionPass*>(P))
Passes.add(new FunctionPassPrinter(Analysis));
else
Passes.add(new ModulePassPrinter(Analysis));
} else
std::cerr << argv[0] << ": cannot create pass: "
<< Analysis->getPassName() << "\n";
}
Passes.run(*CurMod);
delete CurMod;
return 0;
} }

View File

@@ -51,10 +51,11 @@ int main(int argc, char **argv) {
return D.run(); return D.run();
} catch (ToolExecutionError &TEE) { } catch (ToolExecutionError &TEE) {
std::cerr << "Tool execution error: " << TEE.what() << '\n'; std::cerr << "Tool execution error: " << TEE.what() << '\n';
return 1; } catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) { } catch (...) {
std::cerr << "Whoops, an exception leaked out of bugpoint. " std::cerr << "Whoops, an exception leaked out of bugpoint. "
<< "This is a bug in bugpoint!\n"; << "This is a bug in bugpoint!\n";
return 1;
} }
return 1;
} }

View File

@@ -45,53 +45,60 @@ ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"),
cl::value_desc("function")); cl::value_desc("function"));
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
sys::PrintStackTraceOnErrorSignal();
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) { if (M.get() == 0) {
std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
return 1;
}
// Figure out which function we should extract
Function *F = M.get()->getNamedFunction(ExtractFunc);
if (F == 0) {
std::cerr << argv[0] << ": program doesn't contain function named '"
<< ExtractFunc << "'!\n";
return 1;
}
// In addition to deleting all other functions, we also want to spiff it up a
// little bit. Do this now.
//
PassManager Passes;
Passes.add(new TargetData("extract", M.get())); // Use correct TargetData
// Either isolate the function or delete it from the Module
Passes.add(createFunctionExtractionPass(F, DeleteFn));
Passes.add(createGlobalDCEPass()); // Delete unreachable globals
Passes.add(createFunctionResolvingPass()); // Delete prototypes
Passes.add(createDeadTypeEliminationPass()); // Remove dead types...
std::ostream *Out = 0;
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1; return 1;
} }
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout // Figure out which function we should extract
Out = &std::cout; Function *F = M.get()->getNamedFunction(ExtractFunc);
if (F == 0) {
std::cerr << argv[0] << ": program doesn't contain function named '"
<< ExtractFunc << "'!\n";
return 1;
}
// In addition to deleting all other functions, we also want to spiff it up a
// little bit. Do this now.
//
PassManager Passes;
Passes.add(new TargetData("extract", M.get())); // Use correct TargetData
// Either isolate the function or delete it from the Module
Passes.add(createFunctionExtractionPass(F, DeleteFn));
Passes.add(createGlobalDCEPass()); // Delete unreachable globals
Passes.add(createFunctionResolvingPass()); // Delete prototypes
Passes.add(createDeadTypeEliminationPass()); // Remove dead types...
std::ostream *Out = 0;
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout
Out = &std::cout;
}
Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file...
Passes.run(*M.get());
if (Out != &std::cout)
delete Out;
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file...
Passes.run(*M.get());
if (Out != &std::cout)
delete Out;
return 0;
} }

View File

@@ -128,77 +128,85 @@ void AddConfiguredTransformationPasses(PassManager &PM) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm .s -> .o assembler for GCC\n");
sys::PrintStackTraceOnErrorSignal();
std::auto_ptr<Module> M;
try { try {
// Parse the file now... cl::ParseCommandLineOptions(argc, argv,
M.reset(ParseAssemblyFile(InputFilename)); " llvm .s -> .o assembler for GCC\n");
} catch (const ParseException &E) { sys::PrintStackTraceOnErrorSignal();
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1;
}
if (M.get() == 0) { std::auto_ptr<Module> M;
std::cerr << argv[0] << ": assembly didn't read correctly.\n"; try {
return 1; // Parse the file now...
} M.reset(ParseAssemblyFile(InputFilename));
} catch (const ParseException &E) {
std::ostream *Out = 0; std::cerr << argv[0] << ": " << E.getMessage() << "\n";
if (OutputFilename == "") { // Didn't specify an output filename? return 1;
if (InputFilename == "-") {
OutputFilename = "-";
} else {
std::string IFN = InputFilename;
int Len = IFN.length();
if (IFN[Len-2] == '.' && IFN[Len-1] == 's') { // Source ends in .s?
OutputFilename = std::string(IFN.begin(), IFN.end()-2);
} else {
OutputFilename = IFN; // Append a .o to it
}
OutputFilename += ".o";
} }
if (M.get() == 0) {
std::cerr << argv[0] << ": assembly didn't read correctly.\n";
return 1;
}
std::ostream *Out = 0;
if (OutputFilename == "") { // Didn't specify an output filename?
if (InputFilename == "-") {
OutputFilename = "-";
} else {
std::string IFN = InputFilename;
int Len = IFN.length();
if (IFN[Len-2] == '.' && IFN[Len-1] == 's') { // Source ends in .s?
OutputFilename = std::string(IFN.begin(), IFN.end()-2);
} else {
OutputFilename = IFN; // Append a .o to it
}
OutputFilename += ".o";
}
}
if (OutputFilename == "-")
Out = &std::cout;
else {
Out = new std::ofstream(OutputFilename.c_str(), std::ios::out);
// Make sure that the Out file gets unlinked from the disk if we get a
// signal
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
return 1;
}
// In addition to just parsing the input from GCC, we also want to spiff it up
// a little bit. Do this now.
//
PassManager Passes;
// Add an appropriate TargetData instance for this module...
Passes.add(new TargetData("gccas", M.get()));
// Add all of the transformation passes to the pass manager to do the cleanup
// and optimization of the GCC output.
//
AddConfiguredTransformationPasses(Passes);
// Make sure everything is still good.
Passes.add(createVerifierPass());
// Write bytecode to file...
Passes.add(new WriteBytecodePass(Out,false,!NoCompress));
// Run our queue of passes all at once now, efficiently.
Passes.run(*M.get());
if (Out != &std::cout) delete Out;
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
if (OutputFilename == "-")
Out = &std::cout;
else {
Out = new std::ofstream(OutputFilename.c_str(), std::ios::out);
// Make sure that the Out file gets unlinked from the disk if we get a
// signal
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
return 1;
}
// In addition to just parsing the input from GCC, we also want to spiff it up
// a little bit. Do this now.
//
PassManager Passes;
// Add an appropriate TargetData instance for this module...
Passes.add(new TargetData("gccas", M.get()));
// Add all of the transformation passes to the pass manager to do the cleanup
// and optimization of the GCC output.
//
AddConfiguredTransformationPasses(Passes);
// Make sure everything is still good.
Passes.add(createVerifierPass());
// Write bytecode to file...
Passes.add(new WriteBytecodePass(Out,false,!NoCompress));
// Run our queue of passes all at once now, efficiently.
Passes.run(*M.get());
if (Out != &std::cout) delete Out;
return 0;
} }

View File

@@ -63,110 +63,117 @@ GetFileNameRoot(const std::string &InputFilename) {
// main - Entry point for the llc compiler. // main - Entry point for the llc compiler.
// //
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
sys::PrintStackTraceOnErrorSignal();
// Load the module to be compiled... // Load the module to be compiled...
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) { if (M.get() == 0) {
std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
return 1;
}
Module &mod = *M.get();
// Allocate target machine. First, check whether the user has
// explicitly specified an architecture to compile for.
TargetMachine* (*TargetMachineAllocator)(const Module&,
IntrinsicLowering *) = 0;
if (MArch == 0) {
std::string Err;
MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
if (MArch == 0) {
std::cerr << argv[0] << ": error auto-selecting target for module '"
<< Err << "'. Please use the -march option to explicitly "
<< "pick a target.\n";
return 1; return 1;
} }
} Module &mod = *M.get();
std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0)); // Allocate target machine. First, check whether the user has
assert(target.get() && "Could not allocate target machine!"); // explicitly specified an architecture to compile for.
TargetMachine &Target = *target.get(); TargetMachine* (*TargetMachineAllocator)(const Module&,
const TargetData &TD = Target.getTargetData(); IntrinsicLowering *) = 0;
if (MArch == 0) {
// Build up all of the passes that we want to do to the module... std::string Err;
PassManager Passes; MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(), if (MArch == 0) {
TD.getPointerAlignment(), TD.getDoubleAlignment())); std::cerr << argv[0] << ": error auto-selecting target for module '"
<< Err << "'. Please use the -march option to explicitly "
// Figure out where we are going to send the output... << "pick a target.\n";
std::ostream *Out = 0;
if (OutputFilename != "") {
if (OutputFilename != "-") {
// Specified an output filename?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1; return 1;
} }
Out = new std::ofstream(OutputFilename.c_str());
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
} else {
Out = &std::cout;
} }
} else {
if (InputFilename == "-") { std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
OutputFilename = "-"; assert(target.get() && "Could not allocate target machine!");
Out = &std::cout; TargetMachine &Target = *target.get();
const TargetData &TD = Target.getTargetData();
// Build up all of the passes that we want to do to the module...
PassManager Passes;
Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(),
TD.getPointerAlignment(), TD.getDoubleAlignment()));
// Figure out where we are going to send the output...
std::ostream *Out = 0;
if (OutputFilename != "") {
if (OutputFilename != "-") {
// Specified an output filename?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
} else {
Out = &std::cout;
}
} else { } else {
OutputFilename = GetFileNameRoot(InputFilename); if (InputFilename == "-") {
OutputFilename = "-";
Out = &std::cout;
} else {
OutputFilename = GetFileNameRoot(InputFilename);
if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
OutputFilename += ".s"; OutputFilename += ".s";
else else
OutputFilename += ".cbe.c"; OutputFilename += ".cbe.c";
if (!Force && std::ifstream(OutputFilename.c_str())) { if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file! // If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n" << "': file exists!\n"
<< "Use -f command line argument to force output\n"; << "Use -f command line argument to force output\n";
return 1; return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
delete Out;
return 1;
}
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
} }
Out = new std::ofstream(OutputFilename.c_str());
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
delete Out;
return 1;
}
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
} }
}
// Ask the target to add backend passes as necessary // Ask the target to add backend passes as necessary
if (Target.addPassesToEmitAssembly(Passes, *Out)) { if (Target.addPassesToEmitAssembly(Passes, *Out)) {
std::cerr << argv[0] << ": target '" << Target.getName() std::cerr << argv[0] << ": target '" << Target.getName()
<< "' does not support static compilation!\n"; << "' does not support static compilation!\n";
if (Out != &std::cout) delete Out;
// And the Out file is empty and useless, so remove it now.
std::remove(OutputFilename.c_str());
return 1;
} else {
// Run our queue of passes all at once now, efficiently.
Passes.run(*M.get());
}
// Delete the ostream if it's not a stdout stream
if (Out != &std::cout) delete Out; if (Out != &std::cout) delete Out;
// And the Out file is empty and useless, so remove it now.
std::remove(OutputFilename.c_str()); return 0;
return 1; } catch (const std::string& msg) {
} else { std::cerr << argv[0] << ": " << msg << "\n";
// Run our queue of passes all at once now, efficiently. } catch (...) {
Passes.run(*M.get()); std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
// Delete the ostream if it's not a stdout stream
if (Out != &std::cout) delete Out;
return 0;
} }

View File

@@ -47,62 +47,69 @@ namespace {
// main Driver function // main Driver function
// //
int main(int argc, char **argv, char * const *envp) { int main(int argc, char **argv, char * const *envp) {
cl::ParseCommandLineOptions(argc, argv,
" llvm interpreter & dynamic compiler\n");
sys::PrintStackTraceOnErrorSignal();
// Load the bytecode...
std::string ErrorMsg;
ModuleProvider *MP = 0;
try { try {
MP = getBytecodeModuleProvider(InputFile); cl::ParseCommandLineOptions(argc, argv,
} catch (std::string &err) { " llvm interpreter & dynamic compiler\n");
std::cerr << "Error loading program '" << InputFile << "': " << err << "\n"; sys::PrintStackTraceOnErrorSignal();
exit(1);
// Load the bytecode...
std::string ErrorMsg;
ModuleProvider *MP = 0;
try {
MP = getBytecodeModuleProvider(InputFile);
} catch (std::string &err) {
std::cerr << "Error loading program '" << InputFile << "': " << err << "\n";
exit(1);
}
ExecutionEngine *EE = ExecutionEngine::create(MP, ForceInterpreter);
assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?");
// If the user specifically requested an argv[0] to pass into the program, do
// it now.
if (!FakeArgv0.empty()) {
InputFile = FakeArgv0;
} else {
// Otherwise, if there is a .bc suffix on the executable strip it off, it
// might confuse the program.
if (InputFile.rfind(".bc") == InputFile.length() - 3)
InputFile.erase(InputFile.length() - 3);
}
// Add the module's name to the start of the vector of arguments to main().
InputArgv.insert(InputArgv.begin(), InputFile);
// Call the main function from M as if its signature were:
// int main (int argc, char **argv, const char **envp)
// using the contents of Args to determine argc & argv, and the contents of
// EnvVars to determine envp.
//
Function *Fn = MP->getModule()->getMainFunction();
if (!Fn) {
std::cerr << "'main' function not found in module.\n";
return -1;
}
// Run main...
int Result = EE->runFunctionAsMain(Fn, InputArgv, envp);
// If the program didn't explicitly call exit, call exit now, for the program.
// This ensures that any atexit handlers get called correctly.
Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy,
Type::IntTy, 0);
std::vector<GenericValue> Args;
GenericValue ResultGV;
ResultGV.IntVal = Result;
Args.push_back(ResultGV);
EE->runFunction(Exit, Args);
std::cerr << "ERROR: exit(" << Result << ") returned!\n";
abort();
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
ExecutionEngine *EE = ExecutionEngine::create(MP, ForceInterpreter);
assert(EE && "Couldn't create an ExecutionEngine, not even an interpreter?");
// If the user specifically requested an argv[0] to pass into the program, do
// it now.
if (!FakeArgv0.empty()) {
InputFile = FakeArgv0;
} else {
// Otherwise, if there is a .bc suffix on the executable strip it off, it
// might confuse the program.
if (InputFile.rfind(".bc") == InputFile.length() - 3)
InputFile.erase(InputFile.length() - 3);
}
// Add the module's name to the start of the vector of arguments to main().
InputArgv.insert(InputArgv.begin(), InputFile);
// Call the main function from M as if its signature were:
// int main (int argc, char **argv, const char **envp)
// using the contents of Args to determine argc & argv, and the contents of
// EnvVars to determine envp.
//
Function *Fn = MP->getModule()->getMainFunction();
if (!Fn) {
std::cerr << "'main' function not found in module.\n";
return -1;
}
// Run main...
int Result = EE->runFunctionAsMain(Fn, InputArgv, envp);
// If the program didn't explicitly call exit, call exit now, for the program.
// This ensures that any atexit handlers get called correctly.
Function *Exit = MP->getModule()->getOrInsertFunction("exit", Type::VoidTy,
Type::IntTy, 0);
std::vector<GenericValue> Args;
GenericValue ResultGV;
ResultGV.IntVal = Result;
Args.push_back(ResultGV);
EE->runFunction(Exit, Args);
std::cerr << "ERROR: exit(" << Result << ") returned!\n";
abort(); abort();
} }

View File

@@ -52,6 +52,7 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n"); cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n");
sys::PrintStackTraceOnErrorSignal(); sys::PrintStackTraceOnErrorSignal();
int exitCode = 0;
std::ostream *Out = 0; std::ostream *Out = 0;
try { try {
// Parse the file now... // Parse the file now...
@@ -126,10 +127,16 @@ int main(int argc, char **argv) {
WriteBytecodeToFile(M.get(), *Out, !NoCompress); WriteBytecodeToFile(M.get(), *Out, !NoCompress);
} catch (const ParseException &E) { } catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\n"; std::cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1; exitCode = 1;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
exitCode = 1;
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
exitCode = 1;
} }
if (Out != &std::cout) delete Out; if (Out != &std::cout) delete Out;
return 0; return exitCode;
} }

View File

@@ -49,52 +49,58 @@ static cl::opt<bool> Dump ("dump", cl::desc("Dump low level bytecode trace"
static cl::opt<bool> Verify ("verify", cl::desc("Progressively verify module")); static cl::opt<bool> Verify ("verify", cl::desc("Progressively verify module"));
int int
main(int argc, char **argv) main(int argc, char **argv) {
{ try {
cl::ParseCommandLineOptions(argc, argv, cl::ParseCommandLineOptions(argc, argv,
" llvm-bcanalyzer Analysis of ByteCode Dumper\n"); " llvm-bcanalyzer Analysis of ByteCode Dumper\n");
sys::PrintStackTraceOnErrorSignal(); sys::PrintStackTraceOnErrorSignal();
std::ostream* Out = &std::cout; // Default to printing to stdout... std::ostream* Out = &std::cout; // Default to printing to stdout...
std::istream* In = &std::cin; // Default to reading stdin std::istream* In = &std::cin; // Default to reading stdin
std::string ErrorMessage; std::string ErrorMessage;
BytecodeAnalysis bca; BytecodeAnalysis bca;
/// Determine what to generate /// Determine what to generate
bca.detailedResults = !NoDetails; bca.detailedResults = !NoDetails;
bca.progressiveVerify = Verify; bca.progressiveVerify = Verify;
/// Analyze the bytecode file /// Analyze the bytecode file
Module* M = AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage, (Dump?Out:0)); Module* M = AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage, (Dump?Out:0));
// All that bcanalyzer does is write the gathered statistics to the output // All that bcanalyzer does is write the gathered statistics to the output
PrintBytecodeAnalysis(bca,*Out); PrintBytecodeAnalysis(bca,*Out);
if ( M && Verify ) { if ( M && Verify ) {
std::string verificationMsg; std::string verificationMsg;
try { try {
verifyModule( *M, ThrowExceptionAction ); verifyModule( *M, ThrowExceptionAction );
} catch (std::string& errmsg ) { } catch (std::string& errmsg ) {
verificationMsg = errmsg; verificationMsg = errmsg;
}
if ( verificationMsg.length() > 0 )
std::cerr << "Final Verification Message: " << verificationMsg << "\n";
} }
if ( verificationMsg.length() > 0 )
std::cerr << "Final Verification Message: " << verificationMsg << "\n";
}
// If there was an error, print it and stop. // If there was an error, print it and stop.
if ( ErrorMessage.size() ) { if ( ErrorMessage.size() ) {
std::cerr << argv[0] << ": " << ErrorMessage << "\n"; std::cerr << argv[0] << ": " << ErrorMessage << "\n";
return 1; return 1;
} }
if (Out != &std::cout) { if (Out != &std::cout) {
((std::ofstream*)Out)->close(); ((std::ofstream*)Out)->close();
delete Out; delete Out;
}
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 0; return 1;
} }
// vim: sw=2 // vim: sw=2

View File

@@ -50,39 +50,46 @@ namespace {
// main Driver function // main Driver function
// //
int main(int argc, char **argv, char * const *envp) { int main(int argc, char **argv, char * const *envp) {
cl::ParseCommandLineOptions(argc, argv, try {
" llvm source-level debugger\n"); cl::ParseCommandLineOptions(argc, argv,
sys::PrintStackTraceOnErrorSignal(); " llvm source-level debugger\n");
sys::PrintStackTraceOnErrorSignal();
if (!Quiet) if (!Quiet)
std::cout << "llvm-db: The LLVM source-level debugger\n"; std::cout << "llvm-db: The LLVM source-level debugger\n";
// Merge Inputfile and InputArgs into the InputArgs list... // Merge Inputfile and InputArgs into the InputArgs list...
if (!InputFile.empty() && InputArgs.empty()) if (!InputFile.empty() && InputArgs.empty())
InputArgs.push_back(InputFile); InputArgs.push_back(InputFile);
// Create the CLI debugger... // Create the CLI debugger...
CLIDebugger D; CLIDebugger D;
// Initialize the debugger with the command line options we read... // Initialize the debugger with the command line options we read...
Debugger &Dbg = D.getDebugger(); Debugger &Dbg = D.getDebugger();
// Initialize the debugger environment. // Initialize the debugger environment.
Dbg.initializeEnvironment(envp); Dbg.initializeEnvironment(envp);
Dbg.setWorkingDirectory(WorkingDirectory); Dbg.setWorkingDirectory(WorkingDirectory);
for (unsigned i = 0, e = SourceDirectories.size(); i != e; ++i) for (unsigned i = 0, e = SourceDirectories.size(); i != e; ++i)
D.addSourceDirectory(SourceDirectories[i]); D.addSourceDirectory(SourceDirectories[i]);
if (!InputArgs.empty()) { if (!InputArgs.empty()) {
try { try {
D.fileCommand(InputArgs[0]); D.fileCommand(InputArgs[0]);
} catch (const std::string &Error) { } catch (const std::string &Error) {
std::cout << "Error: " << Error << "\n"; std::cout << "Error: " << Error << "\n";
}
Dbg.setProgramArguments(InputArgs.begin()+1, InputArgs.end());
} }
Dbg.setProgramArguments(InputArgs.begin()+1, InputArgs.end()); // Now that we have initialized the debugger, run it.
return D.run();
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
// Now that we have initialized the debugger, run it.
return D.run();
} }

View File

@@ -41,81 +41,88 @@ static cl::opt<bool>
CWriteMode("c", cl::desc("Obsolete option, do not use"), cl::ReallyHidden); CWriteMode("c", cl::desc("Obsolete option, do not use"), cl::ReallyHidden);
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
sys::PrintStackTraceOnErrorSignal();
std::ostream *Out = &std::cout; // Default to printing to stdout... std::ostream *Out = &std::cout; // Default to printing to stdout...
std::string ErrorMessage; std::string ErrorMessage;
if (CWriteMode) { if (CWriteMode) {
std::cerr << "ERROR: llvm-dis no longer contains the C backend. " std::cerr << "ERROR: llvm-dis no longer contains the C backend. "
<< "Use 'llc -march=c' instead!\n"; << "Use 'llc -march=c' instead!\n";
exit(1); exit(1);
}
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage));
if (M.get() == 0) {
std::cerr << argv[0] << ": ";
if (ErrorMessage.size())
std::cerr << ErrorMessage << "\n";
else
std::cerr << "bytecode didn't read correctly.\n";
return 1;
}
if (OutputFilename != "") { // Specified an output filename?
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists! Sending to standard output.\n";
} else {
Out = new std::ofstream(OutputFilename.c_str());
}
} }
} else {
if (InputFilename == "-") { std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage));
OutputFilename = "-"; if (M.get() == 0) {
std::cerr << argv[0] << ": ";
if (ErrorMessage.size())
std::cerr << ErrorMessage << "\n";
else
std::cerr << "bytecode didn't read correctly.\n";
return 1;
}
if (OutputFilename != "") { // Specified an output filename?
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists! Sending to standard output.\n";
} else {
Out = new std::ofstream(OutputFilename.c_str());
}
}
} else { } else {
std::string IFN = InputFilename; if (InputFilename == "-") {
int Len = IFN.length(); OutputFilename = "-";
if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
// Source ends in .bc
OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
} else { } else {
OutputFilename = IFN+".ll"; std::string IFN = InputFilename;
} int Len = IFN.length();
if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
// Source ends in .bc
OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll";
} else {
OutputFilename = IFN+".ll";
}
if (!Force && std::ifstream(OutputFilename.c_str())) { if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file! // If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists! Sending to standard output.\n"; << "': file exists! Sending to standard output.\n";
} else { } else {
Out = new std::ofstream(OutputFilename.c_str()); Out = new std::ofstream(OutputFilename.c_str());
// Make sure that the Out file gets unlinked from the disk if we get a // Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT // SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename)); sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
} }
} }
}
if (!Out->good()) { if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename std::cerr << argv[0] << ": error opening " << OutputFilename
<< ": sending to stdout instead!\n"; << ": sending to stdout instead!\n";
Out = &std::cout; Out = &std::cout;
} }
// All that dis does is write the assembly or C out to a file... // All that dis does is write the assembly or C out to a file...
// //
PassManager Passes; PassManager Passes;
Passes.add(new PrintModulePass(Out)); Passes.add(new PrintModulePass(Out));
Passes.run(*M.get()); Passes.run(*M.get());
if (Out != &std::cout) { if (Out != &std::cout) {
((std::ofstream*)Out)->close(); ((std::ofstream*)Out)->close();
delete Out; delete Out;
}
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 0; return 1;
} }

View File

@@ -45,53 +45,60 @@ ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"),
cl::value_desc("function")); cl::value_desc("function"));
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
sys::PrintStackTraceOnErrorSignal();
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) { if (M.get() == 0) {
std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
return 1;
}
// Figure out which function we should extract
Function *F = M.get()->getNamedFunction(ExtractFunc);
if (F == 0) {
std::cerr << argv[0] << ": program doesn't contain function named '"
<< ExtractFunc << "'!\n";
return 1;
}
// In addition to deleting all other functions, we also want to spiff it up a
// little bit. Do this now.
//
PassManager Passes;
Passes.add(new TargetData("extract", M.get())); // Use correct TargetData
// Either isolate the function or delete it from the Module
Passes.add(createFunctionExtractionPass(F, DeleteFn));
Passes.add(createGlobalDCEPass()); // Delete unreachable globals
Passes.add(createFunctionResolvingPass()); // Delete prototypes
Passes.add(createDeadTypeEliminationPass()); // Remove dead types...
std::ostream *Out = 0;
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1; return 1;
} }
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout // Figure out which function we should extract
Out = &std::cout; Function *F = M.get()->getNamedFunction(ExtractFunc);
if (F == 0) {
std::cerr << argv[0] << ": program doesn't contain function named '"
<< ExtractFunc << "'!\n";
return 1;
}
// In addition to deleting all other functions, we also want to spiff it up a
// little bit. Do this now.
//
PassManager Passes;
Passes.add(new TargetData("extract", M.get())); // Use correct TargetData
// Either isolate the function or delete it from the Module
Passes.add(createFunctionExtractionPass(F, DeleteFn));
Passes.add(createGlobalDCEPass()); // Delete unreachable globals
Passes.add(createFunctionResolvingPass()); // Delete prototypes
Passes.add(createDeadTypeEliminationPass()); // Remove dead types...
std::ostream *Out = 0;
if (OutputFilename != "-") { // Not stdout?
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout
Out = &std::cout;
}
Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file...
Passes.run(*M.get());
if (Out != &std::cout)
delete Out;
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file...
Passes.run(*M.get());
if (Out != &std::cout)
delete Out;
return 0;
} }

View File

@@ -389,126 +389,133 @@ extern void Optimize(Module*);
} }
int main(int argc, char **argv, char **envp) { int main(int argc, char **argv, char **envp) {
// Initial global variable above for convenience printing of program name. try {
progname = sys::Path(argv[0]).getBasename(); // Initial global variable above for convenience printing of program name.
Linker TheLinker(progname, Verbose); progname = sys::Path(argv[0]).getBasename();
Linker TheLinker(progname, Verbose);
// Set up the library paths for the Linker
TheLinker.addPaths(LibPaths); // Set up the library paths for the Linker
TheLinker.addSystemPaths(); TheLinker.addPaths(LibPaths);
TheLinker.addSystemPaths();
// Parse the command line options // Parse the command line options
cl::ParseCommandLineOptions(argc, argv, " llvm linker\n"); cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
sys::PrintStackTraceOnErrorSignal(); sys::PrintStackTraceOnErrorSignal();
// Remove any consecutive duplicates of the same library... // Remove any consecutive duplicates of the same library...
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
Libraries.end()); Libraries.end());
if (LinkAsLibrary) { if (LinkAsLibrary) {
std::vector<sys::Path> Files; std::vector<sys::Path> Files;
for (unsigned i = 0; i < InputFilenames.size(); ++i ) for (unsigned i = 0; i < InputFilenames.size(); ++i )
Files.push_back(sys::Path(InputFilenames[i])); Files.push_back(sys::Path(InputFilenames[i]));
if (TheLinker.LinkInFiles(Files)) if (TheLinker.LinkInFiles(Files))
return 1; // Error already printed return 1; // Error already printed
// The libraries aren't linked in but are noted as "dependent" in the
// module.
for (cl::list<std::string>::const_iterator I = Libraries.begin(),
E = Libraries.end(); I != E ; ++I) {
TheLinker.getModule()->addLibrary(*I);
}
} else {
// Build a list of the items from our command line
Linker::ItemList Items;
BuildLinkItems(Items, InputFilenames, Libraries);
// Link all the items together
if (TheLinker.LinkInItems(Items) )
return 1;
}
std::auto_ptr<Module> Composite(TheLinker.releaseModule());
// Optimize the module
Optimize(Composite.get());
// Generate the bytecode for the optimized module.
std::string RealBytecodeOutput = OutputFilename;
if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
GenerateBytecode(Composite.get(), RealBytecodeOutput);
// If we are not linking a library, generate either a native executable
// or a JIT shell script, depending upon what the user wants.
if (!LinkAsLibrary) {
// If the user wants to generate a native executable, compile it from the
// bytecode file.
//
// Otherwise, create a script that will run the bytecode through the JIT.
if (Native) {
// Name of the Assembly Language output file
sys::Path AssemblyFile ( OutputFilename);
AssemblyFile.appendSuffix("s");
// Mark the output files for removal if we get an interrupt.
sys::RemoveFileOnSignal(AssemblyFile);
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Determine the locations of the llc and gcc programs.
sys::Path llc = FindExecutable("llc", argv[0]);
if (llc.isEmpty())
return PrintAndReturn("Failed to find llc");
sys::Path gcc = FindExecutable("gcc", argv[0]);
if (gcc.isEmpty())
return PrintAndReturn("Failed to find gcc");
// Generate an assembly language file for the bytecode.
if (Verbose) std::cout << "Generating Assembly Code\n";
GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput, llc);
if (Verbose) std::cout << "Generating Native Code\n";
GenerateNative(OutputFilename, AssemblyFile.toString(), Libraries,
gcc, envp);
// Remove the assembly language file.
AssemblyFile.destroyFile();
} else if (NativeCBE) {
sys::Path CFile (OutputFilename);
CFile.appendSuffix("cbe.c");
// Mark the output files for removal if we get an interrupt.
sys::RemoveFileOnSignal(CFile);
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Determine the locations of the llc and gcc programs.
sys::Path llc = FindExecutable("llc", argv[0]);
if (llc.isEmpty())
return PrintAndReturn("Failed to find llc");
sys::Path gcc = FindExecutable("gcc", argv[0]);
if (gcc.isEmpty())
return PrintAndReturn("Failed to find gcc");
// Generate an assembly language file for the bytecode.
if (Verbose) std::cout << "Generating Assembly Code\n";
GenerateCFile(CFile.toString(), RealBytecodeOutput, llc);
if (Verbose) std::cout << "Generating Native Code\n";
GenerateNative(OutputFilename, CFile.toString(), Libraries, gcc, envp);
// Remove the assembly language file.
CFile.destroyFile();
// The libraries aren't linked in but are noted as "dependent" in the
// module.
for (cl::list<std::string>::const_iterator I = Libraries.begin(),
E = Libraries.end(); I != E ; ++I) {
TheLinker.getModule()->addLibrary(*I);
}
} else { } else {
EmitShellScript(argv); // Build a list of the items from our command line
Linker::ItemList Items;
BuildLinkItems(Items, InputFilenames, Libraries);
// Link all the items together
if (TheLinker.LinkInItems(Items) )
return 1;
} }
// Make the script executable...
sys::Path(OutputFilename).makeExecutable();
// Make the bytecode file readable and directly executable in LLEE as well std::auto_ptr<Module> Composite(TheLinker.releaseModule());
sys::Path(RealBytecodeOutput).makeExecutable();
sys::Path(RealBytecodeOutput).makeReadable(); // Optimize the module
Optimize(Composite.get());
// Generate the bytecode for the optimized module.
std::string RealBytecodeOutput = OutputFilename;
if (!LinkAsLibrary) RealBytecodeOutput += ".bc";
GenerateBytecode(Composite.get(), RealBytecodeOutput);
// If we are not linking a library, generate either a native executable
// or a JIT shell script, depending upon what the user wants.
if (!LinkAsLibrary) {
// If the user wants to generate a native executable, compile it from the
// bytecode file.
//
// Otherwise, create a script that will run the bytecode through the JIT.
if (Native) {
// Name of the Assembly Language output file
sys::Path AssemblyFile ( OutputFilename);
AssemblyFile.appendSuffix("s");
// Mark the output files for removal if we get an interrupt.
sys::RemoveFileOnSignal(AssemblyFile);
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Determine the locations of the llc and gcc programs.
sys::Path llc = FindExecutable("llc", argv[0]);
if (llc.isEmpty())
return PrintAndReturn("Failed to find llc");
sys::Path gcc = FindExecutable("gcc", argv[0]);
if (gcc.isEmpty())
return PrintAndReturn("Failed to find gcc");
// Generate an assembly language file for the bytecode.
if (Verbose) std::cout << "Generating Assembly Code\n";
GenerateAssembly(AssemblyFile.toString(), RealBytecodeOutput, llc);
if (Verbose) std::cout << "Generating Native Code\n";
GenerateNative(OutputFilename, AssemblyFile.toString(), Libraries,
gcc, envp);
// Remove the assembly language file.
AssemblyFile.destroyFile();
} else if (NativeCBE) {
sys::Path CFile (OutputFilename);
CFile.appendSuffix("cbe.c");
// Mark the output files for removal if we get an interrupt.
sys::RemoveFileOnSignal(CFile);
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Determine the locations of the llc and gcc programs.
sys::Path llc = FindExecutable("llc", argv[0]);
if (llc.isEmpty())
return PrintAndReturn("Failed to find llc");
sys::Path gcc = FindExecutable("gcc", argv[0]);
if (gcc.isEmpty())
return PrintAndReturn("Failed to find gcc");
// Generate an assembly language file for the bytecode.
if (Verbose) std::cout << "Generating Assembly Code\n";
GenerateCFile(CFile.toString(), RealBytecodeOutput, llc);
if (Verbose) std::cout << "Generating Native Code\n";
GenerateNative(OutputFilename, CFile.toString(), Libraries, gcc, envp);
// Remove the assembly language file.
CFile.destroyFile();
} else {
EmitShellScript(argv);
}
// Make the script executable...
sys::Path(OutputFilename).makeExecutable();
// Make the bytecode file readable and directly executable in LLEE as well
sys::Path(RealBytecodeOutput).makeExecutable();
sys::Path(RealBytecodeOutput).makeReadable();
}
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
return 0;
} }

View File

@@ -75,70 +75,77 @@ static inline std::auto_ptr<Module> LoadFile(const std::string &FN) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm linker\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
assert(InputFilenames.size() > 0 && "OneOrMore is not working"); sys::PrintStackTraceOnErrorSignal();
assert(InputFilenames.size() > 0 && "OneOrMore is not working");
unsigned BaseArg = 0; unsigned BaseArg = 0;
std::string ErrorMessage; std::string ErrorMessage;
std::auto_ptr<Module> Composite(LoadFile(InputFilenames[BaseArg])); std::auto_ptr<Module> Composite(LoadFile(InputFilenames[BaseArg]));
if (Composite.get() == 0) { if (Composite.get() == 0) {
std::cerr << argv[0] << ": error loading file '"
<< InputFilenames[BaseArg] << "'\n";
return 1;
}
for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
std::auto_ptr<Module> M(LoadFile(InputFilenames[i]));
if (M.get() == 0) {
std::cerr << argv[0] << ": error loading file '" std::cerr << argv[0] << ": error loading file '"
<< InputFilenames[i] << "'\n"; << InputFilenames[BaseArg] << "'\n";
return 1; return 1;
} }
if (Verbose) std::cerr << "Linking in '" << InputFilenames[i] << "'\n"; for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
std::auto_ptr<Module> M(LoadFile(InputFilenames[i]));
if (M.get() == 0) {
std::cerr << argv[0] << ": error loading file '"
<< InputFilenames[i] << "'\n";
return 1;
}
if (Linker::LinkModules(Composite.get(), M.get(), &ErrorMessage)) { if (Verbose) std::cerr << "Linking in '" << InputFilenames[i] << "'\n";
std::cerr << argv[0] << ": link error in '" << InputFilenames[i]
<< "': " << ErrorMessage << "\n"; if (Linker::LinkModules(Composite.get(), M.get(), &ErrorMessage)) {
std::cerr << argv[0] << ": link error in '" << InputFilenames[i]
<< "': " << ErrorMessage << "\n";
return 1;
}
}
// TODO: Iterate over the -l list and link in any modules containing
// global symbols that have not been resolved so far.
if (DumpAsm) std::cerr << "Here's the assembly:\n" << Composite.get();
std::ostream *Out = &std::cout; // Default to printing to stdout...
if (OutputFilename != "-") {
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
if (!Out->good()) {
std::cerr << argv[0] << ": error opening '" << OutputFilename << "'!\n";
return 1;
}
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
if (verifyModule(*Composite.get())) {
std::cerr << argv[0] << ": linked module is broken!\n";
return 1; return 1;
} }
if (Verbose) std::cerr << "Writing bytecode...\n";
WriteBytecodeToFile(Composite.get(), *Out, !NoCompress);
if (Out != &std::cout) delete Out;
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
// TODO: Iterate over the -l list and link in any modules containing
// global symbols that have not been resolved so far.
if (DumpAsm) std::cerr << "Here's the assembly:\n" << Composite.get();
std::ostream *Out = &std::cout; // Default to printing to stdout...
if (OutputFilename != "-") {
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
if (!Out->good()) {
std::cerr << argv[0] << ": error opening '" << OutputFilename << "'!\n";
return 1;
}
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
if (verifyModule(*Composite.get())) {
std::cerr << argv[0] << ": linked module is broken!\n";
return 1;
}
if (Verbose) std::cerr << "Writing bytecode...\n";
WriteBytecodeToFile(Composite.get(), *Out, !NoCompress);
if (Out != &std::cout) delete Out;
return 0;
} }

View File

@@ -152,20 +152,27 @@ void DumpSymbolNamesFromFile (std::string &Filename) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n");
sys::PrintStackTraceOnErrorSignal();
ToolName = argv[0]; ToolName = argv[0];
if (BSDFormat) OutputFormat = bsd; if (BSDFormat) OutputFormat = bsd;
if (POSIXFormat) OutputFormat = posix; if (POSIXFormat) OutputFormat = posix;
switch (InputFilenames.size()) { switch (InputFilenames.size()) {
case 0: InputFilenames.push_back("-"); case 0: InputFilenames.push_back("-");
case 1: break; case 1: break;
default: MultipleFiles = true; default: MultipleFiles = true;
}
std::for_each (InputFilenames.begin (), InputFilenames.end (),
DumpSymbolNamesFromFile);
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
std::for_each (InputFilenames.begin (), InputFilenames.end (),
DumpSymbolNamesFromFile);
return 0;
} }

View File

@@ -107,124 +107,131 @@ namespace {
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n"); try {
sys::PrintStackTraceOnErrorSignal(); cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n");
sys::PrintStackTraceOnErrorSignal();
// Read in the bytecode file... // Read in the bytecode file...
std::string ErrorMessage; std::string ErrorMessage;
Module *M = ParseBytecodeFile(BytecodeFile, &ErrorMessage); Module *M = ParseBytecodeFile(BytecodeFile, &ErrorMessage);
if (M == 0) { if (M == 0) {
std::cerr << argv[0] << ": " << BytecodeFile << ": " << ErrorMessage std::cerr << argv[0] << ": " << BytecodeFile << ": " << ErrorMessage
<< "\n"; << "\n";
return 1; return 1;
}
// Read the profiling information
ProfileInfoLoader PI(argv[0], ProfileDataFile, *M);
std::map<const Function *, unsigned> FuncFreqs;
std::map<const BasicBlock*, unsigned> BlockFreqs;
std::map<ProfileInfoLoader::Edge, unsigned> EdgeFreqs;
// Output a report. Eventually, there will be multiple reports selectable on
// the command line, for now, just keep things simple.
// Emit the most frequent function table...
std::vector<std::pair<Function*, unsigned> > FunctionCounts;
PI.getFunctionCounts(FunctionCounts);
FuncFreqs.insert(FunctionCounts.begin(), FunctionCounts.end());
// Sort by the frequency, backwards.
std::sort(FunctionCounts.begin(), FunctionCounts.end(),
PairSecondSortReverse<Function*>());
unsigned long long TotalExecutions = 0;
for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i)
TotalExecutions += FunctionCounts[i].second;
std::cout << "===" << std::string(73, '-') << "===\n"
<< "LLVM profiling output for execution";
if (PI.getNumExecutions() != 1) std::cout << "s";
std::cout << ":\n";
for (unsigned i = 0, e = PI.getNumExecutions(); i != e; ++i) {
std::cout << " ";
if (e != 1) std::cout << i+1 << ". ";
std::cout << PI.getExecution(i) << "\n";
}
std::cout << "\n===" << std::string(73, '-') << "===\n";
std::cout << "Function execution frequencies:\n\n";
// Print out the function frequencies...
printf(" ## Frequency\n");
for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) {
if (FunctionCounts[i].second == 0) {
printf("\n NOTE: %d function%s never executed!\n",
e-i, e-i-1 ? "s were" : " was");
break;
} }
printf("%3d. %5u/%llu %s\n", i+1, FunctionCounts[i].second, TotalExecutions, // Read the profiling information
FunctionCounts[i].first->getName().c_str()); ProfileInfoLoader PI(argv[0], ProfileDataFile, *M);
}
std::set<Function*> FunctionsToPrint; std::map<const Function *, unsigned> FuncFreqs;
std::map<const BasicBlock*, unsigned> BlockFreqs;
std::map<ProfileInfoLoader::Edge, unsigned> EdgeFreqs;
// If we have block count information, print out the LLVM module with // Output a report. Eventually, there will be multiple reports selectable on
// frequency annotations. // the command line, for now, just keep things simple.
if (PI.hasAccurateBlockCounts()) {
std::vector<std::pair<BasicBlock*, unsigned> > Counts;
PI.getBlockCounts(Counts);
TotalExecutions = 0; // Emit the most frequent function table...
for (unsigned i = 0, e = Counts.size(); i != e; ++i) std::vector<std::pair<Function*, unsigned> > FunctionCounts;
TotalExecutions += Counts[i].second; PI.getFunctionCounts(FunctionCounts);
FuncFreqs.insert(FunctionCounts.begin(), FunctionCounts.end());
// Sort by the frequency, backwards. // Sort by the frequency, backwards.
std::sort(Counts.begin(), Counts.end(), std::sort(FunctionCounts.begin(), FunctionCounts.end(),
PairSecondSortReverse<BasicBlock*>()); PairSecondSortReverse<Function*>());
unsigned long long TotalExecutions = 0;
for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i)
TotalExecutions += FunctionCounts[i].second;
std::cout << "===" << std::string(73, '-') << "===\n"
<< "LLVM profiling output for execution";
if (PI.getNumExecutions() != 1) std::cout << "s";
std::cout << ":\n";
for (unsigned i = 0, e = PI.getNumExecutions(); i != e; ++i) {
std::cout << " ";
if (e != 1) std::cout << i+1 << ". ";
std::cout << PI.getExecution(i) << "\n";
}
std::cout << "\n===" << std::string(73, '-') << "===\n"; std::cout << "\n===" << std::string(73, '-') << "===\n";
std::cout << "Top 20 most frequently executed basic blocks:\n\n"; std::cout << "Function execution frequencies:\n\n";
// Print out the function frequencies... // Print out the function frequencies...
printf(" ## %%%% \tFrequency\n"); printf(" ## Frequency\n");
unsigned BlocksToPrint = Counts.size(); for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) {
if (BlocksToPrint > 20) BlocksToPrint = 20; if (FunctionCounts[i].second == 0) {
for (unsigned i = 0; i != BlocksToPrint; ++i) { printf("\n NOTE: %d function%s never executed!\n",
if (Counts[i].second == 0) break; e-i, e-i-1 ? "s were" : " was");
Function *F = Counts[i].first->getParent(); break;
printf("%3d. %5.2f%% %5u/%llu\t%s() - %s\n", i+1, }
Counts[i].second/(double)TotalExecutions*100,
Counts[i].second, TotalExecutions, printf("%3d. %5u/%llu %s\n", i+1, FunctionCounts[i].second, TotalExecutions,
F->getName().c_str(), Counts[i].first->getName().c_str()); FunctionCounts[i].first->getName().c_str());
FunctionsToPrint.insert(F);
} }
BlockFreqs.insert(Counts.begin(), Counts.end()); std::set<Function*> FunctionsToPrint;
}
if (PI.hasAccurateEdgeCounts()) {
std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > Counts;
PI.getEdgeCounts(Counts);
EdgeFreqs.insert(Counts.begin(), Counts.end());
}
if (PrintAnnotatedLLVM || PrintAllCode) { // If we have block count information, print out the LLVM module with
std::cout << "\n===" << std::string(73, '-') << "===\n"; // frequency annotations.
std::cout << "Annotated LLVM code for the module:\n\n"; if (PI.hasAccurateBlockCounts()) {
std::vector<std::pair<BasicBlock*, unsigned> > Counts;
PI.getBlockCounts(Counts);
TotalExecutions = 0;
for (unsigned i = 0, e = Counts.size(); i != e; ++i)
TotalExecutions += Counts[i].second;
// Sort by the frequency, backwards.
std::sort(Counts.begin(), Counts.end(),
PairSecondSortReverse<BasicBlock*>());
std::cout << "\n===" << std::string(73, '-') << "===\n";
std::cout << "Top 20 most frequently executed basic blocks:\n\n";
// Print out the function frequencies...
printf(" ## %%%% \tFrequency\n");
unsigned BlocksToPrint = Counts.size();
if (BlocksToPrint > 20) BlocksToPrint = 20;
for (unsigned i = 0; i != BlocksToPrint; ++i) {
if (Counts[i].second == 0) break;
Function *F = Counts[i].first->getParent();
printf("%3d. %5.2f%% %5u/%llu\t%s() - %s\n", i+1,
Counts[i].second/(double)TotalExecutions*100,
Counts[i].second, TotalExecutions,
F->getName().c_str(), Counts[i].first->getName().c_str());
FunctionsToPrint.insert(F);
}
BlockFreqs.insert(Counts.begin(), Counts.end());
}
ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs); if (PI.hasAccurateEdgeCounts()) {
std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > Counts;
PI.getEdgeCounts(Counts);
EdgeFreqs.insert(Counts.begin(), Counts.end());
}
if (FunctionsToPrint.empty() || PrintAllCode) if (PrintAnnotatedLLVM || PrintAllCode) {
M->print(std::cout, &PA); std::cout << "\n===" << std::string(73, '-') << "===\n";
else std::cout << "Annotated LLVM code for the module:\n\n";
// Print just a subset of the functions...
for (std::set<Function*>::iterator I = FunctionsToPrint.begin(), ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs);
E = FunctionsToPrint.end(); I != E; ++I)
(*I)->print(std::cout, &PA); if (FunctionsToPrint.empty() || PrintAllCode)
M->print(std::cout, &PA);
else
// Print just a subset of the functions...
for (std::set<Function*>::iterator I = FunctionsToPrint.begin(),
E = FunctionsToPrint.end(); I != E; ++I)
(*I)->print(std::cout, &PA);
}
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
return 0;
} }

View File

@@ -368,4 +368,5 @@ int main(int argc, char **argv) {
} catch (...) { } catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
} }

View File

@@ -70,102 +70,109 @@ QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
// main for opt // main for opt
// //
int main(int argc, char **argv) { int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, try {
" llvm .bc -> .bc modular optimizer\n"); cl::ParseCommandLineOptions(argc, argv,
sys::PrintStackTraceOnErrorSignal(); " llvm .bc -> .bc modular optimizer\n");
sys::PrintStackTraceOnErrorSignal();
// Allocate a full target machine description only if necessary... // Allocate a full target machine description only if necessary...
// FIXME: The choice of target should be controllable on the command line. // FIXME: The choice of target should be controllable on the command line.
std::auto_ptr<TargetMachine> target; std::auto_ptr<TargetMachine> target;
TargetMachine* TM = NULL; TargetMachine* TM = NULL;
std::string ErrorMessage; std::string ErrorMessage;
// Load the input module... // Load the input module...
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage)); std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage));
if (M.get() == 0) { if (M.get() == 0) {
std::cerr << argv[0] << ": "; std::cerr << argv[0] << ": ";
if (ErrorMessage.size()) if (ErrorMessage.size())
std::cerr << ErrorMessage << "\n"; std::cerr << ErrorMessage << "\n";
else else
std::cerr << "bytecode didn't read correctly.\n"; std::cerr << "bytecode didn't read correctly.\n";
return 1;
}
// Figure out what stream we are supposed to write to...
std::ostream *Out = &std::cout; // Default to printing to stdout...
if (OutputFilename != "-") {
if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
return 1; return 1;
} }
// Make sure that the Output file gets unlinked from the disk if we get a // Figure out what stream we are supposed to write to...
// SIGINT std::ostream *Out = &std::cout; // Default to printing to stdout...
sys::RemoveFileOnSignal(sys::Path(OutputFilename)); if (OutputFilename != "-") {
} if (!Force && std::ifstream(OutputFilename.c_str())) {
// If force is not specified, make sure not to overwrite a file!
std::cerr << argv[0] << ": error opening '" << OutputFilename
<< "': file exists!\n"
<< "Use -f command line argument to force output\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
// If the output is set to be emitted to standard out, and standard out is a if (!Out->good()) {
// console, print out a warning message and refuse to do it. We don't impress std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
// anyone by spewing tons of binary goo to a terminal. return 1;
if (Out == &std::cout && isStandardOutAConsole() && !Force && !NoOutput }
&& !Quiet) {
std::cerr << "WARNING: It looks like you're attempting to print out a "
<< "bytecode file. I'm\ngoing to pretend you didn't ask me to do"
<< " this (for your own good). If you\nREALLY want to taste LLVM"
<< " bytecode first-hand, you can force output with the\n`-f'"
<< " option.\n\n";
NoOutput = true;
}
// Create a PassManager to hold and optimize the collection of passes we are // Make sure that the Output file gets unlinked from the disk if we get a
// about to build... // SIGINT
// sys::RemoveFileOnSignal(sys::Path(OutputFilename));
PassManager Passes; }
// Add an appropriate TargetData instance for this module... // If the output is set to be emitted to standard out, and standard out is a
Passes.add(new TargetData("opt", M.get())); // console, print out a warning message and refuse to do it. We don't impress
// anyone by spewing tons of binary goo to a terminal.
if (Out == &std::cout && isStandardOutAConsole() && !Force && !NoOutput
&& !Quiet) {
std::cerr << "WARNING: It looks like you're attempting to print out a "
<< "bytecode file. I'm\ngoing to pretend you didn't ask me to do"
<< " this (for your own good). If you\nREALLY want to taste LLVM"
<< " bytecode first-hand, you can force output with the\n`-f'"
<< " option.\n\n";
NoOutput = true;
}
// Create a new optimization pass for each one specified on the command line // Create a PassManager to hold and optimize the collection of passes we are
for (unsigned i = 0; i < OptimizationList.size(); ++i) { // about to build...
const PassInfo *Opt = OptimizationList[i]; //
PassManager Passes;
if (Opt->getNormalCtor())
Passes.add(Opt->getNormalCtor()()); // Add an appropriate TargetData instance for this module...
else if (Opt->getTargetCtor()) { Passes.add(new TargetData("opt", M.get()));
// Create a new optimization pass for each one specified on the command line
for (unsigned i = 0; i < OptimizationList.size(); ++i) {
const PassInfo *Opt = OptimizationList[i];
if (Opt->getNormalCtor())
Passes.add(Opt->getNormalCtor()());
else if (Opt->getTargetCtor()) {
#if 0 #if 0
if (target.get() == NULL) if (target.get() == NULL)
target.reset(allocateSparcTargetMachine()); // FIXME: target option target.reset(allocateSparcTargetMachine()); // FIXME: target option
#endif #endif
assert(target.get() && "Could not allocate target machine!"); assert(target.get() && "Could not allocate target machine!");
Passes.add(Opt->getTargetCtor()(*target.get())); Passes.add(Opt->getTargetCtor()(*target.get()));
} else } else
std::cerr << argv[0] << ": cannot create pass: " << Opt->getPassName() std::cerr << argv[0] << ": cannot create pass: " << Opt->getPassName()
<< "\n"; << "\n";
if (PrintEachXForm) if (PrintEachXForm)
Passes.add(new PrintModulePass(&std::cerr)); Passes.add(new PrintModulePass(&std::cerr));
}
// Check that the module is well formed on completion of optimization
if (!NoVerify)
Passes.add(createVerifierPass());
// Write bytecode out to disk or cout as the last step...
if (!NoOutput)
Passes.add(new WriteBytecodePass(Out, Out != &std::cout));
// Now that we have all of the passes ready, run them.
Passes.run(*M.get());
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
} }
return 1;
// Check that the module is well formed on completion of optimization
if (!NoVerify)
Passes.add(createVerifierPass());
// Write bytecode out to disk or cout as the last step...
if (!NoOutput)
Passes.add(new WriteBytecodePass(Out, Out != &std::cout));
// Now that we have all of the passes ready, run them.
Passes.run(*M.get());
return 0;
} }