Skip to content

Commit 7b69950

Browse files
author
ddeclerck
committed
Add a profiling feature
cobc: * parser.y: generate calls to "cob_prof_function_call" in the parsetree when profiling is unabled, when entering/leaving profiled blocks * flag.def: add `-fprof` to enable profiling * tree.h: add a flags field to cb_goto, add profiling fields to cb_program, add cb_prof_call enum and export cb_build_prof_call and cb_prof_procedure_fivision functions * tree.c (cb_build_program): initialize the new profiling fields of the cb_program structure * tree.c (cb_build_goto): add a "flags" argument (stored in the cb_program structure) * typeck.c (cb_emit_goto): add a "flags" argument (passed to cb_build_goto) * codegen.c: handle profiling code generation under the cb_flag_prof guard libcob: * Makefile.am: add `profiling.c` to sources * profiling.c: implement profiling functions (time spent in each procedure of the program) * common.c: add 4 environments variables COB_PROF_FILE, COB_PROF_MAX_DEPTH,COB_PROF_ENABLE and COB_PROF_FORMAT * common.c (cob_expand_env_string): add $b (executable basename), $f (executable filename), $d (date in yyyymmdd) and $t (time in hhmmss) * common.c (cob_set_main_argv0): extracted from cob_init * fileio.c (cob_path_to_absolute): extracted from insert and cob_set_main_argv0 config: * runtime.cfg: add COB_PROF_FILE
1 parent 14f0d09 commit 7b69950

File tree

21 files changed

+1894
-138
lines changed

21 files changed

+1894
-138
lines changed

NEWS

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ NEWS - user visible changes -*- outline -*-
1313
** support the COLLATING SEQUENCE clause on indexed files
1414
(currently only with the BDB backend)
1515

16+
** Support for time profiling of modules, sections, paragraphs, entries
17+
and external CALLs. This feature is activated by compiling the modules
18+
to be profiled with -fprof, and then executing the code with environment
19+
variable COB_PROF_ENABLE. The output is stored in a CSV file. Further
20+
customization can be done using COB_PROF_FILE, COB_PROF_MAX_DEPTH and
21+
COB_PROF_FORMAT
22+
1623
more work in progress
1724

1825
* Important Bugfixes
@@ -55,6 +62,12 @@ NEWS - user visible changes -*- outline -*-
5562
INSPECT CONVERTING (and "simple" INSPECT REPLACING), in general
5663
and especially if both from and to are constants
5764

65+
* Changes in the COBOL runtime
66+
67+
** more substitutions in environment variables: $f for executable filename,
68+
$b for executable basename, $d for date in YYYYMMDD format, $t for time
69+
in HHMMSS format (before, only $$ was available for pid)
70+
5871
* Known issues in 3.x
5972

6073
** testsuite:

cobc/ChangeLog

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,23 @@
11

2+
2024-03-17 Fabrice Le Fessant <[email protected]>
3+
Emilien Lemaire <[email protected]>
4+
5+
* parser.y: generate calls to "cob_prof_function_call" in the
6+
parsetree when profiling is unabled, when entering/leaving
7+
profiled blocks
8+
* flag.def: add `-fprof` to enable profiling
9+
* tree.h: add a flags field to cb_goto, add profiling
10+
fields to cb_program, add cb_prof_call enum and export
11+
cb_build_prof_call and cb_prof_procedure_fivision functions
12+
* tree.c (cb_build_program): initialize the new profiling
13+
fields of the cb_program structure
14+
* tree.c (cb_build_goto): add a "flags" argument
15+
(stored in the cb_program structure)
16+
* typeck.c (cb_emit_goto): add a "flags" argument
17+
(passed to cb_build_goto)
18+
* codegen.c: handle profiling code generation under the
19+
cb_flag_prof guard
20+
221
2024-02-19 Boris Eng <[email protected]>
322

423
* parser.y (screen_value_clause): replaced basic literals by literals

