1*12066Sbaden (setq SCCS-fpMeasures.l "@(#)fpMeasures.l 1.1 04/27/83") 2*12066Sbaden ; FP interpreter/compiler 3*12066Sbaden ; Copyright (c) 1982 Scott B. Baden 4*12066Sbaden ; Berkeley, California 5*12066Sbaden ; Dynamics Statistics by Dorab Patel (UCLA) 6*12066Sbaden 7*12066Sbaden ; Initialize and update the 'Measures' plist with 8*12066Sbaden ; the run-time measurement data 9*12066Sbaden ; 10*12066Sbaden ; Special symbol 'TracedFns' also manipulated 11*12066Sbaden ; It contains the list of currently traced user defined functions. 12*12066Sbaden ; The attributes for each functional form and function are: 13*12066Sbaden 14*12066Sbaden ; times: the total number of times it has been called 15*12066Sbaden ; size: the sum of the top-level sizes of the arguments given to it 16*12066Sbaden ; funargno: the number of functional arguments to this form 17*12066Sbaden ; (in general this is only for construct) 18*12066Sbaden ; funargtype: the type and total number of functions of that type 19*12066Sbaden ; supplied to this functional form. 20*12066Sbaden ; This is an alist ((fntype.times) ...) 21*12066Sbaden 22*12066Sbaden 23*12066Sbaden 24*12066Sbaden (include specials.l) 25*12066Sbaden (declare (special statport dummy)) 26*12066Sbaden (declare (localf InitSize InitFunArgTyp 27*12066Sbaden InitFunArgNo trace1 28*12066Sbaden extractName goodStats 29*12066Sbaden untrace1 SendMeasures)) 30*12066Sbaden 31*12066Sbaden 32*12066Sbaden ; The following functions are global. i.e. used externally 33*12066Sbaden ; startDynStats clrDynStats IncrTimes IncrSize 34*12066Sbaden ; IncrFunArgNo IncrFunArgTyp size Trace 35*12066Sbaden ; PrintMeasures IncrUDF Untrace stopDynStats 36*12066Sbaden 37*12066Sbaden ; This is called by the main routine to initialize all the 38*12066Sbaden ; measurement stuff 39*12066Sbaden 40*12066Sbaden 41*12066Sbaden (defun clrDynStats nil 42*12066Sbaden (dontLoseStats) 43*12066Sbaden (initStats)) 44*12066Sbaden 45*12066Sbaden 46*12066Sbaden (defun dontLoseStats nil 47*12066Sbaden (cond ((goodStats) ; check to see if there are stats to report 48*12066Sbaden (patom "output dynamic statistics? ") 49*12066Sbaden (let ((response (car (explodec (ratom))))) 50*12066Sbaden (If ptport then (msg (P ptport) response)) 51*12066Sbaden 52*12066Sbaden (Tyi) 53*12066Sbaden (cond ((eq response 'y) 54*12066Sbaden (patom "File: ") 55*12066Sbaden (let ((statFile 56*12066Sbaden (cond ((eq (tyipeek) #.CR) nil) 57*12066Sbaden (t 58*12066Sbaden (let ((fl (ratom))) 59*12066Sbaden (If ptport then (msg (P ptport) fl)) 60*12066Sbaden fl))))) 61*12066Sbaden (Tyi) 62*12066Sbaden (PrintMeasures statFile)))))))) 63*12066Sbaden 64*12066Sbaden (defun initStats nil 65*12066Sbaden 66*12066Sbaden (InitMeasures 67*12066Sbaden `(,@#.dyadFns 68*12066Sbaden ,@#.miscFns 69*12066Sbaden ,@#.multiAdicFns 70*12066Sbaden ,@#.libFns 71*12066Sbaden ,@#.funcForms)) 72*12066Sbaden 73*12066Sbaden (InitSize #.multiAdicFns) 74*12066Sbaden (InitSize #.funcForms) 75*12066Sbaden (InitFunArgNo '(constr$fp)) 76*12066Sbaden 77*12066Sbaden ; included here even though it's not a functional form 78*12066Sbaden (InitFunArgTyp '(select$fp)) 79*12066Sbaden 80*12066Sbaden (InitFunArgTyp #.funcForms)) 81*12066Sbaden 82*12066Sbaden 83*12066Sbaden ; Makes the symbol 'Measures' have the property indicators 84*12066Sbaden ; corresponding to the function names in 'ListOfFns' and the values 85*12066Sbaden ; to be ((times.0)). 86*12066Sbaden 87*12066Sbaden (defun InitMeasures (ListOfFns) 88*12066Sbaden (setplist 'Measures 89*12066Sbaden (apply 'append 90*12066Sbaden (mapcar '(lambda (x) (list x (list (cons 'times 0)))) 91*12066Sbaden ListOfFns)))) 92*12066Sbaden 93*12066Sbaden (defun goodStats nil 94*12066Sbaden (do ((M (plist 'Measures) (cddr M))) 95*12066Sbaden ((null M) nil) 96*12066Sbaden (cond ((not (zerop (cdr (assoc 'times (cadr M))))) 97*12066Sbaden (return t))))) 98*12066Sbaden 99*12066Sbaden 100*12066Sbaden ; This is used to stop the collection of dynamic statistics 101*12066Sbaden ; needs to untrace functions if they still are. i.e. do the traced-expr stuff 102*12066Sbaden ; note that rds which calls this, also calls PrintMeasures, though 103*12066Sbaden ; this may change. 104*12066Sbaden 105*12066Sbaden (defun stopDynStats nil 106*12066Sbaden (cond (TracedFns ; if any fns still being traced 107*12066Sbaden (Untrace TracedFns))) ; untrace them 108*12066Sbaden (setq DynTraceFlg nil)) 109*12066Sbaden 110*12066Sbaden (defun extractName (fnName) 111*12066Sbaden (patom 112*12066Sbaden (implode (reverse (cons "'" (cdddr (reverse (explodec (concat "'" fnName))))))))) 113*12066Sbaden 114*12066Sbaden ; this is the function called by the system function trace to 115*12066Sbaden ; enable the tracing of the User Defined Functions specified 116*12066Sbaden ; NOTE: successive calls will add to the UDFs to be traced. 117*12066Sbaden 118*12066Sbaden (defun Trace (arglist) 119*12066Sbaden (setq traceport poport) 120*12066Sbaden (mapc '(lambda (x) 121*12066Sbaden (cond ((memq x TracedFns) ; if already traced 122*12066Sbaden (setq arglist 123*12066Sbaden (delq x arglist 1)) ; delete from arglist 124*12066Sbaden (extractName x) ; and tell the user 125*12066Sbaden (patom " is already being traced") 126*12066Sbaden (terpr)))) 127*12066Sbaden arglist) 128*12066Sbaden (mapc 'trace1 arglist)) ; set up traced-expr stuff 129*12066Sbaden 130*12066Sbaden ; This is called by the system function untrace to disable the tracing 131*12066Sbaden ; of user defined functions. 132*12066Sbaden ; This removes the named user defined function from the list 133*12066Sbaden ; of traced functions 134*12066Sbaden 135*12066Sbaden (defun Untrace (arglist) 136*12066Sbaden (mapc '(lambda (x) 137*12066Sbaden (cond ((memq x TracedFns) ; if being traced 138*12066Sbaden (setq TracedFns (delq x TracedFns)) ; remove 139*12066Sbaden (untrace1 x)) ; restore stuff 140*12066Sbaden (t (extractName x) ; else complain 141*12066Sbaden (patom " is not being traced") 142*12066Sbaden (terpr)))) 143*12066Sbaden arglist)) 144*12066Sbaden 145*12066Sbaden ; This is called by Trace on each individual function that is to 146*12066Sbaden ; be traced. It does the manipulation of the traced-expr property 147*12066Sbaden 148*12066Sbaden (defun trace1 (name) 149*12066Sbaden ; actually you should check for getd name returning something decent 150*12066Sbaden (let ((zExpr (getd name))) 151*12066Sbaden (cond ((null zExpr) 152*12066Sbaden (patom "Can't trace the undefined fn ") 153*12066Sbaden (extractName name) 154*12066Sbaden (patom ".") 155*12066Sbaden (terpr)) 156*12066Sbaden 157*12066Sbaden (t 158*12066Sbaden (putprop name zExpr 'traced-expr) ; put fn def on traced-expr 159*12066Sbaden (setq TracedFns (append1 TracedFns name)) ; update TracedFns 160*12066Sbaden (InitUDF name) ; set up the measurement stuff 161*12066Sbaden (putd name ; make a new function def 162*12066Sbaden `(lambda (x) 163*12066Sbaden (prog (tmp) 164*12066Sbaden (setq level (1+ level)) ; increment level counter 165*12066Sbaden (printLevel) 166*12066Sbaden (patom " >Enter> " traceport) 167*12066Sbaden (patom (extName ',name) traceport) 168*12066Sbaden (patom " [" traceport) 169*12066Sbaden (d_isplay x traceport) 170*12066Sbaden (patom "]" traceport) 171*12066Sbaden (terpri traceport) 172*12066Sbaden ; now call the actual function 173*12066Sbaden (setq tmp (funcall (get ',name 'traced-expr) x)) 174*12066Sbaden (printLevel) 175*12066Sbaden (patom " <EXIT< " traceport) ; now print epilog 176*12066Sbaden (patom (extName ',name) traceport) 177*12066Sbaden (patom " " traceport) 178*12066Sbaden (d_isplay tmp traceport) 179*12066Sbaden (terpri traceport) 180*12066Sbaden (return tmp)))))))) ; return the return value 181*12066Sbaden 182*12066Sbaden 183*12066Sbaden 184*12066Sbaden (defun extName (fnName) 185*12066Sbaden (let ((zzName (reverse (explodec fnName)))) 186*12066Sbaden (cond ((memq '$ zzName) (implode (reverse (cdr (memq '$ zzName))))) 187*12066Sbaden (t (implode (reverse (cdr (memq '_ zzName)))))))) 188*12066Sbaden 189*12066Sbaden 190*12066Sbaden (defun printLevel nil 191*12066Sbaden (do ((counter 1 (1+ counter))) 192*12066Sbaden ((eq counter level) (patom level traceport)) 193*12066Sbaden (cond ((oddp counter) (patom "|" traceport)) 194*12066Sbaden (t (patom " " traceport))))) 195*12066Sbaden 196*12066Sbaden ; This is called by Untrace for each individaul function to be untraced. 197*12066Sbaden ; It handles the traced-expr property hassles. 198*12066Sbaden 199*12066Sbaden (defun untrace1 (name) 200*12066Sbaden (let ((tmp (get name 'traced-expr))) 201*12066Sbaden (cond ((null tmp) ; if the traced-expr property is unreasonable 202*12066Sbaden ; a better check for unreasonableness is needed 203*12066Sbaden (extractName name) ; complain 204*12066Sbaden (patom " was not traced properly - cant restore") 205*12066Sbaden (terpr)) 206*12066Sbaden (t (putd name tmp) ; else restore and remove the traced-expr 207*12066Sbaden (remprop name 'traced-expr))))) 208*12066Sbaden 209*12066Sbaden ; sz is a function that returns the total number of atoms in its argument 210*12066Sbaden 211*12066Sbaden (defun sz (x) 212*12066Sbaden (cond ((null x) 0) 213*12066Sbaden ((atom x) 1) 214*12066Sbaden (t (add (size (car x)) 215*12066Sbaden (size (cdr x)))))) 216*12066Sbaden 217*12066Sbaden ; inc is a macro used by the increment functions 218*12066Sbaden 219*12066Sbaden (defmacro inc (x) 220*12066Sbaden `(rplacd ,x (1+ (cdr ,x)))) 221*12066Sbaden 222*12066Sbaden ; inctimes is a macro used by IncrFunArgNo 223*12066Sbaden 224*12066Sbaden (defmacro inctimes (x times) 225*12066Sbaden `(rplacd ,x (add times (cdr ,x)))) 226*12066Sbaden 227*12066Sbaden ; increment the 'funargno' attribute of the functional form 228*12066Sbaden 229*12066Sbaden (defun IncrFunArgNo (fform times) 230*12066Sbaden (inctimes (sassq 'funargno 231*12066Sbaden (get 'Measures fform) 232*12066Sbaden '(lambda () 233*12066Sbaden (cprintf "error: %s has no funargno" 234*12066Sbaden fform) 235*12066Sbaden (terpr) 236*12066Sbaden (break))) 237*12066Sbaden times)) 238*12066Sbaden 239*12066Sbaden ; increment the 'funargtyp' information of the functional form 240*12066Sbaden ; if the particular function/form has never yet been used with his 241*12066Sbaden ; functional form, create the entry 242*12066Sbaden 243*12066Sbaden (defun IncrFunArgTyp (fform funct) 244*12066Sbaden (inc (sassoc funct ; get (fn.#oftimes). This has to be sassoc NOT sassq. 245*12066Sbaden (cadr (sassq 'funargtyp ; get (funargtyp ...) 246*12066Sbaden (get 'Measures fform) 247*12066Sbaden '(lambda () 248*12066Sbaden (cprintf "error: %s has no funargtyp" 249*12066Sbaden fform) 250*12066Sbaden (terpr) 251*12066Sbaden (break)))) 252*12066Sbaden ; 'funargtyp' was there but not the funct 253*12066Sbaden ; should return (fn.#oftimes) 254*12066Sbaden '(lambda () 255*12066Sbaden (cond ((setq dummy (cadr (assq 'funargtyp 256*12066Sbaden (get 'Measures fform)))) 257*12066Sbaden ; the alist is not empty and we 258*12066Sbaden ; know that funct was not there 259*12066Sbaden (assq funct 260*12066Sbaden (nconc dummy 261*12066Sbaden (list (cons funct 0))))) 262*12066Sbaden ; the alist is empty, so add the element 263*12066Sbaden (t (assq funct 264*12066Sbaden (cadr (nconc (assq 'funargtyp 265*12066Sbaden (get 'Measures fform)) 266*12066Sbaden (list (list (cons funct 0)))))))))))) 267*12066Sbaden ; increment the 'times' attribute of the function 268*12066Sbaden 269*12066Sbaden (defun IncrTimes (funct) 270*12066Sbaden (inc (assq 'times (get 'Measures funct)))) 271*12066Sbaden 272*12066Sbaden ; update the 'avg arg size' attribute of the function 273*12066Sbaden ; actually it is the total size. it should be divided by the 'times' 274*12066Sbaden ; attribute to get the avg size. 275*12066Sbaden 276*12066Sbaden (defun IncrSize (funct size) 277*12066Sbaden (rplacd (assq 'size (get 'Measures funct)) 278*12066Sbaden (add (cdr (assq 'size (get 'Measures funct))) 279*12066Sbaden size))) 280*12066Sbaden 281*12066Sbaden ; This adds the given function as a property of Measures and 282*12066Sbaden ; initializes it to have the 'times' and 'size' attributes. 283*12066Sbaden 284*12066Sbaden (defun InitUDF (UDF) 285*12066Sbaden (putprop 'Measures '((times . 0) (size . 0)) UDF)) 286*12066Sbaden 287*12066Sbaden 288*12066Sbaden ; This increments the times and the size atribute of a UDF, if it exists 289*12066Sbaden ; Otherwise, it does nothing. 290*12066Sbaden 291*12066Sbaden (defun IncrUDF (UDF seq) 292*12066Sbaden (cond 293*12066Sbaden ((and (memq UDF TracedFns) (get 'Measures UDF)) ;if the UDF is traceable 294*12066Sbaden (IncrTimes UDF) 295*12066Sbaden (IncrSize UDF (size seq))))) 296*12066Sbaden 297*12066Sbaden ; This adds the 'size' attribute to the alist corresponding to each 298*12066Sbaden ; function in 'FnList' and initializes the value to 0. 299*12066Sbaden 300*12066Sbaden (defun InitSize (FnList) 301*12066Sbaden (mapcar '(lambda (funct) (nconc (get 'Measures funct) (list (cons 'size 0)))) 302*12066Sbaden FnList)) 303*12066Sbaden 304*12066Sbaden ; This adds the 'funargtyp' (functional argument type) attribute to 305*12066Sbaden ; the alist corresponding to each functional form in 'FnFormList' and 306*12066Sbaden ; initializes the value to nil. 307*12066Sbaden 308*12066Sbaden (defun InitFunArgTyp (FnFormList) 309*12066Sbaden (mapcar '(lambda (fform) 310*12066Sbaden (nconc (get 'Measures fform) 311*12066Sbaden (list (list 'funargtyp)))) 312*12066Sbaden FnFormList)) 313*12066Sbaden 314*12066Sbaden ; This adds the 'funargno' (number of functional args) attribute to 315*12066Sbaden ; the alist correphsponding to each functional form in 'FnFormList' 316*12066Sbaden ; and initializes the value to 0. 317*12066Sbaden 318*12066Sbaden (defun InitFunArgNo (FnFormList) 319*12066Sbaden (mapcar '(lambda (fform) 320*12066Sbaden (nconc (get 'Measures fform) 321*12066Sbaden (list (cons 'funargno 0)))) 322*12066Sbaden FnFormList)) 323*12066Sbaden 324*12066Sbaden ; Prints out the stats to a file 325*12066Sbaden 326*12066Sbaden (defun PrintMeasures (sFileName) 327*12066Sbaden (cond (sFileName 328*12066Sbaden (let ((statPort nil)) 329*12066Sbaden (cond ((setq statPort (outfile sFileName 'append)) 330*12066Sbaden (SendMeasures statPort) ; write the stuff 331*12066Sbaden (terpri statPort) 332*12066Sbaden (close statPort)) 333*12066Sbaden (t (terpr) 334*12066Sbaden (patom "Cannot open statFile") 335*12066Sbaden (terpr))))) 336*12066Sbaden (t (SendMeasures nil)))) 337*12066Sbaden 338*12066Sbaden 339*12066Sbaden ; Traverses the Measures structure and prints out the 340*12066Sbaden ; info onto 'port'. 341*12066Sbaden ; Also removes the attributes from Measures (during traversal) 342*12066Sbaden 343*12066Sbaden (defun SendMeasures (port) 344*12066Sbaden (do ((functlist (plist 'Measures) 345*12066Sbaden (cddr functlist)));for each alternate elem in functlist 346*12066Sbaden ((null functlist)) ; end when all done 347*12066Sbaden (let ((fnStats (cadr functlist))) 348*12066Sbaden (cond ((and fnStats (not (zerop (cdr (assoc 'times fnStats))))) 349*12066Sbaden (cprintf "%s:" (printName (car functlist)) port) 350*12066Sbaden (do ((proplist fnStats (cdr proplist))) 351*12066Sbaden ((null proplist)) 352*12066Sbaden (let ((prop (car proplist))) ; for each prop in proplist 353*12066Sbaden (cond ((eq (car prop) 'funargtyp) ; if it is funargtyp 354*12066Sbaden (doFuncArg port prop)) 355*12066Sbaden (t (cprintf " %s" (car prop) port);if not funargtyp 356*12066Sbaden (cprintf " %d" (cdr prop) port))))) 357*12066Sbaden ; end of function 358*12066Sbaden (terpri port) 359*12066Sbaden (terpri port)))))); a newline separates functions 360*12066Sbaden 361*12066Sbaden (defun doFuncArg (port prop) 362*12066Sbaden (terpri port) 363*12066Sbaden (terpri port) 364*12066Sbaden (cprintf " Functional Args" nil port) 365*12066Sbaden (terpri port) 366*12066Sbaden (cprintf " Name Times" nil port) 367*12066Sbaden (terpri port) 368*12066Sbaden (do ((funclist (cadr prop) (cdr funclist))) 369*12066Sbaden ((null funclist)) 370*12066Sbaden (cprintf " " nil port) 371*12066Sbaden (patom (printName (caar funclist)) port) 372*12066Sbaden (cprintf " %d" (cdar funclist) port) 373*12066Sbaden (terpri port))) 374*12066Sbaden 375*12066Sbaden (defun printName (fnName) 376*12066Sbaden (let ((zzName (reverse (explodec fnName))) 377*12066Sbaden (tName nil)) 378*12066Sbaden (setq tName (memq '$ zzName)) 379*12066Sbaden (cond (tName (implode (reverse (cdr tName)))) 380*12066Sbaden (t 381*12066Sbaden (setq tName (memq '_ zzName)) 382*12066Sbaden (cond (tName (implode (reverse (cdr tName)))) 383*12066Sbaden ((stringp fnName) (concat '|"| fnName '|"|)) 384*12066Sbaden (t (put_obj fnName))))))) 385*12066Sbaden 386*12066Sbaden ; this is the same as the function in fp_main.l except that it takes 387*12066Sbaden ; an extra argument which is the port name. it is used for printing 388*12066Sbaden ; out a lisp object in the FP form 389*12066Sbaden 390*12066Sbaden (defun d_isplay (obj port) 391*12066Sbaden (cond ((null obj) (patom "<>" port)) 392*12066Sbaden ((atom obj) (patom obj port)) 393*12066Sbaden ((listp obj) 394*12066Sbaden (patom "<" port) 395*12066Sbaden (maplist 396*12066Sbaden '(lambda (x) 397*12066Sbaden (d_isplay (car x) port) 398*12066Sbaden (cond ((not (onep (length x))) (patom " " port)))) obj) 399*12066Sbaden (patom ">" port)))) 400*12066Sbaden 401*12066Sbaden 402*12066Sbaden (defun measAlph (al seq) 403*12066Sbaden (IncrFunArgTyp 'alpha$fp al) 404*12066Sbaden (IncrTimes 'alpha$fp) 405*12066Sbaden (IncrSize 'alpha$fp (size seq))) 406*12066Sbaden 407*12066Sbaden (defun measIns (ins seq) 408*12066Sbaden (IncrFunArgTyp 'insert$fp ins) 409*12066Sbaden (IncrTimes 'insert$fp) 410*12066Sbaden (IncrSize 'insert$fp (size seq))) 411*12066Sbaden 412*12066Sbaden (defun measTi (ains seq) 413*12066Sbaden (IncrFunArgTyp 'ti$fp ains) 414*12066Sbaden (IncrTimes 'ti$fp) 415*12066Sbaden (IncrSize 'ti$fp (size seq))) 416*12066Sbaden 417*12066Sbaden (defun measSel (sel seq) 418*12066Sbaden (IncrFunArgTyp 'select$fp sel) 419*12066Sbaden (IncrTimes 'select$fp) 420*12066Sbaden (IncrSize 'select$fp (size seq))) 421*12066Sbaden 422*12066Sbaden (defun measCons (cons seq) 423*12066Sbaden (IncrFunArgTyp 'constant$fp cons) 424*12066Sbaden (IncrTimes 'constant$fp) 425*12066Sbaden (IncrSize 'constant$fp (size seq))) 426*12066Sbaden 427*12066Sbaden (defun measCond (c1 c2 c3 seq) 428*12066Sbaden (IncrFunArgTyp 'condit$fp c1) 429*12066Sbaden (IncrFunArgTyp 'condit$fp c2) 430*12066Sbaden (IncrFunArgTyp 'condit$fp c3) 431*12066Sbaden (IncrTimes 'condit$fp) 432*12066Sbaden (IncrSize 'condit$fp (size seq))) 433*12066Sbaden 434*12066Sbaden (defun measWhile (w1 w2 seq) 435*12066Sbaden (IncrFunArgTyp 'while$fp w1) 436*12066Sbaden (IncrFunArgTyp 'while$fp w2) 437*12066Sbaden (IncrTimes 'while$fp) 438*12066Sbaden (IncrSize 'while$fp (size seq))) 439*12066Sbaden 440*12066Sbaden (defun measComp (cm1 cm2 seq) 441*12066Sbaden (IncrFunArgTyp 'compos$fp cm1) 442*12066Sbaden (IncrFunArgTyp 'compos$fp cm2) 443*12066Sbaden (IncrTimes 'compos$fp) 444*12066Sbaden (IncrSize 'compos$fp (size seq))) 445*12066Sbaden 446*12066Sbaden (defun measConstr (fns seq) 447*12066Sbaden (mapcar '(lambda (x) (IncrFunArgTyp 'constr$fp x)) fns) 448*12066Sbaden (IncrFunArgNo 'constr$fp (length fns)) 449*12066Sbaden (IncrTimes 'constr$fp) 450*12066Sbaden (IncrSize 'constr$fp (size seq))) 451*12066Sbaden 452*12066Sbaden ; get the corect name of the functional form 453*12066Sbaden 454*12066Sbaden (defmacro getFform (xx) 455*12066Sbaden `(implode (nreverse `(p f ,@(cdr (nreverse (explodec (cxr 0 ,xx)))))))) 456*12066Sbaden 457