Files
mercury/runtime/mercury_term_size.c
Simon Taylor 9c650e1d83 Improvements for bitmap.m, to make it useable as a general container
Estimated hours taken: 80
Branches: main

Improvements for bitmap.m, to make it useable as a general container
for binary data.

library/bitmap.m:
runtime/mercury_bitmap.c:
runtime/mercury_bitmap.h:
	Specialize the representation of bitmaps to an array of unsigned
	bytes defined as a foreign type.

	This is better than building on top of array(int) because it:
	- is better for interfacing with foreign code
	- has a more sensible machine-independent comparison order
	  (same as array(bool))
	- avoids storing the size twice
	- has more efficient copying, unification, comparison and tabling
	  (although we should probably specialize the handling of array(int)
	  and isomorphic types as well)
	- uses GC_MALLOC_ATOMIC to avoid problems with bit patterns that look
	  like pointers (although we should do that for array(int) as well)

	XXX The code for the Java and IL backends is untested.
	Building the library in grade Java with Sun JDK 1.6 failed (but
	at least passed error checking), and I don't have access to a
	copy of MSVS.NET.  The foreign code that needs to be tested is
	trivial.

	Add fields `bit', `bits' and `byte' to get/set a single bit,
	multiple bits (from an int) or an 8 bit byte.

	Add functions for converting bitmaps to hex strings and back,
	for use by stream.string_writer.write and deconstruct.functor/4.

	bitmap.intersect was buggy in the case where the input bitmaps
	had a different size.  Given that bitmaps are implemented with
	a fixed domain (lookups out of range throw an exception), it
	makes more sense to throw an exception in that case anyway,
	so all of the set operations do that now.

	The difference operation actually performed xor.  Fix it and
	add an xor function.

library/version_bitmap.m:
	This hasn't been fully updated to be the same as bitmap.m.
	The payoff would be much less because foreign code can't
	really do anything with version_bitmaps.

	Add a `bit' field.

	Deprecate the `get/2' function in favour of the `bit' field.

	Fix the union, difference, intersection and xor functions
	as for bitmap.m.

	Fix comparison of version_arrays so that it uses the same
	method as array.m: compare size then elements in order.
	The old code found version_arrays to be equal if one was
	a suffix of the other.

library/char.m:
	Add predicates for converting between hex digits and integers.

library/io.m:
library/stream.string_writer.m:
library/term.m:
	Read and write bitmaps.

runtime/mercury_type_info.h:
runtime/mercury_deep_copy_body.h:
runtime/mercury_mcpp.h:
runtime/mercury_table_type_body.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_unify_compare_body.h:
runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_term_size.c:
runtime/mercury_string.h:
library/construct.m:
library/deconstruct.m
compiler/prog_type.m:
compiler/mlds_to_gcc.m:
compiler/rtti.m:
	Add a MR_TypeCtorRep for bitmaps, and handle it in the library
	and runtinme.

