Adding gflags to handle command line flags.
It sucks, but is the best there is without using boost.
This commit is contained in:
parent
01fee047f7
commit
860a0739ec
|
@ -7,3 +7,6 @@
|
|||
[submodule "third_party/gyp"]
|
||||
path = third_party/gyp
|
||||
url = https://github.com/benvanik/gyp.git
|
||||
[submodule "third_party/gflags"]
|
||||
path = third_party/gflags
|
||||
url = https://github.com/benvanik/gflags.git
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
'release': {
|
||||
'defines': [
|
||||
'RELEASE',
|
||||
'NDEBUG',
|
||||
],
|
||||
'msvs_configuration_attributes': {
|
||||
'OutputDirectory': '<(DEPTH)\\build\\xenia\\release',
|
||||
|
|
|
@ -157,6 +157,7 @@ public:
|
|||
|
||||
int GetAllFunctions(vector<FunctionSymbol*>& functions);
|
||||
|
||||
void Write(const char* file_name);
|
||||
void Dump();
|
||||
void DumpFunctionBlocks(FunctionSymbol* fn);
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include <xenia/cpu/ppc.h>
|
||||
#include <xenia/cpu/codegen/function_generator.h>
|
||||
|
||||
#include "cpu/cpu-private.h"
|
||||
|
||||
|
||||
using namespace llvm;
|
||||
using namespace xe;
|
||||
|
@ -234,7 +236,7 @@ void ModuleGenerator::BuildFunction(CodegenFunction* cgf) {
|
|||
|
||||
void ModuleGenerator::OptimizeFunction(Module* m, Function* fn) {
|
||||
FunctionPassManager pm(m);
|
||||
#if XE_OPTION(OPTIMIZED)
|
||||
if (FLAGS_optimize_ir_functions) {
|
||||
PassManagerBuilder pmb;
|
||||
pmb.OptLevel = 3;
|
||||
pmb.SizeLevel = 0;
|
||||
|
@ -242,7 +244,7 @@ void ModuleGenerator::OptimizeFunction(Module* m, Function* fn) {
|
|||
pmb.Vectorize = true;
|
||||
pmb.LoopVectorize = true;
|
||||
pmb.populateFunctionPassManager(pm);
|
||||
#endif // XE_OPTION(OPTIMIZED)
|
||||
}
|
||||
pm.add(createVerifierPass());
|
||||
pm.run(*fn);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PRIVATE_H_
|
||||
#define XENIA_CPU_PRIVATE_H_
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
|
||||
DECLARE_string(dump_path);
|
||||
DECLARE_bool(dump_module_bitcode);
|
||||
DECLARE_bool(dump_module_map);
|
||||
|
||||
DECLARE_bool(optimize_ir_modules);
|
||||
DECLARE_bool(optimize_ir_functions);
|
||||
|
||||
|
||||
#endif // XENIA_CPU_PRIVATE_H_
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "cpu/cpu-private.h"
|
||||
|
||||
|
||||
// Dumping:
|
||||
DEFINE_string(dump_path, "build/",
|
||||
"Directory that dump files are placed into.");
|
||||
DEFINE_bool(dump_module_bitcode, true,
|
||||
"Writes the module bitcode both before and after optimizations.");
|
||||
DEFINE_bool(dump_module_map, true,
|
||||
"Dumps the module symbol database.");
|
||||
|
||||
|
||||
// Optimizations:
|
||||
DEFINE_bool(optimize_ir_modules, true,
|
||||
"Whether to run LLVM optimizations on modules.");
|
||||
DEFINE_bool(optimize_ir_functions, true,
|
||||
"Whether to run LLVM optimizations on functions.");
|
|
@ -31,6 +31,7 @@
|
|||
#include <xenia/cpu/codegen/module_generator.h>
|
||||
#include <xenia/cpu/sdb.h>
|
||||
|
||||
#include "cpu/cpu-private.h"
|
||||
#include "cpu/xethunk/xethunk.h"
|
||||
|
||||
|
||||
|
@ -67,6 +68,8 @@ int ExecModule::Prepare() {
|
|||
int result_code = 1;
|
||||
std::string error_message;
|
||||
|
||||
char file_name[2048];
|
||||
|
||||
OwningPtr<MemoryBuffer> shared_module_buffer;
|
||||
auto_ptr<Module> shared_module;
|
||||
auto_ptr<raw_ostream> outs;
|
||||
|
@ -80,7 +83,7 @@ int ExecModule::Prepare() {
|
|||
// Calculate a cache path based on the module, the CPU version, and other
|
||||
// bits.
|
||||
// TODO(benvanik): cache path calculation.
|
||||
const char *cache_path = "build/generated.bc";
|
||||
//const char *cache_path = "build/generated.bc";
|
||||
|
||||
// Check the cache to see if the bitcode exists.
|
||||
// If it does, load that module directly. In the future we could also cache
|
||||
|
@ -104,6 +107,13 @@ int ExecModule::Prepare() {
|
|||
// Analyze the module and add its symbols to the symbol database.
|
||||
XEEXPECTZERO(sdb_->Analyze());
|
||||
|
||||
// Dump the symbol database.
|
||||
if (FLAGS_dump_module_map) {
|
||||
xesnprintf(file_name, XECOUNT(file_name),
|
||||
"%s%s.map", FLAGS_dump_path.c_str(), module_->name());
|
||||
sdb_->Write(file_name);
|
||||
}
|
||||
|
||||
// Initialize the module.
|
||||
gen_module_ = shared_ptr<Module>(
|
||||
new Module(module_->name(), *context_.get()));
|
||||
|
@ -126,14 +136,19 @@ int ExecModule::Prepare() {
|
|||
context_.get(), gen_module_.get()));
|
||||
XEEXPECTZERO(codegen_->Generate());
|
||||
|
||||
gen_module_->dump();
|
||||
|
||||
// Write to cache.
|
||||
// TODO(benvanik): cache stuff
|
||||
|
||||
// Dump pre-optimized module to disk.
|
||||
if (FLAGS_dump_module_bitcode) {
|
||||
xesnprintf(file_name, XECOUNT(file_name),
|
||||
"%s%s-preopt.bc", FLAGS_dump_path.c_str(), module_->name());
|
||||
outs = auto_ptr<raw_ostream>(new raw_fd_ostream(
|
||||
cache_path, error_message, raw_fd_ostream::F_Binary));
|
||||
file_name, error_message, raw_fd_ostream::F_Binary));
|
||||
XEEXPECTTRUE(error_message.empty());
|
||||
WriteBitcodeToFile(gen_module_.get(), *outs);
|
||||
}
|
||||
}
|
||||
|
||||
// Link optimizations.
|
||||
XEEXPECTZERO(gen_module_->MaterializeAllPermanently(&error_message));
|
||||
|
@ -143,7 +158,7 @@ int ExecModule::Prepare() {
|
|||
|
||||
// Run full module optimizations.
|
||||
pm.add(new DataLayout(gen_module_.get()));
|
||||
#if XE_OPTION(OPTIMIZED)
|
||||
if (FLAGS_optimize_ir_modules) {
|
||||
pm.add(createVerifierPass());
|
||||
pmb.OptLevel = 3;
|
||||
pmb.SizeLevel = 0;
|
||||
|
@ -152,10 +167,20 @@ int ExecModule::Prepare() {
|
|||
pmb.LoopVectorize = true;
|
||||
pmb.populateModulePassManager(pm);
|
||||
pmb.populateLTOPassManager(pm, false, true);
|
||||
#endif // XE_OPTION(OPTIMIZED)
|
||||
}
|
||||
pm.add(createVerifierPass());
|
||||
pm.run(*gen_module_);
|
||||
|
||||
// Dump post-optimized module to disk.
|
||||
if (FLAGS_optimize_ir_modules && FLAGS_dump_module_bitcode) {
|
||||
xesnprintf(file_name, XECOUNT(file_name),
|
||||
"%s%s.bc", FLAGS_dump_path.c_str(), module_->name());
|
||||
outs = auto_ptr<raw_ostream>(new raw_fd_ostream(
|
||||
file_name, error_message, raw_fd_ostream::F_Binary));
|
||||
XEEXPECTTRUE(error_message.empty());
|
||||
WriteBitcodeToFile(gen_module_.get(), *outs);
|
||||
}
|
||||
|
||||
// TODO(benvanik): experiment with LLD to see if we can write out a dll.
|
||||
|
||||
// Initialize the module.
|
||||
|
@ -225,6 +250,6 @@ int ExecModule::Uninit() {
|
|||
}
|
||||
|
||||
void ExecModule::Dump() {
|
||||
// sdb_->Dump();
|
||||
// gen_module_->dump();
|
||||
sdb_->Dump();
|
||||
gen_module_->dump();
|
||||
}
|
||||
|
|
|
@ -241,6 +241,10 @@ int SymbolDatabase::GetAllFunctions(vector<FunctionSymbol*>& functions) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void SymbolDatabase::Write(const char* file_name) {
|
||||
// TODO(benvanik): write to file.
|
||||
}
|
||||
|
||||
void SymbolDatabase::Dump() {
|
||||
uint32_t previous = 0;
|
||||
for (SymbolMap::iterator it = symbols_.begin(); it != symbols_.end(); ++it) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'cpu.cc',
|
||||
'exec_module.cc',
|
||||
'processor.cc',
|
||||
'sdb.cc',
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 56e77c6a2f10020f775cb68022f92fbb38e61804
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'gflags',
|
||||
'type': 'static_library',
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'gflags/src/',
|
||||
],
|
||||
},
|
||||
|
||||
'include_dirs': [
|
||||
'gflags/src/',
|
||||
],
|
||||
|
||||
'sources': [
|
||||
'gflags/src/gflags.cc',
|
||||
'gflags/src/gflags_completions.cc',
|
||||
'gflags/src/gflags_nc.cc',
|
||||
'gflags/src/gflags_reporting.cc',
|
||||
],
|
||||
|
||||
'conditions': [
|
||||
['OS == "win"', {
|
||||
'sources!': [
|
||||
'gflags/src/windows/port.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <xenia/xenia.h>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
|
@ -16,6 +18,12 @@ using namespace xe::kernel;
|
|||
|
||||
|
||||
int xenia_info(int argc, xechar_t **argv) {
|
||||
std::string usage = "usage: ";
|
||||
usage = usage + argv[0] + " some.xex";
|
||||
google::SetUsageMessage(usage);
|
||||
google::SetVersionString("1.0");
|
||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
int result_code = 1;
|
||||
|
||||
xe_pal_ref pal = NULL;
|
||||
|
@ -23,9 +31,9 @@ int xenia_info(int argc, xechar_t **argv) {
|
|||
shared_ptr<Processor> processor;
|
||||
shared_ptr<Runtime> runtime;
|
||||
|
||||
// TODO(benvanik): real command line parsing.
|
||||
// Grab path.
|
||||
if (argc < 2) {
|
||||
printf("usage: xenia-info some.xex\n");
|
||||
google::ShowUsageWithFlags(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const xechar_t *path = argv[1];
|
||||
|
@ -51,6 +59,8 @@ int xenia_info(int argc, xechar_t **argv) {
|
|||
XECLEANUP:
|
||||
xe_memory_release(memory);
|
||||
xe_pal_release(pal);
|
||||
|
||||
google::ShutDownCommandLineFlags();
|
||||
return result_code;
|
||||
}
|
||||
XE_MAIN_THUNK(xenia_info);
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <xenia/xenia.h>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::cpu;
|
||||
|
@ -70,14 +72,20 @@ int Run::Launch() {
|
|||
}
|
||||
|
||||
int xenia_run(int argc, xechar_t **argv) {
|
||||
std::string usage = "usage: ";
|
||||
usage = usage + argv[0] + " some.xex";
|
||||
google::SetUsageMessage(usage);
|
||||
google::SetVersionString("1.0");
|
||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
// Dummy call to keep the GPU code linking in to ensure it's working.
|
||||
do_gpu_stuff();
|
||||
|
||||
int result_code = 1;
|
||||
|
||||
// TODO(benvanik): real command line parsing.
|
||||
// Grab path.
|
||||
if (argc < 2) {
|
||||
printf("usage: xenia-run some.xex\n");
|
||||
google::ShowUsageWithFlags(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
const xechar_t *path = argv[1];
|
||||
|
@ -91,9 +99,10 @@ int xenia_run(int argc, xechar_t **argv) {
|
|||
|
||||
run->Launch();
|
||||
|
||||
return 0;
|
||||
|
||||
result_code = 0;
|
||||
XECLEANUP:
|
||||
|
||||
google::ShutDownCommandLineFlags();
|
||||
return result_code;
|
||||
}
|
||||
XE_MAIN_THUNK(xenia_run);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
'includes': [
|
||||
'common.gypi',
|
||||
'tools/tools.gypi',
|
||||
'third_party/gflags.gypi',
|
||||
],
|
||||
|
||||
'targets': [
|
||||
|
@ -11,6 +12,13 @@
|
|||
'product_name': 'xeniacore',
|
||||
'type': 'static_library',
|
||||
|
||||
'dependencies': [
|
||||
'gflags',
|
||||
],
|
||||
'export_dependent_settings': [
|
||||
'gflags',
|
||||
],
|
||||
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
'include/',
|
||||
|
@ -36,7 +44,6 @@
|
|||
'dependencies': [
|
||||
'xeniacore',
|
||||
],
|
||||
|
||||
'export_dependent_settings': [
|
||||
'xeniacore',
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue