1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00
Commit graph

282 commits

Author SHA1 Message Date
Andy Wingo
9be8a338ac recognize string primitives
* module/language/tree-il/primitives.scm
  (*interesting-primitive-names*): Add string?, string-length, and ref
  and set.
  (*primitive-accessors*): Add string-ref.
  (*effect-free-primitives*): Add string-length and string?
  (*effect+exception-free-primitives*): Add string?.
  (*singly-valued-primitives*): Add string-length and ref and set.
2011-10-10 20:19:07 +02:00
Andy Wingo
a215c15913 Merge remote-tracking branch 'origin/stable-2.0'
Does not include psyntax regeneration.

Conflicts:
	module/ice-9/psyntax-pp.scm
	module/language/tree-il/peval.scm
	test-suite/tests/tree-il.test
2011-10-10 16:20:08 +02:00
Andy Wingo
4bf9e92875 peval support for memq and memv
* module/language/tree-il/peval.scm (peval): Add special handlers for
  memq and memv, as inline.scm used to have.  This is important for
  `case' clauses.  It is very ugly, though.

* test-suite/tests/tree-il.test ("partial evaluation"): Add tests.
2011-10-10 14:43:37 +02:00
Andy Wingo
f26c3a93ec add accessor-primitive?, peval uses it
* module/language/tree-il/primitives.scm (*primitive-accessors*): New
  set of primitives: those that access mutable memory, but are otherwise
  pure.  Include bytevector references here.
  (accessor-primitive?): New public predicate.

* module/language/tree-il/peval.scm (peval): Refactor to distinguish
  constructor-primitive? from accessor-primitive?.
2011-10-10 14:43:37 +02:00
Andy Wingo
751708726b peval: visit operands on-demand, to inline mutually recursive bindings
This commit changes to use <operand> structures to hold the context
needed to visit lexical bindings lazily, in context, instead of eagerly
visiting them for value.  This laziness enables inlining of mutually
recursive bindings.

* module/language/tree-il/peval.scm (<var>): Remove comment about copy
  propagation having to run build-var-table; things don't work like that
  any more.
  (build-var-table): Build <var> entries for all variables, even
  unreferenced variables.
  (alpha-rename): Remove.  We will rename bindings on-demand now.

  (peval lookup-var): New helper, to fetch the <var> of a gensym.

  (peval fresh-gensyms): Fold here, under peval, and in it, handle
  updating the store to record a mapping between new names and <var>
  entries from the source program.

  (peval record-source-expression): Don't call build-var-table on the
  new expression, as alpha-renaming happens on-demand now.

  (peval prune-bindings): Rewrite to work with mutually-recursive
  bindings, while optionally preserving binding order.

  (peval extend-env): New helper.

  (peval loop): OK, here goes... Remove the `operand' context, as now we
  visit operands lazily.  Add a `call' context, which does not
  copy-propagate lambda expressions, used to residualize a call after
  aborting an inlining attempt.  Change the `env' to be a mapping of
  gensym to <operand>.  Instead of looking up the operand's binding then
  alpha-renaming it, just rely on the fact that visiting the operand
  will rename it if necessary.

  If we residualize a lexical, do so with the fresh name from the
  environment.  If we visit an operand and it doesn't turn out to be
  constant, we will never be able to copy it, and so cache that fact in
  the operand.  If we residualize a binding and we know what the value
  should be, record that binding so that prune-bindings won't have to
  visit it again.  If the operand folds to a constant, cache that too,
  to save effort when unrolling loops.

  For let, letrec, fix, and lambda-case, instead of visiting the
  bindings eagerly for value, simply record the source expressions and
  environments in an <operand> and rely on copy-propagation to visit
  them later in the right context.  In the case of letrec and fix, this
  allows mutually-recursive bindings to be inlined.

  Refactor folding of "constructors" (which still need renaming) to
  avoid visiting operands twice in some contexts.

  For applications, if we have to abort, process the procedure in call
  context, which allows some folding but avoids copying lambdas.  If we
  find a recursive procedure, mark intervening counters as recursive
  too, to allow for mutual recursion at the top level.

  For lambdas, if we are processing for value, record the source
  expression so we can detect recursion.  This was previously done in
  the lexical-ref copy propagator.

