Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "gc.h"
2
 
3
void
4
peep(void)
5
{
6
	Reg *r, *r1, *r2;
7
	Prog *p, *p1;
8
	int t;
9
/*
10
 * complete R structure
11
 */
12
	t = 0;
13
	for(r=firstr; r!=R; r=r1) {
14
		r1 = r->link;
15
		if(r1 == R)
16
			break;
17
		p = r->prog->link;
18
		while(p != r1->prog)
19
		switch(p->as) {
20
		default:
21
			r2 = rega();
22
			r->link = r2;
23
			r2->link = r1;
24
 
25
			r2->prog = p;
26
			r2->p1 = r;
27
			r->s1 = r2;
28
			r2->s1 = r1;
29
			r1->p1 = r2;
30
 
31
			r = r2;
32
			t++;
33
 
34
		case ADATA:
35
		case AGLOBL:
36
		case ANAME:
37
		case ASIGNAME:
38
			p = p->link;
39
		}
40
	}
41
 
42
loop1:
43
	t = 0;
44
	for(r=firstr; r!=R; r=r->link) {
45
		p = r->prog;
46
		if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD)
47
		if(regtyp(&p->to)) {
48
			if(regtyp(&p->from))
49
			if(p->from.type == p->to.type) {
50
				if(copyprop(r)) {
51
					excise(r);
52
					t++;
53
				} else
54
				if(subprop(r) && copyprop(r)) {
55
					excise(r);
56
					t++;
57
				}
58
			}
59
			if(regzer(&p->from))
60
			if(p->to.type == D_REG) {
61
				p->from.type = D_REG;
62
				p->from.reg = 0;
63
				if(copyprop(r)) {
64
					excise(r);
65
					t++;
66
				} else
67
				if(subprop(r) && copyprop(r)) {
68
					excise(r);
69
					t++;
70
				}
71
			}
72
		}
73
	}
74
	if(t)
75
		goto loop1;
76
	/*
77
	 * look for MOVB x,R; MOVB R,R
78
	 */
79
	for(r=firstr; r!=R; r=r->link) {
80
		p = r->prog;
81
		switch(p->as) {
82
		default:
83
			continue;
84
		case AMOVH:
85
		case AMOVHU:
86
		case AMOVB:
87
		case AMOVBU:
88
			if(p->to.type != D_REG)
89
				continue;
90
			break;
91
		}
92
		r1 = r->link;
93
		if(r1 == R)
94
			continue;
95
		p1 = r1->prog;
96
		if(p1->as != p->as)
97
			continue;
98
		if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
99
			continue;
100
		if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
101
			continue;
102
		excise(r1);
103
	}
104
}
105
 
106
void
107
excise(Reg *r)
108
{
109
	Prog *p;
110
 
111
	p = r->prog;
112
	p->as = ANOP;
113
	p->from = zprog.from;
114
	p->to = zprog.to;
115
	p->reg = zprog.reg; /**/
116
}
117
 
118
Reg*
119
uniqp(Reg *r)
120
{
121
	Reg *r1;
122
 
123
	r1 = r->p1;
124
	if(r1 == R) {
125
		r1 = r->p2;
126
		if(r1 == R || r1->p2link != R)
127
			return R;
128
	} else
129
		if(r->p2 != R)
130
			return R;
131
	return r1;
132
}
133
 
134
Reg*
135
uniqs(Reg *r)
136
{
137
	Reg *r1;
138
 
139
	r1 = r->s1;
140
	if(r1 == R) {
141
		r1 = r->s2;
142
		if(r1 == R)
143
			return R;
144
	} else
145
		if(r->s2 != R)
146
			return R;
147
	return r1;
148
}
149
 
150
int
151
regzer(Adr *a)
152
{
153
 
154
	if(a->type == D_CONST)
155
		if(a->sym == S)
156
			if(a->offset == 0)
157
				return 1;
158
	if(a->type == D_REG)
159
		if(a->reg == 0)
160
			return 1;
161
	return 0;
162
}
163
 
164
int
165
regtyp(Adr *a)
166
{
167
 
168
	if(a->type == D_REG) {
169
		if(a->reg != 0)
170
			return 1;
171
		return 0;
172
	}
173
	if(a->type == D_FREG)
174
		return 1;
175
	return 0;
176
}
177
 
178
/*
179
 * the idea is to substitute
180
 * one register for another
181
 * from one MOV to another
182
 *	MOV	a, R0
183
 *	ADD	b, R0	/ no use of R1
184
 *	MOV	R0, R1
185
 * would be converted to
186
 *	MOV	a, R1
187
 *	ADD	b, R1
188
 *	MOV	R1, R0
189
 * hopefully, then the former or latter MOV
190
 * will be eliminated by copy propagation.
191
 */
192
int
193
subprop(Reg *r0)
194
{
195
	Prog *p;
196
	Adr *v1, *v2;
197
	Reg *r;
198
	int t;
199
 
200
	p = r0->prog;
201
	v1 = &p->from;
202
	if(!regtyp(v1))
203
		return 0;
204
	v2 = &p->to;
205
	if(!regtyp(v2))
206
		return 0;
207
	for(r=uniqp(r0); r!=R; r=uniqp(r)) {
208
		if(uniqs(r) == R)
209
			break;
210
		p = r->prog;
211
		switch(p->as) {
212
		case AJAL:
213
			return 0;
214
 
215
		case ASGT:
216
		case ASGTU:
217
 
218
		case AADD:
219
		case AADDU:
220
		case ASUB:
221
		case ASUBU:
222
		case ASLL:
223
		case ASRL:
224
		case ASRA:
225
		case AOR:
226
		case AAND:
227
		case AXOR:
228
		case AMUL:
229
		case AMULU:
230
		case ADIV:
231
		case ADIVU:
232
 
233
		case AADDD:
234
		case AADDF:
235
		case ASUBD:
236
		case ASUBF:
237
		case AMULD:
238
		case AMULF:
239
		case ADIVD:
240
		case ADIVF:
241
			if(p->to.type == v1->type)
242
			if(p->to.reg == v1->reg) {
243
				if(p->reg == NREG)
244
					p->reg = p->to.reg;
245
				goto gotit;
246
			}
247
			break;
248
 
249
		case AMOVF:
250
		case AMOVD:
251
		case AMOVW:
252
			if(p->to.type == v1->type)
253
			if(p->to.reg == v1->reg)
254
				goto gotit;
255
			break;
256
		}
257
		if(copyau(&p->from, v2) ||
258
		   copyau1(p, v2) ||
259
		   copyau(&p->to, v2))
260
			break;
261
		if(copysub(&p->from, v1, v2, 0) ||
262
		   copysub1(p, v1, v2, 0) ||
263
		   copysub(&p->to, v1, v2, 0))
264
			break;
265
	}
266
	return 0;
267
 
268
gotit:
269
	copysub(&p->to, v1, v2, 1);
270
	if(debug['P']) {
271
		print("gotit: %D->%D\n%P", v1, v2, r->prog);
272
		if(p->from.type == v2->type)
273
			print(" excise");
274
		print("\n");
275
	}
276
	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
277
		p = r->prog;
278
		copysub(&p->from, v1, v2, 1);
279
		copysub1(p, v1, v2, 1);
280
		copysub(&p->to, v1, v2, 1);
281
		if(debug['P'])
282
			print("%P\n", r->prog);
283
	}
284
	t = v1->reg;
285
	v1->reg = v2->reg;
286
	v2->reg = t;
287
	if(debug['P'])
288
		print("%P last\n", r->prog);
289
	return 1;
290
}
291
 
292
/*
293
 * The idea is to remove redundant copies.
294
 *	v1->v2	F=0
295
 *	(use v2	s/v2/v1/)*
296
 *	set v1	F=1
297
 *	use v2	return fail
298
 *	-----------------
299
 *	v1->v2	F=0
300
 *	(use v2	s/v2/v1/)*
301
 *	set v1	F=1
302
 *	set v2	return success
303
 */
304
int
305
copyprop(Reg *r0)
306
{
307
	Prog *p;
308
	Adr *v1, *v2;
309
	Reg *r;
310
 
311
	p = r0->prog;
312
	v1 = &p->from;
313
	v2 = &p->to;
314
	if(copyas(v1, v2))
315
		return 1;
316
	for(r=firstr; r!=R; r=r->link)
317
		r->active = 0;
318
	return copy1(v1, v2, r0->s1, 0);
319
}
320
 
