ack/util/ego/sr/sr.c
George Koehler 17bc9cdef7 More void, fewer clang warnings in util/ego
Most warnings are for functions implicitly returning int.  Change most
of these functions to return void.  (Traditional K&R C had no void
type, but C89 has it.)

Add prototypes to most function declarations in headers.  This is
easy, because ego declares most of its extern functions, and the
comments listed most parameters.  There were a few outdated or missing
declarations, and a few .c files that failed to include an .h with the
declarations.

Add prototypes to a few function definitions in .c files.  Most
functions still have traditional K&R definitions.  Most STATIC
functions still don't have prototypes, because they have no earlier
declaration where I would have added the prototype.

Change some prototypes in util/ego/share/alloc.h.  Functions newmap()
and oldmap() handle an array of pointers to something; change the
array's type from `short **` to `void **`.  Callers use casts to go
between `void **` and the correct type, like `line_p *`.  Function
oldtable() takes a `short *`, not a `short **`; I added the wrong type
in 5bbbaf4.

Make a few other changes to silence warnings.  There are a few places
where clang wants extra parentheses in the code.

Edit util/ego/ra/build.lua to add the missing dependency on ra*.h; I
needed this to prevent crashes from ra.
2019-11-01 15:27:16 -04:00

244 lines
5 KiB
C

/* $Id$ */
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* S T R E N G T H R E D U C T I O N */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../share/types.h"
#include "sr.h"
#include "../share/debug.h"
#include "../share/global.h"
#include "../share/files.h"
#include "../share/get.h"
#include "../share/put.h"
#include "../share/lset.h"
#include "../share/map.h"
#include "../share/alloc.h"
#include "../share/go.h"
#include "../share/utils.h"
#include "sr_aux.h"
#include "sr_iv.h"
#include "sr_reduce.h"
/* Strength reduction tries to change expensive operators occurring
* in a loop into cheaper operators. The expensive operators considered
* are multiplication, left-shift and array referencing.
* The transformations can be expressed in C as:
*
* [1]: for (i = e1; i <= e2; i++)
* print(118*i);
* becomes:
* for (i = e1, t = 118*e1; i <= e2; i++, t += 118)
* print(t);
*
* [2]: for (i = e1; i <= e2; i++)
* print(a[i]);
* becomes:
* for (i = e1, p = &a[i]; i <= e2; i++, p++)
* print(*p);
* The latter optimization is suppressed if array bound checking
* is required.
*/
/* Machine and/or language dependent parameters: */
int ovfl_harmful;
int arrbound_harmful;
int sli_threshold;
int Ssr; /* #optimizations found */
void sr_machinit(void *vp)
{
/* Read target machine dependent information */
FILE *f = vp;
char s[100];
for (;;) {
while(getc(f) != '\n');
fscanf(f,"%99s",s);
if (strcmp(s,"%%SR") == 0)break;
}
fscanf(f,"%d",&ovfl_harmful);
fscanf(f,"%d",&arrbound_harmful);
fscanf(f,"%d",&sli_threshold);
}
STATIC void del_ivs(ivs)
lset ivs;
{
/* Delete the set of iv structs */
Lindex i;
for (i = Lfirst(ivs); i != (Lindex) 0; i = Lnext(i,ivs)) {
oldiv(Lelem(i));
}
Ldeleteset(ivs);
}
STATIC void do_loop(loop)
loop_p loop;
{
lset ivs, vars;
OUTTRACE("going to process loop %d",loop->lp_id);
induc_vars(loop,&ivs, &vars);
/* Build a set of iv_structs, one for every induction
* variable of the loop, i.e. a variable i that
* is changed only by i := i + c, where c is a loop constant.
* Also detects variables that are changed (including induction
* variables!).
*/
OUTTRACE("loop has %d induction variables",Lnrelems(ivs));
if (Lnrelems(ivs) > 0) {
strength_reduction(loop,ivs,vars);
/* Perform strength reduction. Reduce:
* iv * c to addition
* a[iv] to indirection (*p)
* (unless array bound checking is required)
*/
}
del_ivs(ivs);
Ldeleteset(vars);
}
STATIC void loopblocks(p)
proc_p p;
{
/* Compute the LP_BLOCKS sets for all loops of p */
register bblock_p b;
register Lindex i;
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
for (i = Lfirst(b->b_loops); i != (Lindex) 0;
i = Lnext(i,b->b_loops)) {
Ladd(b,&(((loop_p) Lelem(i))->LP_BLOCKS));
}
}
}
STATIC void opt_proc(p)
proc_p p;
{
/* Optimize all loops of one procedure. We first do all
* outer loops at the lowest nesting level and proceed
* in the inwards direction.
*/
Lindex i;
loop_p lp,outermost;
int min_level;
for (;;) {
min_level = 1000;
outermost = 0;
for (i = Lfirst(p->p_loops); i != (Lindex) 0;
i = Lnext(i,p->p_loops)) {
lp = (loop_p) Lelem(i);
if (!lp->LP_DONE && lp->lp_level < min_level) {
min_level = lp->lp_level;
outermost = lp;
}
}
if (! outermost) break;
do_loop(outermost);
outermost->LP_DONE = TRUE;
OUTTRACE("loop %d processed",outermost->lp_id);
}
}
STATIC bblock_p header(lp)
loop_p lp;
{
/* Try to determine the 'header' block of loop lp.
* If 'e' is the entry block of loop L, then block 'b' is
* called the header block of L, iff:
* SUCC(b) = {e} & b dominates e.
* If lp has no header block, 0 is returned.
*/
bblock_p x = lp->lp_entry->b_idom;
if (x != (bblock_p) 0 && Lnrelems(x->b_succ) == 1 &&
(bblock_p) Lelem(Lfirst(x->b_succ)) == lp->lp_entry) {
return x;
}
return (bblock_p) 0;
}
STATIC void sr_extproc(p)
proc_p p;
{
/* Allocate the extended data structures for procedure p */
register loop_p lp;
register Lindex pi;
for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
pi = Lnext(pi,p->p_loops)) {
lp = (loop_p) Lelem(pi);
lp->lp_extend = newsrlpx();
lp->LP_HEADER = header(lp);
if (lp->LP_HEADER) {
lp->LP_INSTR = last_instr(lp->LP_HEADER);
}
}
}
STATIC void sr_cleanproc(p)
proc_p p;
{
/* Remove the extended data structures for procedure p */
register loop_p lp;
register Lindex pi;
for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
pi = Lnext(pi,p->p_loops)) {
lp = (loop_p) Lelem(pi);
oldsrlpx(lp->lp_extend);
}
}
void sr_optimize(void *vp)
{
proc_p p = vp;
if (IS_ENTERED_WITH_GTO(p)) return;
sr_extproc(p);
loopblocks(p);
opt_proc(p);
sr_cleanproc(p);
}
int main(argc,argv)
int argc;
char *argv[];
{
go(argc,argv,no_action,sr_optimize,sr_machinit,no_action);
report("strength reductions",Ssr);
exit(0);
}