diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-12-05 12:01:21 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-12-05 12:01:21 +0100 |
commit | f69256e3cf778ef6fb1fe450c04eea611d9e0177 (patch) | |
tree | 6a21e121ce95417fe4a5e9a369416c7776435622 | |
parent | acdaac31c648fd10f1bd0a49c4c33b483bb9c35c (diff) |
orcc: allow setting custom backup functionbackup-func
Add a new .backup keyword that instructs the orc compiler to call our
custom backup function instead of generating one. This is interesting if
the generated backup function is slower than a plain C implementation.
-rw-r--r-- | orc/orcparse.c | 8 | ||||
-rw-r--r-- | orc/orcprogram.c | 17 | ||||
-rw-r--r-- | orc/orcprogram.h | 2 | ||||
-rw-r--r-- | tools/orcc.c | 131 |
4 files changed, 151 insertions, 7 deletions
diff --git a/orc/orcparse.c b/orc/orcparse.c index 164fe54..4be32b5 100644 --- a/orc/orcparse.c +++ b/orc/orcparse.c @@ -139,6 +139,14 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log) parser->programs[parser->n_programs] = parser->program; parser->n_programs++; parser->creg_index = 1; + } else if (strcmp (token[0], ".backup") == 0) { + if (n_tokens < 2) { + orc_parse_log (parser, "error: line %d: .backup without function name\n", + parser->line_number); + } else { + orc_program_set_backup_name (parser->program, token[1]); + } + } else if (strcmp (token[0], ".init") == 0) { free (init_function); init_function = NULL; diff --git a/orc/orcprogram.c b/orc/orcprogram.c index 9251b97..1d749c0 100644 --- a/orc/orcprogram.c +++ b/orc/orcprogram.c @@ -179,6 +179,10 @@ orc_program_free (OrcProgram *program) free (program->init_function); program->init_function = NULL; } + if (program->backup_name) { + free (program->backup_name); + program->backup_name = NULL; + } if (program->name) { free (program->name); program->name = NULL; @@ -278,6 +282,19 @@ orc_program_set_backup_function (OrcProgram *program, OrcExecutorFunc func) } /** + * orc_program_set_backup_name: + * @program: a pointer to an OrcProgram structure + * @name: a function name that performs the operations in the program + */ +void +orc_program_set_backup_name (OrcProgram *program, const char *name) +{ + if (program->backup_name) + free (program->backup_name); + program->backup_name = strdup (name); +} + +/** * orc_program_get_name: * @program: a pointer to an OrcProgram structure * diff --git a/orc/orcprogram.h b/orc/orcprogram.h index 4316ef4..436b5ed 100644 --- a/orc/orcprogram.h +++ b/orc/orcprogram.h @@ -81,6 +81,7 @@ struct _OrcProgram { OrcVariable vars[ORC_N_VARIABLES]; void *backup_func; + char *backup_name; int is_2d; int constant_n; int n_multiple; @@ -143,6 +144,7 @@ OrcCompileResult orc_program_compile_for_target (OrcProgram *p, OrcTarget *targe OrcCompileResult orc_program_compile_full (OrcProgram *p, OrcTarget *target, unsigned int flags); void orc_program_set_backup_function (OrcProgram *p, OrcExecutorFunc func); +void orc_program_set_backup_name (OrcProgram *p, const char *name); void orc_program_free (OrcProgram *program); int orc_program_find_var_by_name (OrcProgram *program, const char *name); diff --git a/tools/orcc.c b/tools/orcc.c index fdab530..e29adb1 100644 --- a/tools/orcc.c +++ b/tools/orcc.c @@ -537,13 +537,13 @@ static const char *orcify_typename (const char *s) } void -output_prototype (OrcProgram *p, FILE *output) +output_prototype (OrcProgram *p, FILE *output, int backup) { OrcVariable *var; int i; int need_comma; - fprintf(output, "%s (", p->name); + fprintf(output, "%s (", backup ? p->backup_name : p->name); need_comma = FALSE; for(i=0;i<4;i++){ var = &p->vars[ORC_VAR_D1 + i]; @@ -633,6 +633,114 @@ output_prototype (OrcProgram *p, FILE *output) } void +output_executor_backup_call (OrcProgram *p, FILE *output) +{ + OrcVariable *var; + int i; + + fprintf(output, " %s (", p->backup_name); + for(i=0;i<4;i++){ + var = &p->vars[ORC_VAR_D1 + i]; + if (var->size) { + fprintf(output, "ex->arrays[%s], ", enumnames[ORC_VAR_D1 + i]); + if (p->is_2d) { + fprintf(output, "ex->params[%s], ", enumnames[ORC_VAR_D1 + i]); + } + } + } + for(i=0;i<8;i++){ + var = &p->vars[ORC_VAR_S1 + i]; + if (var->size) { + fprintf(output, "ex->arrays[%s], ", enumnames[ORC_VAR_S1 + i]); + if (p->is_2d) { + fprintf(output, " ex->params[%s], ", enumnames[ORC_VAR_S1 + i]); + } + } + } + for(i=0;i<8;i++){ + var = &p->vars[ORC_VAR_P1 + i]; + if (var->size) { + switch (var->param_type) { + case ORC_PARAM_TYPE_INT: + fprintf(output, "ex->params[%s],", enumnames[ORC_VAR_P1 + i]); + break; + case ORC_PARAM_TYPE_FLOAT: + fprintf(output, "((orc_union32 * )&ex->params[%s])->f, ", + enumnames[ORC_VAR_P1 + i]); + break; + case ORC_PARAM_TYPE_INT64: + fprintf(output, "(ex->params[%s] & 0xffffffff) | ((orc_uint64)(ex->params[%s]) << 32), ", enumnames[ORC_VAR_P1 + i], enumnames[ORC_VAR_T1 + i]); + break; + case ORC_PARAM_TYPE_DOUBLE: + /* FIXME */ + break; + default: + ORC_ASSERT(0); + } + } + } + if (p->constant_n) { + fprintf(output, "%d", p->constant_n); + } else { + fprintf(output, "ex->n"); + } + if (p->is_2d) { + if (p->constant_m) { + fprintf(output, ", %d", p->constant_m); + } else { + fprintf(output, ", ORC_EXECUTOR_M(ex)"); + } + } + fprintf(output, ");\n"); +} + +void +output_backup_call (OrcProgram *p, FILE *output) +{ + OrcVariable *var; + int i; + + fprintf(output, " %s (", p->backup_name); + for(i=0;i<4;i++){ + var = &p->vars[ORC_VAR_D1 + i]; + if (var->size) { + fprintf(output, "%s, ", varnames[ORC_VAR_D1 + i]); + if (p->is_2d) { + fprintf(output, "%s_stride, ", varnames[ORC_VAR_D1 + i]); + } + } + } + for(i=0;i<8;i++){ + var = &p->vars[ORC_VAR_S1 + i]; + if (var->size) { + fprintf(output, "%s, ", varnames[ORC_VAR_S1 + i]); + if (p->is_2d) { + fprintf(output, "%s_stride, ", varnames[ORC_VAR_S1 + i]); + } + } + } + for(i=0;i<8;i++){ + var = &p->vars[ORC_VAR_P1 + i]; + if (var->size) { + fprintf(output, "%s, ", varnames[ORC_VAR_P1 + i]); + } + } + if (p->constant_n) { + fprintf(output, "%d", p->constant_n); + } else { + fprintf(output, "n"); + } + if (p->is_2d) { + if (p->constant_m) { + fprintf(output, ", %d", p->constant_m); + } else { + fprintf(output, ", m"); + } + } + fprintf(output, ");\n"); +} + +void output_code_header (OrcProgram *p, FILE *output) { if(use_internal) { @@ -640,8 +748,13 @@ output_code_header (OrcProgram *p, FILE *output) } else { fprintf(output, "void "); } - output_prototype (p, output); + output_prototype (p, output, 0); fprintf(output, ";\n"); + if (p->backup_name && mode != MODE_TEST) { + fprintf(output, "void "); + output_prototype (p, output, 1); + fprintf(output, ";\n"); + } } void @@ -655,7 +768,9 @@ output_code_backup (OrcProgram *p, FILE *output) fprintf(output, "_backup_%s (OrcExecutor * ORC_RESTRICT ex)\n", p->name); } fprintf(output, "{\n"); - { + if (p->backup_name && mode != MODE_TEST) { + output_executor_backup_call (p, output); + } else { OrcCompileResult result; result = orc_program_compile_full (p, orc_target_get_by_name("c"), @@ -677,9 +792,11 @@ output_code_no_orc (OrcProgram *p, FILE *output) { fprintf(output, "void\n"); - output_prototype (p, output); + output_prototype (p, output, 0); fprintf(output, "{\n"); - { + if (p->backup_name && mode != MODE_TEST) { + output_backup_call (p, output); + } else { OrcCompileResult result; result = orc_program_compile_full (p, orc_target_get_by_name("c"), @@ -740,7 +857,7 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline) } else { fprintf(output, "void\n"); } - output_prototype (p, output); + output_prototype (p, output, 0); fprintf(output, "\n"); fprintf(output, "{\n"); fprintf(output, " OrcExecutor _ex, *ex = &_ex;\n"); |