1994-06-24 11:31:16 +00:00
|
|
|
/* $Id$ */
|
1987-03-09 19:15:41 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1984-11-26 14:14:55 +00:00
|
|
|
/* I N L I N E S U B S T I T U T I O N
|
|
|
|
*
|
|
|
|
* I L 1 _ A U X . C
|
|
|
|
*/
|
|
|
|
|
2013-05-15 20:14:06 +00:00
|
|
|
#include <stdlib.h>
|
1991-03-05 12:44:05 +00:00
|
|
|
#include <em_spec.h>
|
1984-11-26 14:14:55 +00:00
|
|
|
#include "../share/types.h"
|
|
|
|
#include "il.h"
|
|
|
|
#include "../share/debug.h"
|
|
|
|
#include "../share/alloc.h"
|
|
|
|
#include "../share/global.h"
|
|
|
|
#include "../share/lset.h"
|
|
|
|
#include "il_aux.h"
|
|
|
|
#include "il1_aux.h"
|
|
|
|
|
|
|
|
#define USE_INDIR(p) (p->p_use->u_flags & UF_INDIR)
|
|
|
|
|
|
|
|
#define IS_INSTR(c) (c >= sp_fmnem && c <= sp_lmnem)
|
|
|
|
|
|
|
|
|
|
|
|
bool same_size(t1,t2)
|
|
|
|
int t1, t2;
|
|
|
|
{
|
|
|
|
/* See if the two types have the same size */
|
|
|
|
|
|
|
|
return tsize(t1) == tsize(t2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STATIC bool is_reg(off,s)
|
|
|
|
offset off;
|
|
|
|
int s;
|
|
|
|
{
|
|
|
|
/* See if there is a register message
|
|
|
|
* for the local or parameter at offset off
|
|
|
|
* and size s.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Lindex i;
|
|
|
|
arg_p arg;
|
|
|
|
|
|
|
|
for (i = Lfirst(mesregs); i != (Lindex) 0; i = Lnext(i,mesregs)) {
|
|
|
|
arg = ((line_p) Lelem(i))->l_a.la_arg->a_next;
|
|
|
|
if (arg->a_a.a_offset == off &&
|
|
|
|
arg->a_next->a_a.a_offset == s) {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-31 22:05:22 +00:00
|
|
|
void rem_actuals(acts)
|
1984-11-26 14:14:55 +00:00
|
|
|
actual_p acts;
|
|
|
|
{
|
|
|
|
/* remove the actual-list */
|
|
|
|
|
|
|
|
actual_p a,next;
|
|
|
|
|
|
|
|
for (a = acts; a != (actual_p) 0; a = next) {
|
|
|
|
next = a->ac_next;
|
|
|
|
/* REMOVE CODE OF a->ac_exp HERE */
|
|
|
|
oldactual(a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-10-31 22:05:22 +00:00
|
|
|
void remov_formals(p)
|
1984-11-26 14:14:55 +00:00
|
|
|
proc_p p;
|
|
|
|
{
|
|
|
|
/* Remove the list of formals of p */
|
|
|
|
|
|
|
|
formal_p f, next;
|
|
|
|
|
|
|
|
for (f = p->P_FORMALS; f != (formal_p) 0; f = next) {
|
|
|
|
next = f->f_next;
|
|
|
|
oldformal(f);
|
|
|
|
}
|
|
|
|
p->P_FORMALS = (formal_p) 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-11-10 21:04:18 +00:00
|
|
|
void
|
1984-11-26 14:14:55 +00:00
|
|
|
rem_indir_acc(p)
|
|
|
|
proc_p p;
|
|
|
|
{
|
|
|
|
/* Formals that may be accessed indirectly
|
|
|
|
* cannot be expanded in line, so they are
|
|
|
|
* removed from the formals list.
|
|
|
|
*/
|
|
|
|
|
|
|
|
formal_p prev, f, next;
|
|
|
|
|
|
|
|
if (!USE_INDIR(p) && !CHANGE_INDIR(p)) return;
|
|
|
|
/* Any formal for which we don't have
|
|
|
|
* a register message is now doomed.
|
|
|
|
*/
|
|
|
|
prev = (formal_p) 0;
|
|
|
|
for (f = p->P_FORMALS; f != (formal_p) 0; f = next) {
|
|
|
|
next = f->f_next;
|
|
|
|
if (!is_reg(f->f_offset,tsize(f->f_type))) {
|
|
|
|
if (prev == (formal_p) 0) {
|
|
|
|
p->P_FORMALS = next;
|
|
|
|
} else {
|
|
|
|
prev->f_next = next;
|
|
|
|
}
|
|
|
|
oldformal(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool par_overlap(off1,t1,off2,t2)
|
|
|
|
offset off1,off2;
|
|
|
|
int t1,t2;
|
|
|
|
{
|
|
|
|
/* See if the parameter at offset off1 and type t1
|
|
|
|
* overlaps the paramete at offset off2 and type t2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (off1 > off2) {
|
|
|
|
return off2 + tsize(t2) > off1;
|
|
|
|
} else {
|
|
|
|
if (off2 > off1) {
|
|
|
|
return off1 + tsize(t1) > off2;
|
|
|
|
} else {
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
short looplevel(b)
|
|
|
|
bblock_p b;
|
|
|
|
{
|
|
|
|
/* determine the loop nesting level of basic block b;
|
|
|
|
* this is the highest nesting level of all blocks
|
|
|
|
* that b is part of.
|
|
|
|
* Note that the level of a loop is 0 for outer loops,
|
|
|
|
* so a block inside a loop with nesting level N has
|
|
|
|
* looplevel N+1.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Lindex i;
|
|
|
|
short max = 0;
|
|
|
|
|
|
|
|
for (i = Lfirst(b->b_loops); i != (Lindex)0; i = Lnext(i,b->b_loops)) {
|
|
|
|
if (((loop_p) Lelem(i))->lp_level >= max) {
|
|
|
|
max = ((loop_p) Lelem(i))->lp_level + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1989-02-09 10:18:48 +00:00
|
|
|
int proclength(p)
|
1984-11-26 14:14:55 +00:00
|
|
|
proc_p p;
|
|
|
|
{
|
|
|
|
/* count the number of EM instructions of p */
|
|
|
|
|
1989-02-09 10:18:48 +00:00
|
|
|
register int cnt;
|
1984-11-26 14:14:55 +00:00
|
|
|
register bblock_p b;
|
|
|
|
register line_p l;
|
|
|
|
|
|
|
|
cnt = 0;
|
|
|
|
for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
|
|
|
|
for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
|
|
|
|
if (IS_INSTR(INSTR(l))) {
|
|
|
|
/* skip pseudo instructions */
|
|
|
|
cnt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
line_p copy_code(l1,l2)
|
|
|
|
line_p l1,l2;
|
|
|
|
{
|
|
|
|
/* copy the code between l1 and l2 */
|
|
|
|
|
|
|
|
line_p head, tail, l, lnp;
|
|
|
|
|
|
|
|
head = (line_p) 0;
|
|
|
|
for (lnp = l1; ; lnp = lnp->l_next) {
|
|
|
|
l = duplicate(lnp);
|
|
|
|
if (head == (line_p) 0) {
|
|
|
|
head = tail = l;
|
|
|
|
PREV(l) = (line_p) 0;
|
|
|
|
} else {
|
|
|
|
tail->l_next = l;
|
|
|
|
PREV(l) = tail;
|
|
|
|
tail = l;
|
|
|
|
}
|
|
|
|
if (lnp == l2) break;
|
|
|
|
}
|
|
|
|
return head;
|
|
|
|
}
|