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) {
cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
sys::PrintStackTraceOnErrorSignal();
Module *CurMod = 0;
try {
cl::ParseCommandLineOptions(argc, argv, " llvm analysis printer tool\n");
sys::PrintStackTraceOnErrorSignal();
Module *CurMod = 0;
try {
#if 0
TimeRegion RegionTimer(BytecodeLoadTimer);
TimeRegion RegionTimer(BytecodeLoadTimer);
#endif
CurMod = ParseBytecodeFile(InputFilename);
if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
std::cerr << argv[0] << ": input file didn't read correctly.\n";
CurMod = ParseBytecodeFile(InputFilename);
if (!CurMod && !(CurMod = ParseAssemblyFile(InputFilename))){
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;
}
} catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\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;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
}
// 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;
return 1;
}

View File

@ -51,10 +51,11 @@ int main(int argc, char **argv) {
return D.run();
} catch (ToolExecutionError &TEE) {
std::cerr << "Tool execution error: " << TEE.what() << '\n';
return 1;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << "Whoops, an exception leaked out of bugpoint. "
<< "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"));
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
sys::PrintStackTraceOnErrorSignal();
try {
cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
sys::PrintStackTraceOnErrorSignal();
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
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";
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout
Out = &std::cout;
// 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;
}
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";
}
Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file...
Passes.run(*M.get());
if (Out != &std::cout)
delete Out;
return 0;
return 1;
}

View File

@ -128,77 +128,85 @@ void AddConfiguredTransformationPasses(PassManager &PM) {
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 {
// Parse the file now...
M.reset(ParseAssemblyFile(InputFilename));
} catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1;
}
cl::ParseCommandLineOptions(argc, argv,
" llvm .s -> .o assembler for GCC\n");
sys::PrintStackTraceOnErrorSignal();
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";
std::auto_ptr<Module> M;
try {
// Parse the file now...
M.reset(ParseAssemblyFile(InputFilename));
} catch (const ParseException &E) {
std::cerr << argv[0] << ": " << E.getMessage() << "\n";
return 1;
}
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";
}
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;
return 1;
}

View File

