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
static int
4
needc(Prog *p)
5
{
6
	while(p != P) {
7
		switch(p->as) {
8
		case AADCL:
9
		case ASBBL:
10
		case ARCRL:
11
			return 1;
12
		case AADDL:
13
		case ASUBL:
14
		case AJMP:
15
		case ARET:
16
		case ACALL:
17
			return 0;
18
		default:
19
			if(p->to.type == D_BRANCH)
20
				return 0;
21
		}
22
		p = p->link;
23
	}
24
	return 0;
25
}
26
 
27
void
28
peep(void)
29
{
30
	Reg *r, *r1, *r2;
31
	Prog *p, *p1;
32
	int t;
33
 
34
	/*
35
	 * complete R structure
36
	 */
37
	t = 0;
38
	for(r=firstr; r!=R; r=r1) {
39
		r1 = r->link;
40
		if(r1 == R)
41
			break;
42
		p = r->prog->link;
43
		while(p != r1->prog)
44
		switch(p->as) {
45
		default:
46
			r2 = rega();
47
			r->link = r2;
48
			r2->link = r1;
49
 
50
			r2->prog = p;
51
			r2->p1 = r;
52
			r->s1 = r2;
53
			r2->s1 = r1;
54
			r1->p1 = r2;
55
 
56
			r = r2;
57
			t++;
58
 
59
		case ADATA:
60
		case AGLOBL:
61
		case ANAME:
62
		case ASIGNAME:
63
			p = p->link;
64
		}
65
	}
66
 
67
	pc = 0;	/* speculating it won't kill */
68
 
69
loop1:
70
 
71
	t = 0;
72
	for(r=firstr; r!=R; r=r->link) {
73
		p = r->prog;
74
		switch(p->as) {
75
		case AMOVL:
76
			if(regtyp(&p->to))
77
			if(regtyp(&p->from)) {
78
				if(copyprop(r)) {
79
					excise(r);
80
					t++;
81
				}
82
				if(subprop(r) && copyprop(r)) {
83
					excise(r);
84
					t++;
85
				}
86
			}
87
			break;
88
 
89
		case AMOVBLSX:
90
		case AMOVBLZX:
91
		case AMOVWLSX:
92
		case AMOVWLZX:
93
			if(regtyp(&p->to)) {
94
				r1 = uniqs(r);
95
				if(r1 != R) {
96
					p1 = r1->prog;
97
					if(p->as == p1->as && p->to.type == p1->from.type)
98
						p1->as = AMOVL;
99
				}
100
			}
101
			break;
102
		case AADDL:
103
		case AADDW:
104
			if(p->from.type != D_CONST || needc(p->link))
105
				break;
106
			if(p->from.offset == -1){
107
				if(p->as == AADDL)
108
					p->as = ADECL;
109
				else
110
					p->as = ADECW;
111
				p->from = zprog.from;
112
			}
113
			else if(p->from.offset == 1){
114
				if(p->as == AADDL)
115
					p->as = AINCL;
116
				else
117
					p->as = AINCW;
118
				p->from = zprog.from;
119
			}
120
			break;
121
		case ASUBL:
122
		case ASUBW:
123
			if(p->from.type != D_CONST || needc(p->link))
124
				break;
125
			if(p->from.offset == -1) {
126
				if(p->as == ASUBL)
127
					p->as = AINCL;
128
				else
129
					p->as = AINCW;
130
				p->from = zprog.from;
131
			}
132
			else if(p->from.offset == 1){
133
				if(p->as == ASUBL)
134
					p->as = ADECL;
135
				else
136
					p->as = ADECW;
137
				p->from = zprog.from;
138
			}
139
			break;
140
		}
141
	}
142
	if(t)
143
		goto loop1;
144
}
145
 
146
void
147
excise(Reg *r)
148
{
149
	Prog *p;
150
 
151
	p = r->prog;
152
	p->as = ANOP;
153
	p->from = zprog.from;
154
	p->to = zprog.to;
155
}
156
 
157
Reg*
158
uniqp(Reg *r)
159
{
160
	Reg *r1;
161
 
162
	r1 = r->p1;
163
	if(r1 == R) {
164
		r1 = r->p2;
165
		if(r1 == R || r1->p2link != R)
166
			return R;
167
	} else
168
		if(r->p2 != R)
169
			return R;
170
	return r1;
171
}
172
 