* test-suite/tests/tree-il.test ("partial evaluation"): Remove unused
  recursive lexicals in a couple of cases.  Add a couple test cases for
  pruning.  Add a few recursive binding cases.
2011-10-10 13:23:32 +02:00
Andy Wingo
580a59e75e peval: add operand structure
* module/language/tree-il/peval.scm (<operand>): Add operand structure,
  to be used by peval.
2011-10-10 13:23:32 +02:00
Andy Wingo
3066999174 peval: refactor logging
* module/language/tree-il/peval.scm: Make it easier to turn on logging.
2011-10-10 13:23:32 +02:00
Andy Wingo
41d43584f2 peval: logging
* module/language/tree-il/peval.scm: Define a quick and dirty
  infrastructure for logging.  Use it in peval.
2011-10-08 01:54:20 +02:00
Andy Wingo
1082cbba47 peval: bugfix in constant-expression?
* module/language/tree-il/peval.scm (constant-expression?): Correctly
  handle lambda-case alternates.
2011-10-07 11:06:56 +02:00
Andy Wingo
012492a7f1 optimizer verifies its output
* module/language/tree-il/optimize.scm: Verify the result of partial
  evaluation.
2011-10-07 11:06:19 +02:00
Andy Wingo
6d2d689721 add tree-il verifier
* module/Makefile.am: Add debug.scm.
* module/language/tree-il/debug.scm: New file, a verifier for tree-il.
2011-10-07 11:05:43 +02:00
Andy Wingo
904981ee41 peval refactor
* module/language/tree-il/peval.scm (peval): Refactor the for-value, etc
  helpers.
2011-10-06 13:44:05 +02:00
Andy Wingo
47974c308a comment peval.scm
* module/language/tree-il/peval.scm: Add comments.  Move alpha-rename
  later in the file.
2011-10-06 10:39:14 +02:00
Ludovic Courtès
16d50b8e89 peval: Recognize module-refs to primitives.
* module/language/tree-il/optimize.scm (peval): Handle module-refs to
  primitives.

* test-suite/tests/tree-il.test ("partial evaluation"): Add test, using
  `pmatch'.
2011-09-30 15:15:15 +02:00
Andy Wingo
ca12824581 Merge remote-tracking branch 'origin/stable-2.0'
This was a pretty big merge involving a fair amount of porting,
especially to peval and its tests.  I did not update psyntax-pp.scm,
that comes in the next commit.

Conflicts:
	module/ice-9/boot-9.scm
	module/ice-9/psyntax-pp.scm
	module/language/ecmascript/compile-tree-il.scm
	module/language/tree-il.scm
	module/language/tree-il/analyze.scm
	module/language/tree-il/inline.scm
	test-suite/tests/tree-il.test
2011-09-29 18:02:28 +02:00
Andy Wingo
b275fb2691 separate peval and a new canonicalization pass into their own modules
* module/language/tree-il/peval.scm: Move to its own file.  Remove the
  bits about <prompt> thunk-application bodies, as they are not
  optimizations, simply expectations of the compiler.  `canonicalize'
  handles that now.

* module/language/tree-il/optimize.scm: Use peval from its module.
  Don't call `inline!', as that's useless now.

* module/language/tree-il/canonicalize.scm: New file, implementing a
  pass that `compile-tree-il' runs on the result from the optimizer.
  The compiler currently expects a <let> form to have bindings, for
  example, and this pass turns a <let> without bindings into its body.

* module/language/tree-il/inline.scm: Deprecate, as `peval' does
  everything this function ever did.

* module/language/tree-il/compile-glil.scm: Canonicalize after
  optimizing.  This should allow us to skip the optimizer entirely, if
  we want.

* module/Makefile.am: Update and reorder a little bit.
2011-09-28 19:39:39 +02:00
Andy Wingo
0353a2d817 ((lambda ...) ...) fix
* module/language/tree-il/optimize.scm (peval): If it's a lambda in the
  operator position, inline without a nested counter, as it's not
  possible to increase code size.
