ack/util/ego/sr/sr_xform.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

196 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 _ X F O R M . C
*
*/
#include <stdio.h>
#include <em_mnem.h>
#include <em_pseu.h>
#include <em_spec.h>
#include "../share/types.h"
#include "sr.h"
#include "../share/debug.h"
#include "../share/global.h"
#include "../share/alloc.h"
#include "../share/def.h"
#include "../share/get.h"
#include "sr_aux.h"
#include "../share/lset.h"
#include "../share/utils.h"
#include "sr_xform.h"
/* Transformations on EM texts */
line_p move_pointer(tmp,dir)
offset tmp;
int dir;
{
/* Generate EM code to load/store a pointer variable
* onto/from the stack, depending on dir(ection).
* We accept all kinds of pointer sizes.
*/
line_p l;
l = int_line(tmp);
if (ps == ws) {
/* pointer fits in a word */
l->l_instr = (dir == LOAD ? op_lol : op_stl);
} else {
if (ps == 2 * ws) {
/* pointer fits in a double word */
l->l_instr = (dir == LOAD ? op_ldl : op_sdl);
} else {
/* very large pointer size, generate code:
* LAL tmp ; LOI/STI ps */
l->l_instr = op_lal;
l->l_next = newline(OPSHORT);
SHORT(l->l_next) = ps;
l->l_next->l_instr =
(dir == LOAD ? op_loi : op_sti);
PREV(l->l_next) = l;
}
}
return l;
}
/* make_header */
STATIC void copy_loops(b1,b2,except)
bblock_p b1,b2;
loop_p except;
{
/* Copy the loopset of b2 to b1, except for 'except' */
Lindex i;
loop_p lp;
for (i = Lfirst(b2->b_loops); i != (Lindex) 0;
i = Lnext(i,b2->b_loops)) {
lp = (loop_p) Lelem(i);
if (lp != except) {
Ladd(lp,&b1->b_loops);
}
}
}
STATIC lab_id label(b)
bblock_p b;
{
/* Find the label at the head of block b. If there is
* no such label yet, create one.
*/
line_p l;
if (b->b_start && INSTR(b->b_start) == op_lab) {
return INSTRLAB(b->b_start);
}
/* The block has no label yet. */
l = newline(OPINSTRLAB);
l->l_instr = op_lab;
INSTRLAB(l) = freshlabel();
if (b->b_start) {
DLINK(l,b->b_start); /* doubly link them */
}
b->b_start = l;
return INSTRLAB(l);
}
STATIC void adjust_jump(newtarg,oldtarg,c)
bblock_p newtarg,oldtarg,c;
{
/* If the last instruction of c is a jump to the
* old target, then change it into a jump to the
* start of the new target.
*/
line_p l = last_instr(c);
assert(l != (line_p) 0);
if (INSTR(oldtarg->b_start) == op_lab) {
/* If old target has no label, it cannot be jumped to */
if (TYPE(l) == OPINSTRLAB &&
INSTRLAB(l) == INSTRLAB(oldtarg->b_start)) {
INSTRLAB(l) = label(newtarg);
}
}
if (c->b_next == oldtarg && INSTR(l) != op_bra) {
line_p new = newline(OPINSTRLAB);
INSTRLAB(new) = label(newtarg);
new->l_instr = op_bra;
DLINK(l, new);
}
}
void
make_header(lp)
loop_p lp;
{
/* Make sure that the loop has a header block, i.e. a block
* has the loop entry block as its only successor and
* that dominates the loop entry block.
* If there is no header yet, create one.
*/
bblock_p b,c,entry;
Lindex i,next;
if (lp->LP_HEADER != (bblock_p) 0) return;
OUTTRACE("creating a new header block",0);
/* The loop has no header yet. The main problem is to
* keep all relations (SUCC, PRED, NEXT, IDOM, LOOPS)
* up to date.
*/
b = freshblock(); /* new block with new b_id */
entry = lp->lp_entry;
/* update succ/pred. Also take care that any jump from outside
* the loop to the entry block now goes to b.
*/
b->b_succ = Lempty_set();
b->b_pred = Lempty_set();
for (i = Lfirst(entry->b_pred); i != (Lindex) 0; i = next ) {
next = Lnext(i,entry->b_pred);
c = (bblock_p) Lelem(i);
/* c is a predecessor of the entry block */
if (!Lis_elem(c,lp->LP_BLOCKS)) {
/* c is outside the loop */
Lremove(c,&entry->b_pred);
Lremove(entry,&c->b_succ);
Ladd(b,&c->b_succ);
Ladd(c,&b->b_pred);
adjust_jump(b,entry,c);
}
}
assert(lp->LP_INSTR == 0);
lp->LP_INSTR = b->b_start;
Ladd(b,&entry->b_pred);
Ladd(entry,&b->b_succ);
/* put header block at end of procedure */
for (c = curproc->p_start; c->b_next != 0; c = c->b_next);
c->b_next = b;
/* b->b_next = 0; */
copy_loops(b,entry,lp);
b->b_idom = entry->b_idom;
entry->b_idom = b;
lp->LP_HEADER = b;
}