Commit f1cfa5bb authored by Wim Taymans's avatar Wim Taymans

orcc: allow setting custom backup function

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.
parent 1291f79b
......@@ -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;
......
......@@ -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;
......@@ -277,6 +281,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
......
......@@ -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);
......
......@@ -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];
......@@ -632,6 +632,114 @@ output_prototype (OrcProgram *p, FILE *output)
fprintf(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)
{
......@@ -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");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment