Program Listing for File SymbolicBound.h

Program Listing for File SymbolicBound.h#

Return to documentation for file (src/midend/astUtil/symbolicVal/SymbolicBound.h)

#ifndef SYMBOLIC_BOUND_H
#define SYMBOLIC_BOUND_H

#include "SymbolicVal.h"
#include <map>

class SingleValBound : public MapObject<SymbolicVal, SymbolicBound>
{
  SymbolicVal val;
  SymbolicBound bound;
 public:
  SingleValBound( const SymbolicVal& v, const SymbolicVal& lb, const SymbolicVal& ub)
      : val(v), bound(lb, ub) {}
  SymbolicBound operator() ( const SymbolicVal& v)
   {
      return (v == val)? bound : SymbolicBound();
   }
};
class MapVarBound
 : public MapObject<SymbolicVal, SymbolicBound>,
  public SymbolicVisitor
{
  SymbolicBound result;
  typedef std::pair<std::string,AstNodePtr> Key;
  typedef std::map< Key, SymbolicBound, std::less<Key> > MapBound;
  MapBound bmap;

  void VisitVar( const SymbolicVar& var)
  {
    MapBound::const_iterator p = bmap.find(Key(var.GetVarName(), var.GetVarScope()));
    if (p != bmap.end())
       result = (*p).second;
  }
 public:
  void add( const SymbolicVar& var, const SymbolicBound& bound)
  { bmap[Key(var.GetVarName(), var.GetVarScope())] = bound; }
  SymbolicBound operator()(const SymbolicVal& v)
  {
    result = SymbolicBound();
    v.Visit(this);
    return result;
  }
};

class VarInfo : public MapObject<SymbolicVal, SymbolicBound>
{
  SymbolicVar var;
  SymbolicBound b;
 public:
  VarInfo() {}
  VarInfo( const SymbolicVar& _var, const SymbolicVal& _lb,
           const SymbolicVal& _ub) : var(_var),b(_lb,_ub) {}
  VarInfo( const SymbolicVar& _var, const SymbolicBound& _b)
           : var(_var),b(_b) {}
  std::string toString() const {
      return  var.toString() + " : " + b.toString();
  }
  SymbolicBound operator() ( const SymbolicVal& v)
   { return (v == var)? b : SymbolicBound(); }

  const SymbolicVar& GetVar() const { return var; }
  SymbolicVar& GetVar() { return var; }
  const SymbolicBound& GetBound() const { return b; }
  SymbolicBound& GetBound() { return b; }
  bool IsTop() const { return var.GetVarName() == ""; }

  SymbolicBound GetVarRestr( const SymbolicVar v);

};

template <class Stmt, class Interface>
class SymbolicBoundAnalysis
  : public MapObject<SymbolicVal, SymbolicBound>, private SymbolicVisitor
{
 protected:
  Interface iface;
  SymbolicBound result;
  Stmt node, ances;
  void VisitVar( const SymbolicVar& var)
   { result = GetBound(var); }
 public:
  SymbolicBoundAnalysis(Interface _interface, Stmt n, Stmt a = 0)
      : iface(_interface), node(n), ances(a) {}
  SymbolicBound GetBound(const SymbolicVar& var, Stmt* stop = 0)
       {
         SymbolicBound tmp;
         Stmt n = node;
         for ( ; n != ances; n = iface.GetParent(n)) {
             VarInfo info = iface.GetVarInfo(n);
             if (info.IsTop())
                continue;
             if (info.GetVar() == var) {
                if (tmp.lb.IsNIL())
                     tmp.lb = info.GetBound().lb;
                if (tmp.ub.IsNIL())
                     tmp.ub = info.GetBound().ub;
             }
             if (!tmp.lb.IsNIL() && !tmp.ub.IsNIL())
                  break;
         }
         if (stop != 0)
            *stop = n;
         return tmp;
       }
  SymbolicBound operator()( const SymbolicVal &v)
   { result = SymbolicBound();
     v.Visit(this);
     return result;
   }
};

template <class Stmt, class Interface>
class SymbolicConstBoundAnalysis : public SymbolicBoundAnalysis<Stmt,Interface>
{
 protected:
  using SymbolicBoundAnalysis<Stmt,Interface>::result;
  using SymbolicBoundAnalysis<Stmt,Interface>::ances;
  using SymbolicBoundAnalysis<Stmt,Interface>::iface;
  using SymbolicBoundAnalysis<Stmt,Interface>::node;
 private:
  void VisitVar( const SymbolicVar& var)
   { result = GetConstBound(var); }
 public:
  SymbolicConstBoundAnalysis(Interface _interface, Stmt n, Stmt a )
      : SymbolicBoundAnalysis<Stmt,Interface>(_interface,n,a) {}
  SymbolicBound GetConstBound(const SymbolicVar& var)
       {
         Stmt n;
         SymbolicBound tmp = SymbolicBoundAnalysis<Stmt,Interface>::GetBound(var, &n);
         if (n != ances) {
            SymbolicBoundAnalysis<Stmt,Interface> next(iface,iface.GetParent(n),ances);
            if (tmp.lb.IsNIL())
                tmp.lb = var;
            if (tmp.ub.IsNIL())
                tmp.ub = var;
            tmp.lb = GetValBound(tmp.lb,next).lb;
            tmp.ub = GetValBound(tmp.ub,next).ub;
         }
         else if (tmp.lb.IsNIL() && tmp.ub.IsNIL()) {
            for (n = node ; n != ances; n = iface.GetParent(n)) {
               VarInfo info = iface.GetVarInfo(n);
               if (info.IsTop())
                  continue;
               SymbolicCond cond(REL_LE, info.GetBound().lb, info.GetBound().ub);
               SymbolicVal r = UnwrapVarCond(cond,var,tmp);
               if (r != 1) {
                  tmp = SymbolicBound();
                  continue;
               }
               else {
                  if (tmp.lb.GetValType() != VAL_CONST)
                      tmp.lb = SymbolicVal();
                  if (tmp.ub.GetValType() != VAL_CONST)
                      tmp.ub = SymbolicVal();
                  break;
               }
             }
         }
         return tmp;
       }
};
#endif