[PATCH] orcc: Make init_function a per-program property

Maarten Bosmans mkbosmans at gmail.com
Mon Sep 19 08:23:14 PDT 2011


The changes in orcparse.c make sure that the argument of a .init command gets stored in program->init_function.  It is
still possible to provide a global init function by specifying .init before any .function in the input file.

Orcc honors these per program function names and emits init functions for each function name in the input file.  It is
possible for multiple programs to have the same init function, thus grouping initialization together.  Programs without
an init_function default to lazy initialization.

The orcc argument --init-function sets a global function name, which overrides any per-program init_function.  This was
already the case, but this patch adds support for using --init-function without it being followed by a function name on
the command line.  In this case an automatic init_function name of "[program->name]_init" gets assigned.
---
 orc/orcparse.c |   17 +++++----
 tools/orcc.c   |  103 ++++++++++++++++++++++++++++++++++----------------------
 2 files changed, 72 insertions(+), 48 deletions(-)

diff --git a/orc/orcparse.c b/orc/orcparse.c
index d655839..09eb2a0 100644
--- a/orc/orcparse.c
+++ b/orc/orcparse.c
@@ -137,14 +137,19 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log)
         parser->programs[parser->n_programs] = parser->program;
         parser->n_programs++;
         parser->creg_index = 1;
+        if (init_function) {
+          parser->program->init_function = strdup (init_function);
+        }
       } else if (strcmp (token[0], ".init") == 0) {
-        free (init_function);
-        init_function = NULL;
         if (n_tokens < 2) {
           orc_parse_log (parser, "error: line %d: .init without function name\n",
               parser->line_number);
         } else {
-          init_function = strdup (token[1]);
+          if (parser->program) {
+            parser->program->init_function = strdup (token[1]);
+          } else {
+            init_function = strdup (token[1]);
+          }
         }
       } else if (strcmp (token[0], ".flags") == 0) {
         int i;
@@ -318,17 +323,13 @@ orc_parse_full (const char *code, OrcProgram ***programs, char **log)
   }
 
   if (parser->line) free (parser->line);
+  if (init_function) free (init_function);
 
   if (log) {
     *log = parser->log;
   } else {
     free (parser->log);
   }
-  if (parser->programs[0]) {
-    parser->programs[0]->init_function = init_function;
-  } else {
-    free (init_function);
-  }
   *programs = parser->programs;
   return parser->n_programs;
 }
diff --git a/tools/orcc.c b/tools/orcc.c
index 54ea870..304ca51 100644
--- a/tools/orcc.c
+++ b/tools/orcc.c
@@ -30,9 +30,9 @@ OrcProgram **programs;
 
 int use_inline = FALSE;
 int use_code = FALSE;
-int use_lazy_init = FALSE;
 
 const char *init_function = NULL;
+const char **init_functions = NULL;
 
 char *target = "sse";
 
@@ -72,7 +72,8 @@ void help (void)
   printf("  --compat VERSION        Generate code compatible with Orc version VERSION\n");
   printf("  --inline                Generate inline functions in header\n");
   printf("  --no-inline             Do not generate inline functions in header\n");
-  printf("  --init-function FUNCTION  Generate initialization function\n");
+  printf("  --init-function [FUNCTION]\n");
+  printf("                          Generate initialization function\n");
   printf("  --lazy-init             Do Orc compile at function execution\n");
   printf("\n");
 