321
int
322
copy1(Adr *v1, Adr *v2, Reg *r, int f)
323
{
324
	int t;
325
	Prog *p;
326
 
327
	if(r->active) {
328
		if(debug['P'])
329
			print("act set; return 1\n");
330
		return 1;
331
	}
332
	r->active = 1;
333
	if(debug['P'])
334
		print("copy %D->%D f=%d\n", v1, v2, f);
335
	for(; r != R; r = r->s1) {
336
		p = r->prog;
337
		if(debug['P'])
338
			print("%P", p);
339
		if(!f && uniqp(r) == R) {
340
			f = 1;
341
			if(debug['P'])
342
				print("; merge; f=%d", f);
343
		}
344
		t = copyu(p, v2, A);
345
		switch(t) {
346
		case 2:	/* rar, cant split */
347
			if(debug['P'])
348
				print("; %Drar; return 0\n", v2);
349
			return 0;
350
 
351
		case 3:	/* set */
352
			if(debug['P'])
353
				print("; %Dset; return 1\n", v2);
354
			return 1;
355
 
356
		case 1:	/* used, substitute */
357
		case 4:	/* use and set */
358
			if(f) {
359
				if(!debug['P'])
360
					return 0;
361
				if(t == 4)
362
					print("; %Dused+set and f=%d; return 0\n", v2, f);
363
				else
364
					print("; %Dused and f=%d; return 0\n", v2, f);
365
				return 0;
366
			}
367
			if(copyu(p, v2, v1)) {
368
				if(debug['P'])
369
					print("; sub fail; return 0\n");
370
				return 0;
371
			}
372
			if(debug['P'])
373
				print("; sub%D/%D", v2, v1);
374
			if(t == 4) {
375
				if(debug['P'])
376
					print("; %Dused+set; return 1\n", v2);
377
				return 1;
378
			}
379
			break;
380
		}
381
		if(!f) {
382
			t = copyu(p, v1, A);
383
			if(!f && (t == 2 || t == 3 || t == 4)) {
384
				f = 1;
385
				if(debug['P'])
386
					print("; %Dset and !f; f=%d", v1, f);
387
			}
388
		}
389
		if(debug['P'])
390
			print("\n");
391
		if(r->s2)
392
			if(!copy1(v1, v2, r->s2, f))
393
				return 0;
394
	}
395
	return 1;
396
}
397
 
398
/*
399
 * return
400
 * 1 if v only used (and substitute),
401
 * 2 if read-alter-rewrite
402
 * 3 if set
403
 * 4 if set and used
404
 * 0 otherwise (not touched)
405
 */
406
copyu(Prog *p, Adr *v, Adr *s)
407
{
408
 
409
	switch(p->as) {
410
 
411
	default:
412
		if(debug['P'])
413
			print(" (???)");
414
		return 2;
415
 
416
 
417
	case ANOP:	/* read, write */
418
	case AMOVW:
419
	case AMOVF:
420
	case AMOVD:
421
	case AMOVH:
422
	case AMOVHU:
423
	case AMOVB:
424
	case AMOVBU:
425
	case AMOVDW:
426
	case AMOVWD:
427
	case AMOVFD:
428
	case AMOVDF:
429
		if(s != A) {
430
			if(copysub(&p->from, v, s, 1))
431
				return 1;
432
			if(!copyas(&p->to, v))
433
				if(copysub(&p->to, v, s, 1))
434
					return 1;
435
			return 0;
436
		}
437
		if(copyas(&p->to, v)) {
438
			if(copyau(&p->from, v))
439
				return 4;
440
			return 3;
441
		}
442
		if(copyau(&p->from, v))
443
			return 1;
444
		if(copyau(&p->to, v))
445
			return 1;
446
		return 0;
447
 
448
	case ASGT:	/* read, read, write */
449
	case ASGTU:
450
 
451
	case AADD:
452
	case AADDU:
453
	case ASUB:
454
	case ASUBU:
455
	case ASLL:
456
	case ASRL:
457
	case ASRA:
458
	case AOR:
459
	case ANOR:
460
	case AAND:
461
	case AXOR:
462
	case AMUL:
463
	case AMULU:
464
	case ADIV:
465
	case ADIVU:
466
 
467
	case AADDF:
468
	case AADDD:
469
	case ASUBF:
470
	case ASUBD:
471
	case AMULF:
472
	case AMULD:
473
	case ADIVF:
474
	case ADIVD:
475
		if(s != A) {
476
			if(copysub(&p->from, v, s, 1))
477
				return 1;
478
			if(copysub1(p, v, s, 1))
479
				return 1;
480
			if(!copyas(&p->to, v))
481
				if(copysub(&p->to, v, s, 1))
482
					return 1;
483
			return 0;
484
		}
485
		if(copyas(&p->to, v)) {
486
			if(p->reg == NREG)
487
				p->reg = p->to.reg;
488
			if(copyau(&p->from, v))
489
				return 4;
490
			if(copyau1(p, v))
491
				return 4;
492
			return 3;
493
		}
494
		if(copyau(&p->from, v))
495
			return 1;
496
		if(copyau1(p, v))
497
			return 1;
498
		if(copyau(&p->to, v))
499
			return 1;
500
		return 0;
501
 
502
	case ABEQ:	/* read, read */
503
	case ABNE:
504
	case ABGTZ:
505
	case ABGEZ:
506
	case ABLTZ:
507
	case ABLEZ:
508
 
509
	case ACMPEQD:
510
	case ACMPEQF:
511
	case ACMPGED:
512
	case ACMPGEF:
513
	case ACMPGTD:
514
	case ACMPGTF:
515
	case ABFPF:
516
	case ABFPT:
517
		if(s != A) {
518
			if(copysub(&p->from, v, s, 1))
519
				return 1;
520
			return copysub1(p, v, s, 1);
521
		}
522
		if(copyau(&p->from, v))
523
			return 1;
524
		if(copyau1(p, v))
525
			return 1;
526
		return 0;
527
 
528
	case AJMP:	/* funny */
529
		if(s != A) {
530
			if(copysub(&p->to, v, s, 1))
531
				return 1;
532
			return 0;
533
		}
534
		if(copyau(&p->to, v))
535
			return 1;
536
		return 0;
537
 
538
	case ARET:	/* funny */
539
		if(v->type == D_REG)
540
		if(v->reg == REGRET)
541
			return 2;
542
		if(v->type == D_FREG)
543
		if(v->reg == FREGRET)
544
			return 2;
545
 
546
	case AJAL:	/* funny */
547
		if(v->type == D_REG) {
548
			if(v->reg <= REGEXT && v->reg > exregoffset)
549
				return 2;
550
			if(REGARG && v->reg == REGARG)
551
				return 2;
552
		}
553
		if(v->type == D_FREG)
554
			if(v->reg <= FREGEXT && v->reg > exfregoffset)
555
				return 2;
556
 
557
		if(s != A) {
558
			if(copysub(&p->to, v, s, 1))
559
				return 1;
560
			return 0;
561
		}
562
		if(copyau(&p->to, v))
563
			return 4;
564
		return 3;
565
 
566
	case ATEXT:	/* funny */
567
		if(v->type == D_REG)
568
			if(v->reg == REGARG)
569
				return 3;
570
		return 0;
571
	}
572
}
573
 