173
Reg*
174
uniqs(Reg *r)
175
{
176
	Reg *r1;
177
 
178
	r1 = r->s1;
179
	if(r1 == R) {
180
		r1 = r->s2;
181
		if(r1 == R)
182
			return R;
183
	} else
184
		if(r->s2 != R)
185
			return R;
186
	return r1;
187
}
188
 
189
int
190
regtyp(Adr *a)
191
{
192
	int t;
193
 
194
	t = a->type;
195
	if(t >= D_AX && t <= D_DI)
196
		return 1;
197
	return 0;
198
}
199
 
200
/*
201
 * the idea is to substitute
202
 * one register for another
203
 * from one MOV to another
204
 *	MOV	a, R0
205
 *	ADD	b, R0	/ no use of R1
206
 *	MOV	R0, R1
207
 * would be converted to
208
 *	MOV	a, R1
209
 *	ADD	b, R1
210
 *	MOV	R1, R0
211
 * hopefully, then the former or latter MOV
212
 * will be eliminated by copy propagation.
213
 */
214
int
215
subprop(Reg *r0)
216
{
217
	Prog *p;
218
	Adr *v1, *v2;
219
	Reg *r;
220
	int t;
221
 
222
	p = r0->prog;
223
	v1 = &p->from;
224
	if(!regtyp(v1))
225
		return 0;
226
	v2 = &p->to;
227
	if(!regtyp(v2))
228
		return 0;
229
	for(r=uniqp(r0); r!=R; r=uniqp(r)) {
230
		if(uniqs(r) == R)
231
			break;
232
		p = r->prog;
233
		switch(p->as) {
234
		case ACALL:
235
			return 0;
236
 
237
		case AIMULL:
238
		case AIMULW:
239
			if(p->to.type != D_NONE)
240
				break;
241
 
242
		case ADIVB:
243
		case ADIVL:
244
		case ADIVW:
245
		case AIDIVB:
246
		case AIDIVL:
247
		case AIDIVW:
248
		case AIMULB:
249
		case AMULB:
250
		case AMULL:
251
		case AMULW:
252
 
253
		case AROLB:
254
		case AROLL:
255
		case AROLW:
256
		case ARORB:
257
		case ARORL:
258
		case ARORW:
259
		case ASALB:
260
		case ASALL:
261
		case ASALW:
262
		case ASARB:
263
		case ASARL:
264
		case ASARW:
265
		case ASHLB:
266
		case ASHLL:
267
		case ASHLW:
268
		case ASHRB:
269
		case ASHRL:
270
		case ASHRW:
271
 
272
		case AREP:
273
		case AREPN:
274
 
275
		case ACWD:
276
		case ACDQ:
277
 
278
		case ASTOSB:
279
		case ASTOSL:
280
		case AMOVSB:
281
		case AMOVSL:
282
		case AFSTSW:
283
			return 0;
284
 
285
		case AMOVL:
286
			if(p->to.type == v1->type)
287
				goto gotit;
288
			break;
289
		}
290
		if(copyau(&p->from, v2) ||
291
		   copyau(&p->to, v2))
292
			break;
293
		if(copysub(&p->from, v1, v2, 0) ||
294
		   copysub(&p->to, v1, v2, 0))
295
			break;
296
	}
297
	return 0;
298
 
299
gotit:
300
	copysub(&p->to, v1, v2, 1);
301
	if(debug['P']) {
302
		print("gotit: %D->%D\n%P", v1, v2, r->prog);
303
		if(p->from.type == v2->type)
304
			print(" excise");
305
		print("\n");
306
	}
307
	for(r=uniqs(r); r!=r0; r=uniqs(r)) {
308
		p = r->prog;
309
		copysub(&p->from, v1, v2, 1);
310
		copysub(&p->to, v1, v2, 1);
311
		if(debug['P'])
312
			print("%P\n", r->prog);
313
	}
314
	t = v1->type;
315
	v1->type = v2->type;
316
	v2->type = t;
317
	if(debug['P'])
318
		print("%P last\n", r->prog);
319
	return 1;
320
}
321
 
