This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

egcs bug-report


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]