@ -63,110 +63,117 @@ GetFileNameRoot(const std::string &InputFilename) {
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
sys::PrintStackTraceOnErrorSignal();
try {
cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n");
sys::PrintStackTraceOnErrorSignal();
// Load the module to be compiled...
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
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";
// Load the module to be compiled...
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
return 1;
}
}
Module &mod = *M.get();
std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
assert(target.get() && "Could not allocate target machine!");
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";
// 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;
}
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 == "-") {
OutputFilename = "-";
Out = &std::cout;
std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0));
assert(target.get() && "Could not allocate target machine!");
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 {
OutputFilename = GetFileNameRoot(InputFilename);
if (InputFilename == "-") {
OutputFilename = "-";
Out = &std::cout;
} else {
OutputFilename = GetFileNameRoot(InputFilename);
if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
OutputFilename += ".s";
else
OutputFilename += ".cbe.c";
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;
if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE
OutputFilename += ".s";
else
OutputFilename += ".cbe.c";
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";
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
if (Target.addPassesToEmitAssembly(Passes, *Out)) {
std::cerr << argv[0] << ": target '" << Target.getName()
<< "' does not support static compilation!\n";
// Ask the target to add backend passes as necessary
if (Target.addPassesToEmitAssembly(Passes, *Out)) {
std::cerr << argv[0] << ": target '" << Target.getName()
<< "' 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;
// 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());
return 0;
} catch (const std::string& msg) {
std::cerr << argv[0] << ": " << msg << "\n";
} catch (...) {
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
}
// Delete the ostream if it's not a stdout stream
if (Out != &std::cout) delete Out;
return 0;
return 1;
}

View File

@ -47,62 +47,69 @@ namespace {
// main Driver function
//
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 {
MP = getBytecodeModuleProvider(InputFile);
} catch (std::string &err) {
std::cerr << "Error loading program '" << InputFile << "': " << err << "\n";
exit(1);
cl::ParseCommandLineOptions(argc, argv,
" llvm interpreter & dynamic compiler\n");
sys::PrintStackTraceOnErrorSignal();
// 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();
}

View File

@ -52,6 +52,7 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm .ll -> .bc assembler\n");
sys::PrintStackTraceOnErrorSignal();
int exitCode = 0;
std::ostream *Out = 0;
try {
// Parse the file now...
@ -126,10 +127,16 @@ int main(int argc, char **argv) {
WriteBytecodeToFile(M.get(), *Out, !NoCompress);
} catch (const ParseException &E) {
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;
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"));
int
main(int argc, char **argv)
{
cl::ParseCommandLineOptions(argc, argv,
" llvm-bcanalyzer Analysis of ByteCode Dumper\n");
main(int argc, char **argv) {
try {
cl::ParseCommandLineOptions(argc, argv,
" llvm-bcanalyzer Analysis of ByteCode Dumper\n");
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal();
std::ostream* Out = &std::cout; // Default to printing to stdout...
std::istream* In = &std::cin; // Default to reading stdin
std::string ErrorMessage;
BytecodeAnalysis bca;
std::ostream* Out = &std::cout; // Default to printing to stdout...
std::istream* In = &std::cin; // Default to reading stdin
std::string ErrorMessage;
BytecodeAnalysis bca;
/// Determine what to generate
bca.detailedResults = !NoDetails;
bca.progressiveVerify = Verify;
/// Determine what to generate
bca.detailedResults = !NoDetails;
bca.progressiveVerify = Verify;
/// Analyze the bytecode file
Module* M = AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage, (Dump?Out:0));
/// Analyze the bytecode file
Module* M = AnalyzeBytecodeFile(InputFilename, bca, &ErrorMessage, (Dump?Out:0));
// All that bcanalyzer does is write the gathered statistics to the output
PrintBytecodeAnalysis(bca,*Out);
// All that bcanalyzer does is write the gathered statistics to the output
PrintBytecodeAnalysis(bca,*Out);
if ( M && Verify ) {
std::string verificationMsg;
try {
verifyModule( *M, ThrowExceptionAction );
} catch (std::string& errmsg ) {
verificationMsg = errmsg;
if ( M && Verify ) {
std::string verificationMsg;
try {
verifyModule( *M, ThrowExceptionAction );
} catch (std::string& 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 ( ErrorMessage.size() ) {
std::cerr << argv[0] << ": " << ErrorMessage << "\n";
return 1;
}
// If there was an error, print it and stop.
if ( ErrorMessage.size() ) {
std::cerr << argv[0] << ": " << ErrorMessage << "\n";
return 1;
}
if (Out != &std::cout) {
((std::ofstream*)Out)->close();
delete Out;
if (Out != &std::cout) {
((std::ofstream*)Out)->close();
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

View File

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

View File

@ -41,81 +41,88 @@ static cl::opt<bool>
CWriteMode("c", cl::desc("Obsolete option, do not use"), cl::ReallyHidden);
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
sys::PrintStackTraceOnErrorSignal();
try {
cl::ParseCommandLineOptions(argc, argv, " llvm .bc -> .ll disassembler\n");
sys::PrintStackTraceOnErrorSignal();
std::ostream *Out = &std::cout; // Default to printing to stdout...
std::string ErrorMessage;
std::ostream *Out = &std::cout; // Default to printing to stdout...
std::string ErrorMessage;
if (CWriteMode) {
std::cerr << "ERROR: llvm-dis no longer contains the C backend. "
<< "Use 'llc -march=c' instead!\n";
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());
}
if (CWriteMode) {
std::cerr << "ERROR: llvm-dis no longer contains the C backend. "
<< "Use 'llc -march=c' instead!\n";
exit(1);
}
} else {
if (InputFilename == "-") {
OutputFilename = "-";
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 {
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";
if (InputFilename == "-") {
OutputFilename = "-";
} 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 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());
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());
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
// Make sure that the Out file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
}
}
}
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename
<< ": sending to stdout instead!\n";
Out = &std::cout;
}
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename
<< ": sending to stdout instead!\n";
Out = &std::cout;
}
// All that dis does is write the assembly or C out to a file...
//
PassManager Passes;
Passes.add(new PrintModulePass(Out));
Passes.run(*M.get());
// All that dis does is write the assembly or C out to a file...
//
PassManager Passes;
Passes.add(new PrintModulePass(Out));
Passes.run(*M.get());
if (Out != &std::cout) {
((std::ofstream*)Out)->close();
delete Out;
if (Out != &std::cout) {
((std::ofstream*)Out)->close();
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"));
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
sys::PrintStackTraceOnErrorSignal();
try {
cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n");
sys::PrintStackTraceOnErrorSignal();
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
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";
std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename));
if (M.get() == 0) {
std::cerr << argv[0] << ": bytecode didn't read correctly.\n";
return 1;
}
Out = new std::ofstream(OutputFilename.c_str());
} else { // Specified stdout
Out = &std::cout;
// 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;
}
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";
}
Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file...
Passes.run(*M.get());
if (Out != &std::cout)
delete Out;
return 0;
return 1;
}

View File

@ -389,126 +389,133 @@ extern void Optimize(Module*);
}
int main(int argc, char **argv, char **envp) {
// Initial global variable above for convenience printing of program name.
progname = sys::Path(argv[0]).getBasename();
Linker TheLinker(progname, Verbose);
// Set up the library paths for the Linker
TheLinker.addPaths(LibPaths);
TheLinker.addSystemPaths();
try {
// Initial global variable above for convenience printing of program name.
progname = sys::Path(argv[0]).getBasename();
Linker TheLinker(progname, Verbose);
// Set up the library paths for the Linker
TheLinker.addPaths(LibPaths);
TheLinker.addSystemPaths();
// Parse the command line options
cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
sys::PrintStackTraceOnErrorSignal();
// Parse the command line options
cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
sys::PrintStackTraceOnErrorSignal();
// Remove any consecutive duplicates of the same library...
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
Libraries.end());
// Remove any consecutive duplicates of the same library...
Libraries.erase(std::unique(Libraries.begin(), Libraries.end()),
Libraries.end());
if (LinkAsLibrary) {
std::vector<sys::Path> Files;
for (unsigned i = 0; i < InputFilenames.size(); ++i )
Files.push_back(sys::Path(InputFilenames[i]));
if (TheLinker.LinkInFiles(Files))
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();
if (LinkAsLibrary) {
std::vector<sys::Path> Files;
for (unsigned i = 0; i < InputFilenames.size(); ++i )
Files.push_back(sys::Path(InputFilenames[i]));
if (TheLinker.LinkInFiles(Files))
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 {
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
sys::Path(RealBytecodeOutput).makeExecutable();
sys::Path(RealBytecodeOutput).makeReadable();
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();
} 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 0;
return 1;
}

View File

@ -75,70 +75,77 @@ static inline std::auto_ptr<Module> LoadFile(const std::string &FN) {
}
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
sys::PrintStackTraceOnErrorSignal();
assert(InputFilenames.size() > 0 && "OneOrMore is not working");
try {
cl::ParseCommandLineOptions(argc, argv, " llvm linker\n");
sys::PrintStackTraceOnErrorSignal();
assert(InputFilenames.size() > 0 && "OneOrMore is not working");
unsigned BaseArg = 0;
std::string ErrorMessage;
unsigned BaseArg = 0;
std::string ErrorMessage;
std::auto_ptr<Module> Composite(LoadFile(InputFilenames[BaseArg]));
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::auto_ptr<Module> Composite(LoadFile(InputFilenames[BaseArg]));
if (Composite.get() == 0) {
std::cerr << argv[0] << ": error loading file '"
<< InputFilenames[i] << "'\n";
<< InputFilenames[BaseArg] << "'\n";
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)) {
std::cerr << argv[0] << ": link error in '" << InputFilenames[i]
<< "': " << ErrorMessage << "\n";
if (Verbose) std::cerr << "Linking in '" << InputFilenames[i] << "'\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;
}
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";
}
// 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;
return 1;
}

View File

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

View File

@ -107,124 +107,131 @@ namespace {
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n");
sys::PrintStackTraceOnErrorSignal();
try {
cl::ParseCommandLineOptions(argc, argv, " llvm profile dump decoder\n");
sys::PrintStackTraceOnErrorSignal();
// Read in the bytecode file...
std::string ErrorMessage;
Module *M = ParseBytecodeFile(BytecodeFile, &ErrorMessage);
if (M == 0) {
std::cerr << argv[0] << ": " << BytecodeFile << ": " << ErrorMessage
<< "\n";
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;
// Read in the bytecode file...
std::string ErrorMessage;
Module *M = ParseBytecodeFile(BytecodeFile, &ErrorMessage);
if (M == 0) {
std::cerr << argv[0] << ": " << BytecodeFile << ": " << ErrorMessage
<< "\n";
return 1;
}
printf("%3d. %5u/%llu %s\n", i+1, FunctionCounts[i].second, TotalExecutions,
FunctionCounts[i].first->getName().c_str());
}
// Read the profiling information
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
// frequency annotations.
if (PI.hasAccurateBlockCounts()) {
std::vector<std::pair<BasicBlock*, unsigned> > Counts;
PI.getBlockCounts(Counts);
// Output a report. Eventually, there will be multiple reports selectable on
// the command line, for now, just keep things simple.
TotalExecutions = 0;
for (unsigned i = 0, e = Counts.size(); i != e; ++i)
TotalExecutions += Counts[i].second;
// 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(Counts.begin(), Counts.end(),
PairSecondSortReverse<BasicBlock*>());
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 << "Top 20 most frequently executed basic blocks:\n\n";
std::cout << "Function execution frequencies:\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);
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,
FunctionCounts[i].first->getName().c_str());
}
BlockFreqs.insert(Counts.begin(), Counts.end());
}
if (PI.hasAccurateEdgeCounts()) {
std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > Counts;
PI.getEdgeCounts(Counts);
EdgeFreqs.insert(Counts.begin(), Counts.end());
}
std::set<Function*> FunctionsToPrint;
if (PrintAnnotatedLLVM || PrintAllCode) {
std::cout << "\n===" << std::string(73, '-') << "===\n";
std::cout << "Annotated LLVM code for the module:\n\n";
// If we have block count information, print out the LLVM module with
// frequency annotations.
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)
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);
if (PrintAnnotatedLLVM || PrintAllCode) {
std::cout << "\n===" << std::string(73, '-') << "===\n";
std::cout << "Annotated LLVM code for the module:\n\n";
ProfileAnnotator PA(FuncFreqs, BlockFreqs, EdgeFreqs);
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 0;
return 1;
}

View File

@ -368,4 +368,5 @@ int main(int argc, char **argv) {
} catch (...) {
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
//
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv,
" llvm .bc -> .bc modular optimizer\n");
sys::PrintStackTraceOnErrorSignal();
try {
cl::ParseCommandLineOptions(argc, argv,
" llvm .bc -> .bc modular optimizer\n");
sys::PrintStackTraceOnErrorSignal();
// Allocate a full target machine description only if necessary...
// FIXME: The choice of target should be controllable on the command line.
std::auto_ptr<TargetMachine> target;
// Allocate a full target machine description only if necessary...
// FIXME: The choice of target should be controllable on the command line.
std::auto_ptr<TargetMachine> target;
TargetMachine* TM = NULL;
std::string ErrorMessage;
TargetMachine* TM = NULL;
std::string ErrorMessage;
// Load the input module...
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;
}
// 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";
// Load the input module...
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;
}
// Make sure that the Output file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
// 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 the output is set to be emitted to standard out, and standard out is a
// 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;
}
if (!Out->good()) {
std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
return 1;
}
// Create a PassManager to hold and optimize the collection of passes we are
// about to build...
//
PassManager Passes;
// Make sure that the Output file gets unlinked from the disk if we get a
// SIGINT
sys::RemoveFileOnSignal(sys::Path(OutputFilename));
}
// Add an appropriate TargetData instance for this module...
Passes.add(new TargetData("opt", M.get()));
// If the output is set to be emitted to standard out, and standard out is a
// 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
for (unsigned i = 0; i < OptimizationList.size(); ++i) {
const PassInfo *Opt = OptimizationList[i];
if (Opt->getNormalCtor())
Passes.add(Opt->getNormalCtor()());
else if (Opt->getTargetCtor()) {
// 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("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 (target.get() == NULL)
target.reset(allocateSparcTargetMachine()); // FIXME: target option
if (target.get() == NULL)
target.reset(allocateSparcTargetMachine()); // FIXME: target option
#endif
assert(target.get() && "Could not allocate target machine!");
Passes.add(Opt->getTargetCtor()(*target.get()));
} else
std::cerr << argv[0] << ": cannot create pass: " << Opt->getPassName()
<< "\n";
assert(target.get() && "Could not allocate target machine!");
Passes.add(Opt->getTargetCtor()(*target.get()));
} else
std::cerr << argv[0] << ": cannot create pass: " << Opt->getPassName()
<< "\n";
if (PrintEachXForm)
Passes.add(new PrintModulePass(&std::cerr));
if (PrintEachXForm)
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";
}
// 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;
return 1;
}