@@ -130,11 +131,10 @@ main (int argc, char *argv[])
     } else if (strcmp(argv[i], "--no-inline") == 0) {
       use_inline = FALSE;
     } else if (strcmp(argv[i], "--init-function") == 0) {
-      if (i+1 < argc) {
+      init_function = "";
+      if (i+1 < argc && strncmp(argv[i+1], "-", 1) != 0) {
         init_function = argv[i+1];
         i++;
-      } else {
-        help();
       }
     } else if (strcmp(argv[i], "--help") == 0 ||
         strcmp(argv[i], "-h") == 0) {
@@ -153,7 +153,7 @@ main (int argc, char *argv[])
         help();
       }
     } else if (strcmp(argv[i], "--lazy-init") == 0) {
-      use_lazy_init = TRUE;
+      init_function = NULL;
     } else if (strncmp(argv[i], "-", 1) == 0) {
       printf("Unknown option: %s\n", argv[i]);
       exit (1);
@@ -226,12 +226,34 @@ main (int argc, char *argv[])
   n_programs = n;
   printf("%s", log);
 
-  if (init_function == NULL) {
-    init_function = orc_parse_get_init_function (programs[0]);
+  if (init_function) {
+    for(i=0;i<n;i++){
+      if (programs[i]->init_function)
+        free (programs[i]->init_function);
+      if (strlen (init_function) == 0) {
+        char *s = malloc(strlen(programs[i]->name) + 5 + 1);
+        snprintf(s, strlen(programs[i]->name) + 5 + 1, "%s_init", programs[i]->name);
+        programs[i]->init_function = s;
+      } else {
+        programs[i]->init_function = (char *) init_function;
+      }
+    }
   }
 
-  if (init_function == NULL) {
-    use_lazy_init = TRUE;
+  init_functions = malloc(sizeof(size_t) * (n+1));
+  memset(init_functions, 0, sizeof(size_t) * (n+1));
+  for(i=0;i<n;i++){
+    int j;
+    const char *program_init_function = programs[i]->init_function;
+    for(j=0;init_functions[j];j++){
+      if (!program_init_function || strcmp(program_init_function, init_functions[j]) == 0) {
+        program_init_function = NULL;
+        break;
+      }
+    }
+    if (program_init_function) {
+      init_functions[j] = program_init_function;
+    }
   }
 
   output = fopen (output_file, "w");
@@ -260,9 +282,9 @@ main (int argc, char *argv[])
     for(i=0;i<n;i++){
       output_code_header (programs[i], output);
     }
-    if (init_function) {
-      fprintf(output, "\n");
-      fprintf(output, "void %s (void);\n", init_function);
+    fprintf(output, "\n");
+    for(i=0;init_functions[i];i++){
+      fprintf(output, "void %s (void);\n", init_functions[i]);
     }
     fprintf(output, "\n");
     fprintf(output, "%s", orc_target_get_asm_preamble ("c"));
@@ -271,9 +293,8 @@ main (int argc, char *argv[])
       output_code (programs[i], output);
     }
     fprintf(output, "\n");
-    if (init_function) {
+    if (init_functions[0]) {
       output_init_function (output);
-      fprintf(output, "\n");
     }
   } else if (mode == MODE_HEADER) {
     char *barrier = get_barrier (output_file);
@@ -290,9 +311,8 @@ main (int argc, char *argv[])
     fprintf(output, "extern \"C\" {\n");
     fprintf(output, "#endif\n");
     fprintf(output, "\n");
-    if (init_function) {
-      fprintf(output, "void %s (void);\n", init_function);
-      fprintf(output, "\n");
+    for(i=0;init_functions[i];i++){
+      fprintf(output, "void %s (void);\n", init_functions[i]);
     }
     fprintf(output, "\n");
     if (!use_inline) {
@@ -680,6 +700,7 @@ output_code_execute (OrcProgram *p, FILE *output, int is_inline)
 {
   OrcVariable *var;
   int i;
+  int use_lazy_init = (p->init_function == NULL);
 
   if (!use_lazy_init) {
     const char *storage;
@@ -1019,35 +1040,37 @@ output_program_generation (OrcProgram *p, FILE *output, int is_inline)
 void
 output_init_function (FILE *output)
 {
-  int i;
+  int i, j;
 
-  fprintf(output, "void\n");
-  fprintf(output, "%s (void)\n", init_function);
-  fprintf(output, "{\n");
-  if (!use_lazy_init) {
+  for(j=0;init_functions[j];j++){
+    fprintf(output, "void\n");
+    fprintf(output, "%s (void)\n", init_functions[j]);
+    fprintf(output, "{\n");
     fprintf(output, "#ifndef DISABLE_ORC\n");
     for(i=0;i<n_programs;i++){
-      fprintf(output, "  {\n");
-      fprintf(output, "    /* %s */\n", programs[i]->name);
-      fprintf(output, "    OrcProgram *p;\n");
-      fprintf(output, "    \n");
-      output_program_generation (programs[i], output, FALSE);
-      fprintf(output, "\n");
-      fprintf(output, "      orc_program_compile (p);\n");
-      fprintf(output, "\n");
-      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);
+      if (programs[i]->init_function && strcmp(programs[i]->init_function, init_functions[j]) == 0) {
+        fprintf(output, "  {\n");
+        fprintf(output, "    /* %s */\n", programs[i]->name);
+        fprintf(output, "    OrcProgram *p;\n");
+        fprintf(output, "    \n");
+        output_program_generation (programs[i], output, FALSE);
+        fprintf(output, "\n");
+        fprintf(output, "      orc_program_compile (p);\n");
+        fprintf(output, "\n");
+        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, "  }\n");
     }
     fprintf(output, "#endif\n");
+    fprintf(output, "}\n");
+    fprintf(output, "\n");
   }
-  fprintf(output, "}\n");
-  fprintf(output, "\n");
 }
 
 void
-- 
1.7.4.1



More information about the gstreamer-devel mailing list