Opened 9 years ago

Closed 7 years ago

#986 closed enhancement (fixed)

(define ++ string-append) defeats constant-folding

Reported by: Jim Ursetto Owned by: evhan
Priority: not urgent at all Milestone: 4.10.0
Component: compiler Version: 4.8.x
Keywords: Cc:
Estimated difficulty:

Description

Using (define ++ string-append) prevents constant-folding into a literal string when using ++. It does work when using -block, but not inside a module, even when ++ is hidden. Or at least, I can't get it to work.

;; app2.scm
;; although string-append is substituted for ++, the result is not
;; constant-folded, unlike plain string-append

(module foo (bar baz)
 (import scheme chicken)

 (define ++ string-append)
 (define (bar)
   (print (string-append "foo" "bar" "baz")))
 (define (baz)
   (print (++ "quux" "poop")))

)

(import foo)
(bar)
(baz)
;; ----------

$ csc -O3 -debug o app2.scm

hiding nonexported module bindings: foo#++
specializations:
  1 (string-append string string)
safe globals: (foo#baz foo#bar foo#++)
removed side-effect free assignment to unused variable: foo#++
folded constant expression: (string-append (quote "foo") (quote "bar") (quote "baz"))
substituted constant variable: a213
substituted constant variable: a214
replaced variables: 2
removed binding forms: 3
contracted procedure: k202
removed binding forms: 6
substituted constant variable: a201
inlining procedure: "(app2.scm:15) foo#baz"
inlining procedure: "(app2.scm:14) foo#bar"
substituted constant variable: a201229
replaced variables: 2
removed binding forms: 1
removed binding forms: 3

Change History (4)

comment:1 Changed 7 years ago by sjamaan

Milestone: someday4.10.0

Would be nice if we can fix this, or at least seriously look into it for 4.10.0

comment:2 Changed 7 years ago by sjamaan

Component: unknowncompiler

comment:3 Changed 7 years ago by evhan

Owner: set to evhan
Status: newassigned

This isn't actually due to the use of define, but because the scrutinizer rewrites (string-append string string) to use ##sys#string-append before the high-level optimization pass and ##sys#string-append isn't marked as ##compiler#foldable, the opportunity is missed.

;; Folds "quxquuxquuux" as expected:
(define ++ string-append)
(print (string-append "foo" "bar" "baz"))
(print (++ "qux" "quux" "quuux")) ; Three arguments, so no specialization.

;; Doesn't fold "quxquux" due to specialization:
(print (string-append "foo" "bar" "baz"))
(print (string-append "qux" "quux")) ; Two arguments, specialized.

I think ##sys#string-append should be included in foldable-bindings, but there are lots of other internal (##sys#) procedures that should be folded as well, so the fix should probably be more general than just adding ##sys#string-append.

comment:4 Changed 7 years ago by sjamaan

Resolution: fixed
Status: assignedclosed

This particular inconsistency is fixed by 368fca8ccdd22cec65cd0b75fc8f8f08e8267d32. However, it makes both calls non-foldable.

Note: See TracTickets for help on using tickets.