322
/*
323
 * The idea is to remove redundant copies.
324
 *	v1->v2	F=0
325
 *	(use v2	s/v2/v1/)*
326
 *	set v1	F=1
327
 *	use v2	return fail
328
 *	-----------------
329
 *	v1->v2	F=0
330
 *	(use v2	s/v2/v1/)*
331
 *	set v1	F=1
332
 *	set v2	return success
333
 */
334
int
335
copyprop(Reg *r0)
336
{
337
	Prog *p;
338
	Adr *v1, *v2;
339
	Reg *r;
340
 
341
	p = r0->prog;
342
	v1 = &p->from;
343
	v2 = &p->to;
344
	if(copyas(v1, v2))
345
		return 1;
346
	for(r=firstr; r!=R; r=r->link)
347
		r->active = 0;
348
	return copy1(v1, v2, r0->s1, 0);
349
}
350
 
351
int
352
copy1(Adr *v1, Adr *v2, Reg *r, int f)
353
{
354
	int t;
355
	Prog *p;
356
 
357
	if(r->active) {
358
		if(debug['P'])
359
			print("act set; return 1\n");
360
		return 1;
361
	}
362
	r->active = 1;
363
	if(debug['P'])
364
		print("copy %D->%D f=%d\n", v1, v2, f);
365
	for(; r != R; r = r->s1) {
366
		p = r->prog;
367
		if(debug['P'])
368
			print("%P", p);
369
		if(!f && uniqp(r) == R) {
370
			f = 1;
371
			if(debug['P'])
372
				print("; merge; f=%d", f);
373
		}
374
		t = copyu(p, v2, A);
375
		switch(t) {
376
		case 2:	/* rar, cant split */
377
			if(debug['P'])
378
				print("; %D rar; return 0\n", v2);
379
			return 0;
380
 
381
		case 3:	/* set */
382
			if(debug['P'])
383
				print("; %D set; return 1\n", v2);
384
			return 1;
385
 
386
		case 1:	/* used, substitute */
387
		case 4:	/* use and set */
388
			if(f) {
389
				if(!debug['P'])
390
					return 0;
391
				if(t == 4)
392
					print("; %D used+set and f=%d; return 0\n", v2, f);
393
				else
394
					print("; %D used and f=%d; return 0\n", v2, f);
395
				return 0;
396
			}
397
			if(copyu(p, v2, v1)) {
398
				if(debug['P'])
399
					print("; sub fail; return 0\n");
400
				return 0;
401
			}
402
			if(debug['P'])
403
				print("; sub %D/%D", v2, v1);
404
			if(t == 4) {
405
				if(debug['P'])
406
					print("; %D used+set; return 1\n", v2);
407
				return 1;
408
			}
409
			break;
410
		}
411
		if(!f) {
412
			t = copyu(p, v1, A);
413
			if(!f && (t == 2 || t == 3 || t == 4)) {
414
				f = 1;
415
				if(debug['P'])
416
					print("; %D set and !f; f=%d", v1, f);
417
			}
418
		}
419
		if(debug['P'])
420
			print("\n");
421
		if(r->s2)
422
			if(!copy1(v1, v2, r->s2, f))
423
				return 0;
424
	}
425
	return 1;
426
}
427
 
428
/*
429
 * return
430
 * 1 if v only used (and substitute),
431
 * 2 if read-alter-rewrite
432
 * 3 if set
433
 * 4 if set and used
434
 * 0 otherwise (not touched)
435
 */
