x86: Adjust the size of the values written to the x87 misc registers
[gem5.git] / src / base / statistics.hh
index 1f8a5932643a4a14435ff5160dfde4266df8d147..a21bf81d17ba21dda0e6ace9150a396f78b0bd09 100644 (file)
@@ -57,6 +57,7 @@
 #include <iosfwd>
 #include <list>
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -66,7 +67,6 @@
 #include "base/cast.hh"
 #include "base/cprintf.hh"
 #include "base/intmath.hh"
-#include "base/refcnt.hh"
 #include "base/str.hh"
 #include "base/types.hh"
 
@@ -228,12 +228,12 @@ class DataWrap : public InfoAccess
     /**
      * Copy constructor, copies are not allowed.
      */
-    DataWrap(const DataWrap &stat);
+    DataWrap(const DataWrap &stat) {}
 
     /**
      * Can't copy stats.
      */
-    void operator=(const DataWrap &);
+    void operator=(const DataWrap &) {}
 
   public:
     DataWrap()
@@ -331,6 +331,15 @@ class DataWrapVec : public DataWrap<Derived, InfoProxyType>
   public:
     typedef InfoProxyType<Derived> Info;
 
+    DataWrapVec()
+    {}
+
+    DataWrapVec(const DataWrapVec &ref)
+    {}
+
+    void operator=(const DataWrapVec &)
+    {}
+
     // The following functions are specific to vectors.  If you use them
     // in a non vector context, you will get a nice compiler error!
 
@@ -732,7 +741,7 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy>
 class ProxyInfo : public ScalarInfo
 {
   public:
-    std::string str() const { return to_string(value()); }
+    std::string str() const { return std::to_string(value()); }
     size_type size() const { return 1; }
     bool check() const { return true; }
     void prepare() { }
@@ -768,6 +777,25 @@ class FunctorProxy : public ProxyInfo
     Result total() const { return (*functor)(); }
 };
 
+/**
+ * A proxy similar to the FunctorProxy, but allows calling a method of a bound
+ * object, instead of a global free-standing function.
+ */
+template <class T, class V>
+class MethodProxy : public ProxyInfo
+{
+  private:
+    T *object;
+    typedef V (T::*MethodPointer) () const;
+    MethodPointer method;
+
+  public:
+    MethodProxy(T *obj, MethodPointer meth) : object(obj), method(meth) {}
+    Counter value() const { return (object->*method)(); }
+    Result result() const { return (object->*method)(); }
+    Result total() const { return (object->*method)(); }
+};
+
 template <class Derived>
 class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
 {
@@ -796,6 +824,22 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
         return this->self();
     }
 
+    /**
+     * Extended functor that calls the specified method of the provided object.
+     *
+     * @param obj Pointer to the object whose method should be called.
+     * @param method Pointer of the function / method of the object.
+     * @return Updated stats item.
+     */
+    template <class T, class V>
+    Derived &
+    method(T *obj,  V (T::*method)() const)
+    {
+        proxy = new MethodProxy<T,V>(obj, method);
+        this->setInit();
+        return this->self();
+    }
+
     Counter value() { return proxy->value(); }
     Result result() const { return proxy->result(); }
     Result total() const { return proxy->total(); };
@@ -1048,7 +1092,7 @@ class VectorBase : public DataWrapVec<Derived, VectorInfoProxy>
 
   public:
     VectorBase()
-        : storage(NULL)
+        : storage(nullptr), _size(0)
     {}
 
     ~VectorBase()
@@ -1188,7 +1232,7 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
 
   public:
     Vector2dBase()
-        : storage(NULL)
+        : x(0), y(0), _size(0), storage(nullptr)
     {}
 
     ~Vector2dBase()
@@ -1231,7 +1275,7 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
     operator[](off_type index)
     {
         off_type offset = index * y;
-        assert (index >= 0 && offset + index < size());
+        assert (index >= 0 && offset + y <= size());
         return Proxy(this->self(), offset, y);
     }
 
@@ -1317,7 +1361,8 @@ class DistStor
         /** The number of buckets. Equal to (max-min)/bucket_size. */
         size_type buckets;
 
-        Params() : DistParams(Dist) {}
+        Params() : DistParams(Dist), min(0), max(0), bucket_size(0),
+                   buckets(0) {}
     };
 
   private:
