blob: 975ff3d99143a5541b2e394a44ed85207ce3eb52 [file] [log] [blame]
PulkoMandy17fc7592022-07-28 18:27:54 +02001/* $VER: vbcc (loop.c) V0.8 */
2/* schleifenorientierte Optimierungen */
3
4#include "opt.h"
5
6static char FILE_[]=__FILE__;
7
8#define MOVE_IC 1
9#define MOVE_COMP 2
10
11/* Liste, in die ICs eingetragen werden, die aus Schleifen */
12/* gezogen werden sollen. */
13struct movlist{
14 struct movlist *next;
15 struct IC *IC;
16 struct flowgraph *target_fg;
17 int flags;
18};
19
20struct movlist *first_mov,*last_mov;
21
22int report_weird_code,report_suspicious_loops;
23
24/* Bitvektoren fuer schleifeninvariante ICs */
25bvtype *invariant,*inloop,*moved,*moved_completely;
26bvtype *fg_tmp;
27bvtype *not_movable;
28size_t bsize;
29
30
31/* Liste, in die ICs fuer strength-reduction eingetragen */
32/* werden. */
33struct srlist{
34 struct srlist *next;
35 struct IC *ind_var;
36 struct IC *IC;
37 struct flowgraph *target_fg;
38 /* Hilfsvariable, falls eine aequivalente Operation schon reduziert */
39 /* wurde. */
40 struct Var *hv;
41};
42
43struct srlist *first_sr,*last_sr;
44
45/* Liste, in die Daten fuer loop-unrolling eingetragen werden. */
46struct urlist{
47 int flags;
48 long total,unroll;
49 struct IC *cmp,*branch,*ind;
50 struct flowgraph *start,*head;
51 struct urlist *next;
52} *first_ur;
53
54#define UNROLL_COMPLETELY 1
55#define UNROLL_MODULO 2
56#define UNROLL_INVARIANT 4
57#define UNROLL_REVERSE 8
58#define IND_ONLY_COUNTS 16
59#define MULTIPLE_EXITS 32
60
61/* Hier werden Induktionsvariablen vermerkt */
62struct IC **ind_vars;
63
64static struct flowgraph *first_fg;
65
66
67void calc_movable(struct flowgraph *start,struct flowgraph *end)
68/* Berechnet, welche Definitionen nicht aus der Schleife start-end */
69/* verschoben werden duerfen. Eine Def. p von z darf nur verschoben */
70/* werden, wenn keine andere Def. von p existiert und alle */
71/* Verwendungen von z nur von p erreicht werden. */
72/* Benutzt rd_defs. */
73{
74 struct flowgraph *g;struct IC *p;
75 int i,j,k,d;
76 bvtype *changed_vars;
77 if(DEBUG&1024) printf("calculating not_movable for blocks %d to %d\n",start->index,end->index);
78 if(0/*!(optflags&1024)*/){
79 memset(not_movable,UCHAR_MAX,dsize);
80 return;
81 }
82 memset(not_movable,0,dsize);
83 changed_vars=mymalloc(vsize);
84 memset(changed_vars,0,vsize);
85 for(i=0;i<vcount-rcount;i++){
86 if(vilist[i]->vtyp->flags&VOLATILE) BSET(changed_vars,i);
87 if(i<rcount){
88 if(!vilist[i]->vtyp->next||(vilist[i]->vtyp->next->flags&VOLATILE)) BSET(changed_vars,i+vcount-rcount);
89 }
90 }
91 for(g=start;g;g=g->normalout){
92 if(!g->rd_in) ierror(0);
93 memcpy(rd_defs,g->rd_in,dsize);
94 for(p=g->start;p;p=p->next){
95 for(j=0;j<p->change_cnt;j++){
96 i=p->change_list[j].v->index;
97 if(p->change_list[j].flags&DREFOBJ) i+=vcount-rcount;
98 if(i>=vcount) continue;
99 if(BTST(changed_vars,i)||(q1typ(p)&VOLATILE)||(q2typ(p)&VOLATILE)||(ztyp(p)&VOLATILE)){
100 bvunite(not_movable,var_defs[i],dsize);
101 }else{
102 BSET(changed_vars,i);
103 }
104 }
105 for(k=0;k<p->use_cnt;k++){
106 i=p->use_list[k].v->index;
107 if(p->use_list[k].flags&DREFOBJ) i+=vcount-rcount;
108 if(i>=vcount) continue;
109 for(d=-1,j=1;j<=dcount;j++){
110 if(BTST(rd_defs,j)&&BTST(var_defs[i],j)){
111 if(d>=0){ /* mehr als eine Def. */
112 bvunite(not_movable,var_defs[i],dsize);
113 d=-1;break;
114 }else d=j;
115 }
116 if(BTST(rd_defs,UNDEF(j))&&BTST(var_defs[i],UNDEF(j))){
117 bvunite(not_movable,var_defs[i],dsize);
118 d=-1;break;
119 }
120 }
121 }
122 /* Das hier, um rd_defs zu aktualisieren. */
123 rd_change(p);
124 if(p==g->end) break;
125 }
126 if(g==end) break;
127 }
128 free(changed_vars);
129}
130