2011-09-28 00:13:56 +02:00
Andy Wingo
40be30c974 peval: more effective binding pruning
* module/language/tree-il/optimize.scm (peval): Factor prune-bindings
  out of `let' and company.  Have it process unreferenced bindings in
  effect context instead of always residualizing non-constant
  expressions.
2011-09-28 00:13:56 +02:00
Andy Wingo
fc283c92cb don't propagate pure primcalls that might not type-check
* module/language/tree-il/optimize.scm (types-check?): New helper, to
  determine if a primcall will apply without throwing an exception.
  (peval): constant-expression? returns #f for expressions that don't
  types-check?.  Effect-free primitives that type-check are void.
2011-09-28 00:13:56 +02:00
Andy Wingo
1cc1c2d7e3 peval works on all expressions
* module/language/tree-il/optimize.scm (alpha-rename, peval): Add
  <dynset> cases.  Allow any kind of <application>.  Remove the `catch'
  wrapper as now peval handles all kinds of expressions.
2011-09-28 00:13:56 +02:00
Andy Wingo
6c4ffe2b25 peval: elide make-prompt-tag in effect context
* module/language/tree-il/optimize.scm (peval): Fix a duplicate
  traversal for constructors in effect or test context.  Add support for
  eliding make-prompt-tag.

* test-suite/tests/tree-il.test ("partial evaluation"): Update the test
  for make-prompt-tag elision.
2011-09-28 00:13:56 +02:00
Andy Wingo
ea726a53b2 peval: add support for <prompt> and <abort>
* module/language/tree-il/optimize.scm (alpha-rename, peval): Handle
  <prompt> and <abort>.  Attempt to remove the prompt if the tag is
  otherwise unreferenced.

* module/language/tree-il/primitives.scm (*primitive-constructors*): Add
  make-prompt-tag as a constructor.

* test-suite/tests/tree-il.test ("partial evaluation"): Add a test that
  an prompt whose tag is unreferenced is removed.
2011-09-28 00:13:55 +02:00
Andy Wingo
fbc9387f68 peval: fix algorithmic behavior of `cons'
* module/language/tree-il/optimize.scm (peval): Fix treatment of `cons'
  to not process the value twice, leading to n^2 work.  This prevented
  primitives.scm from compiling in a reasonable amount of time, because
  it contained a `(foo ... ,@bar) form that resulted in a long sequence
  of nested conses, and no effort counter was in place as it was not
  within an inlining attempt.
2011-09-28 00:13:55 +02:00
Andy Wingo
153ca1d239 peval: more strict accounting
* module/language/tree-il/optimize.scm (transfer!, make-nested-counter):
  (make-recursive-counter, peval): Limit the algorithm's time to be
  strictly O(N) by transferring effort and size counters of recursive
  inlining attempts from containing counters.

* test-suite/tests/tree-il.test ("partial evaluation"): Update
  expectations for the ((lambda (x) (x x)) (lambda (x) (x x))) case, as
  the new accounting policy will cause the entire inlining attempt to
  abort.
2011-09-27 00:21:16 +02:00
Andy Wingo
05c9389e3f peval: fix inlining of lambda* with #:optional
* module/language/tree-il/optimize.scm (peval): Fix calculation of how
  many init expressions to drop when inlining lambdas.

* test-suite/tests/tree-il.test ("partial evaluation"): Add tests.
2011-09-26 22:34:39 +02:00
Andy Wingo
ef6c0883c3 remove unused peval helpers
* module/language/tree-il/optimize.scm (peval): Remove a couple unused
  helpers.
2011-09-26 22:24:00 +02:00
Andy Wingo
02ebea537f peval: simpler and more precise treatment of mutability
* module/language/tree-il/optimize.scm (peval): The old approach of
  optimistically producing constants and then de-constifying them at
  their uses was not only cumbersome but incorrect: it both failed to
  preserve identity in some cases and failed to retain immutable
  constant values.  Instead, now we only produce constants if they
  really are constant and immutable.  The constant folder has to have a
  few more algebraic cases to be as effective as it was, to destructure
  (car (cons _ _)) appropriately.  On the plus side, now constructors
  and deconstructors can handle impure cases more generally.

* test-suite/tests/tree-il.test ("partial evaluation"): Add constructor
  and destructuring tests.  Adapt other tests to new expectations.
2011-09-25 02:54:45 +02:00
Andy Wingo
cf82943f9f peval: add a bunch of missing maybe-unconst calls
* module/language/tree-il/optimize.scm (peval): Add missing
  maybe-unconst calls.  Things are getting ugly.  They will get better
  in the next commit though.
2011-09-25 02:54:34 +02:00
Andy Wingo
b839233282 peval uses effort counters, propagates lambdas more effectively
* module/language/tree-il/optimize.scm (code-contains-calls?): Remove
  this helper, we will deal with recursion when it happens, not after
  the fact.
  (peval): Add keyword args for various size and effort limits.  Instead
  of keeping a call stack, keep a chain of <counter> records, each with
  an abort continuation.  If ever an inlining attempt is taking too
  long, measured in terms of number of trips through the main loop, the
  counter will abort.  Add new contexts, `operator' and `operand'.  They
  have different default size limits.  In the future we should actually
  use the size counter, instead of these heuristics.

  The <lexical-ref> case is smarter now, and tries to avoid propagating
  too much data.  Perhaps it should be dumber though, and use a
  counter.  That would require changes to the environment structure.

  Inline <lambda> applications to <let>, so that we allow residual
  lexical references to have bindings.  Add a `for-operand' helper, and
  use it for the RHS of `let' expressions.  A `let' is an inlined
  `lambda'.

  `Let' and company no longer elide bindings if the result is a
  constant, as the arguments could have effects.  Peval will still do as
  much as it can, though.

