File: mlrisc-preheaders.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 (76 lines) | stat: -rw-r--r-- 2,656 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
(*
 * This module inserts preheaders
 *
 * -- Allen
 *)

functor InsertPreheaders
  (structure IR        : MLRISC_IR
   structure InsnProps : INSN_PROPERTIES
     sharing IR.CFG.I = InsnProps.I
  ) : MLRISC_IR_OPTIMIZATION =
struct

   structure IR   = IR
   structure CFG  = IR.CFG
   structure Loop = IR.Loop
   structure Util = IR.Util
   structure W    = CFG.W
   structure G    = Graph

   type flowgraph = IR.IR 

   val preheaders = MLRiscControl.getCounter "preheaders-inserted"

   val name = "InsertPreheaders"

   fun error msg = MLRiscErrorMsg.error(name,msg)

   fun run IR =
   let  val CFG as G.GRAPH cfg = IR
        val G.GRAPH loop = IR.loop IR

        fun is_falls_thru(_,_,CFG.EDGE{k=CFG.BRANCH false,...}) = true
          | is_falls_thru(_,_,CFG.EDGE{k=CFG.FALLSTHRU,...}) = true
          | is_falls_thru(_,_,_) = false

        val changed = ref false

        fun process_loop(_,Loop.LOOP{backedges=[],...}) = ()
          | process_loop(_,Loop.LOOP{header,backedges,...}) =
        let fun find_entries([],entries,freq) = (entries,freq)
              | find_entries((e as (i,j,CFG.EDGE{k=CFG.ENTRY,...}))::es,_,_) = 
                 error "insert_preheaders"
              | find_entries((e as (i,j,CFG.EDGE{w,k,...}))::es,entries,freq) = 
                 if List.exists (fn (i',j',_) => i=i' andalso j=j') backedges
                 then find_entries(es,entries,freq)
                 else find_entries(es,e::entries,!w + freq)
            val (entries,w) = find_entries(#in_edges cfg header,[],0)
            val header_node = #node_info cfg header
            val preheader   = #new_id cfg ()
            val preheader_node as CFG.BLOCK{freq,annotations,insns,...} =
                 CFG.newBlock(preheader,ref w)
            val no_jump = List.exists is_falls_thru entries
            val new_edge = CFG.EDGE{k=if no_jump then CFG.FALLSTHRU 
                                      else CFG.JUMP, w=ref w,a=ref []}
        in  changed := true;
            preheaders := !preheaders + 1;
            #add_node cfg (preheader,preheader_node);
            #add_edge cfg (preheader,header,new_edge);
            if no_jump then () 
               else insns := [InsnProps.jump(CFG.defineLabel header_node)];
            app (fn (i,_,_) => 
                let fun edge(i,j,e) = 
                         (i,if j = header then preheader else j,e)
                in  #set_out_edges cfg (i,map edge (#out_edges cfg i));
                    Util.updateJumpLabel CFG i
                end) entries
        end 
   in   
        #forall_nodes loop process_loop;
        if !changed then IR.changed IR else ();
        IR
   end

end