112066Sbaden ; FP interpreter/compiler 212066Sbaden ; Copyright (c) 1982 Scott B. Baden 312066Sbaden ; Berkeley, California 412066Sbaden ; Dynamics Statistics by Dorab Patel (UCLA) 5*21727Sdist ; 6*21727Sdist ; Copyright (c) 1982 Regents of the University of California. 7*21727Sdist ; All rights reserved. The Berkeley software License Agreement 8*21727Sdist ; specifies the terms and conditions for redistribution. 9*21727Sdist ; 10*21727Sdist (setq SCCS-fpMeasures.l "@(#)fpMeasures.l 5.1 (Berkeley) 05/31/85") 1112066Sbaden 1212066Sbaden ; Initialize and update the 'Measures' plist with 1312066Sbaden ; the run-time measurement data 1412066Sbaden ; 1512066Sbaden ; Special symbol 'TracedFns' also manipulated 1612066Sbaden ; It contains the list of currently traced user defined functions. 1712066Sbaden ; The attributes for each functional form and function are: 1812066Sbaden 1912066Sbaden ; times: the total number of times it has been called 2012066Sbaden ; size: the sum of the top-level sizes of the arguments given to it 2112066Sbaden ; funargno: the number of functional arguments to this form 2212066Sbaden ; (in general this is only for construct) 2312066Sbaden ; funargtype: the type and total number of functions of that type 2412066Sbaden ; supplied to this functional form. 2512066Sbaden ; This is an alist ((fntype.times) ...) 2612066Sbaden 2712066Sbaden 2812066Sbaden 2912066Sbaden (include specials.l) 3012066Sbaden (declare (special statport dummy)) 3112066Sbaden (declare (localf InitSize InitFunArgTyp 3212066Sbaden InitFunArgNo trace1 3312066Sbaden extractName goodStats 3412066Sbaden untrace1 SendMeasures)) 3512066Sbaden 3612066Sbaden 3712066Sbaden ; The following functions are global. i.e. used externally 3812066Sbaden ; startDynStats clrDynStats IncrTimes IncrSize 3912066Sbaden ; IncrFunArgNo IncrFunArgTyp size Trace 4012066Sbaden ; PrintMeasures IncrUDF Untrace stopDynStats 4112066Sbaden 4212066Sbaden ; This is called by the main routine to initialize all the 4312066Sbaden ; measurement stuff 4412066Sbaden 4512066Sbaden 4612066Sbaden (defun clrDynStats nil 4712066Sbaden (dontLoseStats) 4812066Sbaden (initStats)) 4912066Sbaden 5012066Sbaden 5112066Sbaden (defun dontLoseStats nil 5212066Sbaden (cond ((goodStats) ; check to see if there are stats to report 5312066Sbaden (patom "output dynamic statistics? ") 5412066Sbaden (let ((response (car (explodec (ratom))))) 5512066Sbaden (If ptport then (msg (P ptport) response)) 5612066Sbaden 5712066Sbaden (Tyi) 5812066Sbaden (cond ((eq response 'y) 5912066Sbaden (patom "File: ") 6012066Sbaden (let ((statFile 6112066Sbaden (cond ((eq (tyipeek) #.CR) nil) 6212066Sbaden (t 6312066Sbaden (let ((fl (ratom))) 6412066Sbaden (If ptport then (msg (P ptport) fl)) 6512066Sbaden fl))))) 6612066Sbaden (Tyi) 6712066Sbaden (PrintMeasures statFile)))))))) 6812066Sbaden 6912066Sbaden (defun initStats nil 7012066Sbaden 7112066Sbaden (InitMeasures 7212066Sbaden `(,@#.dyadFns 7312066Sbaden ,@#.miscFns 7412066Sbaden ,@#.multiAdicFns 7512066Sbaden ,@#.libFns 7612066Sbaden ,@#.funcForms)) 7712066Sbaden 7812066Sbaden (InitSize #.multiAdicFns) 7912066Sbaden (InitSize #.funcForms) 8012066Sbaden (InitFunArgNo '(constr$fp)) 8112066Sbaden 8212066Sbaden ; included here even though it's not a functional form 8312066Sbaden (InitFunArgTyp '(select$fp)) 8412066Sbaden 8512066Sbaden (InitFunArgTyp #.funcForms)) 8612066Sbaden 8712066Sbaden 8812066Sbaden ; Makes the symbol 'Measures' have the property indicators 8912066Sbaden ; corresponding to the function names in 'ListOfFns' and the values 9012066Sbaden ; to be ((times.0)). 9112066Sbaden 9212066Sbaden (defun InitMeasures (ListOfFns) 9312066Sbaden (setplist 'Measures 9412066Sbaden (apply 'append 9512066Sbaden (mapcar '(lambda (x) (list x (list (cons 'times 0)))) 9612066Sbaden ListOfFns)))) 9712066Sbaden 9812066Sbaden (defun goodStats nil 9912066Sbaden (do ((M (plist 'Measures) (cddr M))) 10012066Sbaden ((null M) nil) 10112066Sbaden (cond ((not (zerop (cdr (assoc 'times (cadr M))))) 10212066Sbaden (return t))))) 10312066Sbaden 10412066Sbaden 10512066Sbaden ; This is used to stop the collection of dynamic statistics 10612066Sbaden ; needs to untrace functions if they still are. i.e. do the traced-expr stuff 10712066Sbaden ; note that rds which calls this, also calls PrintMeasures, though 10812066Sbaden ; this may change. 10912066Sbaden 11012066Sbaden (defun stopDynStats nil 11112066Sbaden (cond (TracedFns ; if any fns still being traced 11212066Sbaden (Untrace TracedFns))) ; untrace them 11312066Sbaden (setq DynTraceFlg nil)) 11412066Sbaden 11512066Sbaden (defun extractName (fnName) 11612066Sbaden (patom 11712066Sbaden (implode (reverse (cons "'" (cdddr (reverse (explodec (concat "'" fnName))))))))) 11812066Sbaden 11912066Sbaden ; this is the function called by the system function trace to 12012066Sbaden ; enable the tracing of the User Defined Functions specified 12112066Sbaden ; NOTE: successive calls will add to the UDFs to be traced. 12212066Sbaden 12312066Sbaden (defun Trace (arglist) 12412066Sbaden (setq traceport poport) 12512066Sbaden (mapc '(lambda (x) 12612066Sbaden (cond ((memq x TracedFns) ; if already traced 12712066Sbaden (setq arglist 12812066Sbaden (delq x arglist 1)) ; delete from arglist 12912066Sbaden (extractName x) ; and tell the user 13012066Sbaden (patom " is already being traced") 13112066Sbaden (terpr)))) 13212066Sbaden arglist) 13312066Sbaden (mapc 'trace1 arglist)) ; set up traced-expr stuff 13412066Sbaden 13512066Sbaden ; This is called by the system function untrace to disable the tracing 13612066Sbaden ; of user defined functions. 13712066Sbaden ; This removes the named user defined function from the list 13812066Sbaden ; of traced functions 13912066Sbaden 14012066Sbaden (defun Untrace (arglist) 14112066Sbaden (mapc '(lambda (x) 14212066Sbaden (cond ((memq x TracedFns) ; if being traced 14312066Sbaden (setq TracedFns (delq x TracedFns)) ; remove 14412066Sbaden (untrace1 x)) ; restore stuff 14512066Sbaden (t (extractName x) ; else complain 14612066Sbaden (patom " is not being traced") 14712066Sbaden (terpr)))) 14812066Sbaden arglist)) 14912066Sbaden 15012066Sbaden ; This is called by Trace on each individual function that is to 15112066Sbaden ; be traced. It does the manipulation of the traced-expr property 15212066Sbaden 15312066Sbaden (defun trace1 (name) 15412066Sbaden ; actually you should check for getd name returning something decent 15512066Sbaden (let ((zExpr (getd name))) 15612066Sbaden (cond ((null zExpr) 15712066Sbaden (patom "Can't trace the undefined fn ") 15812066Sbaden (extractName name) 15912066Sbaden (patom ".") 16012066Sbaden (terpr)) 16112066Sbaden 16212066Sbaden (t 16312066Sbaden (putprop name zExpr 'traced-expr) ; put fn def on traced-expr 16412066Sbaden (setq TracedFns (append1 TracedFns name)) ; update TracedFns 16512066Sbaden (InitUDF name) ; set up the measurement stuff 16612066Sbaden (putd name ; make a new function def 16712066Sbaden `(lambda (x) 16812066Sbaden (prog (tmp) 16912066Sbaden (setq level (1+ level)) ; increment level counter 17012066Sbaden (printLevel) 17112066Sbaden (patom " >Enter> " traceport) 17212066Sbaden (patom (extName ',name) traceport) 17312066Sbaden (patom " [" traceport) 17412066Sbaden (d_isplay x traceport) 17512066Sbaden (patom "]" traceport) 17612066Sbaden (terpri traceport) 17712066Sbaden ; now call the actual function 17812066Sbaden (setq tmp (funcall (get ',name 'traced-expr) x)) 17912066Sbaden (printLevel) 18012066Sbaden (patom " <EXIT< " traceport) ; now print epilog 18112066Sbaden (patom (extName ',name) traceport) 18212066Sbaden (patom " " traceport) 18312066Sbaden (d_isplay tmp traceport) 18412066Sbaden (terpri traceport) 18512066Sbaden (return tmp)))))))) ; return the return value 18612066Sbaden 18712066Sbaden 18812066Sbaden 18912066Sbaden (defun extName (fnName) 19012066Sbaden (let ((zzName (reverse (explodec fnName)))) 19112066Sbaden (cond ((memq '$ zzName) (implode (reverse (cdr (memq '$ zzName))))) 19212066Sbaden (t (implode (reverse (cdr (memq '_ zzName)))))))) 19312066Sbaden 19412066Sbaden 19512066Sbaden (defun printLevel nil 19612066Sbaden (do ((counter 1 (1+ counter))) 19712066Sbaden ((eq counter level) (patom level traceport)) 19812066Sbaden (cond ((oddp counter) (patom "|" traceport)) 19912066Sbaden (t (patom " " traceport))))) 20012066Sbaden 20112066Sbaden ; This is called by Untrace for each individaul function to be untraced. 20212066Sbaden ; It handles the traced-expr property hassles. 20312066Sbaden 20412066Sbaden (defun untrace1 (name) 20512066Sbaden (let ((tmp (get name 'traced-expr))) 20612066Sbaden (cond ((null tmp) ; if the traced-expr property is unreasonable 20712066Sbaden ; a better check for unreasonableness is needed 20812066Sbaden (extractName name) ; complain 20912066Sbaden (patom " was not traced properly - cant restore") 21012066Sbaden (terpr)) 21112066Sbaden (t (putd name tmp) ; else restore and remove the traced-expr 21212066Sbaden (remprop name 'traced-expr))))) 21312066Sbaden 21412066Sbaden ; sz is a function that returns the total number of atoms in its argument 21512066Sbaden 21612066Sbaden (defun sz (x) 21712066Sbaden (cond ((null x) 0) 21812066Sbaden ((atom x) 1) 21912066Sbaden (t (add (size (car x)) 22012066Sbaden (size (cdr x)))))) 22112066Sbaden 22212066Sbaden ; inc is a macro used by the increment functions 22312066Sbaden 22412066Sbaden (defmacro inc (x) 22512066Sbaden `(rplacd ,x (1+ (cdr ,x)))) 22612066Sbaden 22712066Sbaden ; inctimes is a macro used by IncrFunArgNo 22812066Sbaden 22912066Sbaden (defmacro inctimes (x times) 23012066Sbaden `(rplacd ,x (add times (cdr ,x)))) 23112066Sbaden 23212066Sbaden ; increment the 'funargno' attribute of the functional form 23312066Sbaden 23412066Sbaden (defun IncrFunArgNo (fform times) 23512066Sbaden (inctimes (sassq 'funargno 23612066Sbaden (get 'Measures fform) 23712066Sbaden '(lambda () 23812066Sbaden (cprintf "error: %s has no funargno" 23912066Sbaden fform) 24012066Sbaden (terpr) 24112066Sbaden (break))) 24212066Sbaden times)) 24312066Sbaden 24412066Sbaden ; increment the 'funargtyp' information of the functional form 24512066Sbaden ; if the particular function/form has never yet been used with his 24612066Sbaden ; functional form, create the entry 24712066Sbaden 24812066Sbaden (defun IncrFunArgTyp (fform funct) 24912066Sbaden (inc (sassoc funct ; get (fn.#oftimes). This has to be sassoc NOT sassq. 25012066Sbaden (cadr (sassq 'funargtyp ; get (funargtyp ...) 25112066Sbaden (get 'Measures fform) 25212066Sbaden '(lambda () 25312066Sbaden (cprintf "error: %s has no funargtyp" 25412066Sbaden fform) 25512066Sbaden (terpr) 25612066Sbaden (break)))) 25712066Sbaden ; 'funargtyp' was there but not the funct 25812066Sbaden ; should return (fn.#oftimes) 25912066Sbaden '(lambda () 26012066Sbaden (cond ((setq dummy (cadr (assq 'funargtyp 26112066Sbaden (get 'Measures fform)))) 26212066Sbaden ; the alist is not empty and we 26312066Sbaden ; know that funct was not there 26412066Sbaden (assq funct 26512066Sbaden (nconc dummy 26612066Sbaden (list (cons funct 0))))) 26712066Sbaden ; the alist is empty, so add the element 26812066Sbaden (t (assq funct 26912066Sbaden (cadr (nconc (assq 'funargtyp 27012066Sbaden (get 'Measures fform)) 27112066Sbaden (list (list (cons funct 0)))))))))))) 27212066Sbaden ; increment the 'times' attribute of the function 27312066Sbaden 27412066Sbaden (defun IncrTimes (funct) 27512066Sbaden (inc (assq 'times (get 'Measures funct)))) 27612066Sbaden 27712066Sbaden ; update the 'avg arg size' attribute of the function 27812066Sbaden ; actually it is the total size. it should be divided by the 'times' 27912066Sbaden ; attribute to get the avg size. 28012066Sbaden 28112066Sbaden (defun IncrSize (funct size) 28212066Sbaden (rplacd (assq 'size (get 'Measures funct)) 28312066Sbaden (add (cdr (assq 'size (get 'Measures funct))) 28412066Sbaden size))) 28512066Sbaden 28612066Sbaden ; This adds the given function as a property of Measures and 28712066Sbaden ; initializes it to have the 'times' and 'size' attributes. 28812066Sbaden 28912066Sbaden (defun InitUDF (UDF) 29012066Sbaden (putprop 'Measures '((times . 0) (size . 0)) UDF)) 29112066Sbaden 29212066Sbaden 29312066Sbaden ; This increments the times and the size atribute of a UDF, if it exists 29412066Sbaden ; Otherwise, it does nothing. 29512066Sbaden 29612066Sbaden (defun IncrUDF (UDF seq) 29712066Sbaden (cond 29812066Sbaden ((and (memq UDF TracedFns) (get 'Measures UDF)) ;if the UDF is traceable 29912066Sbaden (IncrTimes UDF) 30012066Sbaden (IncrSize UDF (size seq))))) 30112066Sbaden 30212066Sbaden ; This adds the 'size' attribute to the alist corresponding to each 30312066Sbaden ; function in 'FnList' and initializes the value to 0. 30412066Sbaden 30512066Sbaden (defun InitSize (FnList) 30612066Sbaden (mapcar '(lambda (funct) (nconc (get 'Measures funct) (list (cons 'size 0)))) 30712066Sbaden FnList)) 30812066Sbaden 30912066Sbaden ; This adds the 'funargtyp' (functional argument type) attribute to 31012066Sbaden ; the alist corresponding to each functional form in 'FnFormList' and 31112066Sbaden ; initializes the value to nil. 31212066Sbaden 31312066Sbaden (defun InitFunArgTyp (FnFormList) 31412066Sbaden (mapcar '(lambda (fform) 31512066Sbaden (nconc (get 'Measures fform) 31612066Sbaden (list (list 'funargtyp)))) 31712066Sbaden FnFormList)) 31812066Sbaden 31912066Sbaden ; This adds the 'funargno' (number of functional args) attribute to 32012066Sbaden ; the alist correphsponding to each functional form in 'FnFormList' 32112066Sbaden ; and initializes the value to 0. 32212066Sbaden 32312066Sbaden (defun InitFunArgNo (FnFormList) 32412066Sbaden (mapcar '(lambda (fform) 32512066Sbaden (nconc (get 'Measures fform) 32612066Sbaden (list (cons 'funargno 0)))) 32712066Sbaden FnFormList)) 32812066Sbaden 32912066Sbaden ; Prints out the stats to a file 33012066Sbaden 33112066Sbaden (defun PrintMeasures (sFileName) 33212066Sbaden (cond (sFileName 33312066Sbaden (let ((statPort nil)) 33412066Sbaden (cond ((setq statPort (outfile sFileName 'append)) 33512066Sbaden (SendMeasures statPort) ; write the stuff 33612066Sbaden (terpri statPort) 33712066Sbaden (close statPort)) 33812066Sbaden (t (terpr) 33912066Sbaden (patom "Cannot open statFile") 34012066Sbaden (terpr))))) 34112066Sbaden (t (SendMeasures nil)))) 34212066Sbaden 34312066Sbaden 34412066Sbaden ; Traverses the Measures structure and prints out the 34512066Sbaden ; info onto 'port'. 34612066Sbaden ; Also removes the attributes from Measures (during traversal) 34712066Sbaden 34812066Sbaden (defun SendMeasures (port) 34912066Sbaden (do ((functlist (plist 'Measures) 35012066Sbaden (cddr functlist)));for each alternate elem in functlist 35112066Sbaden ((null functlist)) ; end when all done 35212066Sbaden (let ((fnStats (cadr functlist))) 35312066Sbaden (cond ((and fnStats (not (zerop (cdr (assoc 'times fnStats))))) 35412066Sbaden (cprintf "%s:" (printName (car functlist)) port) 35512066Sbaden (do ((proplist fnStats (cdr proplist))) 35612066Sbaden ((null proplist)) 35712066Sbaden (let ((prop (car proplist))) ; for each prop in proplist 35812066Sbaden (cond ((eq (car prop) 'funargtyp) ; if it is funargtyp 35912066Sbaden (doFuncArg port prop)) 36012066Sbaden (t (cprintf " %s" (car prop) port);if not funargtyp 36112066Sbaden (cprintf " %d" (cdr prop) port))))) 36212066Sbaden ; end of function 36312066Sbaden (terpri port) 36412066Sbaden (terpri port)))))); a newline separates functions 36512066Sbaden 36612066Sbaden (defun doFuncArg (port prop) 36712066Sbaden (terpri port) 36812066Sbaden (terpri port) 36912066Sbaden (cprintf " Functional Args" nil port) 37012066Sbaden (terpri port) 37112066Sbaden (cprintf " Name Times" nil port) 37212066Sbaden (terpri port) 37312066Sbaden (do ((funclist (cadr prop) (cdr funclist))) 37412066Sbaden ((null funclist)) 37512066Sbaden (cprintf " " nil port) 37612066Sbaden (patom (printName (caar funclist)) port) 37712066Sbaden (cprintf " %d" (cdar funclist) port) 37812066Sbaden (terpri port))) 37912066Sbaden 38012066Sbaden (defun printName (fnName) 38112066Sbaden (let ((zzName (reverse (explodec fnName))) 38212066Sbaden (tName nil)) 38312066Sbaden (setq tName (memq '$ zzName)) 38412066Sbaden (cond (tName (implode (reverse (cdr tName)))) 38512066Sbaden (t 38612066Sbaden (setq tName (memq '_ zzName)) 38712066Sbaden (cond (tName (implode (reverse (cdr tName)))) 38812066Sbaden ((stringp fnName) (concat '|"| fnName '|"|)) 38912066Sbaden (t (put_obj fnName))))))) 39012066Sbaden 39112066Sbaden ; this is the same as the function in fp_main.l except that it takes 39212066Sbaden ; an extra argument which is the port name. it is used for printing 39312066Sbaden ; out a lisp object in the FP form 39412066Sbaden 39512066Sbaden (defun d_isplay (obj port) 39612066Sbaden (cond ((null obj) (patom "<>" port)) 39712066Sbaden ((atom obj) (patom obj port)) 39812066Sbaden ((listp obj) 39912066Sbaden (patom "<" port) 40012066Sbaden (maplist 40112066Sbaden '(lambda (x) 40212066Sbaden (d_isplay (car x) port) 40312066Sbaden (cond ((not (onep (length x))) (patom " " port)))) obj) 40412066Sbaden (patom ">" port)))) 40512066Sbaden 40612066Sbaden 40712066Sbaden (defun measAlph (al seq) 40812066Sbaden (IncrFunArgTyp 'alpha$fp al) 40912066Sbaden (IncrTimes 'alpha$fp) 41012066Sbaden (IncrSize 'alpha$fp (size seq))) 41112066Sbaden 41212066Sbaden (defun measIns (ins seq) 41312066Sbaden (IncrFunArgTyp 'insert$fp ins) 41412066Sbaden (IncrTimes 'insert$fp) 41512066Sbaden (IncrSize 'insert$fp (size seq))) 41612066Sbaden 41712066Sbaden (defun measTi (ains seq) 41812066Sbaden (IncrFunArgTyp 'ti$fp ains) 41912066Sbaden (IncrTimes 'ti$fp) 42012066Sbaden (IncrSize 'ti$fp (size seq))) 42112066Sbaden 42212066Sbaden (defun measSel (sel seq) 42312066Sbaden (IncrFunArgTyp 'select$fp sel) 42412066Sbaden (IncrTimes 'select$fp) 42512066Sbaden (IncrSize 'select$fp (size seq))) 42612066Sbaden 42712066Sbaden (defun measCons (cons seq) 42812066Sbaden (IncrFunArgTyp 'constant$fp cons) 42912066Sbaden (IncrTimes 'constant$fp) 43012066Sbaden (IncrSize 'constant$fp (size seq))) 43112066Sbaden 43212066Sbaden (defun measCond (c1 c2 c3 seq) 43312066Sbaden (IncrFunArgTyp 'condit$fp c1) 43412066Sbaden (IncrFunArgTyp 'condit$fp c2) 43512066Sbaden (IncrFunArgTyp 'condit$fp c3) 43612066Sbaden (IncrTimes 'condit$fp) 43712066Sbaden (IncrSize 'condit$fp (size seq))) 43812066Sbaden 43912066Sbaden (defun measWhile (w1 w2 seq) 44012066Sbaden (IncrFunArgTyp 'while$fp w1) 44112066Sbaden (IncrFunArgTyp 'while$fp w2) 44212066Sbaden (IncrTimes 'while$fp) 44312066Sbaden (IncrSize 'while$fp (size seq))) 44412066Sbaden 44512066Sbaden (defun measComp (cm1 cm2 seq) 44612066Sbaden (IncrFunArgTyp 'compos$fp cm1) 44712066Sbaden (IncrFunArgTyp 'compos$fp cm2) 44812066Sbaden (IncrTimes 'compos$fp) 44912066Sbaden (IncrSize 'compos$fp (size seq))) 45012066Sbaden 45112066Sbaden (defun measConstr (fns seq) 45212066Sbaden (mapcar '(lambda (x) (IncrFunArgTyp 'constr$fp x)) fns) 45312066Sbaden (IncrFunArgNo 'constr$fp (length fns)) 45412066Sbaden (IncrTimes 'constr$fp) 45512066Sbaden (IncrSize 'constr$fp (size seq))) 45612066Sbaden 45712066Sbaden ; get the corect name of the functional form 45812066Sbaden 45912066Sbaden (defmacro getFform (xx) 46012066Sbaden `(implode (nreverse `(p f ,@(cdr (nreverse (explodec (cxr 0 ,xx)))))))) 46112066Sbaden 462