File: alphaRewrite.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (217 lines) | stat: -rw-r--r-- 8,584 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
(* alphaRewrite.sml -- rewrite an alpha instruction 
 *
 * COPYRIGHT (c) 1997 Bell Labs
 *)

functor AlphaRewrite(Instr : ALPHAINSTR) = struct
  structure I=Instr
  structure C=I.C
  structure CB=CellsBasis
  structure CS=CB.CellSet
  fun error msg = MLRiscErrorMsg.error ("AlphaRewrite", msg)

  fun rewriteUse(instr, rs, rt) = let
    fun match r = CB.sameColor(r,rs)
    fun replace r = if match r then rt else r
    fun replaceEA(SOME(I.Displace{base, disp, mem})) = 
	  SOME(I.Displace{base=replace base, disp=disp, mem=mem})
      | replaceEA ea = ea
    fun alphaUse(instr) = let
      fun isRegOp (I.REGop r) = match r
	| isRegOp _ = false
      fun rwOperand(opnd as I.REGop r) = 
	   if match r then I.REGop rt else opnd
	| rwOperand opnd = opnd
      fun load(ldClass, {ldOp, r, b, d, mem}) =
	 if match b
	 then ldClass{ldOp=ldOp, r=r, b=rt, d=d, mem=mem}
	 else instr
      fun fstore(stClass, {stOp, r, b, d, mem}) =
	 if match b then stClass{stOp=stOp, r=r, b=rt, d=d, mem=mem}
	 else instr
      fun store{stOp, r, b, d, mem} = 
	if match r then
	  if match b then
	    I.STORE{stOp=stOp, r=rt, b=rt, d=d, mem=mem}
	  else
	    I.STORE{stOp=stOp, r=rt, b=b, d=d, mem=mem}
	else if match b then
	  I.STORE{stOp=stOp, r=r, b=rt, d=d, mem=mem}
	else instr
      fun operate(opClass, {oper, ra, rb, rc}) = 
	if match ra then
	  if isRegOp rb then 
	    opClass{oper=oper, ra=rt, rb=I.REGop rt, rc=rc}
	  else opClass{oper=oper, ra=rt, rb=rb, rc=rc}
	else if isRegOp rb then
	  opClass{oper=oper, ra=ra, rb=I.REGop rt, rc=rc}
	else instr

    in
      case instr
      of I.LDA{r, b, d} => if match b then I.LDA{r=r, b=rt, d=d} else instr
       | I.LDAH{r, b, d} => if match b then I.LDAH{r=r, b=rt, d=d} else instr
       | I.LOAD arg => load(I.LOAD, arg)
       | I.FLOAD farg => load(I.FLOAD, farg)
       | I.STORE arg => store arg
       | I.FSTORE farg => fstore(I.FSTORE, farg)
       | I.JMPL({r, b, d}, labs) =>
	 if match b then I.JMPL({r=r, b=rt, d=d}, labs) else instr
       | I.JSR{r, b, d, defs, uses, cutsTo, mem} =>
	   I.JSR{r=r, b=replace b, d=d, defs=defs, 
		 uses=CS.map {from=rs,to=rt} uses, cutsTo=cutsTo, mem=mem}
       | I.BSR{r, lab, defs, uses, cutsTo, mem} =>
	   I.BSR{r=r, lab=lab, defs=defs, 
		 uses=CS.map {from=rs,to=rt} uses, cutsTo=cutsTo, mem=mem}
       | I.RET{r,b,d} => I.RET{r=r, b=replace b, d=d}
       | I.BRANCH{b=I.BR, ...} => instr
       | I.BRANCH{b, r, lab} => if match r then I.BRANCH{b=b, r=rt, lab=lab} 
				else instr
       | I.OPERATE arg => operate(I.OPERATE, arg)
       | I.OPERATEV arg => operate(I.OPERATEV, arg)
       | I.CMOVE{oper,ra,rb,rc} => 
	   I.CMOVE{oper=oper,ra=replace ra,rb=rwOperand rb,rc=replace rc}
       | I.CALL_PAL{code, def, use } => 
	   I.CALL_PAL{code=code, def=def, use=CS.map {from=rs,to=rt} use}
       | I.PSEUDOARITH{oper, ra, rb, rc, tmps} => 
	   I.PSEUDOARITH{oper=oper, ra=replace ra, rb=rwOperand rb, rc=rc,
			 tmps=tmps}
       | _ => instr
    end
  in
      case instr
       of (I.ANNOTATION{i, ...}) => rewriteUse(i, rs, rt)
	| I.LIVE{regs, spilled} => I.LIVE{regs=C.addReg(rt, C.rmvReg(rs, regs)),
					   spilled=spilled}
        | I.INSTR(i) => I.INSTR(alphaUse(i))
        | I.COPY{k as CB.GP, sz, dst, src, tmp} => 
	   I.COPY{k=k, sz=sz, dst=dst, src=map replace src, tmp=replaceEA tmp}
	| _ => error "rewriteUse"
  end


  fun frewriteUse(instr, fs, ft) = let
    fun match f = CB.sameColor(f,fs)
    fun replace f = if match f then ft else f
    fun alphaUse(instr) = let
      fun foperate(opClass, {oper, fa, fb, fc}) = 
	if match fa then 
	  opClass{oper=oper, fa=ft, fc=fc, fb=replace fb}
	else if match fb then opClass{oper=oper, fa=fa, fb=ft, fc=fc}
	else instr
    in
      case instr
      of I.FBRANCH{b, f, lab} =>
	 if match f then I.FBRANCH{b=b, f=ft, lab=lab} else instr
       | I.FSTORE{stOp, r, b, d, mem} => 
	  if match r then I.FSTORE{stOp=stOp, r=ft, b=b, d=d, mem=mem} else instr
       | I.FOPERATE arg => foperate(I.FOPERATE, arg)
       | I.FOPERATEV arg => foperate(I.FOPERATEV, arg)
       | I.FUNARY{oper,fb,fc} =>
	  if match fb then I.FUNARY{oper=oper,fb=ft,fc=fc} else instr
       | I.FCMOVE{oper,fa,fb,fc} => 
	   I.FCMOVE{oper=oper,fa=replace fa,fb=replace fb,fc=replace fc}
       | I.JSR{r, b, d, defs, uses, cutsTo, mem} => 
	   I.JSR{r=r, b=b, d=d, defs=defs, 
		 uses=CS.map {from=fs,to=ft} uses, cutsTo=cutsTo, mem=mem}
       | I.BSR{r, lab, defs, uses, cutsTo, mem} => 
	   I.BSR{r=r, lab=lab, defs=defs, 
		 uses=CS.map {from=fs,to=ft} uses, cutsTo=cutsTo, mem=mem}
       | _ => instr
    end
  in
    case instr
    of I.ANNOTATION{i, ...} => frewriteUse(i, fs, ft)
     | I.LIVE{regs, spilled} => I.LIVE{regs=C.addFreg(ft, C.rmvFreg(fs, regs)),
					spilled=spilled}
     | I.COPY{k as CB.FP, sz, dst, src, tmp} => 
	  I.COPY{k=k, sz=sz, dst=dst, tmp=tmp, src=map replace src}
     | I.INSTR(i) => I.INSTR(alphaUse(i))
     | _ => error "frewriteUse"
  end


  fun rewriteDef(instr, rs, rt) = let
    fun match r = CB.sameColor(r,rs)
    fun rewrite r = if match r then rt else r
    fun ea (SOME(I.Direct r)) = SOME(I.Direct (rewrite r))
      | ea x = x
    fun alphaDef(instr) =
     (case instr
      of I.LDA{r, b, d} => if match r then I.LDA{r=rt, b=b, d=d} else instr
       | I.LDAH{r, b, d} => if match r then I.LDAH{r=rt, b=b, d=d} else instr
       | I.LOAD{ldOp, r, b, d, mem} => 
	 if match r then I.LOAD{ldOp=ldOp, r=rt, b=b, d=d, mem=mem} else instr
       | I.JMPL({r, b, d}, labs) =>
	 if match r then I.JMPL({r=rt, b=b, d=d}, labs) else instr
       | I.JSR{r, b, d, defs, uses, cutsTo, mem} =>
	   I.JSR{r=rewrite r, b=b, d=d, defs=CS.map {from=rs,to=rt} defs, 
		 uses=uses, cutsTo=cutsTo, mem=mem}
       | I.BSR{r, lab, defs, uses, cutsTo, mem} =>
	   I.BSR{r=rewrite r, lab=lab, defs=CS.map {from=rs,to=rt} defs, 
		 uses=uses, cutsTo=cutsTo, mem=mem}
       | I.RET{r, b, d} => I.RET{r=rewrite r, b=b, d=d}
       | I.BRANCH{b=I.BR, r, lab} => 
	 if match r then I.BRANCH{b=I.BR, r=rt, lab=lab} else instr
       | I.OPERATE{oper, ra, rb, rc} => 
	 if match rc then I.OPERATE{oper=oper, ra=ra, rb=rb, rc=rt} else instr
       | I.OPERATEV{oper, ra, rb, rc} =>
	 if match rc then I.OPERATEV{oper=oper, ra=ra, rb=rb, rc=rt} else instr
       | I.CMOVE{oper,ra,rb,rc} => I.CMOVE{oper=oper,ra=ra,rb=rb,rc=rewrite rc}
       | I.CALL_PAL{code, def, use} => 
	   I.CALL_PAL{code=code, def=CS.map {from=rs,to=rt} def, use=use}
       | I.PSEUDOARITH{oper, ra, rb, rc, tmps} => 
	   I.PSEUDOARITH{oper=oper, ra=ra, rb=rb, rc=rewrite rc,
			 tmps=CS.map {from=rs,to=rt} tmps}
       | _ => instr
    (*esac*))
  in
      case instr
      of I.ANNOTATION{i, ...} => rewriteDef(i,rs,rt)
       | I.KILL{regs, spilled} => 
	   I.KILL{regs=C.addReg(rt, C.rmvReg(rs, regs)), spilled=spilled}
       | I.INSTR(i) => I.INSTR(alphaDef(i))
       | I.COPY{k as CB.GP, sz, dst, src, tmp} =>
	  I.COPY{k=k, sz=sz, dst=map rewrite dst, src=src, tmp=ea tmp}
       | _ => error "rewriteDef"
  end

  fun frewriteDef(instr, fs, ft) = let
    fun match f = CB.sameColor(f,fs)
    fun rewrite f = if match f then ft else f
    fun ea (SOME(I.FDirect f)) = SOME(I.FDirect(rewrite f))
      | ea x  = x
    fun alphaDef(instr) = 
     (case instr
      of I.FLOAD{ldOp, r, b, d, mem} => 
	  if match r then I.FLOAD{ldOp=ldOp, r=ft, b=b, d=d, mem=mem} else instr
       | I.FOPERATE{oper, fa, fb, fc} =>
	  if match fc then I.FOPERATE{oper=oper, fa=fa, fb=fb, fc=ft} else instr
       | I.FOPERATEV{oper, fa, fb, fc} =>
	  if match fc then I.FOPERATEV{oper=oper, fa=fa, fb=fb, fc=ft} else instr
       | I.FUNARY{oper,fb,fc} =>
	  if match fc then I.FUNARY{oper=oper,fb=fb,fc=ft} else instr
       | I.FCMOVE{oper,fa,fb,fc} => I.FCMOVE{oper=oper,fa=fa,fb=fb,fc=rewrite fc}
       | I.JSR{r, b, d, defs, uses, cutsTo, mem} => 
	  I.JSR{r=r, b=b, d=d, defs=CS.map {from=fs,to=ft} defs, 
		uses=uses, cutsTo=cutsTo, mem=mem}
       | I.BSR{r, lab, defs, uses, cutsTo, mem} => 
	  I.BSR{r=r, lab=lab, defs=CS.map {from=fs,to=ft} defs, 
		uses=uses, cutsTo=cutsTo, mem=mem}
       | I.PSEUDOARITH{oper, ra, rb, rc, tmps} => 
	   I.PSEUDOARITH{oper=oper, ra=ra, rb=rb, rc=rc, 
			 tmps=CS.map {from=fs,to=ft} tmps}
       | _  => instr
    (*esac*))
  in
      case instr
       of I.ANNOTATION{i,a} => frewriteDef(i, fs, ft)
        | I.KILL{regs, spilled} => 
	   I.KILL{regs=C.addFreg(ft, C.rmvFreg(fs, regs)), spilled=spilled}
        | I.COPY{k as CB.FP, sz, dst, src, tmp} =>
	   I.COPY{k=k, sz=sz, dst=map rewrite dst, src=src, tmp=ea tmp}
	| I.INSTR(i) => I.INSTR(alphaDef(i))
	| _  => error "frewriteDef"
  end
end