17bc9cdef7
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.
204 lines
4.2 KiB
C
204 lines
4.2 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
|
|
*
|
|
* S R _ E X P R . C
|
|
*
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <em_mnem.h>
|
|
#include "../share/types.h"
|
|
#include "sr.h"
|
|
#include "../share/debug.h"
|
|
#include "../share/global.h"
|
|
#include "../share/utils.h"
|
|
#include "sr_aux.h"
|
|
#include "../share/lset.h"
|
|
#include "sr_iv.h"
|
|
|
|
|
|
|
|
#define ME_NONE 0
|
|
#define ME_UNAIR 1
|
|
#define ME_BINAIR 2
|
|
#define ME_LOOPCONST 3
|
|
#define ME_IV 4
|
|
|
|
|
|
|
|
STATIC iv_p last_iv;
|
|
STATIC int iv_sign;
|
|
STATIC lset ivars, loopvars;
|
|
|
|
STATIC bool is_loadiv(lnp)
|
|
line_p lnp;
|
|
{
|
|
/* See if lnp is a LOL iv instruction, where iv is an
|
|
* induction variable of the set ivars. If so, set the
|
|
* the global variable last_iv to its descriptor.
|
|
*/
|
|
|
|
Lindex i;
|
|
iv_p iv;
|
|
offset off;
|
|
|
|
if (INSTR(lnp) == op_lol) {
|
|
off = off_set(lnp);
|
|
for (i = Lfirst(ivars); i != (Lindex) 0; i = Lnext(i,ivars)) {
|
|
iv = (iv_p) Lelem(i);
|
|
if (iv->iv_off == off) {
|
|
last_iv = iv;
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
#define size_ok(l) (TYPE(l) == OPSHORT && SHORT(l) == ws)
|
|
|
|
|
|
STATIC int me_kind(l,sign_in,sign_out)
|
|
line_p l;
|
|
int sign_in, *sign_out;
|
|
{
|
|
if (l != (line_p) 0) {
|
|
switch(INSTR(l)) {
|
|
case op_adi:
|
|
case op_adu:
|
|
if (size_ok(l)) {
|
|
*sign_out = sign_in;
|
|
return ME_BINAIR;
|
|
}
|
|
break;
|
|
case op_sbi:
|
|
case op_sbu:
|
|
if (size_ok(l)) {
|
|
*sign_out = - sign_in;
|
|
return ME_BINAIR;
|
|
}
|
|
break;
|
|
case op_ngi:
|
|
if (size_ok(l)) {
|
|
*sign_out = - sign_in;
|
|
return ME_UNAIR;
|
|
}
|
|
break;
|
|
case op_inc:
|
|
case op_dec:
|
|
*sign_out = sign_in;
|
|
return ME_UNAIR;
|
|
case op_loc:
|
|
return ME_LOOPCONST;
|
|
case op_lol:
|
|
if (is_loadiv(l)) {
|
|
iv_sign = sign_in;
|
|
return ME_IV;
|
|
}
|
|
if (is_loopconst(l,loopvars)) return ME_LOOPCONST;
|
|
}
|
|
}
|
|
return ME_NONE;
|
|
}
|
|
|
|
|
|
|
|
STATIC bool
|
|
match_expr(line_p l, bool iv_allowed, line_p *lbegin, bool *iv_seen,
|
|
int sign)
|
|
{
|
|
/* This routine is a top down parser for simple
|
|
* EM expressions. It recognizes expressions that
|
|
* have as operators + and - (unary - is also allowed)
|
|
* and that have as operands a number of loop constants
|
|
* (either a constant or a variable that is not
|
|
* changed within the loop) and at most one induction
|
|
* variable.
|
|
* The parameter iv_allowed is propagated downwards
|
|
* in the expression tree, indicating whether the
|
|
* subexpression may use an induction variable as
|
|
* operand. The parameter iv_seen is propagated
|
|
* upwards, indicating if the subexpression has used
|
|
* an induction variable. The parameter sign is
|
|
* propagated downwards; it indicates the sign of
|
|
* the subexpression. lbegin will point to the
|
|
* beginning of the recognized subexpression
|
|
* (it is an out parameter). Note that we scan the
|
|
* EM text from right to left (i.e. top down).
|
|
*/
|
|
|
|
line_p l1;
|
|
bool iv_insubexpr;
|
|
int sign2;
|
|
|
|
switch(me_kind(l,sign,&sign2)) {
|
|
case ME_UNAIR:
|
|
/* unairy operator, match one subexpression */
|
|
if (match_expr(PREV(l),iv_allowed,&l1,&iv_insubexpr,sign2)) {
|
|
*lbegin = l1;
|
|
*iv_seen = iv_insubexpr;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
case ME_BINAIR:
|
|
/* binairy operator, match two subexpressions */
|
|
if (match_expr(PREV(l), iv_allowed, &l1, &iv_insubexpr,sign2)) {
|
|
l = PREV(l1);
|
|
iv_allowed = iv_allowed && !iv_insubexpr;
|
|
if (match_expr(l,iv_allowed,&l1,
|
|
&iv_insubexpr,sign)) {
|
|
*lbegin = l1;
|
|
*iv_seen = !iv_allowed || iv_insubexpr;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE; /* subexpression not recognized */
|
|
case ME_LOOPCONST:
|
|
*lbegin = l; /* expression is a loop constant */
|
|
*iv_seen = FALSE;
|
|
return TRUE;
|
|
case ME_IV:
|
|
if (iv_allowed) {
|
|
*iv_seen = TRUE;
|
|
*lbegin = l;
|
|
return TRUE;
|
|
}
|
|
/* fall through ... */
|
|
default:
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
bool is_ivexpr(l,ivs,vars,lbegin_out,iv_out,sign_out)
|
|
line_p l, *lbegin_out;
|
|
lset ivs,vars;
|
|
iv_p *iv_out;
|
|
int *sign_out;
|
|
{
|
|
line_p l2;
|
|
bool iv_seen;
|
|
|
|
|
|
loopvars = vars;
|
|
ivars = ivs;
|
|
if (match_expr(l,TRUE,&l2,&iv_seen,1)) {
|
|
if (iv_seen) {
|
|
/* recognized a correct expression */
|
|
*lbegin_out = l2;
|
|
*iv_out = last_iv;
|
|
*sign_out = iv_sign;
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|