orcc: Use OrcCode as persistent storage
authorDavid Schleef <ds@schleef.org>
Mon, 6 Dec 2010 00:28:07 +0000 (16:28 -0800)
committerDavid Schleef <ds@schleef.org>
Mon, 6 Dec 2010 00:28:07 +0000 (16:28 -0800)
Pull the OrcCode object out of a compiled program and hold on
to that instead of the (large) OrcProgram.  This requires a few
lib changes, so requires --compat=0.4.11.1.

orc/orccompiler.c
orc/orcexecutor.c
orc/orcprogram.h
tools/orcc.c

index a9b2ada..a3b6cbf 100644 (file)
@@ -202,12 +202,6 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target,
   compiler->target = target;
   compiler->target_flags = flags;
 
-  if (program->backup_func && _orc_compiler_flag_backup) {
-    ORC_COMPILER_ERROR(compiler, "Compilation disabled");
-    compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE;
-    goto error;
-  }
-
   {
     ORC_LOG("variables");
     for(i=0;i<ORC_N_VARIABLES;i++){
@@ -297,6 +291,7 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target,
   program->orccode->is_2d = program->is_2d;
   program->orccode->constant_n = program->constant_n;
   program->orccode->constant_m = program->constant_m;
+  program->orccode->exec = program->code_exec;
 
   program->orccode->n_insns = compiler->n_insns;
   program->orccode->insns = malloc(sizeof(OrcInstruction) * compiler->n_insns);
@@ -312,8 +307,15 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target,
     program->orccode->vars[i].value = compiler->vars[i].value;
   }
 
+  if (program->backup_func && _orc_compiler_flag_backup) {
+    ORC_COMPILER_ERROR(compiler, "Compilation disabled");
+    compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE;
+    goto error;
+  }
+
   if (_orc_compiler_flag_emulate || target == NULL) {
     program->code_exec = (void *)orc_executor_emulate;
+    program->orccode->exec = (void *)orc_executor_emulate;
     compiler->result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE;
     goto error;
   }
index 2713029..46c0517 100644 (file)
@@ -40,7 +40,12 @@ orc_executor_run (OrcExecutor *ex)
 {
   void (*func) (OrcExecutor *);
 
-  func = ex->program->code_exec;
+  if (ex->program) {
+    func = ex->program->code_exec;
+  } else {
+    OrcCode *code = (OrcCode *)ex->arrays[ORC_VAR_A2];
+    func = code->exec;
+  }
   if (func) {
     func (ex);
     //ORC_ERROR("counters %d %d %d", ex->counter1, ex->counter2, ex->counter3);
@@ -54,7 +59,12 @@ orc_executor_run_backup (OrcExecutor *ex)
 {
   void (*func) (OrcExecutor *);
 
-  func = ex->program->backup_func;
+  if (ex->program) {
+    func = ex->program->backup_func;
+  } else {
+    OrcCode *code = (OrcCode *)ex->arrays[ORC_VAR_A2];
+    func = code->exec;
+  }
   if (func) {
     func (ex);
     //ORC_ERROR("counters %d %d %d", ex->counter1, ex->counter2, ex->counter3);
@@ -214,12 +224,18 @@ orc_executor_emulate (OrcExecutor *ex)
   int j;
   int k;
   int m, m_index;
-  OrcCode *code = ex->program->orccode;
+  OrcCode *code;
   OrcInstruction *insn;
   OrcStaticOpcode *opcode;
   OrcOpcodeExecutor *opcode_ex;
   void *tmpspace[ORC_N_COMPILER_VARIABLES] = { 0 };
 
+  if (ex->program) {
+    code = ex->program->orccode;
+  } else {
+    code = (OrcCode *)ex->arrays[ORC_VAR_A2];
+  }
+
   ex->accumulators[0] = 0;
   ex->accumulators[1] = 0;
   ex->accumulators[2] = 0;
index 844f9ae..3d1bbe7 100644 (file)
@@ -525,6 +525,7 @@ struct _OrcExecutor {
   int params[ORC_N_VARIABLES];
   int accumulators[4];
   /* exec pointer is stored in arrays[ORC_VAR_A1] */
+  /* OrcCode pointer is stored in arrays[ORC_VAR_A2] */
   /* row pointers are stored in arrays[i+ORC_VAR_C1] */
   /* the stride for arrays[x] is stored in params[x] */
   /* m is stored in params[ORC_VAR_A1] */
@@ -544,7 +545,8 @@ struct _OrcExecutorAlt {
 
   void *arrays[ORC_N_ARRAYS];
   OrcExecutorFunc exec;
-  void *unused1[ORC_N_VARIABLES - ORC_N_ARRAYS - 1];
+  OrcCode *code;
+  void *unused1[ORC_N_VARIABLES - ORC_N_ARRAYS - 2];
   int strides[ORC_N_ARRAYS];
   int m;
   int m_index;
@@ -570,12 +572,14 @@ struct _OrcCodeVariable {
 };
 
 struct _OrcCode {
+  /*< public >*/
+  OrcExecutorFunc exec;
+
   /*< private >*/
   OrcCompileResult result;
   char *name;
 
   /* for execution */
-  OrcExecutorFunc exec;
   unsigned char *code;
   int code_size;
   void *chunk;
index f6a3f3a..5eaf194 100644 (file)
@@ -29,6 +29,7 @@ int n_programs;
 OrcProgram **programs;
 
 int use_inline = FALSE;
+int use_code = FALSE;
 
 const char *init_function = NULL;
 
@@ -190,6 +191,9 @@ main (int argc, char *argv[])
       exit (1);
     }
   }
+  if (compat >= ORC_VERSION(0,4,11,1)) {
+    use_code = TRUE;
+  }
 
   if (output_file == NULL) {
     switch (mode) {
@@ -656,15 +660,21 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
   int i;
 
   if (init_function) {
+    const char *storage;
     if (is_inline) {
-      fprintf(output, "extern OrcProgram *_orc_program_%s;\n", p->name);
+      storage = "extern ";
     } else {
       if (use_inline) {
-        fprintf(output, "OrcProgram *_orc_program_%s;\n", p->name);
+        storage = "";
       } else {
-        fprintf(output, "static OrcProgram *_orc_program_%s;\n", p->name);
+        storage = "static ";
       }
     }
+    if (use_code) {
+      fprintf(output, "%sOrcCode *_orc_code_%s;\n", storage, p->name);
+    } else {
+      fprintf(output, "%sOrcProgram *_orc_program_%s;\n", storage, p->name);
+    }
   }
   if (is_inline) {
     fprintf(output, "static inline void\n");
@@ -676,10 +686,22 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
   fprintf(output, "{\n");
   fprintf(output, "  OrcExecutor _ex, *ex = &_ex;\n");
   if (init_function) {
-    fprintf(output, "  OrcProgram *p = _orc_program_%s;\n", p->name);
+    if (use_code) {
+      fprintf(output, "  OrcCode *c = _orc_code_%s;\n", p->name);
+    } else {
+      if (use_code) {
+        fprintf(output, "  OrcCode *c = _orc_code_%s;\n", p->name);
+      } else {
+        fprintf(output, "  OrcProgram *p = _orc_program_%s;\n", p->name);
+      }
+    }
   } else {
     fprintf(output, "  static int p_inited = 0;\n");
-    fprintf(output, "  static OrcProgram *p = 0;\n");
+    if (use_code) {
+      fprintf(output, "  static OrcCode *c = 0;\n");
+    } else {
+      fprintf(output, "  static OrcProgram *p = 0;\n");
+    }
   }
   fprintf(output, "  void (*func) (OrcExecutor *);\n");
   fprintf(output, "\n");
@@ -688,16 +710,28 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
     fprintf(output, "    orc_once_mutex_lock ();\n");
     fprintf(output, "    if (!p_inited) {\n");
     fprintf(output, "      OrcCompileResult result;\n");
+    if (use_code) {
+      fprintf(output, "      OrcProgram *p;\n");
+    }
     fprintf(output, "\n");
     output_program_generation (p, output, is_inline);
     fprintf(output, "\n");
     fprintf(output, "      result = orc_program_compile (p);\n");
+    if (use_code) {
+      fprintf(output, "      c = orc_program_take_code (p);\n");
+      fprintf(output, "      orc_program_free (p);\n");
+    }
     fprintf(output, "    }\n");
     fprintf(output, "    p_inited = TRUE;\n");
     fprintf(output, "    orc_once_mutex_unlock ();\n");
     fprintf(output, "  }\n");
   }
-  fprintf(output, "  ex->program = p;\n");
+  if (use_code) {
+    fprintf(output, "  ex->arrays[ORC_VAR_A2] = c;\n");
+    fprintf(output, "  ex->program = 0;\n");
+  } else {
+    fprintf(output, "  ex->program = p;\n");
+  }
   fprintf(output, "\n");
   if (p->constant_n) {
     fprintf(output, "  ex->n = %d;\n", p->constant_n);
@@ -778,7 +812,11 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
     }
   }
   fprintf(output, "\n");
-  fprintf(output, "  func = p->code_exec;\n");
+  if (use_code) {
+    fprintf(output, "  func = c->exec;\n");
+  } else {
+    fprintf(output, "  func = p->code_exec;\n");
+  }
   fprintf(output, "  func (ex);\n");
   for(i=0;i<4;i++){
     var = &p->vars[ORC_VAR_A1 + i];
@@ -948,7 +986,13 @@ output_init_function (FILE *output)
     fprintf(output, "\n");
     fprintf(output, "      result = orc_program_compile (p);\n");
     fprintf(output, "\n");
-    fprintf(output, "    _orc_program_%s = p;\n", programs[i]->name);
+    if (use_code) {
+      fprintf(output, "    _orc_code_%s = orc_program_take_code (p);\n",
+          programs[i]->name);
+      fprintf(output, "    orc_program_free (p);\n");
+    } else {
+      fprintf(output, "    _orc_program_%s = p;\n", programs[i]->name);
+    }
     fprintf(output, "  }\n");
   }
   fprintf(output, "#endif\n");