Browse files

Add command line options for JIT.

Example:

  -O-dce  -Omaxmcode=1024 -Ocbn

This disables dead code (dce) elimination and enables
call-by-name (cbn).  It also doubles the maximum size of the compiled
machine code by setting it to 1024 KBytes.
  • Loading branch information...
1 parent 0551b8b commit 8eaf8ca732bd388aa071c3fe49f14ef13d052d9a @nominolo committed Apr 14, 2012
Showing with 121 additions and 4 deletions.
  1. +2 −1 Makefile
  2. +14 −1 includes/Jit.h
  3. +88 −0 rts/Jit.c
  4. +17 −1 rts/Main.c
  5. +0 −1 rts/Record.c
View
3 Makefile
@@ -66,7 +66,8 @@ SRCS = rts/Bytecode.c rts/Capability.c rts/ClosureFlags.c \
rts/InterpIR.c rts/Stats.c \
rts/codegen/MCode.c rts/codegen/InterpAsm.c \
rts/codegen/AsmCodeGen.c \
- rts/GC.c rts/ShadowHeap.c
+ rts/GC.c rts/ShadowHeap.c \
+ rts/Jit.c
UTILSRCS = utils/genopcodes.c
View
15 includes/Jit.h
@@ -159,6 +159,9 @@ JIT_PARAMDEF(JIT_PARAMENUM)
#define JIT_P_STRING JIT_PARAMDEF(JIT_PARAMSTR)
// -- Optimisations --------------------------------------------------
+
+#define JIT_OPT_FIRST 1
+
// Perform dead code elimination
#define JIT_OPT_DCE (1UL<<0)
@@ -169,7 +172,15 @@ JIT_PARAMDEF(JIT_PARAMENUM)
// unrolling loops).
#define JIT_OPT_SINK_ALLOC (1UL<<2)
-#define JIT_OPT_DEFAULT (JIT_OPT_DCE|JIT_OPT_UNROLL)
+#define JIT_OPT_CALL_BY_NAME (1UL<<3)
+
+#define JIT_OPT_CSE (1UL<<4)
+
+#define JIT_OPT_DEFAULT \
+ (JIT_OPT_DCE|JIT_OPT_UNROLL|JIT_OPT_SINK_ALLOC|JIT_OPT_CSE)
+
+#define JIT_OPTSTRING \
+ "\3dce\6unroll\4sink\3cbn\3cse"
typedef enum {
@@ -401,6 +412,8 @@ extern u4 G_jitstep;
void printIRBuffer(JitState *J);
bool checkPerOpcodeLinks(JitState *J);
+bool parseJitOpt(int32_t *param, uint32_t *flags, const char *str);
+void setJitOpts(JitState *J, int32_t *param, uint32_t flags);
#ifdef LC_SELF_CHECK_MODE
View
88 rts/Jit.c
@@ -0,0 +1,88 @@
+#include "Common.h"
+#include "Jit.h"
+#include <string.h>
+#include <stdio.h>
+
+/**
+ * Parse and set a JIT parameter.
+ *
+ * Parse a string of the form "<param>=<value>" where <param> must be
+ * a JIT parameter (see Jit.h) and <value> must be an integer.
+ *
+ * @returns whether the parameter was parsed and set successfully.
+ */
+static bool parseJitParam(int32_t *param, const char *str) {
+ /* JIT_P_STRING has the form: `(length of following string)(string)` */
+ const char *options = JIT_P_STRING;
+ int i;
+ for (i = 0; i < JIT_P__MAX; i++) {
+ size_t len = *(const uint8_t *)options;
+ LC_ASSERT(len > 0);
+ if (strncmp(str, options + 1, len) == 0 &&
+ str[len] == '=') {
+ int32_t value = 0;
+ const char *p = &str[len+1];
+ while (*p >= '0' && *p <= '9') {
+ value = value * 10 + (*p++ - '0');
+ }
+ if (*p != 0) {
+ /* Could not parse complete number. */
+ return false;
+ }
+ /* TODO: Validate range */
+ param[i] = value;
+ return true;
+ }
+ options += 1 + len;
+ }
+ return false;
+}
+
+/**
+ * Parse and set/clear a JIT flag.
+ *
+ * Parse a string of the form "[+-]?<jit-flag>" and sets or clears the
+ * corresponding JIT flag. For example, "+cse" enables the common subexpression
+ * elimination optimisation. If no prefix is given, sets the flag.
+ */
+static bool parseJitFlag(uint32_t *flags, const char *str) {
+ const char *options = JIT_OPTSTRING;
+ uint32_t opt;
+ int set = 1;
+ if (str[0] == '+') {
+ str++;
+ } else if (str[0] == '-') {
+ str++;
+ set = 0;
+ }
+ for (opt = JIT_OPT_FIRST; ; opt <<= 1) {
+ size_t len = *(const uint8_t *)options;
+ if (len == 0)
+ break;
+ if (strncmp(str, options + 1, len) == 0 && str[len] == '\0') {
+ if (set) {
+ *flags |= opt;
+ } else {
+ *flags &= ~opt;
+ }
+ return true;
+ }
+ options += 1 + len;
+ }
+ return false;
+}
+
+/**
+ * Parse and set a JIT parameter or flag.
+ */
+bool parseJitOpt(int32_t *param, uint32_t *flags, const char *str) {
+ return parseJitFlag(flags, str) || parseJitParam(param, str);
+}
+
+void setJitOpts(JitState *J, int32_t *param, uint32_t flags) {
+ int i;
+ for (i = 0; i < JIT_P__MAX; i++) {
+ J->param[i] = param[i];
+ }
+ J->flags = flags;
+}
View
18 rts/Main.c
@@ -29,6 +29,14 @@ static Opts opts = {
.stack_size = 1024,
};
+static int32_t jitParams[JIT_P__MAX] = {
+#define JIT_PARAMDEFAULT(len, name, value) [JIT_P_##name] = value,
+ JIT_PARAMDEF(JIT_PARAMDEFAULT)
+#undef JIT_PARAMDEFAULT
+};
+
+static uint32_t jitFlags = JIT_OPT_DEFAULT;
+
typedef enum {
OPT_PRINT_LOADER_STATE = 0x1000,
} OptionFlags;
@@ -65,7 +73,7 @@ main(int argc, char *argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "he:B:", long_options, &option_index);
+ c = getopt_long(argc, argv, "he:B:O:", long_options, &option_index);
if (c == -1)
break;
@@ -104,6 +112,11 @@ main(int argc, char *argv[])
case 'l':
opts.main_closure = NULL;
break;
+ case 'O':
+ if (!parseJitOpt(jitParams, &jitFlags, optarg)) {
+ fprintf(stderr, "Unrecognized value for -O\n");
+ }
+ break;
case 'h':
printf("Usage: %s [options] MODULE_NAME\n\n"
"Options:\n"
@@ -171,6 +184,9 @@ main(int argc, char *argv[])
initStorageManager();
initVM(&opts);
+#ifdef LC_HAS_JIT
+ setJitOpts(&G_cap0->J, jitParams, jitFlags);
+#endif
initLoader(&opts);
#ifdef LC_SELF_CHECK_MODE
initShadowHeap();
View
1 rts/Record.c
@@ -204,7 +204,6 @@ recordSetup(JitState *J, Thread *T)
// J->{pc,func} is set by recording code
- J->flags = 0; // TODO: Default flags
J->irmin = 0;
J->irmax = 0;

0 comments on commit 8eaf8ca

Please sign in to comment.