summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-12-05 12:01:21 +0100
committerWim Taymans <wtaymans@redhat.com>2014-12-05 12:01:21 +0100
commitf69256e3cf778ef6fb1fe450c04eea611d9e0177 (patch)
tree6a21e121ce95417fe4a5e9a369416c7776435622
parentacdaac31c648fd10f1bd0a49c4c33b483bb9c35c (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.c8
-rw-r--r--orc/orcprogram.c17
-rw-r--r--orc/orcprogram.h2
-rw-r--r--tools/orcc.c131
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");