|
|
1.1 ! root 1: (* Copyright 1989 by AT&T Bell Laboratories *) ! 2: signature PROF = sig ! 3: type profileInfo ! 4: val instrumDec : Absyn.dec -> (Absyn.dec * profileInfo) ! 5: val instrumStrb : Absyn.strb -> (Absyn.strb * profileInfo) ! 6: val instrumFctb : Absyn.fctb -> (Absyn.fctb * profileInfo) ! 7: val bindLambda : (Lambda.lexp * profileInfo) -> Lambda.lexp ! 8: end ! 9: ! 10: abstraction Prof : PROF = ! 11: struct ! 12: ! 13: open Access Absyn Lambda Basics BasicTypes ErrorMsg ! 14: ! 15: type profileInfo = (lvar * string) list ! 16: ! 17: val symbol = Symbol.symbol ! 18: ! 19: (* Profiling globals *) ! 20: val profiling = System.Control.Profile.profiling ! 21: val profileList = ref([]: (Access.lvar * string) list) ! 22: ! 23: val anonSym = symbol "anon" ! 24: ! 25: val intreftype = CONty(refTycon,[intTy]) ! 26: val alpha = VARty(mkTyvar(IBOUND 0)) ! 27: ! 28: fun topCCa() = VALvar{name = [symbol "toplevel.CC"], ! 29: access = PATH(!CoreInfo.toplevelPath), ! 30: typ = ref intreftype} ! 31: val assop = VALvar{name = [symbol "unboxedassign"], ! 32: access = INLINE P.unboxedassign, ! 33: typ = ref(tupleTy[intreftype,intTy] --> unitTy)} ! 34: val derefop = VALvar{name = [symbol "!"], ! 35: access = INLINE P.!, ! 36: typ = ref(CONty(refTycon,[alpha]) --> alpha)} ! 37: val addop = VALvar{name = [symbol "iadd"], ! 38: access = INLINE P.+, ! 39: typ = ref(tupleTy[intTy,intTy] --> intTy)} ! 40: fun currentvar() = VALvar{name = [symbol "current"], ! 41: access = PATH(!CoreInfo.currentPath), ! 42: typ = ref intreftype} ! 43: ! 44: fun tmpvar str = ! 45: let val lvar = mkLvar() ! 46: val name = [symbol str] ! 47: in (VALvar{name=name, access=LVAR(lvar), typ = ref UNDEFty}, ! 48: VALvar{name=name, access=PATH[lvar], typ = ref UNDEFty}) ! 49: end ! 50: ! 51: fun clean (path as name::names) = if Symbol.eq(name,anonSym) then names else path ! 52: | clean x = x ! 53: ! 54: fun instrdec(sp as (names,ccvara), VALdec vbl) = ! 55: let fun instrvb (vb as VB{pat=VARpat(VALvar{access=INLINE _,...}),...}) = vb ! 56: | instrvb (vb as VB{pat=CONSTRAINTpat ! 57: (VARpat (VALvar{access=INLINE _,...}),_),...}) = vb ! 58: | instrvb (VB{pat as VARpat(VALvar{access=LVAR v,name=[n],...}),exp,tyvars}) = ! 59: VB{pat=pat,exp=instrexp(n::clean names,ccvara)false exp, ! 60: tyvars=tyvars} ! 61: | instrvb (VB{pat,exp,tyvars}) = ! 62: VB{pat=pat, exp=instrexp sp false exp, tyvars=tyvars} ! 63: in VALdec (map instrvb vbl) ! 64: end ! 65: | instrdec(sp as (names,ccvara), VALRECdec rvbl) = ! 66: let fun instrrvb (RVB{var=var as VALvar{access=LVAR v, name=[n],...}, ! 67: exp,resultty,tyvars}) = ! 68: RVB{var=var, exp=instrexp (n::clean names, ccvara) false exp, ! 69: resultty=resultty, tyvars=tyvars} ! 70: | instrrvb _ = impossible "VALRECdec in instrdec" ! 71: in VALRECdec(map instrrvb rvbl) ! 72: end ! 73: | instrdec(sp, ABSTYPEdec {abstycs,withtycs,body}) = ! 74: ABSTYPEdec {abstycs=abstycs,withtycs=withtycs, body=instrdec(sp,body)} ! 75: | instrdec(sp, STRdec strbl) = STRdec (map (fn strb => instrstrb(sp,strb)) strbl) ! 76: | instrdec(sp, ABSdec strbl) = ABSdec (map (fn strb => instrstrb(sp,strb)) strbl) ! 77: | instrdec(sp, FCTdec fctbl) = FCTdec (map (fn fctb => instrfctb(sp,fctb)) fctbl) ! 78: | instrdec(sp, LOCALdec(localdec,visibledec)) = ! 79: LOCALdec(instrdec (sp,localdec), instrdec (sp,visibledec)) ! 80: | instrdec(sp, SEQdec decl) = SEQdec (map (fn dec => instrdec(sp,dec)) decl) ! 81: | instrdec(sp, MARKdec(dec,a,b)) = MARKdec(instrdec (sp,dec), a,b) ! 82: | instrdec(sp, other) = other ! 83: ! 84: and instrstrexp(names, STRUCTstr {body,locations}) = ! 85: STRUCTstr{body = (map (fn dec => instrdec((names,topCCa()),dec)) body), ! 86: locations=locations} ! 87: | instrstrexp(names, APPstr {oper,argexp,argthin}) = ! 88: APPstr{oper=oper, argexp=instrstrexp(names,argexp),argthin=argthin} ! 89: | instrstrexp(names, VARstr x) = VARstr x ! 90: | instrstrexp(names, LETstr(d,body)) = ! 91: LETstr(instrdec((names,topCCa()),d), instrstrexp(names,body)) ! 92: ! 93: and instrstrb ((names,ccvara), STRB{strvar=strvar as STRvar{name,...}, ! 94: def,thin,constraint}) = ! 95: STRB{strvar=strvar,def = instrstrexp(name@names,def), ! 96: thin=thin, constraint=constraint} ! 97: ! 98: and instrfctb ((names,ccvara), FCTB{fctvar=fctvar as FCTvar{name,...}, ! 99: param,def,thin,constraint}) = ! 100: FCTB{fctvar=fctvar,param=param,def=instrstrexp(name::names,def), ! 101: thin=thin, constraint=constraint} ! 102: ! 103: and instrexp(sp as (names,ccvara)) = ! 104: let fun istail tail = ! 105: let fun iinstr exp = istail false exp ! 106: fun oinstr exp = istail true exp ! 107: fun instrrules tr = map (fn (RULE(p,e)) => RULE(p, tr e)) ! 108: fun BUMPCCexp ccvara = ! 109: APPexp(VARexp(ref assop), ! 110: TUPLEexp[VARexp(ref ccvara), ! 111: APPexp(VARexp(ref addop), ! 112: TUPLEexp[APPexp(VARexp(ref derefop), ! 113: VARexp(ref ccvara)), ! 114: INTexp(1)])]) ! 115: fun SETCURRENTexp ccvara = ! 116: APPexp(VARexp(ref assop), ! 117: TUPLEexp[VARexp(ref (currentvar())), VARexp(ref ccvara)]) ! 118: val rec instr:(exp->exp) = ! 119: fn RECORDexp l => RECORDexp(map (fn (lab,exp) => (lab,iinstr exp)) l) ! 120: | SEQexp l => ! 121: let fun seq [e] = [instr e] ! 122: | seq (e::r) = (iinstr e)::(seq r) ! 123: | seq nil = nil ! 124: in SEQexp (seq l) ! 125: end ! 126: | APPexp (f,a) => ! 127: let fun safe(VARexp(ref(VALvar{access=INLINE P.callcc,...})))=false ! 128: | safe(VARexp(ref(VALvar{access=INLINE _,...}))) = true ! 129: | safe _ = false ! 130: in if tail orelse (safe f) ! 131: then APPexp (iinstr f, iinstr a) ! 132: else let val (lvarb,lvara) = tmpvar("appvar") ! 133: in LETexp (VALdec[VB{pat=VARpat(lvarb), ! 134: exp=APPexp(iinstr f, iinstr a), ! 135: tyvars=nil}], ! 136: SEQexp([SETCURRENTexp(ccvara), VARexp(ref lvara)])) ! 137: end ! 138: end ! 139: | CONSTRAINTexp(e,t) => CONSTRAINTexp(instr e, t) ! 140: | HANDLEexp (e, HANDLER(FNexp l))=> ! 141: let fun rule(RULE(p,e)) = ! 142: RULE(p,SEQexp[SETCURRENTexp ccvara, instr e]) ! 143: in HANDLEexp (instr e, HANDLER(FNexp(map rule l))) ! 144: end ! 145: | RAISEexp e => RAISEexp(oinstr e) ! 146: | LETexp (d,e) => LETexp (instrdec(sp,d), instr e) ! 147: | CASEexp (e,l) => CASEexp(iinstr e, instrrules instr l) ! 148: | FNexp l => ! 149: let fun dot (a,[z]) = Symbol.name z :: a ! 150: | dot (a,x::rest) = dot("." :: Symbol.name x :: a, rest) ! 151: | dot _ = impossible "no path in instrexp" ! 152: val name = implode (dot ([], names)) ! 153: val ccsym = symbol (name^".CC") ! 154: val ccvar = namedLvar(ccsym) ! 155: val ccvara' = VALvar{name=[ccsym], ! 156: access=PATH[ccvar], ! 157: typ = ref intreftype} ! 158: val (lvarb,lvara) = tmpvar "fnvar"; ! 159: in profileList := (ccvar,name) :: !profileList; ! 160: FNexp ([RULE(VARpat(lvarb), ! 161: SEQexp ([BUMPCCexp(ccvara'), ! 162: SETCURRENTexp(ccvara'), ! 163: CASEexp(VARexp(ref lvara), ! 164: instrrules (instrexp (anonSym::names, ! 165: ccvara') true) l)]))]) ! 166: end ! 167: | MARKexp(e,a,b) => MARKexp(instr e, a, b) ! 168: | e => e ! 169: in instr ! 170: end ! 171: in istail ! 172: end ! 173: ! 174: fun instrumDec absyn = ! 175: (profileList := []; ! 176: (if !profiling then instrdec(([],topCCa()),absyn) else absyn, !profileList)) ! 177: ! 178: fun instrumStrb absyn = ! 179: (profileList := []; ! 180: (if !profiling then instrstrb(([],topCCa()),absyn) else absyn, !profileList)) ! 181: ! 182: fun instrumFctb absyn = ! 183: (profileList := []; ! 184: (if !profiling then instrfctb(([],topCCa()),absyn) else absyn, !profileList)) ! 185: ! 186: fun bindLambda (lexp, profileList) = ! 187: fold (fn ((var,string),x) => APP(FN(var,x),STRING("aaaaaaaa"^string))) ! 188: profileList ! 189: (RECORD[lexp,RECORD(map (VAR o #1) profileList)]) ! 190: ! 191: end (* structure Instrum *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.