This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
egcs bug-report
- To: egcs-bugs at cygnus dot com
- Subject: egcs bug-report
- From: Helmut dot Bohr at t-online dot de (Helmut Bohr)
- Date: Fri, 16 Jan 1998 11:19:55 +0100
While compiling the HINT benchmark (http://www.scl.ameslab.gov/Projects/HINT/)
I´ve found the following bug.
gcc -c -O -Dunix -DLONGLONG -DIINT hint.c -o hint.o
hint.c: In function `main':
hint.c:285: internal error--insn does not satisfy its constraints:
(insn 207 1561 1563 (parallel[
(set (reg:DI 1 %edx)
(plus:DI (reg:DI 1 %edx)
(reg:DI 1 %edx)))
(clobber (scratch:SI))
] ) 142 {adddi3} (nil)
(expr_list:REG_UNUSED (scratch:SI)
(nil)))
gcc: Internal compiler error: program cc1 got fatal signal 6
make: *** [hint.o] Error 1
output from gcc -v
Reading specs from /usr/local/lib/gcc-lib/i486-pc-linux-gnulibc1/egcs-2.90.23/specs
gcc version egcs-2.90.23 980102 (egcs-1.0.1 release)
When compiling without -O there is error.
--
Helmut Bohr Helmut.Bohr@T-Online.de
hbohr@dvo.de
# __ __
# \/ \/ __ __ __ ________ TM
# ||_ || \/ \ \ \/ |/~||~\|
# ||-\-|| || ||\\ || ||
# || ~|| || || \\|| ||
# /\ /\ /\ /\ \ | /\
# ~~ ~~ ~~ ~~ \/ ~~
#
# Creating HINT(tm)
# 1. Change ARCH to reflect your architecture. We currently support
# unix serial version only - general unix machine
# NCUBE2S requires mimd code
# NCUBE2 requires mimd code
# PARAGON requires mimd code
# SGI shared memory parallel version - requires Power C
# KSR Kendall Square - requires shared memory version
# MP1 MasPar 1 - requires SIMD version
# MP2 MasPar 2 - requires SIMD version
# note: If your architecture is not present, you will have to add a
# define and the architecture specific code within the HINT
# source code. See the README.porting and the comments within
# the source code for help.
# 2. Set DATATYPE to the appropriate C data type to run your test on.
# We have found that setting DATATYPE equal to DOUBLE is large enough
# to sufficiently exercise most architectures. For integer testing, you
# need to use at least a 32 bit integer. Supported data types are:
# DOUBLE double
# FLOAT float
# LONGLONG long long
# LONG long
# INT int
# 3. Set CC to the appropriate compiler.
# 4. Set the various FLAGS variables appropriately.
# The "-D$(ARCH) -D$(DATATYPE)" _MUST_ be present on both the
# KERN_CFLAGS and the DRIV_CFLAGS.
# 5. Save the Makefile and type 'make' to create the executables.
# To run the benchmark type 'make run'.
ARCH = unix
DATATYPE = LONGLONG
DRIV_SRC = hint.c
KERN_SRC = hkernel.c
INCLUDES = hint.h typedefs.h
TARGET = hint
DATAFILE = $(DATATYPE)
CC = gcc
COPT = -O
KERN_CFLAGS= -c $(COPT) -D$(ARCH) -D$(DATATYPE)
DRIV_CFLAGS= -c $(COPT) -D$(ARCH) -D$(DATATYPE)
LFLAGS = -lm
targets: $(TARGET)
run: $(TARGET) $(DATAFILE)
rerun:
/bin/rm -f $(DATAFILE)
make run
clean:
/bin/rm -f $(DATAFILE) hint.o hkernel.o
clobber:
/bin/rm -f $(DATAFILE)
/bin/rm -f $(TARGET)
#
# This section of the Makefile is for compiling the binaries
#
hint: hint.o hkernel.o Makefile
$(CC) hint.o hkernel.o -o hint $(LFLAGS)
hint.o: $(DRIV_SRC) $(INCLUDES) Makefile
$(CC) $(DRIV_CFLAGS) -DIINT $(DRIV_SRC) -o hint.o
hkernel.o: $(KERN_SRC) $(INCLUDES) Makefile
$(CC) $(KERN_CFLAGS) -DIINT $(KERN_SRC) -o hkernel.o
#
# This section has the data file dependancies
#
$(DATATYPE): hint
./hint
/******************************************************************************/
/* "HINT" -- Hierarchical INTegration. SERIAL VERSION */
/* Copyright (C) 1994 by Iowa State University Research Foundation, Inc. */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation. You should have received a copy of the */
/* GNU General Public License along with this program; if not, write to the */
/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* Files needed for use: */
/* * hint.c ---- Driver source */
/* * hkernel.c ---- Kernel source */
/* * hint.h ---- General include file */
/* * typedefs.h ---- Include file for DSIZE and ISIZE */
/* * README ---- These are the rules. Follow them!!! */
/******************************************************************************/
/* Refer to hint.h and typedefs.h for all-capitalized definitions. */
#include "hint.h"
/******************************************************************************/
/* This sets the data file name. */
/******************************************************************************/
#if defined(LDOUBLE)
char *filnm="LDOUBLE";
#elif defined(DOUBLE)
char *filnm="DOUBLE";
#elif defined(FLOAT)
char *filnm="FLOAT";
#elif defined(LONGLONG)
char *filnm="LONGLONG";
#elif defined(LONG)
char *filnm="LONG";
#elif defined(INT)
char *filnm="INT";
#elif defined(SHORT)
char *filnm="SHORT";
#elif defined(CHAR)
char *filnm="CHAR";
#endif
main(int argc, char *argv[])
{
FILE *curv; /* Output file for QUIPS curve */
Speed qdata[NSAMP]; /* Array to keep track of QUIPs and time */
ERROR eflag; /* Stopping condition returned from Hint */
ISIZE imax, /* Maximum representable index */
itm, /* Scratch values to find imax */
n, /* Number of goal subintervals */
nscout; /* Number of survey subintervals */
volatile
DSIZE tm1; /* Scratch to prevent use of registers */
volatile
ISIZE itm2; /* Scratch to prevent use of registers */
DSIZE dmax, /* Maximum associative whole number */
gamut, /* Range of result from Hint, high minus low bound */
scx, /* Scale factor for x values */
scy, /* Scale factor for y values */
tm, tm2; /* Scratch values to find dmax */
double delq, /* Change in Quality */
quips, /* QUality Improvement Per Second */
qpnet, /* Net QUIPS; integral of QUIPS d(log t) */
qpeak, /* Peak QUIPS attained */
qprat, /* Ratio of current QUIPS to peak QUIPS */
qptmp, /* QUIPS temporary for calculating Net QUIPS */
t, /* Time for a given trial */
t0, /* Starting time */
t1, /* Ending time */
tdelta, /* Timer resolution */
tlast, /* Time of last recorded trial */
tscout; /* Time for initial survey */
int dbits, /* Number of bits of accuracy for dmax */
ibits, /* Number of bits for imax */
i, j, k, /* Loop counters */
laps, /* Approximate number of laps in a trial */
memuse; /* Amount of memory used, in bytes */
printf(" _ _\n");
printf(" | | _ _ _ _____ TM\n");
printf(" |-- | | |\\ | | | |\n");
printf(" | --| | | \\ | |\n");
printf(" | | | | \\| |\n");
printf(" ^ ^ ^ ^ ^ ^\n\n");
printf("*** The HINT PERFORMANCE ANALYZER ***\n");
printf(" Version 1.0 June 1994\n");
printf(" John L. Gustafson & Quinn O. Snell\n");
printf(" Scalable Computing Laboratory\n");
printf(" 236 Wilhelm, Iowa State University\n");
printf(" Ames, Iowa 50011-3020\n");
printf(" (515) 294 - 9294\n\n");
printf("Copyright (C) 1994");
printf(" Iowa State University Research Foundation, Inc.\n");
printf("Please send results and questions to: hint@scl.ameslab.gov\n");
printf("When sending results please follow the form in README\n");
printf("________________________________________________________\n");
#ifdef DEBUG
curv = stdout;
#else
if ((curv = fopen(filnm, "w")) == NULL)
{
printf("Could not open data file %s\n", filnm);
exit(1);
}
#endif
/* Attempt to find timer resolution. Loop until the time changes. */
for (t0 = When(); ((t1 = When()) == t0););
tdelta = t1 - t0;
/* Find the largest associative whole number, dmax. */
dbits = 0;
tm = (DSIZE)1;
tm2 = tm + tm;
tm1 = tm2 + 1;
/* Double until it fails to increment or it overflows. */
while (((tm1 - tm2) == (DSIZE)1) && (tm2 > (DSIZE)0))
{
dbits++;
tm += tm;
tm2 += tm2;
tm1 = tm2 + 1;
}
dbits++;
/* We use a grid of dmax + 1 squares, but this might overflow, so back off 1.*/
dmax = tm + (tm - 1);
printf("Apparent number of bits of accuracy: %d\n", dbits);
printf("Maximum associative whole number: %.0lf\n",(double)dmax);
/* Find the largest representable index number. */
ibits = 0;
itm = (ISIZE)1;
itm2 = itm + itm;
/* Double it until it overflows. */
while (itm2 > (ISIZE)0)
{
ibits++;
itm += itm;
itm2 += itm2;
}
imax = itm;
printf("Maximum number of bits of index: %d\n", ibits);
printf("Maximum representable index: %.0lf\n\n", (double)imax);
/* Calculate usable maxima, from whichever is most restrictive. */
if ((ibits + ibits) < dbits)
{
dmax = (DSIZE)imax * (DSIZE)imax - 1;
dbits = ibits + ibits;
}
printf("Index-limited data accuracy: %d bits\n", dbits);
printf("Maximum usable whole number: %.0lf\n",(double)dmax);
/* Half the bits, biased downward, go to x. */
j = (dbits)/2;
/* Now loop to take 2 to the appropriate power for grid dimensions. */
for (i = 0, scx = 1; i < j; scx += scx, i++);
for (i = 0, scy = 1; i < dbits - j; scy += scy, i++);
printf("Grid: %.0lf wide by %.0lf high.\n",(double)scx,(double)scy);
/* This loop is used as a survey. */
for (nscout = NMIN, laps = 3; nscout < scx; )
{
t = Run(laps, &gamut, scx, scy, dmax, nscout, &eflag);
if (eflag != NOERROR)
{
nscout /= 2;
break;
}
else if ((t > RUNTM) && (eflag == NOERROR))
{
tscout = t;
break;
}
else
{
tscout = t;
nscout *= 2;
if (nscout > scx)
{
nscout /= 2;
break;
}
}
}
if (tscout == 0)
{
printf( "Data type for %s is too small\n", argv[0]);
exit(0);
}
if ((tscout < RUNTM) && (eflag == NOMEM))
printf("Memory is not sufficient for > %3.1lf second runs.\n",
RUNTM);
else if (tscout < RUNTM)
printf("Precision is not sufficient for > %3.1lf second runs.\n",
RUNTM);
/* This loop is the main loop driver of the HINT kernel. */
for (t = 0, i = 0, n = NMIN, qpeak = 0, qprat = 1, tlast = 0;
((i < NSAMP) && (t < STOPTM) && (n < scx) && (qprat > STOPRT));
i++, n = ((int)(n * ADVANCE) > n)? (n * ADVANCE) : n + 1)
{
printf(".");
fflush(stdout);
/* Use enough laps to fill RUNTM time, roughly. */
laps = MAX(RUNTM * nscout / (tscout * n), 1);
t = Run(laps, &gamut, scx, scy, dmax, n, &eflag);
if (t == 0)
t = tdelta;
if (eflag != NOERROR)
break;
/* Calculate QUIPS. We must add 1 to dmax, but do it in steps. */
/* This is to avoid overflow of dmax */
delq = (double)dmax / gamut - 1;
quips = delq / t + 1.0 / gamut / t;
qdata[i].t = t;
qdata[i].qp = quips;
qdata[i].n = n;
qpeak = MAX(qpeak, quips);
qprat = quips / qpeak;
}
memuse = (int)(qdata[i-1].n * (sizeof(RECT)+sizeof(DSIZE)+sizeof(ISIZE)));
if ((qprat > STOPRT) && (eflag == NOMEM))
printf("\nThis run was memory limited at %d subintervals -> %d bytes\n",
n, memuse);
printf("\nDone with first pass. Now computing net QUIPS\n");
fprintf(curv,"%12.10lf %10.0lf %12.0lf %12.0lf %10d\n",
qdata[i-1].t, qdata[i-1].qp, qdata[i-1].t * qdata[i-1].qp,
(double)qdata[i-1].n, memuse);
/* Now go backwards through the data to calculate net QUIPS, and filter data.*/
for (qpnet = qdata[i-1].qp, j = i - 2; j >= 0; j--)
{
/* If more work takes less time, we need to rerun the case of less work. */
for (k = 0; ((qdata[j+1].t < qdata[j].t) && (k < PATIENCE)); k++)
{
printf("#", (double)qdata[j].n);
laps = MAX(RUNTM * nscout / (tscout * qdata[j].n), 1);
t = Run(laps, &gamut, scx, scy, dmax, qdata[j].n, &eflag);
if (t == 0)
t = tdelta;
delq = (double)dmax / gamut - 1;
quips = delq / t + 1.0 / gamut / t;
qdata[j].t = t;
qdata[j].qp = quips;
}
if (qdata[j+1].t < qdata[j].t)
{
printf(" Forcing a time for %d subintervals\n", qdata[j].n);
qdata[j].t = qdata[j+1].t;
delq = (double)dmax / gamut - 1;
qdata[j].qp = delq / qdata[j].t + 1.0 / gamut / qdata[j].t;
}
memuse = (int)(qdata[j].n * (sizeof(RECT)+sizeof(DSIZE)+sizeof(ISIZE)));
fprintf(curv,"%12.10lf %10.0lf %12.0lf %12.0lf %10d\n",
qdata[j].t, qdata[j].qp, qdata[j].t * qdata[j].qp,
(double)qdata[j].n, memuse);
/* Now calculate the addition to the net QUIPS. */
/* This is calculated as the sum of QUIPS(j) * (1 - time(j) / time(j+1)).*/
qptmp = qdata[j].qp * qdata[j].t / qdata[j+1].t;
qpnet += (qdata[j].qp - qptmp);
}
printf("\nFinished with %lf net QUIPs\n", qpnet);
fclose(curv);
}
double
Run(int laps,
DSIZE *gamut, DSIZE scx, DSIZE scy, DSIZE dmax, ISIZE memry, ERROR *eflag)
{
RECT *rect=NULL; /* Array for saving hierarchical information */
ISIZE *ixes=NULL; /* Array for indices of queued entries */
DSIZE *errs=NULL; /* Array of error values */
int i, j; /* Loop counters */
double t0, t1, tm, /* Time variables */
mint = 1e32; /* Minimum time recorded for a given run */
/* Allocate the memory for the arrays. */
rect = (RECT *)malloc((MSIZE)(memry * sizeof(RECT)));
errs = (DSIZE *)malloc((MSIZE)(memry * sizeof(DSIZE) * 2));
ixes = (ISIZE *)malloc((MSIZE)(memry * sizeof(ISIZE) * 2));
/* If the memory is unavailable, free what was allocated and return. */
if ((rect == NULL) || (errs == NULL) || (ixes == NULL))
{
if (rect != NULL)
free(rect);
if (errs != NULL)
free(errs);
if (ixes != NULL)
free(ixes);
*eflag = NOMEM;
return (-NOMEM);
}
for (i = 0; i < NTRIAL; i++)
{
t0 = When();
/* Run the benchmark for this trial. */
for (j = 0; j < laps; j++)
*gamut = Hint(&scx, &scy, &dmax, &memry, rect, errs, ixes, eflag);
t1 = When();
/* Track the minimun time thus far for this trial. */
tm = (t1 - t0) / laps;
mint = MIN(mint, tm);
}
/* Free up the memory. */
free(rect);
free(errs);
free(ixes);
return (mint);
}
/* Return the current time in seconds, using a double precision number. */
double
When()
{
struct timeval tp;
gettimeofday(&tp, NULL);
return ((double) tp.tv_sec + (double) tp.tv_usec * 1e-6);
}
/******************************************************************************/
/* "HINT" -- Hierarchical INTegration. */
/* Copyright (C) 1994 by Iowa State University Research Foundation, Inc. */
/* */
/* Files needed for use: */
/* * hint.c ---- Driver source */
/* * hkernel.c ---- Kernel source */
/* * hint.h ---- General include file */
/* * typedefs.h ---- Include file for DSIZE and ISIZE */
/* * README ---- These are the rules. Follow them!!! */
/******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
/******************************************************************************/
/* Vendor Specific defines and includes */
/******************************************************************************/
#if defined(NCUBE2S) /* Correction for 25 MHz clock on Ncube 2s */
#define NTIME 0.8
#else
#define NTIME 1.0
#endif
#if defined(MP1) || defined(MP2)
#include <mpl.h> /* MasPar specific includes */
#include <mp_time.h> /* MasPar timer prototypes and data declarations */
#else
#include <sys/time.h>/* Unix timer prototypes and data declarations */
#endif
#if defined(SGI) /* SGI specific includes for shared memory support.*/
#include <ulocks.h>
#include <task.h>
#endif
#if defined(KSR) /* Kendall Square Research includes for shared mem */
#include <ksr/numarg.h>
#endif
#if defined(SUNMOS) || defined(PARAGON)
#include <nx.h> /* Intel Paragon specific includes */
#define USE_DCLOCK /* Use the Intel timer routine. */
#endif
#ifdef FORTRAN /* SGI Fortran compiler forces trailing underscore */
#define Hint hint_
#endif
/******************************************************************************/
/* Macro Declarations */
/******************************************************************************/
#define MIN(x,y) (((x) > (y))? (y): (x))
#define MAX(x,y) (((x) > (y))? (x): (y))
/******************************************************************************/
/* Adjustable Defines */
/* These may be adjusted according to the HINT rules. */
/******************************************************************************/
#define ADVANCE 1.2589 /* Multiplier. We use roughly 1 decibel step size. */
/* Closer to 1.0 takes longer to run, but might */
/* produce slightly higher net QUIPS. */
#define NCHUNK 4 /* Number of chunks for scatter decomposition */
/* Larger numbers increase time to first result */
/* (latency) but sample domain more evenly. */
#define NSAMP 200 /* Maximum number of QUIPS measurements */
/* Increase if needed, e.g. if ADVANCE is smaller */
#define NTRIAL 3 /* Normal number of times to run a trial */
/* Increase if computer is prone to interruption */
#define PATIENCE 999 /* Number of times to rerun a bogus trial */
#define RUNTM 0.5 /* Target time, seconds. Reduce for high-res timer.*/
/* Should be much larger than timer resolution. */
#define STOPRT 0.1 /* Ratio of current to peak QUIPS to stop at */
/* Smaller numbers will beat on virtual memory. */
#define STOPTM 100 /* Longest time acceptable, seconds. Most systems */
/* run out of decent-speed memory well before this */
/******************************************************************************/
/* Non - Adjustable Defines */
/******************************************************************************/
#define HI 0 /* Index of high values */
#define LO 1 /* Index of low values */
#define TRUE (1==1) /* Self explanatory */
#define FALSE (1==0) /* Self explanatory */
#define MSIZE int /* Integral type for allocating memory */
#define NMIN 2 /* Minimum number of subintervals */
/******************************************************************************/
/* Type Defines */
/******************************************************************************/
#include "typedefs.h" /* Sets data type DSIZE and index type ISIZE */
/******************************************************************************/
/* Type Declarations */
/******************************************************************************/
typedef struct {
DSIZE ahi, /* Upper bound on rectangle areas */
alo, /* Lower bound on rectangle areas */
dx, /* Interval widths */
flh, /* Function values of left coordinates, high */
fll, /* Function values of left coordinates, low */
frh, /* Function values of right coordinates, high */
frl, /* Function values of right coordinates, low */
xl, /* Left x-coordinates of subintervals */
xr; /* Right x-coordinates of subintervals */
}RECT;
typedef struct {
double t, /* Time for a given run */
qp; /* QUIPS for a given run */
ISIZE n; /* Subintervals for a given run */
}Speed;
typedef ISIZE ERROR;
/******************************************************************************/
/* Prototypes */
/******************************************************************************/
double When();
double
Run(int laps,
DSIZE *gamut, DSIZE scx, DSIZE scy, DSIZE dmax, ISIZE memry, ERROR *eflag);
#if defined(MP1) || defined(MP2)
DSIZE
Hint(DSIZE *scx, DSIZE *scy, DSIZE *xmax, ISIZE *mcnt, plural RECT *rect,
plural DSIZE *errs, plural ISIZE *ixes, ERROR *eflag);
#elif defined(SGI) || defined(KSR) || defined(CONVEX)
void
Hint(DSIZE scx, DSIZE scy, ISIZE mcnt, int iproc, double gs[2],
RECT *rect, DSIZE *errs, ISIZE *ixes, ERROR *eflag);
#else
DSIZE
Hint(DSIZE *scx, DSIZE *scy, DSIZE *dmax, ISIZE *mcnt, RECT *rect,
DSIZE *errs, ISIZE *ixes, ERROR *eflag);
#endif
/******************************************************************************/
/* "HINT" -- Hierarchical INTegration. SERIAL VERSION */
/* Copyright (C) 1994 by Iowa State University Research Foundation, Inc. */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation. You should have received a copy of the */
/* GNU General Public License along with this program; if not, write to the */
/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* */
/* Files needed for use: */
/* * hint.c ---- Driver source */
/* * hkernel.c ---- Kernel source */
/* * hint.h ---- General include file */
/* * typedefs.h ---- Include file for DSIZE and ISIZE */
/* * README ---- These are the rules. Follow them!!! */
/******************************************************************************/
#include "hint.h"
DSIZE
Hint(DSIZE *scx, DSIZE *scy, DSIZE *dmax, ISIZE *mcnt, RECT *rect,
DSIZE *errs, ISIZE *ixes, ERROR *eflag)
{
DSIZE errio, /* Error value for io */
errjo, /* Error value for jo */
sh, /* Sum of areas, high bound */
sl, /* Sum of areas, low bound */
tm, /* Temporary value for computing function */
tm2, /* Temporary value for doubling tm */
tmerr; /* Temporary error value for swaps */
ISIZE inc, jnc, /* Indices of queue positions */
io, /* Index of left child */
iq, /* Index of end of the sorted error queue */
it, /* Iteration counter */
itmp, /* Temporary */
jo, /* Index of right child */
ma; /* Index of parent */
/* Initialize the first interval. */
rect[0].xl = (DSIZE)0;
rect[0].xr = *scx;
rect[0].dx = *scx;
rect[0].fll = *scy;
rect[0].flh = *scy;
rect[0].frl = (DSIZE)0;
rect[0].frh = (DSIZE)0;
rect[0].ahi = *dmax;
rect[0].alo = (DSIZE)0;
iq = 0;
errs[iq] = rect[0].ahi - rect[0].alo;
ixes[iq] = iq;
sh = rect[0].ahi;
sl = rect[0].alo;
for (it = 0; ((it < *mcnt - 1) && (it <= iq)); it++)
{
io = ma = ixes[it]; /* Head of list has maximum error */
jo = it + 1; /* Find right child index */
tm = rect[ma].dx;
/* Since dx is always a power of 2, it halves evenly. */
rect[io].dx = rect[jo].dx = tm / (DSIZE)2;
/* Right child gets right boundary. */
rect[jo].xr = rect[ma].xr;
/* New point in the middle is shared by child subintervals */
rect[io].xr = rect[io].xl +
rect[io].dx;
rect[jo].xl = rect[io].xr;
/* Right child gets right f value upper and lower bounds */
rect[jo].frl = rect[ma].frl;
rect[jo].frh = rect[ma].frh;
/* Note that the left child simply inherits much of its info from ma. */
/* This is the function evaluation. */
tm = (*scx + rect[io].xr);
tm2 = (*scy * (*scx - rect[io].xr));
itmp = tm2 / tm;
rect[io].frl = itmp;
/* Here we need boolean true == 1. Otherwise use if's. */
rect[io].frh = rect[io].frl + ((tm * rect[io].frl) != tm2);
rect[jo].fll = rect[io].frl;
rect[jo].flh = rect[io].frh;
/* Compute the left daughter error. */
tm = (rect[io].fll - rect[io].frh) * (rect[io].dx - (DSIZE)2);
if (tm < (DSIZE)0)
tm = (DSIZE)0;
errio = (rect[io].flh - rect[io].frh +
rect[io].fll - rect[io].frl) *
(rect[io].dx - (DSIZE)1) - tm;
/* Repeat for the right daughter. */
tm = (rect[jo].fll - rect[jo].frh) * (rect[jo].dx - (DSIZE)2);
if (tm < (DSIZE)0)
tm = (DSIZE)0;
errjo = (rect[jo].flh - rect[jo].frh +
rect[jo].fll - rect[jo].frl) *
(rect[jo].dx - (DSIZE)1) - tm;
/* Compute indices for io and jo on the queue. */
/* This is done with a boolean. If boolean true is not 1 use if's. */
inc = (errio < errjo) + 1;
jnc = 3 - inc;
/* Put on both io and jo. If one is zero we will not use it. */
errs[iq + inc] = errio;
ixes[iq + inc] = io;
errs[iq + jnc] = errjo;
ixes[iq + jnc] = jo;
/* Decide how much to increment iq. Again we need boolean true == 1. */
iq = iq + (errs[iq + 2] != 0) + 1;
/* Remove parent sum contributions. Replace with child contributions. */
tm = rect[ma].alo;
rect[io].alo = rect[io].frl * rect[io].dx;
rect[jo].alo = rect[jo].frl * rect[jo].dx;
sl -= tm;
sl += rect[io].alo + rect[jo].alo;
tm = rect[ma].ahi;
rect[io].ahi = rect[io].flh * rect[io].dx;
rect[jo].ahi = rect[jo].flh * rect[jo].dx;
sh -= tm;
sh += rect[io].ahi + rect[jo].ahi;
}
if (it > iq)
*eflag = DISCRET;
else
*eflag = NOERROR;
return (sh - sl);
}
/******************************************************************************/
/* "HINT" -- Hierarchical INTegration. */
/* Copyright (C) 1994 by Iowa State University Research Foundation, Inc. */
/* */
/* Files needed for use: */
/* * hint.c ---- Driver source */
/* * hkernel.c ---- Kernel source */
/* * hint.h ---- General include file */
/* * typedefs.h ---- Include file for DSIZE and ISIZE */
/* * README ---- These are the rules. Follow them!!! */
/******************************************************************************/
/******************************************************************************/
/* Defines */
/******************************************************************************/
#define NOERROR 0 /* Self explanatory */
#define DISCRET 1 /* Error condition for out of discretization error */
#define NOMEM 2 /* Error for out of memory */
/******************************************************************************/
/* Type Defines */
/******************************************************************************/
#if defined(LDOUBLE)
#define DSIZE long double
#elif defined(DOUBLE)
#define DSIZE double
#define DSIZEF REAL*8
#elif defined(FLOAT)
#define DSIZE float
#define DSIZEF REAL*4
#elif defined(LONGLONG)
#define DSIZE long long
#define DSIZEF INTEGER*8
#elif defined(LONG)
#define DSIZE long
#define DSIZEF INTEGER*4
#elif defined(INT)
#define DSIZE int
#define DSIZEF INTEGER
#elif defined(SHORT)
#define DSIZE short
#define DSIZEF INTEGER*2
#elif defined(CHAR)
#define DSIZE char
#define DSIZEF INTEGER*1
#endif
#if defined(ILONGLONG)
#define ISIZE long long
#define ISIZEF INTEGER*8
#elif defined(ILONG)
#define ISIZE long
#define ISIZEF INTEGER*4
#elif defined(IINT)
#define ISIZE int
#define ISIZEF INTEGER
#endif