436
int
437
copyu(Prog *p, Adr *v, Adr *s)
438
{
439
 
440
	switch(p->as) {
441
 
442
	default:
443
		if(debug['P'])
444
			print("unknown op %A\n", p->as);
445
		return 2;
446
 
447
	case ANEGB:
448
	case ANEGW:
449
	case ANEGL:
450
	case ANOTB:
451
	case ANOTW:
452
	case ANOTL:
453
		if(copyas(&p->to, v))
454
			return 2;
455
		break;
456
 
457
	case ALEAL:	/* lhs addr, rhs store */
458
		if(copyas(&p->from, v))
459
			return 2;
460
 
461
 
462
	case ANOP:	/* rhs store */
463
	case AMOVL:
464
	case AMOVBLSX:
465
	case AMOVBLZX:
466
	case AMOVWLSX:
467
	case AMOVWLZX:
468
		if(copyas(&p->to, v)) {
469
			if(s != A)
470
				return copysub(&p->from, v, s, 1);
471
			if(copyau(&p->from, v))
472
				return 4;
473
			return 3;
474
		}
475
		goto caseread;
476
 
477
	case AROLB:
478
	case AROLL:
479
	case AROLW:
480
	case ARORB:
481
	case ARORL:
482
	case ARORW:
483
	case ASALB:
484
	case ASALL:
485
	case ASALW:
486
	case ASARB:
487
	case ASARL:
488
	case ASARW:
489
	case ASHLB:
490
	case ASHLL:
491
	case ASHLW:
492
	case ASHRB:
493
	case ASHRL:
494
	case ASHRW:
495
		if(copyas(&p->to, v))
496
			return 2;
497
		if(copyas(&p->from, v))
498
			if(p->from.type == D_CX)
499
				return 2;
500
		goto caseread;
501
 
502
	case AADDB:	/* rhs rar */
503
	case AADDL:
504
	case AADDW:
505
	case AANDB:
506
	case AANDL:
507
	case AANDW:
508
	case ADECL:
509
	case ADECW:
510
	case AINCL:
511
	case AINCW:
512
	case ASUBB:
513
	case ASUBL:
514
	case ASUBW:
515
	case AORB:
516
	case AORL:
517
	case AORW:
518
	case AXORB:
519
	case AXORL:
520
	case AXORW:
521
	case AMOVB:
522
	case AMOVW:
523
 
524
	case AFMOVB:
525
	case AFMOVBP:
526
	case AFMOVD:
527
	case AFMOVDP:
528
	case AFMOVF:
529
	case AFMOVFP:
530
	case AFMOVL:
531
	case AFMOVLP:
532
	case AFMOVV:
533
	case AFMOVVP:
534
	case AFMOVW:
535
	case AFMOVWP:
536
	case AFMOVX:
537
	case AFMOVXP:
538
	case AFADDDP:
539
	case AFADDW:
540
	case AFADDL:
541
	case AFADDF:
542
	case AFADDD:
543
	case AFMULDP:
544
	case AFMULW:
545
	case AFMULL:
546
	case AFMULF:
547
	case AFMULD:
548
	case AFSUBDP:
549
	case AFSUBW:
550
	case AFSUBL:
551
	case AFSUBF:
552
	case AFSUBD:
553
	case AFSUBRDP:
554
	case AFSUBRW:
555
	case AFSUBRL:
556
	case AFSUBRF:
557
	case AFSUBRD:
558
	case AFDIVDP:
559
	case AFDIVW:
560
	case AFDIVL:
561
	case AFDIVF:
562
	case AFDIVD:
563
	case AFDIVRDP:
564
	case AFDIVRW:
565
	case AFDIVRL:
566
	case AFDIVRF:
567
	case AFDIVRD:
568
		if(copyas(&p->to, v))
569
			return 2;
570
		goto caseread;
571
 
572
	case ACMPL:	/* read only */
573
	case ACMPW:
574
	case ACMPB:
575
 
576
	case AFCOMB:
577
	case AFCOMBP:
578
	case AFCOMD:
579
	case AFCOMDP:
580
	case AFCOMDPP:
581
	case AFCOMF:
582
	case AFCOMFP:
583
	case AFCOML:
584
	case AFCOMLP:
585
	case AFCOMW:
586
	case AFCOMWP:
587
	case AFUCOM:
588
	case AFUCOMP:
589
	case AFUCOMPP:
590
	caseread:
591
		if(s != A) {
592
			if(copysub(&p->from, v, s, 1))
593
				return 1;
594
			return copysub(&p->to, v, s, 1);
595
		}
596
		if(copyau(&p->from, v))
597
			return 1;
598
		if(copyau(&p->to, v))
599
			return 1;
600
		break;
601
 
602
	case AJGE:	/* no reference */
603
	case AJNE:
604
	case AJLE:
605
	case AJEQ:
606
	case AJHI:
607
	case AJLS:
608
	case AJMI:
609
	case AJPL:
610
	case AJGT:
611
	case AJLT:
612
	case AJCC:
613
	case AJCS:
614
 
615
	case AADJSP:
616
	case AFLDZ:
617
	case AWAIT:
618
		break;
619
 
620
	case AIMULL:
621
	case AIMULW:
622
		if(p->to.type != D_NONE) {
623
			if(copyas(&p->to, v))
624
				return 2;
625
			goto caseread;
626
		}
627
 
628
	case ADIVB:
629
	case ADIVL:
630
	case ADIVW:
631
	case AIDIVB:
632
	case AIDIVL:
633
	case AIDIVW:
634
	case AIMULB:
635
	case AMULB:
636
	case AMULL:
637
	case AMULW:
638
 
639
	case ACWD:
640
	case ACDQ:
641
		if(v->type == D_AX || v->type == D_DX)
642
			return 2;
643
		goto caseread;
644
 
645
	case AREP:
646
	case AREPN:
647
		if(v->type == D_CX)
648
			return 2;
649
		goto caseread;
650
 
651
	case AMOVSB:
652
	case AMOVSL:
653
		if(v->type == D_DI || v->type == D_SI)
654
			return 2;
655
		goto caseread;
656
 
657
	case ASTOSB:
658
	case ASTOSL:
659
		if(v->type == D_AX || v->type == D_DI)
660
			return 2;
661
		goto caseread;
662
 
663
	case AFSTSW:
664
		if(v->type == D_AX)
665
			return 2;
666
		goto caseread;
667
 
668
	case AJMP:	/* funny */
669
		if(s != A) {
670
			if(copysub(&p->to, v, s, 1))
671
				return 1;
672
			return 0;
673
		}
674
		if(copyau(&p->to, v))
675
			return 1;
676
		return 0;
677
 
678
	case ARET:	/* funny */
679
		if(v->type == REGRET)
680
			return 2;
681
		if(s != A)
682
			return 1;
683
		return 3;
684
 
685
	case ACALL:	/* funny */
686
		if(REGARG>=0 && v->type == REGARG)
687
			return 2;
688
 
689
		if(s != A) {
690
			if(copysub(&p->to, v, s, 1))
691
				return 1;
692
			return 0;
693
		}
694
		if(copyau(&p->to, v))
695
			return 4;
696
		return 3;
697
	}
698
	return 0;
699
}
700
 
