changeset 24563:8f2c479eb125

eliminate unnecessary value stack in evaluator * pt-eval.h, pt-eval.cc (tree_evaluator::result_type): New enum. (tree_evaluator::m_result_type, tree_evaluator::m_expr_result_value, tree_evaluator::m_expr_result_value_list): New data members. (tree_evaluator::push_result): New functions. Store either a single octave_value or octave_value_list along with the type (RT_VALUE or RT_VALUE_LIST). (tree_evaluator::evaluate, tree_evaluator::evaluate_n): Use new result values instead of m_value_stack. (tree_evaluator::value_stack): Delete. A stack is not needed for evaluation results. Instead of pushing results on the value stack, call push_result.
author John W. Eaton <jwe@octave.org>
date Mon, 08 Jan 2018 13:25:10 -0500
parents 5a10409695b7
children 07876b7127bf
files libinterp/parse-tree/pt-eval.cc libinterp/parse-tree/pt-eval.h
diffstat 2 files changed, 91 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/pt-eval.cc	Mon Jan 08 16:13:27 2018 -0800
+++ b/libinterp/parse-tree/pt-eval.cc	Mon Jan 08 13:25:10 2018 -0500
@@ -78,7 +78,9 @@
   void
   tree_evaluator::reset (void)
   {
-    m_value_stack.clear ();
+    m_result_type = RT_UNDEFINED;
+    m_expr_result_value = octave_value ();
+    m_expr_result_value_list = octave_value_list ();
     m_lvalue_list_stack.clear ();
     m_nargout_stack.clear ();
   }
@@ -151,7 +153,7 @@
 
     octave_value fh (octave_fcn_binder::maybe_binder (ov_fcn, this));
 
-    m_value_stack.push (ovl (fh));
+    push_result (fh);
   }
 
   void
@@ -186,7 +188,7 @@
                     if (etype == octave_value::op_el_or)
                       {
                         expr.matlab_style_short_circuit_warning ("|");
-                        m_value_stack.push (ovl (octave_value (true)));
+                        push_result (octave_value (true));
                         return;
                       }
                   }
@@ -195,7 +197,7 @@
                     if (etype == octave_value::op_el_and)
                       {
                         expr.matlab_style_short_circuit_warning ("&");
-                        m_value_stack.push (ovl (octave_value (false)));
+                        push_result (octave_value (false));
                         return;
                       }
                   }
@@ -207,7 +209,7 @@
                     result = b.is_true ();
                   }
 
-                m_value_stack.push (ovl (octave_value (result)));
+                push_result (octave_value (result));
                 return;
               }
           }
@@ -237,7 +239,7 @@
           }
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
@@ -266,7 +268,7 @@
           {
             if (etype == tree_boolean_expression::bool_or)
               {
-                m_value_stack.push (ovl (octave_value (true)));
+                push_result (octave_value (true));
                 return;
               }
           }
@@ -274,7 +276,7 @@
           {
             if (etype == tree_boolean_expression::bool_and)
               {
-                m_value_stack.push (ovl (octave_value (false)));
+                push_result (octave_value (false));
                 return;
               }
           }
@@ -291,7 +293,7 @@
         val = octave_value (result);
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
@@ -320,7 +322,7 @@
           }
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
@@ -352,7 +354,7 @@
 
     if (! op_base || ! op_limit)
       {
-        m_value_stack.push (ovl (octave_value (val)));
+        push_result (octave_value (val));
         return;
       }
 
@@ -402,7 +404,7 @@
                            expr.is_for_cmd_expr ());
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
@@ -1087,7 +1089,8 @@
                 feval ("display", args);
               }
 
-            retval = val;
+            push_result (val);
+            return;
           }
       }
     else if (sym.is_added_static ())
@@ -1095,7 +1098,7 @@
     else
       expr.eval_undefined_error ();
 
-    m_value_stack.push (retval);
+    push_result (retval);
   }
 
   void
@@ -1355,7 +1358,7 @@
                   {
                     // No more indices, so we are done.
 
-                    m_value_stack.push (retval);
+                    push_result (retval);
                     return;
                   }
               }
@@ -1542,7 +1545,7 @@
           }
       }
 
-    m_value_stack.push (retval);
+    push_result (retval);
   }
 
   void
@@ -1739,7 +1742,7 @@
           }
       }
 
-    m_value_stack.push (retval);
+    push_result (retval);
   }
 
   void
@@ -1801,7 +1804,7 @@
 
     retval = val;
 
-    m_value_stack.push (retval);
+    push_result (retval);
   }
 
   void
@@ -1966,7 +1969,7 @@
         val = retval_list;
       }
 
-    m_value_stack.push (val);
+    push_result (val);
   }
 
   void