cobc/codegen.c

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4328,7 +4328,6 @@ output_funcall_item (cb_tree x, const int i, unsigned int func_nolitcast)
43284328
output_param (x, i);
43294329
}
43304330

4331-
43324331
static void
43334332
output_funcall (cb_tree x)
43344333
{
@@ -4344,6 +4343,61 @@ output_funcall (cb_tree x)
43444343
return;
43454344
}
43464345

4346+
if ( cb_flag_prof && p->name == cob_prof_function_call_str ) {
4347+
4348+
int proc_idx ;
4349+
4350+
switch ( CB_INTEGER (p->argv[0])->val ){
4351+
4352+
case COB_PROF_EXIT_PARAGRAPH:
4353+
proc_idx = CB_INTEGER(p->argv[1])->val;
4354+
output ("cob_prof_exit_procedure (prof_info, %d)", proc_idx);
4355+
break;
4356+
case COB_PROF_ENTER_SECTION:
4357+
proc_idx = CB_INTEGER(p->argv[1])->val;
4358+
output ("cob_prof_enter_section (prof_info, %d)", proc_idx);
4359+
break;
4360+
case COB_PROF_EXIT_SECTION:
4361+
proc_idx = CB_INTEGER(p->argv[1])->val;
4362+
output ("cob_prof_exit_section (prof_info, %d)", proc_idx);
4363+
break;
4364+
case COB_PROF_ENTER_CALL:
4365+
proc_idx = CB_INTEGER(p->argv[1])->val;
4366+
output ("cob_prof_enter_procedure (prof_info, %d)", proc_idx);
4367+
break;
4368+
case COB_PROF_EXIT_CALL:
4369+
proc_idx = CB_INTEGER(p->argv[1])->val;
4370+
output ("cob_prof_exit_procedure (prof_info, %d)", proc_idx);
4371+
break;
4372+
case COB_PROF_ENTER_PARAGRAPH:
4373+
proc_idx = CB_INTEGER(p->argv[1])->val;
4374+
output ("cob_prof_enter_procedure (prof_info, %d);", proc_idx);
4375+
output_newline ();
4376+
output_prefix ();
4377+
output ("fallthrough_label = 0");
4378+
break;
4379+
case COB_PROF_USE_PARAGRAPH_ENTRY: {
4380+
int paragraph_idx = CB_INTEGER(p->argv[1])->val;
4381+
int entry_idx = CB_INTEGER(p->argv[2])->val;
4382+
output ("if (!fallthrough_label)");
4383+
output_block_open ();
4384+
output_line ("cob_prof_use_paragraph_entry (prof_info, %d, %d);",
4385+
paragraph_idx, entry_idx);
4386+
output_block_close ();
4387+
output_line ("else");
4388+
output_block_open ();
4389+
output_line ("fallthrough_label = 0;");
4390+
output_block_close ();
4391+
break;
4392+
}
4393+
case COB_PROF_STAYIN_PARAGRAPH:
4394+
output ("fallthrough_label = 1");
4395+
break;
4396+
}
4397+
return;
4398+
}
4399+
4400+
43474401
screenptr = p->screenptr;
43484402
output ("%s (", p->name);
43494403
for (i = 0; i < p->argc; i++) {
@@ -7936,6 +7990,13 @@ output_goto (struct cb_goto *p)
79367990
struct cb_field *f;
79377991
int i;
79387992

7993+
if (cb_flag_prof) {
7994+
/* Output this only if we are exiting the paragraph... */
7995+
if ( !(p->flags & CB_GOTO_FLAG_SAME_PARAGRAPH) ){
7996+
output_line ("cob_prof_goto (prof_info);");
7997+
}
7998+
}
7999+
79398000
i = 1;
79408001
if (p->depending) {
79418002
/* Check for debugging on the DEPENDING item */
@@ -12256,6 +12317,19 @@ output_internal_function (struct cb_program *prog, cb_tree parameter_list)
1225612317

1225712318
/* Entry dispatch */
1225812319
output_line ("/* Entry dispatch */");
12320+
if (cb_flag_prof) {
12321+
output_line ("if (!prof_info) {");
12322+
output_line (
12323+
"\tprof_info = cob_prof_init_module (module, prof_procedures, %d);",
12324+
prog->procedure_list_len);
12325+
output_line ("}");
12326+
12327+
/* Prevent CANCEL from dlclose() the module, because
12328+
we keep pointers to static data there. */
12329+
output_line ("if (prof_info) { module->flag_no_phys_canc = 1; }");
12330+
12331+
output_line ("cob_prof_enter_procedure (prof_info, 0);");
12332+
}
1225912333
if (cb_flag_stack_extended) {
1226012334
/* entry marker = first frameptr is the one with
1226112335
an empty (instead of NULL) section name */;
@@ -12350,7 +12424,9 @@ output_internal_function (struct cb_program *prog, cb_tree parameter_list)
1235012424
output_newline ();
1235112425
}
1235212426
}
12353-
12427+
if (cb_flag_prof){
12428+
output_line ("cob_prof_exit_procedure (prof_info, 0);");
12429+
}
1235412430
if (!prog->flag_recursive) {
1235512431
output_line ("/* Decrement module active count */");
1235612432
output_line ("if (module->module_active) {");
@@ -13679,6 +13755,45 @@ output_header (const char *locbuff, const struct cb_program *cp)
1367913755
}
1368013756
}
1368113757

