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