File: operand-table.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • 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 (189 lines) | stat: -rw-r--r-- 5,815 bytes parent folder | download | duplicates (5)
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
(*
 * A table for storing operands for a compilation unit.
 * We give each distinct operand a unique (negative) value number.
 *)
functor OperandTable(Props : INSN_PROPERTIES) : OPERAND_TABLE =
struct

   structure I  = Props.I
   structure C  = I.C
   structure IH = IntHashTable
   structure H  = HashTable
       
   type valueNumber = C.cell

   datatype const =
     INT     of int           (* small integer operands *)
   | INTINF  of IntInf.int    (* large integer operands *)
   | OPERAND of I.operand     (* other operand *)

   structure IntInfMap =
      RedBlackMapFn(type ord_key = IntInf.int
                    val compare = IntInf.compare
                   )

   datatype operandTable =
      TABLE of 
      {  intTable   : valueNumber IH.hash_table,
         miTable    : valueNumber IntInfMap.map ref,
         opnTable   : (I.operand,valueNumber) H.hash_table,
         nextValueNumber : int ref
      }

   datatype valueNumberMethods =
      VALUE_NUMBERING of
      { int     : int -> valueNumber,
        word    : word -> valueNumber,
        int32   : Int32.int -> valueNumber,
        word32  : Word32.word -> valueNumber,
        intinf  : IntInf.int -> valueNumber,
        operand : I.operand -> valueNumber
      }

   exception NoOperand
   exception NoConst
   exception NoInt
   exception NoIntInf

   val gp = C.cellkindDesc C.GP

   exception CONST of const

   fun mkConst(vn, const) = 
       C.CELL{id=vn, an=ref [CONST const], col=ref C.PSEUDO, desc=gp}

   val bot = C.CELL{id= ~9999999, an=ref [], col=ref C.PSEUDO, desc=gp}
   val top = C.CELL{id= ~9999998, an=ref [], col=ref C.PSEUDO, desc=gp}
   val volatile = C.CELL{id= ~9999997, an=ref [], col=ref C.PSEUDO, desc=gp}

   fun create(nextValueNumber) =
   let 
       val opnTable = H.mkTable(Props.hashOpn,Props.eqOpn) (32,NoOperand)
       val intTable = IH.mkTable (32, NoInt)
       val miTable  = ref IntInfMap.empty

       fun newInt i =
       let val vn = !nextValueNumber (* value number *)
           val _ = nextValueNumber := vn - 1;
           val v = mkConst(vn, INT i)
       in  IH.insert intTable (i, v)
       end

       fun init(n,0) = ()
         | init(n,m) = (newInt n; init(n+1,m-1))

   in  init(0,2);
       TABLE{ intTable        = intTable,
              miTable         = miTable,
              opnTable        = opnTable,
              nextValueNumber = nextValueNumber
            }
   end

   fun wordToIntInf w   = IntInf.fromInt(Word.toIntX w)
   fun word32ToIntInf w = Word32.toLargeIntX w
   fun wordToInt w      = Word.toIntX w
   fun word32ToInt w    = Word32.toIntX w
   fun intInfToInt i    = IntInf.toInt i
   fun intInfToInt32 i  = Int32.fromLarge i
   fun intToIntInf i    = IntInf.fromInt i
   fun intToInt32 i     = Int32.fromInt i
   fun int32ToIntInf i  = Int32.toLarge i
   fun int32ToInt i     = Int32.toInt i
   
   (* Lookup the value number of a constant *)
   fun int(TABLE{intTable, ...}) = IH.lookup intTable  

   fun word(TABLE{intTable, ...}) w = IH.lookup intTable (wordToInt w)

   fun word32(TABLE{intTable, miTable, ...}) w = 
         IH.lookup intTable (word32ToInt w) handle Overflow =>
          case IntInfMap.find(!miTable, word32ToIntInf w) of
             SOME v => v
          |  NONE => raise NoIntInf

   fun int32(TABLE{intTable, miTable, ...}) w = 
         IH.lookup intTable (int32ToInt w) handle Overflow =>
          case IntInfMap.find(!miTable, int32ToIntInf w) of
             SOME v => v
          |  NONE => raise NoIntInf

   fun intinf(TABLE{intTable, miTable, ...}) i = 
         IH.lookup intTable (intInfToInt i) handle Overflow =>
          case IntInfMap.find(!miTable,i) of
            SOME v => v
          | NONE => raise NoIntInf

   fun operand(TABLE{opnTable,...}) = H.lookup opnTable

   fun lookupValueNumbers tbl =
       VALUE_NUMBERING
       { int = int tbl,
         word = word tbl,
         word32 = word32 tbl,
         int32 = int32 tbl,
         intinf = intinf tbl,
         operand = operand tbl
       }

   (* create new value numebers *)
   fun makeNewValueNumbers(TABLE{opnTable,
                                 nextValueNumber,intTable,miTable,...}) =
   let val findOpn = H.find opnTable
       val findInt = IH.find intTable
       val insertOpn = H.insert opnTable
       val insertInt = IH.insert intTable

       fun newConst(const) = 
       let val vn = !nextValueNumber
       in  nextValueNumber := vn - 1;
           mkConst(vn,const)
       end

       fun mkOpn opn = 
           case findOpn opn of
             SOME v => v 
           | NONE => let val v = newConst(OPERAND opn)
                     in  insertOpn(opn, v); v end
       fun mkInt i =
           case findInt i of
             SOME v => v
           | NONE => let val v = newConst(INT i)
                     in  insertInt(i, v); v end

       fun insertIntInf(i, v) =
           miTable := IntInfMap.insert(!miTable, i, v)

       fun mkIntInf' i =
           case IntInfMap.find(!miTable, i) of
             SOME v => v
           | NONE => let val v = newConst(INTINF i)
                     in  insertIntInf(i, v); v end

       fun mkIntInf i = mkInt(intInfToInt i) handle _ => mkIntInf' i

       fun mkWord w = mkInt(wordToInt w)

       fun mkInt32 i = mkInt(int32ToInt i)
                        handle _ => mkIntInf'(int32ToIntInf i)

       fun mkWord32 w = mkInt(word32ToInt w)
                        handle _ => mkIntInf'(word32ToIntInf w)
   in  VALUE_NUMBERING
       {int=mkInt,
        word=mkWord,
        word32=mkWord32,
        int32=mkInt32,
        intinf=mkIntInf,
        operand=mkOpn
       }
   end

   (* value number -> const *)
   fun const(C.CELL{an, ...}) = 
   let fun find(CONST c::_) = c
         | find(_::an) = find an
         | find [] = raise NoConst
   in  find(!an) end

end