Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
a05beb9ceThis file is pinned to the selected release. Download the original to open it in your design tool.
/* $VER: vbcc (loop.c) V0.8 */
/* schleifenorientierte Optimierungen */
#include "opt.h"
static char FILE_[]=__FILE__;
#define MOVE_IC 1
#define MOVE_COMP 2
/* Liste, in die ICs eingetragen werden, die aus Schleifen */
/* gezogen werden sollen. */
struct movlist{
struct movlist *next;
struct IC *IC;
struct flowgraph *target_fg;
int flags;
};
struct movlist *first_mov,*last_mov;
int report_weird_code,report_suspicious_loops;
/* Bitvektoren fuer schleifeninvariante ICs */
bvtype *invariant,*inloop,*moved,*moved_completely;
bvtype *fg_tmp;
bvtype *not_movable;
size_t bsize;
/* Liste, in die ICs fuer strength-reduction eingetragen */
/* werden. */
struct srlist{
struct srlist *next;
struct IC *ind_var;
struct IC *IC;
struct flowgraph *target_fg;
/* Hilfsvariable, falls eine aequivalente Operation schon reduziert */
/* wurde. */
struct Var *hv;
};
struct srlist *first_sr,*last_sr;
/* Liste, in die Daten fuer loop-unrolling eingetragen werden. */
struct urlist{
int flags;
long total,unroll;
struct IC *cmp,*branch,*ind;
struct flowgraph *start,*head;
struct urlist *next;
} *first_ur;
#define UNROLL_COMPLETELY 1
#define UNROLL_MODULO 2
#define UNROLL_INVARIANT 4
#define UNROLL_REVERSE 8
#define IND_ONLY_COUNTS 16
#define MULTIPLE_EXITS 32
/* Hier werden Induktionsvariablen vermerkt */
struct IC **ind_vars;
static struct flowgraph *first_fg;
void calc_movable(struct flowgraph *start,struct flowgraph *end)
/* Berechnet, welche Definitionen nicht aus der Schleife start-end */
/* verschoben werden duerfen. Eine Def. p von z darf nur verschoben */
/* werden, wenn keine andere Def. von p existiert und alle */
/* Verwendungen von z nur von p erreicht werden. */
/* Benutzt rd_defs. */
{
struct flowgraph *g;struct IC *p;
int i,j,k,d;
bvtype *changed_vars;
if(DEBUG&1024) printf("calculating not_movable for blocks %d to %d\n",start->index,end->index);
if(0/*!(optflags&1024)*/){
memset(not_movable,UCHAR_MAX,dsize);
return;
}
memset(not_movable,0,dsize);
changed_vars=mymalloc(vsize);
memset(changed_vars,0,vsize);
for(i=0;i<vcount-rcount;i++){
if(vilist[i]->vtyp->flags&VOLATILE) BSET(changed_vars,i);
if(i<rcount){
if(!vilist[i]->vtyp->next||(vilist[i]->vtyp->next->flags&VOLATILE)) BSET(changed_vars,i+vcount-rcount);
}
}
for(g=start;g;g=g->normalout){
if(!g->rd_in) ierror(0);
memcpy(rd_defs,g->rd_in,dsize);
for(p=g->start;p;p=p->next){
for(j=0;j<p->change_cnt;j++){
i=p->change_list[j].v->index;
if(p->change_list[j].flags&DREFOBJ) i+=vcount-rcount;
if(i>=vcount) continue;
if(BTST(changed_vars,i)||(q1typ(p)&VOLATILE)||(q2typ(p)&VOLATILE)||(ztyp(p)&VOLATILE)){
bvunite(not_movable,var_defs[i],dsize);
}else{
BSET(changed_vars,i);
}
}
for(k=0;k<p->use_cnt;k++){
i=p->use_list[k].v->index;
if(p->use_list[k].flags&DREFOBJ) i+=vcount-rcount;
if(i>=vcount) continue;
for(d=-1,j=1;j<=dcount;j++){
if(BTST(rd_defs,j)&&BTST(var_defs[i],j)){
if(d>=0){ /* mehr als eine Def. */
bvunite(not_movable,var_defs[i],dsize);
d=-1;break;
}else d=j;
}
if(BTST(rd_defs,UNDEF(j))&&BTST(var_defs[i],UNDEF(j))){
bvunite(not_movable,var_defs[i],dsize);
d=-1;break;
}
}
}
/* Das hier, um rd_defs zu aktualisieren. */
rd_change(p);
if(p==g->end) break;
}
if(g==end) break;
}
free(changed_vars);
}