Annotation of researchv10no/cmd/sml/src/cps/hoist.sml, revision 1.1

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: structure Hoist : sig val hoist : (string->unit)->CPS.cexp->CPS.cexp end =
        !             3: struct
        !             4:  open Access CPS SortedList
        !             5: 
        !             6: type fv = lvar list
        !             7: 
        !             8: datatype cexp'
        !             9:   = RECORD' of (lvar * accesspath) list * lvar * cexp' * fv
        !            10:   | SELECT' of int * lvar * lvar * cexp' * fv
        !            11:   | OFFSET' of int * lvar * lvar * cexp' * fv
        !            12:   | APP' of lvar * lvar list
        !            13:   | FIX' of function' list * fv * cexp' * fv
        !            14:   | SWITCH' of lvar * (cexp' * fv) list
        !            15:   | PRIMOP' of Access.primop * lvar list * lvar list * (cexp' * fv) list
        !            16: withtype function' = lvar * lvar list * cexp'
        !            17: 
        !            18:  fun sum f = let fun h [] = 0 
        !            19:                   | h (a::r) = f a + h r
        !            20:              in h
        !            21:             end
        !            22: 
        !            23:  fun hoist click cexp =
        !            24:   let (* val _ = CPSprint.show (output std_out) (Intmap.map ctab) cexp *)
        !            25:       val clicked = ref false
        !            26:       val click = fn x => (clicked := true; click x)
        !            27:       infix 6 \/ val op \/ = merge
        !            28:       infix 7 /\ val op /\ = intersect
        !            29:       infix 6 -- val op -- = fn(a,b) => remove(b,a)
        !            30:       val rec hoist = 
        !            31:        fn RECORD(vl, w, e) =>
        !            32:           (case hoist e
        !            33:            of (e as FIX'(l,v1,e',v2), v3) => 
        !            34:                    if member v1 w
        !            35:                      then (RECORD'(vl, w, e, v3), v3--[w]\/uniq(map #1 vl))
        !            36:                      else let val defined = uniq(map #1 l)
        !            37:                               val v4 = v2--[w]\/uniq(map #1 vl)
        !            38:                            in (FIX'(l,v1,RECORD'(vl,w,e',v2),v4), v1\/(v4--defined))
        !            39:                           end
        !            40:            | (e,v1) => (RECORD'(vl, w, e, v1), v1--[w]\/uniq(map #1 vl)))
        !            41:         | SELECT(i,v,w,e) =>
        !            42:           (case hoist e of
        !            43:              (e as FIX'(l,v1,e',v2), v3) => if member v1 w
        !            44:                      then (SELECT'(i, v, w, e, v3), v3--[w]\/[v])
        !            45:                      else let val defined = uniq(map #1 l)
        !            46:                               val v4 = v2--[w]\/[v]
        !            47:                            in (FIX'(l,v1,SELECT'(i,v,w,e',v2),v4),v1\/(v4--defined))
        !            48:                           end
        !            49:            | (e,v1) => (SELECT'(i, v, w, e, v1),v1--[w]\/[v]))
        !            50:         | PRIMOP(i,vl,wl,[e]) =>
        !            51:           (case hoist e
        !            52:             of(e as FIX'(l,v1,e',v2),v3) =>
        !            53:              (case uniq wl /\ v1
        !            54:                of [] => let val v4 = v2--uniq wl\/uniq vl
        !            55:                             val defined = uniq(map #1 l)
        !            56:                          in (FIX'(l,v1,PRIMOP'(i,vl,wl,[(e',v2)]),v4),v1\/(v4--defined))
        !            57:                         end
        !            58:                 | _  =>  (PRIMOP'(i, vl, wl, [(e,v3)]),v3--uniq wl\/uniq vl))
        !            59:            | (e,v1) => (PRIMOP'(i, vl, wl, [(e,v1)]),v1--uniq wl\/uniq vl))
        !            60:         | PRIMOP(i,vl,wl,el) => 
        !            61:                    let val el' = map hoist el
        !            62:                     in (PRIMOP'(i,vl,wl,el'), foldmerge(map #2 el')--uniq wl\/uniq vl)
        !            63:                    end
        !            64:         | APP(f,vl) => (APP'(f,vl), uniq(f::vl))
        !            65:         | SWITCH(v,el) => 
        !            66:                    let val el' = map hoist el
        !            67:                     in (SWITCH'(v, el'), foldmerge(map #2 el')\/[v])
        !            68:                    end
        !            69:         | FIX(l,e) =>
        !            70:           let fun h((f,vl,(e as FIX'(l',v1,e',v2),v3))::r) =
        !            71:                         let val (ll, v4) = h r
        !            72:                          in case uniq vl /\ v1
        !            73:                            of [] => (click "p"; 
        !            74:                                      ((f,vl,e')::l'@ll,
        !            75:                                        v2--(uniq vl)\/v1\/v4))
        !            76:                             | _ => ((f,vl,e) :: ll, v3--(uniq vl)\/v4)
        !            77:                         end
        !            78:                 | h((f,vl,(e,v3)):: r) = 
        !            79:                            let val (ll, v4) = h r
        !            80:                             in ((f,vl,e) :: ll, v3--(uniq vl)\/v4)
        !            81:                            end
        !            82:                 | h [] = ([],[])
        !            83:               val (l,v1) = h (map (fn(f,vl,a)=>(f,vl,hoist a)) l)
        !            84:               val defined = uniq(map #1 l)
        !            85:               val v1 = v1 -- defined
        !            86:               val (e,v2) = hoist e
        !            87:               exception Down
        !            88:               fun check vl = case defined /\ uniq vl of [] => () 
        !            89:                                                    | _ => raise Down
        !            90:               fun present (_,vx) = case defined/\vx
        !            91:                                      of []=>0 | _ => 1
        !            92:               val rec down' = fn (cexp,vx) => 
        !            93:                            case defined /\ vx
        !            94:                             of [] => (cexp,vx)
        !            95:                              | _ => down cexp 
        !            96:                                     handle Down => (FIX'(l,v1,cexp,vx),
        !            97:                                                     vx--defined\/v1)
        !            98:               and down =
        !            99:                fn RECORD'(vl,w,e,v3) => (check(map #1 vl); 
        !           100:                            let val (e',v4) = down e
        !           101:                             in (RECORD'(vl,w,e',v4),v4--[w]\/uniq(map #1 vl))
        !           102:                            end)
        !           103:                 | SELECT'(i,v,w,e,v3) => 
        !           104:                            let val (e',v4) = down e
        !           105:                             in (SELECT'(i,v,w,e',v4), v4--[w]\/[v])
        !           106:                            end
        !           107:                 | PRIMOP'(i,vl,wl,[(e,_)]) => (check vl;
        !           108:                            let val (e',v4) = down e
        !           109:                             in (PRIMOP'(i,vl,wl,[(e',v4)]), v4--uniq wl\/uniq vl)
        !           110:                            end)
        !           111:                 | PRIMOP'(i,vl,wl,el) => 
        !           112:                     (check vl;
        !           113:                      if sum present el < 2 
        !           114:                            then let val el' = map down' el
        !           115:                                  in (PRIMOP'(i,vl,wl,el'), foldmerge(map #2 el')--uniq wl\/uniq vl)
        !           116:                                 end
        !           117:                            else raise Down)
        !           118:                 | SWITCH'(v,el) => (* can't switch on a function *)
        !           119:                       if sum present el < 2
        !           120:                          then let val el' = map down' el
        !           121:                                in (SWITCH'(v,el'), foldmerge(map #2 el')\/[v])
        !           122:                               end
        !           123:                          else raise Down
        !           124:                 | e as APP'(f,vl) => (check(f::vl); click "s"; (e, uniq(f::vl)))
        !           125:                 | FIX'(m,v3,e',v4) => 
        !           126:                        let val v5 = v1\/(v3--defined)
        !           127:                         in click "r"; 
        !           128:                            (FIX'(l@m,v5,e',v4),v5\/(v4--(defined\/uniq(map #1 m))))
        !           129:                        end
        !           130:            in down e handle Down => (FIX'(l,v1,e,v2),
        !           131:                                      v2--defined\/v1)
        !           132:           end
        !           133:       val rec clean =
        !           134:        fn RECORD'(vl,w,e,_) => RECORD(vl,w,clean e)
        !           135:         | SELECT'(i,v,w,e,_) => SELECT(i,v,w, clean e)
        !           136:         | PRIMOP'(i,vl,wl,el) => PRIMOP(i,vl,wl,map (clean o #1) el)
        !           137:          | SWITCH'(v,el) => SWITCH(v, map (clean o #1) el)
        !           138:         | APP'(f,vl) => APP(f,vl)
        !           139:         | FIX'(l,_,e,_) => FIX(map (fn (f,vl,e)=>(f,vl,clean e)) l, clean e)
        !           140:       val cexp' = #1(hoist cexp)
        !           141:    in if !clicked then clean cexp' else cexp
        !           142:   end
        !           143: 
        !           144: end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.