Skip to content

Commit 4bbd5d2

Browse files
committed
Normalize impl->fpcore outputs in one place
1 parent b1e772f commit 4bbd5d2

3 files changed

Lines changed: 43 additions & 27 deletions

File tree

src/syntax/platform.rkt

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
prog->spec
3636
batch-to-spec!
3737
get-fpcore-impl
38+
impl->fpcore
3839
(struct-out $platform)
3940
;; Platform API
4041
;; Operator sets
@@ -176,11 +177,16 @@
176177
(apply cost-proc (map loop args itypes))]))))
177178

178179
;; Extracts the `fpcore` field of an operator implementation
179-
;; as a property dictionary and expression.
180+
;; as a property dictionary and operation.
180181
(define (impl->fpcore impl)
181-
(match (impl-info impl 'fpcore)
182-
[(list '! props ... body) (values (props->dict props) body)]
183-
[body (values '() body)]))
182+
(define-values (props body)
183+
(match (impl-info impl 'fpcore)
184+
[(list '! props ... body) (values (props->dict props) body)]
185+
[body (values '() body)]))
186+
(values props
187+
(if (symbol? body)
188+
(list body)
189+
body)))
184190

185191
(define/reset op-hash #f)
186192

@@ -192,12 +198,8 @@
192198
(define h (make-hash))
193199
(for ([impl (in-list (platform-impls (*active-platform*)))])
194200
(define-values (_ expr) (impl->fpcore impl))
195-
(define expr*
196-
(if (symbol? expr)
197-
(list expr)
198-
expr))
199-
(when (list? expr*)
200-
(hash-update! h (car expr*) (curry cons impl) '())))
201+
(when (list? expr)
202+
(hash-update! h (car expr) (curry cons impl) '())))
201203
(op-hash h))
202204

203205
; gather all implementations that have the same spec, input representations,
@@ -207,12 +209,8 @@
207209
(for ([impl (in-list (hash-ref (op-hash) op '()))]
208210
#:when (equal? ireprs (impl-info impl 'itype)))
209211
(define-values (prop-dict* expr) (impl->fpcore impl))
210-
(define expr*
211-
(if (symbol? expr)
212-
(list expr)
213-
expr)) ; Handle named constants
214212
(define pattern (cons op (map (lambda (_) (gensym)) ireprs)))
215-
(when (and (subset? prop-dict* prop-dict) (pattern-match pattern expr*))
213+
(when (and (subset? prop-dict* prop-dict) (pattern-match pattern expr))
216214
(sow impl)))))
217215
; check that we have any matching impls
218216
(cond

src/syntax/sugar.rkt

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@
8686
[(approx impl spec) (approx (loop impl) (loop spec))]
8787
[(list op args ...) (cons op (map loop args))])))
8888

89+
(define (fpcore-extension-spec expr)
90+
(define specs
91+
(remove-duplicates (filter identity
92+
(for/list ([impl (in-list (platform-impls (*active-platform*)))])
93+
(define-values (_ body) (impl->fpcore impl))
94+
(define subst (pattern-match (expand-expr body) expr))
95+
(and subst (pattern-substitute (impl-info impl 'spec) subst))))))
96+
(match specs
97+
['() #f]
98+
[(list spec) spec]
99+
[_ (error 'fpcore->spec "ambiguous platform specs for `~a`: ~a" expr specs)]))
100+
89101
;; Expression pre-processing for normalizing expressions.
90102
;; Used for conversion from FPCore to other IRs.
91103
(define (expand-expr expr)
@@ -156,7 +168,7 @@
156168
; applications
157169
[`(,op ,args ...) `(,op ,@(map (curryr loop env) args))]
158170
; constants
159-
[(? operator-exists? op) (list expr)]
171+
[(? operator-exists? op) (list op)]
160172
; variables
161173
[(? symbol?) (dict-ref env expr expr)]
162174
; other
@@ -176,7 +188,13 @@
176188
[(? symbol?) expr]
177189
[(list '! _ ... body) (loop body)]
178190
[(list 'cast arg) (loop arg)]
179-
[(list op args ...) `(,op ,@(map loop args))])))
191+
[(list op args ...)
192+
(define args* (map loop args))
193+
(define expr* `(,op ,@args*))
194+
(match (fpcore-extension-spec expr*)
195+
[#f expr*]
196+
[(== expr*) expr*]
197+
[spec (loop spec)])])))
180198

181199
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
182200
;; FPCore -> LImpl
@@ -195,11 +213,8 @@
195213
(define ireprs (map (lambda (arg) (repr-of arg ctx)) args))
196214
(define impl (assert-fpcore-impl op prop-dict ireprs))
197215
(define vars (impl-info impl 'vars))
198-
(define pattern
199-
(match (impl-info impl 'fpcore)
200-
[(list '! _ ... body) body]
201-
[body body]))
202-
(define subst (pattern-match pattern (cons op args)))
216+
(define-values (_ body) (impl->fpcore impl))
217+
(define subst (pattern-match body (cons op args)))
203218
(pattern-substitute (cons impl vars) subst))
204219

205220
;; Translates from FPCore to an LImpl.
@@ -235,11 +250,8 @@
235250
(define idx-repr (repr-of idx* ctx))
236251
(define impl (assert-fpcore-impl 'ref prop-dict (list arr-repr idx-repr)))
237252
(define vars (impl-info impl 'vars))
238-
(define pattern
239-
(match (impl-info impl 'fpcore)
240-
[(list '! _ ... body) body]
241-
[body body]))
242-
(define subst (pattern-match pattern (list 'ref arr* idx*)))
253+
(define-values (_ body) (impl->fpcore impl))
254+
(define subst (pattern-match body (list 'ref arr* idx*)))
243255
(pattern-substitute (cons impl vars) subst)]
244256
[(list op args ...)
245257
(define args* (map (lambda (arg) (loop arg prop-dict)) args))

src/syntax/test-syntax.rkt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
(require "syntax.rkt"
44
"platform.rkt"
5+
"sugar.rkt"
56
"types.rkt")
67

78
(module+ test
@@ -24,4 +25,9 @@
2425
'+.f64)
2526
(check-equal? (get-impl 'sin '((:precision . binary64)) (list f64)) 'sin.f64)
2627

28+
; fpcore->spec
29+
(check-equal? (fpcore->spec '(log1p x)) '(log (+ 1 x)))
30+
(check-equal? (fpcore->spec '(hypot x y)) '(sqrt (+ (* x x) (* y y))))
31+
(check-equal? (fpcore->spec '(fma x y z)) '(+ (* x y) z))
32+
2733
(void))

0 commit comments

Comments
 (0)