574
int
575
a2type(Prog *p)
576
{
577
 
578
	switch(p->as) {
579
	case ABEQ:
580
	case ABNE:
581
	case ABGTZ:
582
	case ABGEZ:
583
	case ABLTZ:
584
	case ABLEZ:
585
 
586
	case ASGT:
587
	case ASGTU:
588
 
589
	case AADD:
590
	case AADDU:
591
	case ASUB:
592
	case ASUBU:
593
	case ASLL:
594
	case ASRL:
595
	case ASRA:
596
	case AOR:
597
	case AAND:
598
	case AXOR:
599
	case AMUL:
600
	case AMULU:
601
	case ADIV:
602
	case ADIVU:
603
		return D_REG;
604
 
605
	case ACMPEQD:
606
	case ACMPEQF:
607
	case ACMPGED:
608
	case ACMPGEF:
609
	case ACMPGTD:
610
	case ACMPGTF:
611
 
612
	case AADDF:
613
	case AADDD:
614
	case ASUBF:
615
	case ASUBD:
616
	case AMULF:
617
	case AMULD:
618
	case ADIVF:
619
	case ADIVD:
620
		return D_FREG;
621
	}
622
	return D_NONE;
623
}
624
 
625
/*
626
 * direct reference,
627
 * could be set/use depending on
628
 * semantics
629
 */
630
int
631
copyas(Adr *a, Adr *v)
632
{
633
 
634
	if(regtyp(v))
635
		if(a->type == v->type)
636
		if(a->reg == v->reg)
637
			return 1;
638
	return 0;
639
}
640
 
641
/*
642
 * either direct or indirect
643
 */
644
int
645
copyau(Adr *a, Adr *v)
646
{
647
 
648
	if(copyas(a, v))
649
		return 1;
650
	if(v->type == D_REG)
651
		if(a->type == D_OREG)
652
			if(v->reg == a->reg)
653
				return 1;
654
	return 0;
655
}
656
 
657
int
658
copyau1(Prog *p, Adr *v)
659
{
660
 
661
	if(regtyp(v))
662
		if(p->from.type == v->type || p->to.type == v->type)
663
		if(p->reg == v->reg) {
664
			if(a2type(p) != v->type)
665
				print("botch a2type %P\n", p);
666
			return 1;
667
		}
668
	return 0;
669
}
670
 
671
/*
672
 * substitute s for v in a
673
 * return failure to substitute
674
 */
675
int
676
copysub(Adr *a, Adr *v, Adr *s, int f)
677
{
678
 
679
	if(f)
680
	if(copyau(a, v))
681
		a->reg = s->reg;
682
	return 0;
683
}
684
 
685
int
686
copysub1(Prog *p1, Adr *v, Adr *s, int f)
687
{
688
 
689
	if(f)
690
	if(copyau1(p1, v))
691
		p1->reg = s->reg;
692
	return 0;
693
}