mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
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:
parent
c18671cdcd
commit
1ef8bdaedb
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -368,4 +368,5 @@ int main(int argc, char **argv) {
|
||||
} catch (...) {
|
||||
std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user