df9962950d28

Elide the unnecessary ALOC/DEAL from chain rules

Save the frames, kill the `alloc`ations.
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Tue, 12 Jul 2016 15:52:13 +0000
parents 2ce458ef85fd
children eda9b4d218f4
branches/tags (none)
files src/wam/compiler.lisp

Changes

--- a/src/wam/compiler.lisp	Tue Jul 12 15:46:22 2016 +0000
+++ b/src/wam/compiler.lisp	Tue Jul 12 15:52:13 2016 +0000
@@ -1241,8 +1241,14 @@
           (variable-count (length (clause-permanent-vars clause-props))))
       ;; We need to compile facts and rules differently.  Facts end with
       ;; a PROCEED and rules are wrapped in ALOC/DEAL.
-      (case clause-type
-        ((:chain :rule) ; a full-ass rule
+      (ecase clause-type
+        (:chain
+         ;; Chain rules don't need anything at all.  They just unify, set up
+         ;; the next predicate's arguments, and JUMP.  By definition, in a chain
+         ;; rule all variables must be temporary, so we don't need a stack frame
+         ;; at all!
+         nil)
+        (:rule ; a full-ass rule
          ;; Non-chain rules need an ALLOC at the head and a DEALLOC right before
          ;; the tail call:
          ;;
@@ -1253,10 +1259,10 @@
          (circle-insert-beginning instructions `(:allocate ,variable-count))
          (circle-insert-before (circle-backward instructions) `(:deallocate)))
 
-        ((:fact)
+        (:fact
          (circle-insert-end instructions `(:proceed)))
 
-        ((:query)
+        (:query
          ;; The book doesn't have this ALOC here, but we do it to aid in result
          ;; extraction.  Basically, to make extracting th results of a query
          ;; easier we allocate all of its variables on the stack, so we need