|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: structure Insert : sig val insert : (CPS.function * bool) list -> ! 3: (CPS.function * bool) list ! 4: end = ! 5: struct ! 6: open Access CPS ! 7: fun makecallers (arg : (CPS.function * bool) list) = ! 8: let local open Intmap ! 9: in exception Body ! 10: val bodymap: (function * lvar list ref) intmap = ! 11: Intmap.new(32, Body) ! 12: val getbody = map bodymap ! 13: val setbody = add bodymap ! 14: ! 15: exception Caller ! 16: val callermap : function list intmap = Intmap.new(32, Caller) ! 17: val callers = map callermap ! 18: val setcallers = add callermap ! 19: end ! 20: fun initcalled(func as (f,vl,e)) = setbody(f, (func,ref nil)) ! 21: ! 22: fun findcalled(f,vl,e) = ! 23: let fun g(RECORD(_,_,e)) = g e ! 24: | g(SELECT(_,_,_,e)) = g e ! 25: | g(OFFSET(_,_,_,e)) = g e ! 26: | g(SWITCH(_,el)) = app g el ! 27: | g(PRIMOP(_,_,_,el)) = app g el ! 28: | g(APP(f',_)) = let val (_,r) = getbody f' ! 29: in r := f :: !r ! 30: end handle Body => () ! 31: in g e ! 32: end ! 33: ! 34: val sort = Sort.sort (op > : int * int -> bool) ! 35: fun mashcallers (f,vl,e) = ! 36: let val (_, ref callers) = getbody f ! 37: in setcallers(f, map (#1 o getbody) (SortedList.uniq(sort callers))) ! 38: end ! 39: ! 40: in app (initcalled o #1) arg; ! 41: app (findcalled o #1) arg; ! 42: app (mashcallers o #1) arg; ! 43: callers ! 44: end ! 45: ! 46: fun insert(arg : (CPS.function * bool) list) = ! 47: let val callers = makecallers arg ! 48: ! 49: val OKset = Intset.new() ! 50: val markOK = Intset.add OKset ! 51: val isOK = Intset.mem OKset ! 52: ! 53: fun dfs(f,vl,e) = ! 54: let fun bad(RECORD(_,_,e)) = false ! 55: | bad(SELECT(_,_,_,e)) = bad e ! 56: | bad(OFFSET(_,_,_,e)) = bad e ! 57: | bad(SWITCH(_,el)) = exists bad el ! 58: | bad(PRIMOP(P.:=,_,_,_)) = false ! 59: | bad(PRIMOP(P.update,_,_,_)) = false ! 60: | bad(PRIMOP(_,_,_,el)) = exists bad el ! 61: | bad(APP(f,_)) = not(isOK f) ! 62: in if isOK f orelse bad e ! 63: then () ! 64: else (markOK f; app dfs (callers f)) ! 65: end ! 66: ! 67: fun makeOK(func as (f,vl,e)) = ! 68: let fun g(e as RECORD _) = e ! 69: | g(SELECT(i,v,w,e)) = SELECT(i,v,w,g e) ! 70: | g(OFFSET(i,v,w,e)) = OFFSET(i,v,w,g e) ! 71: | g(SWITCH(v,el)) = SWITCH(v, map g el) ! 72: | g(e as PRIMOP(P.:=,_,_,_)) = e ! 73: | g(e as PRIMOP(P.update,_,_,_)) = e ! 74: | g(PRIMOP(p,vl,wl,el)) = PRIMOP(p,vl,wl, map g el) ! 75: | g(e as APP(f',v::_)) = if isOK f' then e ! 76: else RECORD([(v,OFFp 0)],mkLvar(),e) ! 77: in if isOK f then func ! 78: else let val func' = (f,vl,g e) ! 79: in dfs func'; func' ! 80: end ! 81: end ! 82: ! 83: in app (dfs o #1) arg; ! 84: map (fn (func,known) => (makeOK func, known)) arg ! 85: end ! 86: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.