File: mlrisc-ir.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 (164 lines) | stat: -rw-r--r-- 5,640 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
(*
 * MLRISC IR
 *
 * This is for performing whole program analysis.
 * All optimizations are based on this representation.
 * It provides a few useful views: dominator tree, control dependence graph,
 * loop nesting (interval) structure etc. Also there is a mechanism to
 * incrementally attach additional views to the IR.  The SSA infrastructure
 * is implemented in such a manner.
 *
 * -- Allen
 *)

functor MLRISC_IR
   (structure CFG         : CONTROL_FLOW_GRAPH
    structure CDG         : CONTROL_DEPENDENCE_GRAPH
    structure Loop        : LOOP_STRUCTURE
    structure GraphViewer : GRAPH_VIEWER
    structure Util        : CFG_UTIL
       sharing Loop.Dom = CDG.Dom
       sharing Util.CFG = CFG
   ) : MLRISC_IR =
struct

   structure I    = CFG.I
   structure CFG  = CFG
   structure Dom  = Loop.Dom
   structure CDG  = CDG
   structure Loop = Loop
   structure G    = Graph
   structure A    = Annotations
   structure Util = Util
   structure L    = GraphLayout
  
   type cfg  = CFG.cfg
   type IR   = CFG.cfg
   type dom  = (CFG.block,CFG.edge_info,CFG.info) Dom.dominator_tree
   type pdom = (CFG.block,CFG.edge_info,CFG.info) Dom.postdominator_tree
   type cdg  = (CFG.block,CFG.edge_info,CFG.info) CDG.cdg
   type loop = (CFG.block,CFG.edge_info,CFG.info) Loop.loop_structure

   val layouts = ref [] : (string * (IR -> L.layout)) list ref

   fun addLayout name layout =
   let fun f((x,y)::rest) = if x = name then (x,layout)::rest
                            else (x,y)::f rest
         | f [] = [(name,layout)]
   in  layouts := f(!layouts) end

   exception NoLayout 

   fun findLayout name =
   let fun f [] = (print ("[Can't find "^name^"]\n"); raise NoLayout)
         | f((x,layout)::rest) = if x = name then layout else f rest
   in  f(!layouts) end

   fun view name IR = GraphViewer.view(findLayout name IR) 
           handle NoLayout => ()

   fun views names IR = 
       let val layouts = map (fn n => findLayout n IR) names
       in  GraphViewer.view(GraphCombinations.sums layouts)
       end handle NoLayout => ()

   fun viewSubgraph IR subgraph = 
         GraphViewer.view (CFG.subgraphLayout{cfg=IR,subgraph=subgraph})

   (*
    * This function defines how we compute a new view 
    *)

   val verbose = MLRiscControl.getFlag "verbose"

   fun memo name compute = 
   let val {get,set,...} = A.new(SOME(fn _ => name))
       fun getView(IR as G.GRAPH ir : IR)=
       let val CFG.INFO{annotations, ...} = #graph_info ir 
           fun process(SOME(ref(SOME info))) =
                 (if !verbose then print ("[reusing "^name^"]") else (); info)
             | process(SOME r) =
                 let val _    = 
                        if !verbose then print("[computing "^name) else ()
                     val info = compute IR
                     val _    = if !verbose then print "]" else ()
                 in  r := SOME info; info end
           |  process NONE = 
              let val r = ref NONE
                  fun kill() = (r := NONE; 
                                if !verbose then print("[uncaching "^name^"]")
                                else ())
              in  annotations := #create CFG.CHANGED(name, kill) :: 
                                 set(r,!annotations);
                  process(SOME r) 
              end
       in  process(get (!annotations)) end
   in  getView
   end

   (*
    *  Extract various views from an IR
    *) 

   val dom = memo "dom" Dom.makeDominator
   val pdom = memo "pdom" Dom.makePostdominator
   fun doms IR = (dom IR,pdom IR)
   val cdg  = memo "cdg" 
             (fn IR => CDG.control_dependence_graph CFG.cdgEdge (pdom IR))
   val loop = memo "loop" (Loop.loop_structure o dom)
   val changed = CFG.changed 

   (*
    *  Methods to layout various graphs
    *)
   fun defaultEdge _  = [L.COLOR "red"]
   fun defaultGraph _ = []  
   fun layoutDom' IR G = 
   let val {node,...} = CFG.viewStyle IR
   in  L.makeLayout {edge = defaultEdge,
                     graph= defaultGraph,
                     node = node} G
   end
 
   fun layoutDom IR  = layoutDom' IR (dom IR)
   fun layoutPdom IR = layoutDom' IR (pdom IR)
   fun layoutDoms IR = layoutDom' IR
       let val (dom,pdom) = doms IR
       in  GraphCombinations.sum(dom,ReversedGraphView.rev_view pdom)
       end
   fun layoutCDG IR = CFG.viewLayout(cdg IR)
   fun layoutLoop (IR as G.GRAPH cfg) = 
       let val loop   = loop IR
           val an     = !(CFG.annotations IR)
           fun mkNodes nodes =
              String.concat(map (fn i => Int.toString i^" ") nodes)
           fun mkEdges edges = 
              String.concat(map 
                (fn (i,j,_) => Int.toString i^"->"^Int.toString j^" ") edges)
           fun node(_,Loop.LOOP{nesting,header,loop_nodes,
                                backedges,exits,...}) =
               [L.LABEL
                ("nesting: "^Int.toString nesting^"\n"^
                 CFG.show_block an (#node_info cfg header)^
                 "entry edges: "^mkEdges(Loop.entryEdges loop header)^"\n"^
                 "loop_nodes: "^mkNodes loop_nodes^"\n"^
                 "backedges: "^mkEdges backedges^"\n"^
                 "exits: "^mkEdges exits^"\n"
                )]
       in  L.makeLayout {edge=defaultEdge,
                         graph=defaultGraph,
                         node=node} loop
       end
 
   (*
    *  Insert the layout methods here.
    *)
   val _ = addLayout "cfg" CFG.viewLayout
   val _ = addLayout "dom"  layoutDom
   val _ = addLayout "pdom" layoutPdom
   val _ = addLayout "doms" layoutDoms
   val _ = addLayout "cdg"  layoutCDG
   val _ = addLayout "loop" layoutLoop

end