@@ -1991,7 +1994,7 @@
     if (nargout > 1)
       error ("invalid number of output arguments for constant expression");
 
-    m_value_stack.push (ovl (expr.value ()));
+    push_result (expr.value ());
   }
 
   void
@@ -2001,7 +2004,7 @@
 
     octave_value fh = make_fcn_handle (nm);
 
-    m_value_stack.push (ovl (fh));
+    push_result (fh);
   }
 
   void
@@ -2033,7 +2036,7 @@
           }
       }
 
-    m_value_stack.push (retval);
+    push_result (retval);
   }
 
   void
@@ -2077,7 +2080,7 @@
           }
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
@@ -2120,7 +2123,7 @@
           }
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
@@ -2232,7 +2235,7 @@
           }
       }
 
-    m_value_stack.push (ovl (val));
+    push_result (val);
   }
 
   void
--- a/libinterp/parse-tree/pt-eval.h	Mon Jan 08 16:13:27 2018 -0800
+++ b/libinterp/parse-tree/pt-eval.h	Mon Jan 08 13:25:10 2018 -0500
@@ -31,6 +31,7 @@
 #include <string>
 
 #include "call-stack.h"
+#include "ov.h"
 #include "ovl.h"
 #include "profiler.h"
 #include "pt-exp.h"
@@ -45,6 +46,13 @@
   class interpreter;
   class unwind_protect;
 
+  enum result_type
+  {
+    RT_UNDEFINED = 0,
+    RT_VALUE = 1,
+    RT_VALUE_LIST = 2
+  };
+
   // How to evaluate the code that the parse trees represent.
 
   class OCTINTERP_API tree_evaluator : public tree_walker
@@ -115,8 +123,10 @@
     typedef void (*decl_elt_init_fcn) (tree_decl_elt&);
 
     tree_evaluator (interpreter& interp)
-      : m_interpreter (interp), m_value_stack (), m_lvalue_list_stack (),
-        m_nargout_stack (), m_call_stack (interp), m_profiler (),
+      : m_interpreter (interp), m_result_type (RT_UNDEFINED),
+        m_expr_result_value (), m_expr_result_value_list (),
+        m_lvalue_list_stack (), m_nargout_stack (),
+        m_call_stack (interp), m_profiler (),
         m_max_recursion_depth (256), m_silent_functions (false),
         m_string_fill_char (' '), m_PS4 ("+ "), m_echo (ECHO_OFF),
         m_echo_state (false), m_echo_file_name (), m_echo_file_pos (1),
@@ -269,28 +279,73 @@
               ? nullptr : m_lvalue_list_stack.top ());
     }
 
+    void push_result (const octave_value& val)
+    {
+      m_result_type = RT_VALUE;
+      m_expr_result_value = val;
+    }
+
+    void push_result (const octave_value_list& vals)
+    {
+      m_result_type = RT_VALUE_LIST;
+      m_expr_result_value_list = vals;
+    }
+
     octave_value evaluate (tree_expression *expr, int nargout = 1)
     {
+      octave_value retval;
+
       m_nargout_stack.push (nargout);
 
       expr->accept (*this);
 
       m_nargout_stack.pop ();
 
-      octave_value_list tmp = m_value_stack.val_pop ();
+      switch (m_result_type)
+        {
+        case RT_UNDEFINED:
+          panic_impossible ();
+          break;
 
-      return tmp.empty () ? octave_value () : tmp(0);
+        case RT_VALUE:
+          retval = m_expr_result_value;
+          break;
+
+        case RT_VALUE_LIST:
+          retval = (m_expr_result_value_list.empty ()
+                    ? octave_value () : m_expr_result_value_list(0));
+          break;
+        }
+
+      return retval;
     }
 
     octave_value_list evaluate_n (tree_expression *expr, int nargout = 1)
     {
+      octave_value_list retval;
+
       m_nargout_stack.push (nargout);
 
       expr->accept (*this);
 
       m_nargout_stack.pop ();
 
-      return m_value_stack.val_pop ();
+      switch (m_result_type)
+        {
+        case RT_UNDEFINED:
+          panic_impossible ();
+          break;
+
+        case RT_VALUE:
+          retval = ovl (m_expr_result_value);
+          break;
+
+        case RT_VALUE_LIST:
+          retval = m_expr_result_value_list;
+          break;
+        }
+
+      return retval;
     }
 
     octave_value evaluate (tree_decl_elt *);
@@ -424,7 +479,9 @@
 
     interpreter& m_interpreter;
 
-    value_stack<octave_value_list> m_value_stack;
+    result_type m_result_type;
+    octave_value m_expr_result_value;
+    octave_value_list m_expr_result_value_list;
 
     value_stack<const std::list<octave_lvalue>*> m_lvalue_list_stack;