diff options
author | Jan Voung <jvoung@chromium.org> | 2013-03-06 11:30:09 -0800 |
---|---|---|
committer | Jan Voung <jvoung@chromium.org> | 2013-03-06 11:30:09 -0800 |
commit | 79da56afe68a0c5b2c2227681014dd13705d78cc (patch) | |
tree | 6ec02dd9b1f9044debee27453c019905f8837141 | |
parent | 49fee2bce88cbc7b2a5aad63ec2d23fca648c9c4 (diff) |
Add an RPC to LLC.nexe to init with appended flags (vs set all flags).
This will take the default flags and append any extra flags.
For now, this is only intended to support -O in the browser,
and perhaps -mcpu=.*, -mattr=. We move the tuning parameters
like -mcpu out of the default, so that a user does not end up
setting the -mcpu more than once (which is disallowed).
What does go into the default is -mtriple, which we may want
to hard-code into the build somehow (but it's not yet clear
how to do that cleanly). That way, a user does not need
to specify that portion. We also hardcode the -sfi-* flags.
Sort of tested by: https://codereview.chromium.org/12459004/
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3325
Review URL: https://codereview.chromium.org/12490004
-rw-r--r-- | tools/llc/nacl_file.cpp | 116 |
1 files changed, 98 insertions, 18 deletions
diff --git a/tools/llc/nacl_file.cpp b/tools/llc/nacl_file.cpp index c5cd4d55ae..3d56b79840 100644 --- a/tools/llc/nacl_file.cpp +++ b/tools/llc/nacl_file.cpp @@ -23,7 +23,6 @@ #endif #include "SRPCStreamer.h" - #include <string> #include <map> #include <vector> @@ -120,13 +119,58 @@ string_vector* CommandLineFromArgz(char* str, size_t str_len) { vec->push_back(entry); entry = argz_next(str, str_len, entry); } + return vec; +} + +void AddFixedArguments(string_vector* vec) { // Add fixed arguments to the command line. These specify the bitcode // and object code filenames, removing them from the contract with the // coordinator. vec->push_back(kBitcodeFilename); vec->push_back("-o"); vec->push_back(kObjectFilename); - return vec; +} + +bool AddDefaultCPU(string_vector* vec) { +#if defined (__pnacl__) + switch (__builtin_nacl_target_arch()) { + case PnaclTargetArchitectureX86_32: { + vec->push_back("-mcpu=pentium4"); + break; + } + case PnaclTargetArchitectureX86_64: { + vec->push_back("-mcpu=core2"); + break; + } + case PnaclTargetArchitectureARM_32: { + vec->push_back("-mcpu=cortex-a8"); + break; + } + default: + printerr("no target architecture match.\n"); + return false; + } +// Some cases for building this with nacl-gcc. +#elif defined (__i386__) + vec->push_back("-mcpu=pentium4"); +#elif defined (__x86_64__) + vec->push_back("-mcpu=core2"); +#elif defined (__arm__) + vec->push_back("-mcpu=cortex-a8"); +#error "Unknown architecture" +#endif + return true; +} + +bool HasCPUOverride(string_vector* vec) { + std::string mcpu = std::string("-mcpu="); + size_t len = mcpu.length(); + for (size_t i = 0; i < vec->size(); ++i) { + std::string prefix = (*vec)[i].substr(0, len); + if (prefix.compare(mcpu) == 0) + return true; + } + return false; } string_vector* GetDefaultCommandLine() { @@ -134,24 +178,16 @@ string_vector* GetDefaultCommandLine() { size_t i; // First, those common to all architectures. static const char* common_args[] = { "pnacl_translator", - "-filetype=obj", - kBitcodeFilename, - "-o", - kObjectFilename }; + "-filetype=obj" }; for (i = 0; i < ARRAY_SIZE(common_args); ++i) { command_line->push_back(common_args[i]); } // Then those particular to a platform. - static const char* llc_args_x8632[] = { "-march=x86", - "-mcpu=pentium4", - "-mtriple=i686-none-nacl-gnu", + static const char* llc_args_x8632[] = { "-mtriple=i686-none-nacl-gnu", NULL }; - static const char* llc_args_x8664[] = { "-march=x86-64", - "-mcpu=core2", - "-mtriple=x86_64-none-nacl-gnu", + static const char* llc_args_x8664[] = { "-mtriple=x86_64-none-nacl-gnu", NULL }; - static const char* llc_args_arm[] = { "-mcpu=cortex-a8", - "-mtriple=armv7a-none-nacl-gnueabi", + static const char* llc_args_arm[] = { "-mtriple=armv7a-none-nacl-gnueabi", "-arm-reserve-r9", "-sfi-disable-cp", "-sfi-store", @@ -181,15 +217,17 @@ string_vector* GetDefaultCommandLine() { default: printerr("no target architecture match.\n"); delete command_line; - command_line = NULL; - break; + return NULL; } +// Some cases for building this with nacl-gcc. #elif defined (__i386__) llc_args = llc_args_x8632; #elif defined (__x86_64__) llc_args = llc_args_x8664; +#elif defined (__arm__) + llc_args = llc_args_arm; #else -#error +#error "Unknown architecture" #endif for (i = 0; llc_args[i] != NULL; i++) command_line->push_back(llc_args[i]); return command_line; @@ -253,7 +291,15 @@ void stream_init(NaClSrpcRpc *rpc, NaClSrpcClosure *done) { // cmd_line_vec allocated by GetDefaultCommandLine() is freed by the // translation thread in run_streamed() - do_stream_init(rpc, in_args, out_args, done, GetDefaultCommandLine()); + string_vector* cmd_line_vec = GetDefaultCommandLine(); + if (!cmd_line_vec || !AddDefaultCPU(cmd_line_vec)) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + out_args[0]->arrays.str = strdup("Failed to get default commandline."); + return; + } + AddFixedArguments(cmd_line_vec); + do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); } // Invoked by StreamInitWithCommandLine RPC. Same as stream_init, but @@ -266,10 +312,43 @@ void stream_init_with_command_line(NaClSrpcRpc *rpc, size_t command_line_len = in_args[1]->u.count; string_vector* cmd_line_vec = CommandLineFromArgz(command_line, command_line_len); + AddFixedArguments(cmd_line_vec); // cmd_line_vec is freed by the translation thread in run_streamed do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); } +// Invoked by StreamInitWithOverrides RPC. Same as stream_init, but +// provides commandline flag overrides (appended to the default). +void stream_init_with_overrides(NaClSrpcRpc *rpc, + NaClSrpcArg **in_args, + NaClSrpcArg **out_args, + NaClSrpcClosure *done) { + string_vector* cmd_line_vec = GetDefaultCommandLine(); + if (!cmd_line_vec) { + NaClSrpcClosureRunner runner(done); + rpc->result = NACL_SRPC_RESULT_APP_ERROR; + out_args[0]->arrays.str = strdup("Failed to get default commandline."); + return; + } + AddFixedArguments(cmd_line_vec); + + char* command_line = in_args[1]->arrays.carr; + size_t command_line_len = in_args[1]->u.count; + llvm::OwningPtr<string_vector> extra_vec( + CommandLineFromArgz(command_line, command_line_len)); + cmd_line_vec->insert(cmd_line_vec->end(), + extra_vec->begin(), extra_vec->end()); + // Make sure some -mcpu override exists for now to prevent + // auto-cpu feature detection from triggering instructions that + // we do not validate yet. + if (!HasCPUOverride(extra_vec.get())) { + AddDefaultCPU(cmd_line_vec); + } + extra_vec.reset(NULL); + // cmd_line_vec is freed by the translation thread in run_streamed. + do_stream_init(rpc, in_args, out_args, done, cmd_line_vec); +} + // Invoked by the StreamChunk RPC. Receives a chunk of the bitcode and // buffers it for later retrieval by the compilation thread. void stream_chunk(NaClSrpcRpc *rpc, @@ -318,6 +397,7 @@ const struct NaClSrpcHandlerDesc srpc_methods[] = { // StreamEnd() -> (is_shared_lib,soname,dependencies,error_str) { "StreamInit:h:s", stream_init }, { "StreamInitWithCommandLine:hC:s:", stream_init_with_command_line }, + { "StreamInitWithOverrides:hC:s:", stream_init_with_overrides }, { "StreamChunk:C:", stream_chunk }, { "StreamEnd::isss", stream_end }, { NULL, NULL }, |