13758+
static void
13759+
output_cob_prof_data ( struct cb_program * program )
13760+
{
13761+
if (cb_flag_prof) {
13762+
struct cb_procedure_list *l;
13763+
char sep = ' ';
13764+
13765+
output_local ("/* cob_prof data */\n\n");
13766+
13767+
output_local ("static const int nprocedures = %d;\n",
13768+
program->procedure_list_len);
13769+
output_local ("static struct cob_prof_procedure prof_procedures[%d] = {\n",
13770+
program->procedure_list_len);
13771+
sep = ' ';
13772+
for (l = program->procedure_list; l; l=l->next) {
13773+
output_local (" %c { \"%s\", \"%s\", %d, %d, %d }\n",
13774+
sep,
13775+
l->proc.text,
13776+
l->proc.file,
13777+
l->proc.line,
13778+
l->proc.section,
13779+
l->proc.kind
13780+
);
13781+
sep = ',';
13782+
}
13783+
output_local ("};\n");
13784+
13785+
output_local ("static int fallthrough_label = 0;\n");
13786+
output_local ("static struct cob_prof_module *prof_info;\n");
13787+
13788+
output_local ("\n/* End of cob_prof data */\n");
13789+
13790+
program->procedure_list = NULL;
13791+
program->procedure_list_len = 0;
13792+
program->prof_current_section = -1;
13793+
program->prof_current_paragraph = -1;
13794+
}
13795+
}
13796+
1368213797
void
1368313798
codegen (struct cb_program *prog, const char *translate_name)
1368413799
{
@@ -13954,6 +14069,7 @@ codegen_internal (struct cb_program *prog, const int subsequent_call)
1395414069

1395514070
output_local_base_cache ();
1395614071
output_local_field_cache (prog);
14072+
output_cob_prof_data (prog);
1395714073

1395814074
/* Report data fields */
1395914075
if (prog->report_storage) {

cobc/flag.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,7 @@ CB_FLAG_ON (cb_diagnostics_show_line_numbers, 1, "diagnostics-show-line-numbers"
262262

263263
CB_FLAG (cb_diagnostics_absolute_paths, 1, "diagnostics-absolute-paths",
264264
_(" -fdiagnostics-absolute-paths\tprint absolute paths in diagnostics"))
265+
266+
CB_FLAG (cb_flag_prof, 1, "prof",
267+
_(" -fprof enable profiling of the COBOL program"))
268+

0 commit comments

Comments
 (0)