aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Voung <jvoung@chromium.org>2013-03-06 11:30:09 -0800
committerJan Voung <jvoung@chromium.org>2013-03-06 11:30:09 -0800
commit79da56afe68a0c5b2c2227681014dd13705d78cc (patch)
tree6ec02dd9b1f9044debee27453c019905f8837141
parent49fee2bce88cbc7b2a5aad63ec2d23fca648c9c4 (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.cpp116
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 },