From 33380e814be22e08e57390c6f0866c00b6565213 Mon Sep 17 00:00:00 2001 From: Vincent St-Amour Date: Mon, 27 Jun 2011 15:34:31 -0400 Subject: [PATCH] Rewrite TR logging facilities to play nicely with the DrRacket tool. original commit: 975cb7ad9d1cb2ca3f4cf78a8635c83a5c1494de --- collects/typed-scheme/optimizer/float.rkt | 2 + collects/typed-scheme/optimizer/logging.rkt | 238 +++++++++++--------- 2 files changed, 134 insertions(+), 106 deletions(-) diff --git a/collects/typed-scheme/optimizer/float.rkt b/collects/typed-scheme/optimizer/float.rkt index 1593ef65..26151d8d 100644 --- a/collects/typed-scheme/optimizer/float.rkt +++ b/collects/typed-scheme/optimizer/float.rkt @@ -76,6 +76,8 @@ (define (log-float-real-missed-opt stx irritants) (log-missed-optimization + "all args float-arg-expr, result not Float" + #:msg (format "This expression has type ~a. It would be better optimized if it had a Float type. To fix this, change the irritant~a to have~a Float type~a." (print-res (type-of stx)) (if (> (length irritants) 1) "s" "") diff --git a/collects/typed-scheme/optimizer/logging.rkt b/collects/typed-scheme/optimizer/logging.rkt index 6136dbe2..9117f4da 100644 --- a/collects/typed-scheme/optimizer/logging.rkt +++ b/collects/typed-scheme/optimizer/logging.rkt @@ -7,16 +7,11 @@ (provide log-optimization log-missed-optimization print-log clear-log with-intercepted-tr-logging with-tr-logging-to-port - (struct-out log-entry)) + (struct-out log-entry) + (struct-out opt-log-entry) + (struct-out missed-opt-log-entry)) -(define (line+col->string stx) - (let ([line (syntax-line stx)] - [col (syntax-column stx)]) - (if (and line col) - (format "~a:~a" line col) - "(no location)"))) - -(struct log-entry (msg raw-msg stx pos irritants) #:prefab) +;;-------------------------------------------------------------------- ;; to identify log messages that come from the optimizer ;; to be stored in the data section of log messages @@ -29,64 +24,17 @@ ;; a problem per se) (define log-so-far '()) -(define (gen-log-message msg stx from show-badness?) - (let* ([stx (locate-stx stx)] - [str (format "~a: ~a ~a ~s -- ~a" - from - (syntax-source-file-name stx) - (line+col->string stx) - (syntax->datum stx) - msg)]) - (if show-badness? ; #f or integer - (format "~a (~a times)" str show-badness?) - str))) +;; msg is for consumption by the DrRacket tool +(struct log-entry (kind msg stx pos) #:prefab) +;; for optimizations only (not missed optimizations, those are below) +(struct opt-log-entry log-entry () #:prefab) -(define (log-optimization msg stx - #:from [from "TR opt"] - #:show-badness? [show-badness? #f] - #:irritants [irritants #f]) - (let* ([new-message (gen-log-message msg stx from show-badness?)] - [new-entry (log-entry new-message msg stx (syntax-position stx) - irritants)]) + +(define (log-optimization msg stx) + (let ([new-entry (opt-log-entry msg msg stx (syntax-position stx))]) (set! log-so-far (cons new-entry log-so-far)))) -;; once the optimizer is done, we sort the log according to source -;; location, then print it -(define (print-log) - (define logger (current-logger)) - ;; add missed optimizations messages to the log, now that we know all of them - (for-each (lambda (x) - (log-optimization - (format-missed-optimization x) - (missed-optimization-stx x) - #:from "TR missed opt" - #:show-badness? - (let ([badness (missed-optimization-badness x)]) - (and (> badness 1) badness)) - #:irritants (missed-optimization-irritants x))) - missed-optimizations-log) - (for-each (lambda (x) (log-message logger 'warning (log-entry-msg x) - (cons optimization-log-key x))) - (sort (remove-duplicates log-so-far) - (match-lambda* - [(list (log-entry msg-x raw-x stx-x pos-x irr-x) - (log-entry msg-y raw-y stx-y pos-y irr-y)) - (cond [(not (or pos-x pos-y)) - ;; neither have location, sort by message - (stringstring irritant) - (syntax->datum irritant)))) - (sort irritants < - #:key (lambda (x) - (or (syntax-position x) 0)))) - ", ")) - kind))) +;; When we know all missed opts are known and merging has been done, we +;; can add them to the regular log. +(define (add-missed-opts-to-log) + (set! log-so-far (append log-so-far missed-optimizations-log))) + + +;;-------------------------------------------------------------------- + +;; Sort log according to source location. Returns the sorted log. +(define (sort-log) + (sort (remove-duplicates log-so-far) + (match-lambda* + [(list (log-entry kind-x msg-x stx-x pos-x) + (log-entry kind-y msg-y stx-y pos-y)) + (cond [(not (or pos-x pos-y)) + ;; neither have location, sort by message + (stringstring stx) + (let ([line (syntax-line stx)] + [col (syntax-column stx)]) + (if (and line col) + (format "~a:~a" line col) + "(no location)"))) + +(define (format-irritants irritants) + (if (null? irritants) + "" + (format " -- caused by: ~a" + (string-join + (map (lambda (irritant) + (let ([irritant (locate-stx irritant)]) + (format "~a ~s" + (line+col->string irritant) + (syntax->datum irritant)))) + (sort irritants < + #:key (lambda (x) + (or (syntax-position x) 0)))) + ", ")))) + +;; For command-line printing purposes. +;; Not as user friendly as what's produced by the DrRacket tool. +(define (format-log-entry entry) + (define stx (locate-stx (log-entry-stx entry))) + (define msg + (format "~a ~a ~s -- ~a" + (syntax-source-file-name stx) + (line+col->string stx) + (syntax->datum stx) + (log-entry-kind entry))) + (cond [(opt-log-entry? entry) + (format "TR opt: ~a" msg)] + [(missed-opt-log-entry? entry) + (define badness (missed-opt-log-entry-badness entry)) + (format "TR missed opt: ~a~a~a" + msg + (format-irritants (missed-opt-log-entry-irritants entry)) + (if (> badness 1) + (format " (~a times)" badness) + ""))])) + + +;; Once the optimizer is done, we sort the log according to source +;; location, then print it. +(define (print-log) + (define logger (current-logger)) + (add-missed-opts-to-log) + (for ([x (sort-log)]) + (log-message logger 'warning + (format-log-entry x) + (cons optimization-log-key x)))) + +(define (clear-log) + (set! log-so-far '()) + (set! missed-optimizations-log '())) + +;;-------------------------------------------------------------------- ;; only intercepts TR log messages (define (with-intercepted-tr-logging interceptor thunk)