library/Mercury.options:
	Compile bitmap.m with `--no-warn-insts-without-matching-type'.

runtime/mercury_type_info.h:
	Bump MR_RTTI_VERSION.

NEWS:
	Document the changes.

tests/hard_coded/Mmakefile:
tests/hard_coded/bitmap_test.m:
tests/hard_coded/bitmap_simple.m:
tests/hard_coded/bitmap_tester.m:
tests/hard_coded/bitmap_test.exp:
tests/tabling/Mmakefile:
tests/tabling/expand_bitmap.m:
tests/tabling/expand_bitmap.exp:
tests/hard_coded/version_array_test.m:
tests/hard_coded/version_array_test.exp:
	Test cases.
2007-02-13 01:59:04 +00:00

712 lines
23 KiB
C

/*
** vim:ts=4 sw=4 expandtab
*/
/*
** Copyright (C) 2003-2005, 2007 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/*
** mercury_term_size.c
**
** This module defines a function for measuring the sizes of terms.
*/
#include "mercury_imp.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifdef MR_RECORD_TERM_SIZES
MR_ComplexityCounter MR_complexity_word_counter = 0;
MR_ComplexityCounter MR_complexity_cell_counter = 0;
MR_ComplexityCounter MR_complexity_tick_counter = 0;
static void MR_write_complexity_proc(MR_ComplexityProc *proc);
static void MR_complexity_output_args_desc(FILE *fp,
MR_ComplexityProc *proc);
MR_Unsigned
MR_term_size(MR_TypeInfo type_info, MR_Word term)
{
MR_TypeCtorInfo type_ctor_info;
MR_DuTypeLayout du_type_layout;
const MR_DuPtagLayout *ptag_layout;
int ptag;
int sectag;
int arity;
int size;
try_again:
type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
if (! MR_type_ctor_has_valid_rep(type_ctor_info)) {
MR_fatal_error("MR_term_size: term of unknown representation");
}
switch (MR_type_ctor_rep(type_ctor_info)) {
case MR_TYPECTOR_REP_RESERVED_ADDR:
case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ:
/* XXX the code to handle these cases hasn't been written yet */
MR_fatal_error("MR_term_size: RESERVED_ADDR");
case MR_TYPECTOR_REP_DU:
case MR_TYPECTOR_REP_DU_USEREQ:
du_type_layout = MR_type_ctor_layout(type_ctor_info).MR_layout_du;
ptag = MR_tag(term);
ptag_layout = &du_type_layout[ptag];
switch (ptag_layout->MR_sectag_locn) {
case MR_SECTAG_NONE:
#ifdef MR_DEBUG_TERM_SIZES
if (ptag_layout->MR_sectag_alternatives[0]->
MR_du_functor_orig_arity <= 0)
{
MR_fatal_error("MR_term_size: zero arity ptag none");
}
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: du sectag none %p -> %d\n",
(void *) term,
(int) MR_field(MR_mktag(ptag), term, -1));
printf("type %s.%s/%d, functor %s\n",
type_ctor_info->MR_type_ctor_module_name,
type_ctor_info->MR_type_ctor_name,
type_ctor_info->MR_type_ctor_arity,
ptag_layout->MR_sectag_alternatives[0]->
MR_du_functor_name);
}
#endif
return MR_field(MR_mktag(ptag), term, -1);
case MR_SECTAG_LOCAL:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: du sectag local %p\n",
(void *) term);
}
#endif
return 0;
case MR_SECTAG_REMOTE:
#ifdef MR_DEBUG_TERM_SIZES
sectag = MR_field(MR_mktag(ptag), term, 0);
if (ptag_layout->MR_sectag_alternatives[sectag]->
MR_du_functor_orig_arity <= 0)
{
MR_fatal_error("MR_term_size: zero arity ptag remote");
}
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: du sectag remote %p -> %d\n",
(void *) term,
(int) MR_field(MR_mktag(ptag), term, -1));
printf("type %s.%s/%d, functor %s\n",
type_ctor_info->MR_type_ctor_module_name,
type_ctor_info->MR_type_ctor_name,
type_ctor_info->MR_type_ctor_arity,
ptag_layout->MR_sectag_alternatives[sectag]->
MR_du_functor_name);
}
#endif
return MR_field(MR_mktag(ptag), term, -1);
case MR_SECTAG_VARIABLE:
MR_fatal_error("MR_term_size: VARIABLE");
default:
fprintf(stderr, "sectag_locn: %d\n",
(int) ptag_layout->MR_sectag_locn);
MR_fatal_error("MR_term_size: sectag_locn");
}
case MR_TYPECTOR_REP_EQUIV:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: equiv %p\n", (void *) term);
}
#endif
type_info = MR_create_type_info(
MR_TYPEINFO_GET_FIXED_ARITY_ARG_VECTOR(type_info),
MR_type_ctor_layout(type_ctor_info).MR_layout_equiv);
goto try_again;
case MR_TYPECTOR_REP_EQUIV_GROUND:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: equiv ground %p\n", (void *) term);
}
#endif
type_info = MR_pseudo_type_info_is_ground(
MR_type_ctor_layout(type_ctor_info).MR_layout_equiv);
goto try_again;
case MR_TYPECTOR_REP_NOTAG:
case MR_TYPECTOR_REP_NOTAG_USEREQ:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: notag (usereq) %p\n", (void *) term);
}
#endif
MR_save_transient_hp();
type_info = MR_create_type_info(
MR_TYPEINFO_GET_FIXED_ARITY_ARG_VECTOR(type_info),
MR_type_ctor_layout(type_ctor_info).MR_layout_notag->
MR_notag_functor_arg_type);
MR_restore_transient_hp();
goto try_again;
case MR_TYPECTOR_REP_NOTAG_GROUND:
case MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: notag ground (usereq) %p\n",
(void *) term);
}
#endif
type_info = MR_pseudo_type_info_is_ground(
MR_type_ctor_layout(type_ctor_info).MR_layout_notag
->MR_notag_functor_arg_type);
goto try_again;
case MR_TYPECTOR_REP_TUPLE:
arity = MR_TYPEINFO_GET_VAR_ARITY_ARITY(type_info);
if (arity == 0) {
/* term may be a NULL pointer, so don't follow it */
size = 0;
} else {
size = MR_field(MR_mktag(0), term, -1);
}
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: tuple %p -> %d\n",
(void *) term, size);
}
#endif
return size;
case MR_TYPECTOR_REP_PRED:
case MR_TYPECTOR_REP_FUNC:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: pred/func %p\n", (void *) term);
}
#endif
/* currently we don't collect stats on closure sizes */
return 0;
case MR_TYPECTOR_REP_ARRAY:
/* currently we don't collect stats on array sizes */
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: array %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_BITMAP:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: bitmap %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_ENUM:
case MR_TYPECTOR_REP_ENUM_USEREQ:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: enum (usereq) %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_INT:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: int %p %ld\n",
(void *) term, (long) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_CHAR:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: char %p %c\n",
(void *) term, (char) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_FLOAT:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: float %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_STRING:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: string %p '%s'\n",
(void *) term, (char *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_SUCCIP:
case MR_TYPECTOR_REP_HP:
case MR_TYPECTOR_REP_CURFR:
case MR_TYPECTOR_REP_MAXFR:
case MR_TYPECTOR_REP_REDOFR:
case MR_TYPECTOR_REP_REDOIP:
case MR_TYPECTOR_REP_TRAIL_PTR:
case MR_TYPECTOR_REP_TICKET:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: impl artifact type %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_TYPEINFO:
case MR_TYPECTOR_REP_TYPECLASSINFO:
case MR_TYPECTOR_REP_TYPECTORINFO:
case MR_TYPECTOR_REP_BASETYPECLASSINFO:
case MR_TYPECTOR_REP_TYPEDESC:
case MR_TYPECTOR_REP_TYPECTORDESC:
case MR_TYPECTOR_REP_PSEUDOTYPEDESC:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: type_info etc %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_SUBGOAL:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: subgoal %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_C_POINTER:
case MR_TYPECTOR_REP_STABLE_C_POINTER:
case MR_TYPECTOR_REP_FOREIGN:
case MR_TYPECTOR_REP_STABLE_FOREIGN:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: c_pointer/foreign %p\n", (void *) term);
}
#endif
return 0;
case MR_TYPECTOR_REP_REFERENCE:
#ifdef MR_DEBUG_TERM_SIZES
if (MR_heapdebug && MR_lld_print_enabled) {
printf("MR_term_size: reference %p\n", (void *) term);
}
#endif
return 1;
case MR_TYPECTOR_REP_VOID:
MR_fatal_error("MR_term_size: VOID");
case MR_TYPECTOR_REP_UNKNOWN:
MR_fatal_error("MR_term_size: UNKNOWN");
default:
fprintf(stderr, "default rep: %d\n",
(int) MR_type_ctor_rep(type_ctor_info));
MR_fatal_error("MR_term_size: default");
}
MR_fatal_error("MR_term_size: unexpected fallthrough");
}
void
MR_write_complexity_procs(void)
{
int proc_num;
MR_ComplexityProc *proc;
for (proc_num = 0; proc_num < MR_num_complexity_procs; proc_num++) {
proc = &MR_complexity_procs[proc_num];
if (proc->MR_clp_num_profiled_args >= 0) {
MR_write_complexity_proc(proc);
}
}
}
#define MR_COMPLEXITY_ARGS_DIR "ComplexityArgs"
#define MR_COMPLEXITY_DATA_DIR "ComplexityData"
static MR_bool MR_have_created_complexity_dirs = MR_FALSE;
static MR_bool MR_have_printed_complexity_dirs_error = MR_FALSE;
static void
MR_write_complexity_proc(MR_ComplexityProc *proc)
{
char *full_proc_name;
int full_proc_name_len;
FILE *fp;
char *args_filename;
char *data_filename;
const char *data_filemode;
struct stat statbuf;
char *slash;
MR_ComplexityMetrics *metrics;
int num_profiled_args;
int *sizes;
int num_slots;
MR_ComplexityPastSlots *past_slots;
char *cmd_buf;
full_proc_name_len = strlen(proc->MR_clp_full_proc_name);
full_proc_name = MR_malloc(100 + full_proc_name_len);
strcpy(full_proc_name, proc->MR_clp_full_proc_name);
/*
** We can't have slash characters in the filenames we construct from
** full_proc_name.
*/
while ((slash = strchr(full_proc_name, '/')) != NULL) {
*slash = ':';
}
cmd_buf = MR_malloc(100 + 2 * full_proc_name_len);
/* will be big enough */
if (! MR_have_created_complexity_dirs) {
sprintf(cmd_buf, "mkdir -p %s %s",
MR_COMPLEXITY_ARGS_DIR, MR_COMPLEXITY_DATA_DIR);
if (system(cmd_buf) != 0) {
if (! MR_have_printed_complexity_dirs_error) {
fprintf(stderr, "%s: cannot create %s and %s: %s\n",
MR_progname, MR_COMPLEXITY_ARGS_DIR,
MR_COMPLEXITY_DATA_DIR, strerror(errno));
/* there is no point in aborting */
MR_have_printed_complexity_dirs_error = MR_TRUE;
return;
}
}
MR_have_created_complexity_dirs = MR_TRUE;
}
args_filename = MR_malloc(100 + full_proc_name_len);
/* will be big enough */
sprintf(args_filename, "%s/%s", MR_COMPLEXITY_ARGS_DIR, full_proc_name);
if (stat(args_filename, &statbuf) != 0) {
/* args_filename does not exist */
fp = fopen(args_filename, "w");
if (fp == NULL) {
fprintf(stderr, "%s: cannot open %s: %s\n",
MR_progname, args_filename, strerror(errno));
/* there is no point in aborting */
return;
}
MR_complexity_output_args_desc(fp, proc);
fclose(fp);
data_filemode = "w";
} else {
/* args_filename does exist */
char *tmp_filename;
tmp_filename = MR_malloc(100 + full_proc_name_len);
sprintf(tmp_filename, "%s/%s.tmp",
MR_COMPLEXITY_ARGS_DIR, full_proc_name);
fp = fopen(tmp_filename, "w");
if (fp == NULL) {
fprintf(stderr, "%s: cannot open %s: %s\n",
MR_progname, tmp_filename, strerror(errno));
/* there is no point in aborting */
return;
}
MR_complexity_output_args_desc(fp, proc);
fclose(fp);
sprintf(cmd_buf, "cmp -s %s %s", args_filename, tmp_filename);
if (system(cmd_buf) == 0) {
/* the files are identical */
(void) unlink(tmp_filename);
data_filemode = "a";
} else {
/* the files are different */
rename(tmp_filename, args_filename);
data_filemode = "w";
}
}
data_filename = MR_malloc(100 + full_proc_name_len);
sprintf(data_filename, "%s/%s", MR_COMPLEXITY_DATA_DIR, full_proc_name);
fp = fopen(data_filename, data_filemode);
if (fp == NULL) {
fprintf(stderr, "%s: cannot open %s: %s\n",
MR_progname, data_filename, strerror(errno));
/* there is no point in aborting */
return;
}
num_profiled_args = proc->MR_clp_num_profiled_args;
metrics = proc->MR_clp_metrics;
sizes = proc->MR_clp_sizes;
num_slots = proc->MR_clp_next_slot_num;
past_slots = proc->MR_clp_past_slots;
do {
int slot, arg;
for (slot = num_slots - 1; slot >= 0; slot--) {
fprintf(fp, "%d %d %d",
metrics[slot].MR_clpm_num_words,
metrics[slot].MR_clpm_num_cells,
metrics[slot].MR_clpm_num_ticks);
for (arg = 0; arg < num_profiled_args; arg++) {
fprintf(fp, " %d", sizes[slot * num_profiled_args + arg]);
}
fprintf(fp, "\n");
}
if (past_slots == NULL) {
break;
}
metrics = past_slots->MR_clpps_metrics;
sizes = past_slots->MR_clpps_sizes;
num_slots = MR_COMPLEXITY_SLOTS_PER_CHUNK;
past_slots = past_slots->MR_clpps_previous;
} while (MR_TRUE);
(void) fclose(fp);
}
static void
MR_complexity_output_args_desc(FILE *fp, MR_ComplexityProc *proc)
{
int arg;
int num_args;
MR_ComplexityArgInfo *arg_infos;
arg_infos = proc->MR_clp_arg_infos;
num_args = proc->MR_clp_num_args;
for (arg = 0; arg < num_args; arg++) {
if (arg_infos[arg].MR_clpai_maybe_name != NULL) {
fprintf(fp, "%s ", arg_infos[arg].MR_clpai_maybe_name);
} else {
fprintf(fp, "_ ");
}
switch (arg_infos[arg].MR_clpai_kind) {
case MR_COMPLEXITY_INPUT_VAR_SIZE:
fprintf(fp, "profiled_input\n");
break;
case MR_COMPLEXITY_INPUT_FIX_SIZE:
fprintf(fp, "unprofiled_input\n");
break;
case MR_COMPLEXITY_OUTPUT:
fprintf(fp, "output\n");
break;
default:
fprintf(fp, "unknown\n");
break;
}
}
}
void
MR_init_complexity_proc(int proc_num, const char *fullname,
int num_profiled_args, int num_args, MR_ComplexityArgInfo *arg_infos)
{
MR_ComplexityProc *proc;
if (MR_complexity_procs == NULL) {
fprintf(stderr, "%s: executable wasn't fully prepared "
"for complexity experiment\n", MR_progname);
exit(1);
}
proc = &MR_complexity_procs[proc_num];
if (! MR_streq(fullname, proc->MR_clp_full_proc_name)) {
fprintf(stderr, "%s: proc_num %d is %s: expected %s\n",
MR_progname, proc_num, proc->MR_clp_full_proc_name, fullname);
exit(1);
}
if (proc->MR_clp_num_profiled_args >= 0) {
fprintf(stderr, "%s: proc_num %d: duplicate initialization\n",
MR_progname, proc_num);
exit(1);
}
if (num_profiled_args < 0) {
fprintf(stderr, "%s: proc_num %d: bad num_profiled_args\n",
MR_progname, proc_num);
exit(1);
}
proc->MR_clp_num_profiled_args = num_profiled_args;
proc->MR_clp_num_args = num_args;
proc->MR_clp_arg_infos = arg_infos;
proc->MR_clp_metrics = MR_NEW_ARRAY(MR_ComplexityMetrics,
MR_COMPLEXITY_SLOTS_PER_CHUNK);
proc->MR_clp_sizes = MR_NEW_ARRAY(int,
MR_COMPLEXITY_SLOTS_PER_CHUNK * num_profiled_args);
}
void
MR_check_complexity_init(void)
{
int proc_num;
MR_bool printed_heading;
MR_ComplexityProc *proc;
printed_heading = MR_FALSE;
for (proc_num = 0; proc_num < MR_num_complexity_procs; proc_num++) {
proc = &MR_complexity_procs[proc_num];
if (proc->MR_clp_num_profiled_args < 0) {
if (! printed_heading) {
fprintf(stderr, "%s: the following procedures are "
"not available for complexity experiment:\n",
MR_progname);
printed_heading = MR_TRUE;
}
fprintf(stderr, "%s\n", proc->MR_clp_full_proc_name);
}
}
if (printed_heading) {
exit(1);
}
}
MR_ComplexityIsActive
MR_complexity_is_active_func(int num_procs, int proc_num, const char *name,
int num_profiled_inputs)
{
MR_ComplexityProc *proc;
if (num_procs != MR_num_complexity_procs || MR_complexity_procs == NULL) {
fprintf(stderr, "%s: executable wasn't fully prepared "
"for complexity experiment\n", MR_progname);
exit(1);
}
if (proc_num >= num_procs) {
fprintf(stderr, "%s: proc_num %d >= num_procs %d\n",
MR_progname, proc_num, num_procs);
exit(1);
}
proc = &MR_complexity_procs[proc_num];
if (! MR_streq(name, proc->MR_clp_full_proc_name)) {
fprintf(stderr, "%s: proc_num %d is %s: expected %s\n",
MR_progname, proc_num, proc->MR_clp_full_proc_name, name);
exit(1);
}
if (proc->MR_clp_num_profiled_args != num_profiled_inputs) {
fprintf(stderr, "%s: proc_num %d: bad num_profiled_inputs\n",
MR_progname, proc_num);
exit(1);
}
return proc->MR_clp_is_active;
}
int
MR_complexity_call_func(int procnum)
{
MR_ComplexityProc *proc;
MR_ComplexityMetrics *metrics;
int slot;
proc = &MR_complexity_procs[procnum];
slot = proc->MR_clp_next_slot_num;
if (slot < MR_COMPLEXITY_SLOTS_PER_CHUNK) {
proc->MR_clp_next_slot_num++;
} else {
MR_ComplexityPastSlots *past_slots;
past_slots = MR_NEW(MR_ComplexityPastSlots);
past_slots->MR_clpps_metrics = proc->MR_clp_metrics;
past_slots->MR_clpps_sizes = proc->MR_clp_sizes;
past_slots->MR_clpps_previous = proc->MR_clp_past_slots;
proc->MR_clp_past_slots = past_slots;
proc->MR_clp_metrics = MR_NEW_ARRAY(MR_ComplexityMetrics,
MR_COMPLEXITY_SLOTS_PER_CHUNK);
proc->MR_clp_sizes = MR_NEW_ARRAY(int,
MR_COMPLEXITY_SLOTS_PER_CHUNK * proc->MR_clp_num_profiled_args);
proc->MR_clp_next_slot_num = 1;
slot = 0;
}
metrics = &proc->MR_clp_metrics[slot];
metrics->MR_clpm_num_words -= MR_complexity_word_counter;
metrics->MR_clpm_num_cells -= MR_complexity_cell_counter;
metrics->MR_clpm_num_ticks -= MR_complexity_tick_counter;
proc->MR_clp_is_active = MR_COMPLEXITY_IS_ACTIVE;
return slot;
}
void
MR_complexity_fill_size_slot(MR_ComplexityProc *proc, int slot,
int num_profiled_args, int argnum, int size)
{
MR_ComplexityCounter *sizes;
sizes = proc->MR_clp_sizes;
sizes[(slot * proc->MR_clp_num_profiled_args) + argnum] = size;
}
void
MR_complexity_leave_func(int procnum, int slot)
{
MR_ComplexityProc *proc;
MR_ComplexityMetrics *metrics;
proc = &MR_complexity_procs[procnum];
metrics = &proc->MR_clp_metrics[slot];
metrics->MR_clpm_num_words += MR_complexity_word_counter;
metrics->MR_clpm_num_cells += MR_complexity_cell_counter;
metrics->MR_clpm_num_ticks += MR_complexity_tick_counter;
proc->MR_clp_is_active = MR_COMPLEXITY_IS_INACTIVE;
}
void
MR_complexity_redo_func(int procnum, int slot)
{
MR_ComplexityProc *proc;
MR_ComplexityMetrics *metrics;
proc = &MR_complexity_procs[procnum];
metrics = &proc->MR_clp_metrics[slot];
metrics->MR_clpm_num_words -= MR_complexity_word_counter;
metrics->MR_clpm_num_cells -= MR_complexity_cell_counter;
metrics->MR_clpm_num_ticks -= MR_complexity_tick_counter;
proc->MR_clp_is_active = MR_COMPLEXITY_IS_ACTIVE;
}
#endif /* MR_RECORD_TERM_SIZES */