701
/*
702
 * direct reference,
703
 * could be set/use depending on
704
 * semantics
705
 */
706
int
707
copyas(Adr *a, Adr *v)
708
{
709
	if(a->type != v->type)
710
		return 0;
711
	if(regtyp(v))
712
		return 1;
713
	if(v->type == D_AUTO || v->type == D_PARAM)
714
		if(v->offset == a->offset)
715
			return 1;
716
	return 0;
717
}
718
 
719
/*
720
 * either direct or indirect
721
 */
722
int
723
copyau(Adr *a, Adr *v)
724
{
725
 
726
	if(copyas(a, v))
727
		return 1;
728
	if(regtyp(v)) {
729
		if(a->type-D_INDIR == v->type)
730
			return 1;
731
		if(a->index == v->type)
732
			return 1;
733
	}
734
	return 0;
735
}
736
 
737
/*
738
 * substitute s for v in a
739
 * return failure to substitute
740
 */
741
int
742
copysub(Adr *a, Adr *v, Adr *s, int f)
743
{
744
	int t;
745
 
746
	if(copyas(a, v)) {
747
		t = s->type;
748
		if(t >= D_AX && t <= D_DI) {
749
			if(f)
750
				a->type = t;
751
		}
752
		return 0;
753
	}
754
	if(regtyp(v)) {
755
		t = v->type;
756
		if(a->type == t+D_INDIR) {
757
			if(s->type == D_BP && a->index != D_NONE)
758
				return 1;	/* can't use BP-base with index */
759
			if(f)
760
				a->type = s->type+D_INDIR;
761
//			return 0;
762
		}
763
		if(a->index == t) {
764
			if(f)
765
				a->index = s->type;
766
			return 0;
767
		}
768
		return 0;
769
	}
770
	return 0;
771
}