* test-suite/tests/tree-il.test ("partial evaluation"): Update the tests
  for the new expectations.  They are uniformly awesomer, with the
  exception of two cases in which pure but not constant data is not
  propagated.
2011-09-25 02:49:02 +02:00
Andy Wingo
fab137869e prune unused letrec bindings
* module/language/tree-il/optimize.scm (peval): Prune unused `letrec'
  bindings.
2011-09-24 20:37:12 +02:00
Andy Wingo
062bf3aa44 more peval refactoring
* module/language/tree-il/optimize.scm (peval): Rename `var-table' to
  `store', as we're going to put some more things in it.  Rename
  `record-lexical-bindings' to `record-source-expression', which also
  takes the original, pre-renaming expression.  Keep a mapping from new
  expressions to original expressions, available using the
  `source-expression' helper.
2011-09-24 20:34:43 +02:00
Andy Wingo
8018dfdc02 add helpers for effort counters
* module/language/tree-il/optimize.scm (<counter>, abort-counter)
  (record-effort!, record-size!, find-counter, make-top-counter)
  (make-nested-counter, make-recursive-counter): New helpers, as yet
  unused, but which will implement fixed effort bounds on the inlining
  algorithm.
2011-09-24 20:34:33 +02:00
Andy Wingo
ded8ad84a7 peval refactor
* module/language/tree-il/optimize.scm (peval): Add for-value, for-test,
  for-effect, and for-tail helpers.  Use them.
2011-09-24 20:34:12 +02:00
Andy Wingo
f6123e4fda attempt to prune unreferenced bindings
* module/language/tree-il/optimize.scm (peval): Rename `record-lexicals'
  to `record-lexical-bindings'.  Record residualized lexical
  references.  Record lexical references in maybe-unlambda.
  Unfortunately this has the disadvantage that the speculative mapping
  of lambda expressions to lexical references records that reference,
  even if we are not going to residualize it.  After processing a `let',
  prune pure unreferenced bindings.  (We can do better than this in the
  future: we can simply process them for effect.)

* test-suite/tests/tree-il.test (pass-if-peval): More debugging.
  ("partial evaluation"): Update to reflect the fact that the `y'
  binding won't be emitted.
2011-09-24 19:08:09 +02:00
Andy Wingo
e43921a982 peval handles lexical-set
* module/language/tree-il/optimize.scm (alpha-rename, peval): Add
  support for lexical-set, while avoiding copy propagation and pruning
  of assigned variables.
2011-09-24 19:02:53 +02:00
Andy Wingo
b8a2b628e9 peval: pre-analyze mutated or reffed-once lexicals
* module/language/tree-il/optimize.scm (<var>, build-var-table, peval):
  Before going into peval, build a table indicating refcounts and a set?
  flag for all lexicals.  Add to the table when introducing new bindings
  (via alpha-renaming).
2011-09-24 19:00:53 +02:00
Andy Wingo
1eb4886ffa peval: don't propagate expressions that access memory
* module/language/tree-il/optimize.scm (peval): Rename
  `pure-expression?' to `constant-expression?', in the sense of GCC's
  `pure' and `const'.  A <toplevel-ref> is not constant, because it can
  be mutated.  A <dynref> isn't constant either, for the same reason.