@@ -1327,8 +1372,6 @@ class DistStor
     Counter max_track;
     /** The number of entries in each bucket. */
     Counter bucket_size;
-    /** The number of buckets. Equal to (max-min)/bucket_size. */
-    size_type buckets;
 
     /** The smallest value sampled. */
     Counter min_val;
@@ -1416,9 +1459,8 @@ class DistStor
         data.underflow = underflow;
         data.overflow = overflow;
 
-        size_type buckets = params->buckets;
-        data.cvec.resize(buckets);
-        for (off_type i = 0; i < buckets; ++i)
+        data.cvec.resize(params->buckets);
+        for (off_type i = 0; i < params->buckets; ++i)
             data.cvec[i] = cvec[i];
 
         data.sum = sum;
@@ -1464,7 +1506,7 @@ class HistStor
         /** The number of buckets.. */
         size_type buckets;
 
-        Params() : DistParams(Hist) {}
+        Params() : DistParams(Hist), buckets(0) {}
     };
 
   private:
@@ -1496,6 +1538,7 @@ class HistStor
     void grow_up();
     void grow_out();
     void grow_convert();
+    void add(HistStor *);
 
     /**
      * Add a value to the distribution for the given number of times.
@@ -1525,7 +1568,7 @@ class HistStor
         size_type index =
             (int64_t)std::floor((val - min_bucket) / bucket_size);
 
-        assert(index >= 0 && index < size());
+        assert(index < size());
         cvec[index] += number;
 
         sum += val * number;
@@ -1834,6 +1877,12 @@ class DistBase : public DataWrap<Derived, DistInfoProxy>
     {
         data()->reset(this->info());
     }
+
+    /**
+     *  Add the argument distribution to the this distibution.
+     */
+    void add(DistBase &d) { data()->add(d.data()); }
+
 };
 
 template <class Stat>
@@ -2001,7 +2050,7 @@ class DistProxy
  * Base class for formula statistic node. These nodes are used to build a tree
  * that represents the formula.
  */
-class Node : public RefCounted
+class Node
 {
   public:
     /**
@@ -2026,8 +2075,8 @@ class Node : public RefCounted
     virtual std::string str() const = 0;
 };
 
-/** Reference counting pointer to a function Node. */
-typedef RefCountingPtr<Node> NodePtr;
+/** Shared pointer to a function Node. */
+typedef std::shared_ptr<Node> NodePtr;
 
 class ScalarStatNode : public Node
 {
@@ -2122,7 +2171,7 @@ class ConstNode : public Node
     const VResult &result() const { return vresult; }
     Result total() const { return vresult[0]; };
     size_type size() const { return 1; }
-    std::string str() const { return to_string(vresult[0]); }
+    std::string str() const { return std::to_string(vresult[0]); }
 };
 
 template <class T>
@@ -2152,7 +2201,7 @@ class ConstVectorNode : public Node
         size_type size = this->size();
         std::string tmp = "(";
         for (off_type i = 0; i < size; i++)
-            tmp += csprintf("%s ",to_string(vresult[i]));
+            tmp += csprintf("%s ", std::to_string(vresult[i]));
         tmp += ")";
         return tmp;
     }
@@ -2289,9 +2338,31 @@ class BinaryNode : public Node
     total() const
     {
         const VResult &vec = this->result();
+        const VResult &lvec = l->result();
+        const VResult &rvec = r->result();
         Result total = 0.0;
-        for (off_type i = 0; i < size(); i++)
+        Result lsum = 0.0;
+        Result rsum = 0.0;
+        Op op;
+
+        assert(lvec.size() > 0 && rvec.size() > 0);
+        assert(lvec.size() == rvec.size() ||
+               lvec.size() == 1 || rvec.size() == 1);
+
+        /** If vectors are the same divide their sums (x0+x1)/(y0+y1) */
+        if (lvec.size() == rvec.size() && lvec.size() > 1) {
+            for (off_type i = 0; i < size(); ++i) {
+                lsum += lvec[i];
+                rsum += rvec[i];
+            }
+            return op(lsum, rsum);
+        }
+
+        /** Otherwise divide each item by the divisor */
+        for (off_type i = 0; i < size(); ++i) {
             total += vec[i];
+        }
+
         return total;
     }
 
