home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / set.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  16.2 KB  |  681 lines

  1. // $Id: set.h,v 1.13 2001/02/01 10:24:07 mdejong Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef set_INCLUDED
  11. #define set_INCLUDED
  12.  
  13. #include "platform.h"
  14. #include "symbol.h"
  15.  
  16. #ifdef    HAVE_JIKES_NAMESPACE
  17. namespace Jikes {    // Open namespace Jikes block
  18. #endif
  19.  
  20. class ShadowSymbol
  21. {
  22. public:
  23.     ShadowSymbol *next;
  24.     Symbol *symbol;
  25.     int pool_index;
  26.  
  27.     inline NameSymbol *Identity() { return symbol -> Identity(); }
  28.  
  29.     ShadowSymbol(Symbol *symbol_) : symbol(symbol_),
  30.                                     conflict(NULL)
  31.     {}
  32.  
  33.     ~ShadowSymbol() { delete conflict; }
  34.  
  35.     Symbol *Conflict(int i) { return (*conflict)[i]; }
  36.  
  37.     inline int NumConflicts()
  38.     {
  39.         return (conflict ? conflict -> Length() : 0);
  40.     }
  41.  
  42.     inline void AddConflict(Symbol *conflict_symbol)
  43.     {
  44.         if ((symbol != conflict_symbol) && (! Find(conflict_symbol)))
  45.             conflict -> Next() = conflict_symbol;
  46.         return;
  47.     }
  48.  
  49.     inline void RemoveConflict(int k)
  50.     {
  51.         int last_index = conflict -> Length() - 1;
  52.         if (k < 0) // when k is negative, it identifies the main symbol
  53.              symbol = (*conflict)[last_index];
  54.         else (*conflict)[k] = (*conflict)[last_index];
  55.         conflict -> Reset(last_index);
  56.     }
  57.  
  58. private:
  59.     Tuple<Symbol *> *conflict;
  60.  
  61.     bool Find(Symbol *conflict_symbol)
  62.     {
  63.         if (! conflict)
  64.             conflict = new Tuple<Symbol *>(4);
  65.         for (int k = 0; k < conflict -> Length(); k++)
  66.             if ((*conflict)[k] == conflict_symbol)
  67.                 return true;
  68.         return false;
  69.     }
  70. };
  71.  
  72.  
  73. class SymbolSet
  74. {
  75. public:
  76.     enum
  77.     {
  78.         DEFAULT_HASH_SIZE = 13,
  79.         MAX_HASH_SIZE = 1021
  80.     };
  81.  
  82.     SymbolSet(int hash_size_ = DEFAULT_HASH_SIZE) : symbol_pool(256),
  83.                                                     main_index(0),
  84.                                                     sub_index(0)
  85.     {
  86.         hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  87.  
  88.         prime_index = -1;
  89.         do
  90.         {
  91.             if (hash_size < primes[prime_index + 1])
  92.                 break;
  93.             prime_index++;
  94.         } while (primes[prime_index] < MAX_HASH_SIZE);
  95.  
  96.         base = (ShadowSymbol **) memset(new ShadowSymbol *[hash_size], 0, hash_size * sizeof(ShadowSymbol *));
  97.     }
  98.  
  99.     ~SymbolSet();
  100.  
  101.     //
  102.     // Calculate the size of the set an return the value.
  103.     //
  104.     inline int Size()
  105.     {
  106.         int size = 0;
  107.  
  108.         for (int i = 0; i < symbol_pool.Length(); i++)
  109.         {
  110.             ShadowSymbol *shadow = symbol_pool[i];
  111.             Symbol *symbol = shadow -> symbol;
  112.             for (int k = 0; symbol; symbol = (Symbol *) (k < shadow -> NumConflicts() ? shadow -> Conflict(k++) : NULL))
  113.                 size++;
  114.         }
  115.  
  116.         return size;
  117.     }
  118.  
  119.     //
  120.     // Empty out the set in question - i.e., remove all its elements
  121.     //
  122.     inline void SetEmpty()
  123.     {
  124.         for (int i = 0; i < symbol_pool.Length(); i++)
  125.             delete symbol_pool[i];
  126.         symbol_pool.Reset();
  127.         base = (ShadowSymbol **) memset(base, 0, hash_size * sizeof(ShadowSymbol *));
  128.     }
  129.  
  130.     //
  131.     // Empty out the set in question - i.e., remove all its elements
  132.     //
  133.     bool IsEmpty() { return symbol_pool.Length() == 0; }
  134.  
  135.     //
  136.     // Assignment of a set to another.
  137.     //
  138.     SymbolSet &operator=(SymbolSet &rhs)
  139.     {
  140.         if (this != &rhs)
  141.         {
  142.             this -> SetEmpty();
  143.             this -> Union(rhs);
  144.         }
  145.  
  146.         return *this;
  147.     }
  148.  
  149.     //
  150.     // Equality comparison of two sets
  151.     //
  152.     bool operator==(SymbolSet &);
  153.  
  154.     //
  155.     // NonEquality comparison of two sets
  156.     //
  157.     inline bool operator!=(SymbolSet &rhs)
  158.     {
  159.         return ! (*this == rhs);
  160.     }
  161.  
  162.     //
  163.     // Union the set in question with the set passed as argument: "set"
  164.     //
  165.     void Union(SymbolSet &);
  166.  
  167.     //
  168.     // Intersect the set in question with the set passed as argument: "set"
  169.     //
  170.     void Intersection(SymbolSet &);
  171.  
  172.     //
  173.     // Return a bolean value indicating whether or not the set in question intersects the set passed as argument: "set"
  174.     // i.e., is there at least one element of set that is also an element of "this" set.
  175.     //
  176.     bool Intersects(SymbolSet &);
  177.  
  178.     //
  179.     // How many elements with this name symbol do we have?
  180.     //
  181.     inline int NameCount(Symbol *element)
  182.     {
  183.         NameSymbol *name_symbol = element -> Identity();
  184.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  185.         {
  186.             if (shadow -> Identity() == name_symbol)
  187.                 return shadow -> NumConflicts() + 1;
  188.         }
  189.  
  190.         return 0;
  191.     }
  192.  
  193.     //
  194.     // Is "element" an element of the set in question ?
  195.     //
  196.     inline bool IsElement(Symbol *element)
  197.     {
  198.         assert(element);
  199.  
  200.         NameSymbol *name_symbol = element -> Identity();
  201.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  202.         {
  203.             if (shadow -> Identity() == name_symbol)
  204.             {
  205.                 Symbol *symbol = shadow -> symbol;
  206.                 for (int k = 0; symbol; symbol = (Symbol *) (k < shadow -> NumConflicts() ? shadow -> Conflict(k++) : NULL))
  207.                 {
  208.                     if (symbol == element)
  209.                         return true;
  210.                 }
  211.  
  212.                 return false;
  213.             }
  214.         }
  215.  
  216.         return false;
  217.     }
  218.  
  219.     //
  220.     // Add element to the set in question if was not already there.
  221.     //
  222.     inline void AddElement(Symbol *element)
  223.     {
  224.         NameSymbol *name_symbol = element -> Identity();
  225.         int i = name_symbol -> index % hash_size;
  226.  
  227.         ShadowSymbol *shadow;
  228.         for (shadow = base[i]; shadow; shadow = shadow -> next)
  229.         {
  230.             if (shadow -> Identity() == name_symbol)
  231.             {
  232.                 shadow -> AddConflict(element);
  233.                 return;
  234.             }
  235.         }
  236.  
  237.         shadow = new ShadowSymbol(element);
  238.         shadow -> pool_index = symbol_pool.Length();
  239.         symbol_pool.Next() = shadow;
  240.  
  241.         shadow -> next = base[i];
  242.         base[i] = shadow;
  243.  
  244.         //
  245.         // If the set is "adjustable" and the number of unique elements in it exceeds
  246.         // 2 times the size of the base, and we have not yet reached the maximum
  247.         // allowable size for a base, reallocate a larger base and rehash the elements.
  248.         //
  249.         if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  250.             Rehash();
  251.  
  252.         return;
  253.     }
  254.  
  255.  
  256.     void RemoveElement(Symbol *);
  257.  
  258.     Symbol* FirstElement()
  259.     {
  260.         main_index = 0;
  261.         sub_index = 0;
  262.         return (main_index < symbol_pool.Length() ? symbol_pool[main_index] -> symbol : (Symbol *) NULL);
  263.     }
  264.  
  265.     Symbol* NextElement()
  266.     {
  267.         Symbol *symbol = NULL;
  268.  
  269.         if (main_index < symbol_pool.Length())
  270.         {
  271.              if (sub_index < symbol_pool[main_index] -> NumConflicts())
  272.                   symbol = symbol_pool[main_index] -> Conflict(sub_index++);
  273.              else
  274.              {
  275.                  main_index++;
  276.                  sub_index = 0;
  277.                  symbol = (main_index < symbol_pool.Length() ? symbol_pool[main_index] -> symbol : (Symbol *) NULL);
  278.              }
  279.         }
  280.  
  281.         return symbol;
  282.     }
  283.  
  284. protected:
  285.  
  286.     Tuple<ShadowSymbol *> symbol_pool;
  287.  
  288.     int main_index,
  289.         sub_index;
  290.  
  291.     ShadowSymbol **base;
  292.     int hash_size;
  293.  
  294.     static int primes[];
  295.     int prime_index;
  296.  
  297.     void Rehash();
  298. };
  299.  
  300.  
  301. //
  302. // Single-value Mapping from a name_symbol into a symbol with that name.
  303. //
  304. class NameSymbolMap : public SymbolSet
  305. {
  306. public:
  307.     NameSymbolMap(int hash_size_ = DEFAULT_HASH_SIZE) : SymbolSet(hash_size_)
  308.     {}
  309.  
  310.     //
  311.     // Is there an element with this name in the map ?
  312.     //
  313.     inline Symbol *Image(NameSymbol *name_symbol)
  314.     {
  315.         assert(name_symbol);
  316.  
  317.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  318.         {
  319.             if (shadow -> Identity() == name_symbol)
  320.                 return shadow -> symbol;
  321.         }
  322.  
  323.         return NULL;
  324.     }
  325.  
  326.     //
  327.     // Add element to the set in question if was not already there.
  328.     //
  329.     inline void AddElement(Symbol *element)
  330.     {
  331.         assert(element);
  332.  
  333.         ShadowSymbol *shadow = NULL;
  334.         for (shadow = base[element -> Identity() -> index % hash_size]; shadow; shadow = shadow -> next)
  335.         {
  336.             if (shadow -> Identity() == element -> Identity())
  337.                 break;
  338.         }
  339.  
  340.         //
  341.         // If an element was already mapped into that name, replace it.
  342.         // Otherwise, add the new element.
  343.         //
  344.         if (shadow)
  345.              shadow -> symbol = element;
  346.         else SymbolSet::AddElement(element);
  347.  
  348.         return;
  349.     }
  350. };
  351.  
  352.  
  353. //
  354. // Single-value Mapping from an arbitrary symbol into another arbitrary symbol.
  355. //
  356. class SymbolMap
  357. {
  358. public:
  359.     enum
  360.     {
  361.         DEFAULT_HASH_SIZE = 13,
  362.         MAX_HASH_SIZE = 1021
  363.     };
  364.  
  365.     SymbolMap(int hash_size_ = DEFAULT_HASH_SIZE);
  366.     ~SymbolMap();
  367.  
  368.     //
  369.     // Has symbol been mapped to an image, yet? If so, return the image.
  370.     //
  371.     inline Symbol *Image(Symbol *symbol)
  372.     {
  373.         assert(symbol);
  374.  
  375.         int k = symbol -> Identity() -> index % hash_size;
  376.         for (Element *element = base[k]; element; element = element -> next)
  377.         {
  378.             if (element -> domain_element == symbol)
  379.                 return element -> image;
  380.         }
  381.  
  382.         return NULL;
  383.     }
  384.  
  385.     //
  386.     // Map or remap symbol to a given image.
  387.     //
  388.     void Map(Symbol *, Symbol *);
  389.  
  390. private:
  391.  
  392.     class Element
  393.     {
  394.     public:
  395.         Element *next;
  396.         Symbol  *domain_element,
  397.                 *image;
  398.     };
  399.  
  400.     Tuple<Element *> symbol_pool;
  401.  
  402.     Element **base;
  403.     int hash_size;
  404.  
  405.     static int primes[];
  406.     int prime_index;
  407.  
  408.     void Rehash();
  409. };
  410.  
  411.  
  412. //
  413. // This Bitset template class can be used to construct sets of
  414. // integers. The template takes as argument the address of an integer
  415. // variable, set_size, which indicates that the universe of the sets
  416. // is: {0..*set_size}.
  417. //
  418. class BitSet
  419. {
  420.     typedef unsigned CELL;
  421.  
  422.     CELL *s;
  423.     const int set_size;
  424.  
  425. public:
  426.  
  427.     enum { EMPTY, UNIVERSE, cell_size = sizeof(CELL) * CHAR_BIT };
  428.  
  429.     //
  430.     // Produce the empty set.
  431.     //
  432.     void SetEmpty()
  433.     {
  434.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  435.             s[i] = 0;
  436.     }
  437.  
  438.     //
  439.     // Produce the universe set.
  440.     //
  441.     void SetUniverse()
  442.     {
  443.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  444.             s[i] = ~((CELL) 0);
  445.     }
  446.  
  447.     //
  448.     // This function takes as argument the size of a hash table, table_size.
  449.     // It hashes a bitset into a location within the range <1..table_size-1>.
  450.     //
  451.     int Hash(int table_size)
  452.     {
  453.         unsigned long hash_address = 0;
  454.  
  455.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  456.             hash_address += s[i];
  457.  
  458.         return hash_address % table_size;
  459.     }
  460.  
  461.     //
  462.     // Assignment of a bitset to another.
  463.     //
  464.     BitSet& operator=(const BitSet& rhs)
  465.     {
  466.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  467.             s[i] = rhs.s[i];
  468.  
  469.         return *this;
  470.     }
  471.  
  472.     //
  473.     // Constructor of an uninitialized bitset.
  474.     //
  475.     BitSet(int set_size_) : set_size(set_size_)
  476.     {
  477.         //
  478.         // Note that we comment out the -1 because some C++ compilers
  479.         // do not know how to allocate an array of size 0. Note that
  480.         // we assert that set_size >= 0.
  481.         //
  482.         s = new CELL[(set_size + cell_size /* - 1 */) / cell_size];
  483.     }
  484.  
  485.     //
  486.     // Constructor of an initialized bitset.
  487.     //
  488.     BitSet(int set_size_, int init) : set_size(set_size_)
  489.     {
  490.         //
  491.         // Note that we comment out the -1 because some C++ compilers
  492.         // do not know how to allocate an array of size 0. Note that
  493.         // we assert that set_size >= 0.
  494.         //
  495.         s = new CELL[(set_size + cell_size /* - 1 */) / cell_size];
  496.         if (init == UNIVERSE)
  497.              SetUniverse();
  498.         else SetEmpty();
  499.     }
  500.  
  501.     //
  502.     // Constructor to clone a bitset.
  503.     //
  504.     BitSet(const BitSet& rhs) : set_size(rhs.set_size)
  505.     {
  506.         //
  507.         // Note that we comment out the -1 because some C++ compilers
  508.         // do not know how to allocate an array of size 0. Note that
  509.         // we assert that set_size >= 0.
  510.         //
  511.         s = new CELL[(set_size + cell_size /* - 1 */) / cell_size];
  512.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  513.             s[i] = rhs.s[i];
  514.     }
  515.  
  516.     //
  517.     // Destructor of a bitset.
  518.     //
  519.     ~BitSet() { delete [] s; }
  520.  
  521.     //
  522.     // Return size of a bit set.
  523.     //
  524.     int Size() { return set_size; }
  525.  
  526.     //
  527.     // Return a boolean value indicating whether or not the element i
  528.     // is in the bitset in question.
  529.     //
  530.     bool operator[](const int i)
  531.     {
  532.         assert(i >= 0 && i < set_size);
  533.  
  534.         return (s[i / cell_size] &
  535.                 ((i + cell_size) % cell_size
  536.                           ? (CELL) 1 << ((i + cell_size) % cell_size)
  537.                           : (CELL) 1)) != 0;
  538.     }
  539.  
  540.     //
  541.     // Insert an element i in the bitset in question.
  542.     //
  543.     void AddElement(int i)
  544.     {
  545.         assert(i >= 0 && i < set_size);
  546.  
  547.         s[i / cell_size] |= ((i + cell_size) % cell_size
  548.                                              ? (CELL) 1 << ((i + cell_size) % cell_size)
  549.                                              : (CELL) 1);
  550.     }
  551.  
  552.     //
  553.     // Remove an element i from the bitset in question.
  554.     //
  555.     void RemoveElement(int i)
  556.     {
  557.         assert(i >= 0 && i < set_size);
  558.  
  559.         s[i / cell_size] &= ~((i + cell_size) % cell_size
  560.                                               ? (CELL) 1 << ((i + cell_size) % cell_size)
  561.                                               : (CELL) 1);
  562.     }
  563.  
  564.     //
  565.     // Yield a boolean result indicating whether or not two sets are
  566.     // identical.
  567.     //
  568.     int operator==(const BitSet& rhs)
  569.     {
  570.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  571.         {
  572.             if (s[i] != rhs.s[i])
  573.                 return 0;
  574.         }
  575.  
  576.         return 1;
  577.     }
  578.  
  579.     //
  580.     // Yield a boolean result indicating whether or not two sets are
  581.     // identical.
  582.     //
  583.     int operator!=(const BitSet& rhs)
  584.     {
  585.         return ! (*this == rhs);
  586.     }
  587.  
  588.     //
  589.     // Union of two bitsets.
  590.     //
  591.     BitSet operator+(const BitSet& rhs)
  592.     {
  593.         BitSet result(set_size);
  594.  
  595.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  596.             result.s[i] = s[i] | rhs.s[i];
  597.  
  598.         return result;
  599.     }
  600.  
  601.     //
  602.     // Union of an lvalue bitset and a rhs bitset.
  603.     //
  604.     BitSet& operator+=(const BitSet& rhs)
  605.     {
  606.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  607.             s[i] |= rhs.s[i];
  608.  
  609.         return *this;
  610.     }
  611.  
  612.     //
  613.     // Intersection of two bitsets.
  614.     //
  615.     BitSet operator*(const BitSet& rhs)
  616.     {
  617.         BitSet result(set_size);
  618.  
  619.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  620.             result.s[i] = s[i] & rhs.s[i];
  621.  
  622.         return result;
  623.     }
  624.  
  625.     //
  626.     // Intersection of an lvalue bitset and a rhs bitset.
  627.     //
  628.     BitSet& operator*=(const BitSet& rhs)
  629.     {
  630.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  631.             s[i] &= rhs.s[i];
  632.  
  633.         return *this;
  634.     }
  635.  
  636.     //
  637.     // Difference of two bitsets.
  638.     //
  639.     BitSet operator-(const BitSet& rhs)
  640.     {
  641.         BitSet result(set_size);
  642.  
  643.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  644.             result.s[i] = s[i] & (~ rhs.s[i]);
  645.  
  646.         return result;
  647.     }
  648.  
  649.     //
  650.     // Difference of an lvalue bitset and a rhs bitset.
  651.     //
  652.     BitSet& operator-=(const BitSet& rhs)
  653.     {
  654.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  655.             s[i] &= (~ rhs.s[i]);
  656.  
  657.         return *this;
  658.     }
  659. };
  660.  
  661. class DefiniteAssignmentSet
  662. {
  663. public:
  664.     int set_size;
  665.  
  666.     BitSet true_set,
  667.            false_set;
  668.  
  669.     DefiniteAssignmentSet(int set_size_) : set_size(set_size_),
  670.                                            true_set(set_size),
  671.                                            false_set(set_size)
  672.     {}
  673. };
  674.  
  675. #ifdef    HAVE_JIKES_NAMESPACE
  676. }            // Close namespace Jikes block
  677. #endif
  678.  
  679. #endif
  680.  
  681.