* test-suite/tests/tree-il.test ("partial evaluation"): Add a test, and
  update existing tests that assumed that toplevel-ref would propagate.
2011-09-24 18:57:59 +02:00
Andy Wingo
8d06538e82 context-specific folding for peval in test and effect contexts
* module/language/tree-il/optimize.scm (peval): Add a "test" context,
  which folds statically decidable values to <const>.  Fold pure
  expressions to <void> in "effect" contexts.  Adapt the <conditional>
  and <sequence> tests to simply look for <const> or <void> expressions,
  respectively.
2011-09-24 17:17:13 +02:00
Andy Wingo
e535a37db8 thread a context through peval
* module/language/tree-il/optimize.scm (peval): Thread a "context"
  through the evaluator.
2011-09-24 17:17:11 +02:00
Andy Wingo
250991010f peval: various bugfixes
* module/language/tree-il/optimize.scm (alpha-rename): Rename the
  init
  expressions of a <lambda-case>.
  (peval): Coalesce the <let-values> clauses.
  Fix pure-expression? matching of <lambda> clauses.
  Loop over and maybe-unconst the inits of a <lambda-case>.
2011-09-24 17:15:32 +02:00
Andy Wingo
9e8a5b6637 tree-il-any bugfix
* module/language/tree-il/optimize.scm (tree-il-any): Fix to be called
  on all values, including leaves.  It didn't matter for the use case,
  though.
2011-09-24 17:09:40 +02:00
Andy Wingo
dd7ab5d8a4 minor peval style tweak
* module/language/tree-il/optimize.scm (peval): Minor refactor to
  <lexical-ref> copy propagation.
2011-09-24 17:09:40 +02:00
Andy Wingo
c829531a46 fix alpha-rename for kwargs
* module/language/tree-il/optimize.scm (alpha-rename): Fix
  alpha-renaming of keyword arguments.
2011-09-24 17:09:40 +02:00
Ludovic Courtès
ec6e09bee7 peval: Rectify style.
* module/language/tree-il/optimize.scm (peval): Rename `src' to
  `lv-src', and `src2' to `src'; pass `make-let-values' the right source
  locations.  Reindent `let*'.
2011-09-23 18:12:28 +02:00
Andy Wingo
d851e32fdc prevent propagation for memory-dependent operations like `car'
* module/language/tree-il/primitives.scm (*primitive-constructors*):
  Record car, cdr, vector-ref, and struct-ref as "constructors".
  Comment to come later.
  (*effect-free-primitives*): Update.

* test-suite/tests/tree-il.test ("partial evaluation"): Add tests.
2011-09-23 18:02:05 +02:00
Andy Wingo
40bd6a7e57 peval comment & reindentation
* module/language/tree-il/optimize.scm (peval): Add a comment regarding
  failure modes, and reindent one clause.
2011-09-21 08:58:27 +02:00
Andy Wingo
9581febbb0 fix comment regarding alpha-renaming
* module/language/tree-il/optimize.scm (peval): Fix comment regarding
  alpha-renaming: it's not simply the allocator that needs unique names;
  rather, all transformations depend on it.
2011-09-21 08:58:27 +02:00
Andy Wingo
2605b6ba27 better pure-expression?
* module/language/tree-il/optimize.scm (peval): Allow dynref, fix, and
  let-values to be pure expressions.
2011-09-21 08:58:27 +02:00
Andy Wingo
ddbee5c00f more alpha-rename robustness
* module/language/tree-il/optimize.scm (alpha-rename): Handle all kinds
  of tree-il, with the current exceptions of lexical set!, prompt, and
  abort.
2011-09-21 08:58:27 +02:00
Andy Wingo
5d5e4f399a more robust alpha-renaming
* module/language/tree-il/optimize.scm (fresh-gensyms): New helper.
  (alpha-rename): Name the new gensyms using the old names as templates,
  not the old gensyms.  This prevents accidental collisions between
  gensyms, if #{x 1}# becomes #{x 12}# instead of #{x 2}#.
2011-09-21 08:58:27 +02:00