@@ -2350,13 +2421,13 @@ class SumNode : public Node
         size_type size = lvec.size();
         assert(size > 0);
 
-        Result vresult = 0.0;
+        Result result = 0.0;
 
         Op op;
         for (off_type i = 0; i < size; ++i)
-            vresult = op(vresult, lvec[i]);
+            result = op(result, lvec[i]);
 
-        return vresult;
+        return result;
     }
 
     size_type size() const { return 1; }
@@ -2837,6 +2908,14 @@ class Formula : public DataWrapVec<Formula, FormulaInfoProxy>
      * @return a reference to this formula.
      */
     const Formula &operator+=(Temp r);
+
+    /**
+     * Divide the existing tree by the given one.
+     * @param r The root of the expression tree.
+     * @return a reference to this formula.
+     */
+    const Formula &operator/=(Temp r);
+
     /**
      * Return the result of the Fomula in a vector.  If there were no Vector
      * components to the Formula, then the vector is size 1.  If there were,
@@ -2910,7 +2989,9 @@ class Temp
      * Copy the given pointer to this class.
      * @param n A pointer to a Node object to copy.
      */
-    Temp(NodePtr n) : node(n) { }
+    Temp(const NodePtr &n) : node(n) { }
+
+    Temp(NodePtr &&n) : node(std::move(n)) { }
 
     /**
      * Return the node pointer.
@@ -2918,6 +2999,11 @@ class Temp
      */
     operator NodePtr&() { return node; }
 
+    /**
+     * Makde gcc < 4.6.3 happy and explicitly get the underlying node.
+     */
+    NodePtr getNodePtr() const { return node; }
+
   public:
     /**
      * Create a new ScalarStatNode.
@@ -3076,56 +3162,67 @@ class Temp
 inline Temp
 operator+(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::plus<Result> > >(l, r));
 }
 
 inline Temp
 operator-(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::minus<Result> > >(l, r));
 }
 
 inline Temp
 operator*(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::multiplies<Result> > >(l, r));
 }
 
 inline Temp
 operator/(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::divides<Result> > >(l, r));
 }
 
 inline Temp
 operator-(Temp l)
 {
-    return NodePtr(new UnaryNode<std::negate<Result> >(l));
+    return Temp(std::make_shared<UnaryNode<std::negate<Result> > >(l));
 }
 
 template <typename T>
 inline Temp
 constant(T val)
 {
-    return NodePtr(new ConstNode<T>(val));
+    return Temp(std::make_shared<ConstNode<T> >(val));
 }
 
 template <typename T>
 inline Temp
 constantVector(T val)
 {
-    return NodePtr(new ConstVectorNode<T>(val));
+    return Temp(std::make_shared<ConstVectorNode<T> >(val));
 }
 
 inline Temp
 sum(Temp val)
 {
-    return NodePtr(new SumNode<std::plus<Result> >(val));
+    return Temp(std::make_shared<SumNode<std::plus<Result> > >(val));
 }
 
 /** Dump all statistics data to the registered outputs */
 void dump();
 void reset();
+void enable();
+bool enabled();
+
+/**
+ * Register reset and dump handlers.  These are the functions which
+ * will actually perform the whole statistics reset/dump actions
+ * including processing the reset/dump callbacks
+ */
+typedef void (*Handler)();
+
+void registerHandlers(Handler reset_handler, Handler dump_handler);
 
 /**
  * Register a callback that should be called whenever statistics are
@@ -3133,8 +3230,34 @@ void reset();
  */
 void registerResetCallback(Callback *cb);
 
+/**
+ * Register a callback that should be called whenever statistics are
+ * about to be dumped
+ */
+void registerDumpCallback(Callback *cb);
+
+/**
+ * Process all the callbacks in the reset callbacks queue
+ */
+void processResetQueue();
+
+/**
+ * Process all the callbacks in the dump callbacks queue
+ */
+void processDumpQueue();
+
 std::list<Info *> &statsList();
 
+typedef std::map<const void *, Info *> MapType;
+MapType &statsMap();
+
+typedef std::map<std::string, Info *> NameMapType;
+NameMapType &nameMap();
+
+bool validateStatName(const std::string &name);
+
 } // namespace Stats
 
+void debugDumpStats();
+
 #endif // __BASE_STATISTICS_HH__