Changeset 4287


Ignore:
Timestamp:
Nov 2, 2014, 3:06:46 PM (5 years ago)
Author:
nmedfort
Message:

More work on multiplexing.

Location:
icGREP/icgrep-devel/icgrep
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/cc/cc_compiler.cpp

    r4286 r4287  
    1818#include <re/printer_re.h>
    1919#include <cc/cc_namemap.hpp>
    20 
     20#include <pablo/printer_pablos.h>
    2121#include <utility>
    2222#include <string>
     
    2424#include <map>
    2525#include <algorithm>
    26 
     26#include <boost/graph/adjacency_list.hpp>
    2727#include <cassert>
    2828#include <stdlib.h>
     
    335335
    336336    // Compute the constraint and subset graphs.
    337 
    338337    ConstraintGraph C(n);
    339338    SubsetGraph S(n);
     
    341340    for (auto i = 0; i != n; ++i) {
    342341        const CC * const cc1 = mVariableVector[i].first;
     342
    343343        for (auto j = i + 1; j != n; ++j) {
    344             const CC * const cc2 = mVariableVector[i].first;
     344            const CC * const cc2 = mVariableVector[j].first;
    345345            switch(cc1->compare(cc2)) {
    346                 case CC::Relationship::OVERLAPPING:
     346                case CC::SetRelationship::OVERLAPPING:
    347347                    add_edge(i, j, C);
    348348                    add_edge(j, i, C);
    349349                    break;
    350                 case CC::Relationship::SUBSET:
     350                case CC::SetRelationship::SUBSET:
    351351                    add_edge(i, j, S);
    352352                    break;
    353                 case CC::Relationship::SUPERSET:
     353                case CC::SetRelationship::SUPERSET:
    354354                    add_edge(j, i, S);
    355355                    break;
    356356                default:
    357                     /* do nothing */
     357                    /* do nothing; here just to prevent warning */
    358358                    break;
    359359            }
     
    362362
    363363    // Write out the constraints and subset relationships as metadata
    364 
    365364    for (auto i = 0; i != n; ++i) {
    366365        std::vector<PabloAST *> constraints;
     
    378377        Assign * assign = mVariableVector[i].second;
    379378        if (!constraints.empty()) {
    380             assign->setMetadata("constraints", PMDVector::get(std::move(constraints)));
     379            assign->setMetadata("constraints", PMDSet::get(constraints.begin(), constraints.end()));
    381380        }
    382381        if (!subsets.empty()) {
    383             assign->setMetadata("subsets", PMDVector::get(std::move(subsets)));
    384         }
    385     }
    386 
    387 
    388 
     382            assign->setMetadata("subsets", PMDSet::get(subsets.begin(), subsets.end()));
     383        }
     384    }
    389385}
    390386
  • icGREP/icgrep-devel/icgrep/cc/cc_compiler.h

    r4286 r4287  
    1414#include <unordered_map>
    1515#include <string>
    16 #include <boost/graph/adjacency_list.hpp>
    1716
    1817namespace cc {
  • icGREP/icgrep-devel/icgrep/compiler.cpp

    r4280 r4287  
    4040namespace icgrep {
    4141
    42 LLVM_Gen_RetVal compile(const Encoding encoding, const std::string input_string, const bool show_compile_time) {
     42LLVM_Gen_RetVal compile(const Encoding encoding, const std::string input_string, const bool show_compile_time, const bool enable_multiplexing) {
    4343    RE * re_ast = nullptr;
    4444    try
     
    9797    PabloBlock main(symgen);
    9898
    99     CC_Compiler cc_compiler(main, encoding);
     99    CC_Compiler cc_compiler(main, encoding, enable_multiplexing);
    100100    auto basisBits = cc_compiler.compile(nameMap);
    101101    #ifdef DEBUG_PRINT_PBIX_AST
  • icGREP/icgrep-devel/icgrep/compiler.h

    r4242 r4287  
    1414namespace icgrep {
    1515
    16 pablo::LLVM_Gen_RetVal compile(const Encoding encoding, const std::string input_string, const bool show_compile_time = false);
     16pablo::LLVM_Gen_RetVal compile(const Encoding encoding, const std::string input_string, const bool show_compile_time = false, const bool enable_multiplexing = false);
    1717
    1818}
  • icGREP/icgrep-devel/icgrep/icgrep.cpp

    r4242 r4287  
    9393
    9494    int opt_code;
    95     int count_only_option = 0;
    96     int print_version_option = 0;
    97     int regex_from_file_option = 0;
    98     int ascii_only_option = 0;
    99 
    100     int compile_time_option = 0;
     95    bool count_only_option = 0;
     96    bool print_version_option = 0;
     97    bool regex_from_file_option = 0;
     98    bool ascii_only_option = 0;
     99    bool compile_time_option = 0;
     100    bool enable_multiplexing = 0;
     101    bool print_usage = 0;
    101102
    102103    unsigned long long cycles = 0;
    103     double timer = 0;
     104
    104105
    105106    long lSize = 0;
     
    107108    size_t result;
    108109
    109     while ((opt_code = getopt(argc, argv, "cvfta")) != -1)
     110    while ((opt_code = getopt(argc, argv, "cvftam")) != -1)
    110111    {
    111112        switch (opt_code)
     
    126127            ascii_only_option = 1;
    127128            break;
     129        case 'm':
     130            enable_multiplexing = 1;
     131            break;
    128132        case '?':
    129133            break;
    130134        default:
    131135            printf ("Invalid option: %c\n", opt_code);
    132             printf("Usage: %s [-c] [-v] [-f] [-t] [-a] <regex|regexfile> <inputfile> [<outputfile>]\n", argv[0]);
    133                     exit(-1);
     136            print_usage = 1;
    134137        }
    135138    }
     
    138141    {
    139142        printf ("Too few arguments\n");
    140         printf("Usage: %s [-c] [-v] [-f] [-t] [-a] <regex|regexfile> <inputfile> [<outputfile>]\n", argv[0]);
     143        print_usage = 1;
     144    }
     145
     146    if (print_usage) {
     147        printf("Usage: %s [-a] [-c] [-f] [-m] [-t] [-v] <regex|regexfile> <inputfile> [<outputfile>]\n", argv[0]);
    141148        exit(-1);
    142149    }
     
    187194        if (optind != argc)
    188195        {
    189             printf ("Too many arguments\n");
    190             printf("Usage: %s [-c] [-v] [-f] [-t] [-a] <regex|regexfile> <inputfile> [<outputfile>]\n", argv[0]);
     196            printf("Too many arguments\n");
     197            printf("Usage: %s [-a] [-c] [-f] [-m] [-t] [-v] <regex|regexfile> <inputfile> [<outputfile>]\n", argv[0]);
    191198            exit(-1);
    192199        }
     
    229236    {
    230237        cycles = get_hrcycles();
    231         timer = getElapsedTime();
    232     }
    233     const auto llvm_codegen = icgrep::compile(encoding, (regex_from_file_option ? fileregex : inregex), compile_time_option);
     238    }
     239    const auto llvm_codegen = icgrep::compile(encoding, (regex_from_file_option ? fileregex : inregex), compile_time_option, enable_multiplexing);
    234240
    235241    if (compile_time_option)
    236242    {
    237243        cycles = get_hrcycles() - cycles;
    238         timer = getElapsedTime() - timer;
    239244        std::cout << "Total compile time - cycles:       " << cycles << std::endl;
    240         std::cout << "Total compile time - milliseconds: " << timer << std::endl;
    241245    }
    242246
  • icGREP/icgrep-devel/icgrep/pablo/optimizers/pablo_automultiplexing.cpp

    r4270 r4287  
    11#include "pablo_automultiplexing.hpp"
     2#include <pablo/pe_metadata.h>
     3#include <pablo/pe_advance.h>
     4
     5#include <llvm/ADT/SmallVector.h>
     6#include <llvm/ADT/DenseMap.h>
     7#include <llvm/ADT/DenseSet.h>
     8#include <boost/pool/object_pool.hpp>
     9
     10
     11using namespace llvm;
    212
    313namespace pablo {
     
    2333}
    2434
    25 
    26 
     35struct AdvancedStreamGraph {
     36
     37    struct Vertex;
     38
     39    typedef std::pair<Vertex *, bool>                   Edge;
     40    typedef SmallVector<Edge, 1>                        Edges;
     41    typedef std::vector<Vertex *>                       Verticies;
     42    typedef Verticies::iterator                         iterator;
     43    typedef Verticies::const_iterator                   const_iterator;
     44    typedef Verticies::size_type                        size_type;
     45    typedef PMDSet                                   VariableConstraintNode;
     46
     47    struct Vertex {
     48        Vertex(size_type index, const Advance * advance, const VariableConstraintNode * constraints)
     49        : _index(index)
     50        , _advance(advance)
     51        , _constraints(constraints)
     52        , _accept(true)
     53        {
     54        }
     55
     56        inline void setConstraintSet(const VariableConstraintNode * constraints) {
     57            assert (!_constraints && constraints);
     58            _constraints = constraints;
     59        }
     60
     61        inline const VariableConstraintNode * constraintSet() const {
     62            return _constraints;
     63        }
     64
     65        inline bool hasConstraint(const Vertex * other) const {
     66            return VariableConstraintGraph::hasConstraint(constraintSet(), other->constraintSet());
     67        }
     68
     69        inline void addPrecessor(Vertex * predecessor, bool negated = false) {
     70            assert (predecessor);
     71            _dependencies.push_back(std::make_pair(predecessor, negated));
     72            predecessor->_accept = false;
     73        }
     74
     75        Edges & predecessors() {
     76            return _dependencies;
     77        }
     78
     79        const Edges & predecessors() const {
     80            return _dependencies;
     81        }
     82
     83        const Advance * advance() const {
     84            return _advance;
     85        }
     86
     87        bool accept() const {
     88            return _accept;
     89        }
     90
     91        size_type index() const {
     92            return _index;
     93        }
     94
     95        const size_type                 _index;
     96        const Advance *                 _advance;
     97        const VariableConstraintNode *  _constraints;
     98        Edges                           _dependencies;
     99        bool                            _accept;
     100    };
     101
     102    inline Vertex * add(const Advance * advance, const VariableConstraintNode * constraints) {
     103        Vertex * const v = _pool.construct(_verticies.size(), advance, constraints);
     104        _map.insert(std::make_pair(advance, v));
     105        _verticies.push_back(v);
     106        return v;
     107    }
     108
     109    inline Vertex * find(const Advance * advance) const {
     110        auto itr = _map.find(advance);
     111        if (itr == _map.end()) {
     112            return nullptr;
     113        }
     114        return itr->second;
     115    }
     116
     117    static inline bool hasConstraint(const Vertex * a, const Vertex * b)  {
     118        return VariableConstraintGraph::hasConstraint(a->constraintSet(), b->constraintSet());
     119    }
     120
     121    inline static bool hasCharacterClassConstraint(const Edge & a, const Edge & b, const VariableConstraintGraph & U) {
     122        if (a.second == b.second) {
     123            DenseSet<const Advance *> set;
     124            const auto * CCA = a.first->constraintSet();
     125            set.insert(CCA->begin(), CCA->end());
     126            const auto * CCB = b.first->constraintSet();
     127            set.insert(CCB->begin(), CCB->end());
     128            if (!a.second) {
     129                // Neither predecessor is from a negated advanced stream.
     130                //
     131                // CC(A) ∩ CC(B) ≠ âˆ
     132 -> ∃a ∈ CC(A) : a ∈ CC(B) ∧ ∃b ∈ CC(B) : b ∈ CC(A) -> |CC(A) ∪ CC(B)| < |CC(A)| + |CC(B)|
     133                return set.size() < (CCA->size() + CCB->size());
     134            }
     135            else { // if (a.second && b.second)
     136                // Both predecessors are from negated advanced streams; ergo by De Morgan's law:
     137                // _____   _____       _____________
     138                // CC(A) ∩ CC(B) ≠ âˆ
     139 â‰¡ CC(A) ∪ CC(B) ≠ âˆ
     140 -> |CC(A) ∪ CC(B)| ≠ |U|
     141                return set.size() != U.size();
     142            }
     143        }
     144        else {
     145            // One (and only one) of the predecessors is from a negated advanced stream; thus:
     146            // _____
     147            // CC(A) ∩ CC(B) ≠ âˆ
     148 -> ∄a ∈ CC(A) : a ∈ CC(B)
     149            const auto * CCA = a.first->constraintSet();
     150            const auto * CCB = b.first->constraintSet();
     151            if (b.second) { // if B is the negated class, swap them for simplicity
     152                std::swap(CCA, CCB);
     153            }
     154            for (const Advance * a : *CCA) {
     155                if (CCB->count(a)) {
     156                    return false;
     157                }
     158            }
     159            return true;
     160        }
     161    }
     162
     163    iterator begin() {
     164        return _verticies.begin();
     165    }
     166
     167    iterator end() {
     168        return _verticies.end();
     169    }
     170
     171    const_iterator begin() const {
     172        return _verticies.begin();
     173    }
     174
     175    const_iterator end() const {
     176        return _verticies.end();
     177    }
     178
     179    bool empty() const {
     180        return _verticies.empty();
     181    }
     182
     183    Verticies::size_type size() const {
     184        return _verticies.size();
     185    }
     186
     187    inline void clear() {
     188        for (Vertex * v : *this) {
     189            _pool.destroy(v);
     190        }
     191        _map.clear();
     192        _verticies.clear();
     193    }
     194
     195private:
     196
     197    DenseMap<const Advance *, Vertex *>         _map;
     198    Verticies                                   _verticies;
     199    boost::object_pool<Vertex>                  _pool;
     200};
     201
     202typedef AdvancedStreamGraph::Vertex AdvanceNode;
     203
     204
     205/** ------------------------------------------------------------------------------------------------------------- *
     206 * @brief initializeSuffixConstraints
     207 * @param bb
     208 * @return if any multiplexing opportunities exist
     209 ** ------------------------------------------------------------------------------------------------------------- */
     210bool AutoMultiplexing::initializeSuffixConstraints(PabloBlock & bb) {
     211
     212    AdvancedStreamGraph G;
     213    // scan through the graph and compute the advance suffix constraints ...
     214    for (PabloAST * inst : bb) {
     215        if (Advance * advance = dyn_cast<Advance>(inst)) {
     216            VariableConstraintNode * set = _variableConstraints.find(variable);
     217            AdvanceNode * node = G.add(&advance, set);
     218            // If this is an initial advance, we'll find the set directly; otherwise
     219            // we'll have to search for it. Since we cannot be certain that we'll end
     220            // up parsing the blocks in sequential order, just buffer them for now.
     221            if (set == nullptr) {
     222                // first test for the most common case: we're ANDing a previously advanced
     223                // stream with some character class.
     224                if (variable->getOpcode() == Instruction::And) {
     225                    assert (variable->getNumOperands() == 2);
     226                    int index = 1;
     227                    VariableConstraintNode * set = nullptr;
     228                    for (;;) {
     229                        set = _variableConstraints.find(dyn_cast<Instruction>(variable->getOperand(index)));
     230                        if (set) {
     231                            node->setConstraintSet(set);
     232                            break;
     233                        }
     234                        if (index == 0) {
     235                            break;
     236                        }
     237                        --index;
     238                    }
     239
     240                    // If we found a character class constraint set for one of the operands; select the other as our preceeding
     241                    // (advance) stream; otherwise test to see if the variable is the preceeding stream (i.e., there is no CC)
     242
     243                    Instruction * preceedingStream = set ? dyn_cast<Instruction>(variable->getOperand(1 - index)) : variable;
     244
     245                    // is this a negated stream?
     246                    bool negated = false;
     247                    while (preceedingStream->getOpcode() == Instruction::Xor) {
     248                        assert (preceedingStream->getNumOperands() == 2);
     249                        for (unsigned i = 0; i < 2; ++i) {
     250                            Value * const operand = preceedingStream->getOperand(i);
     251                            if (isa<Constant>(operand) && dyn_cast<Constant>(operand)->isAllOnesValue()) {
     252                                negated = !negated;
     253                                preceedingStream = dyn_cast<Instruction>(preceedingStream->getOperand(1 - i));
     254                            }
     255                        }
     256                    }
     257
     258                    // If we reach a PHINode, we'll end up handling this through the advance chains anyway. Ignore it.
     259                    if (isa<PHINode>(preceedingStream)) {
     260                        continue;
     261                    }
     262
     263                    // did we find an immediate predecessor?
     264                    AdvanceNode * predecessor = G.find(preceedingStream);
     265
     266                    if (predecessor == nullptr && preceedingStream->getOpcode() == Instruction::And) {
     267                        assert (preceedingStream->getNumOperands() == 2);
     268                        for (unsigned i = 0; i < 2; ++i) {
     269                            Instruction * const operand = dyn_cast<Instruction>(preceedingStream->getOperand(i));
     270                            if (operand) {
     271                                if (operand->getOpcode() == Instruction::Xor) {
     272                                    continue;
     273                                }
     274                                predecessor = G.find(operand);
     275                                break;
     276                            }
     277                        }
     278                    }
     279                    if (predecessor) {
     280                        node->addPrecessor(predecessor, negated);
     281                        continue;
     282                    }
     283
     284                    // if not, we could be dealing with a series of disjunctions ORing together the results
     285                    // of several preceeding streams.
     286                    if (preceedingStream->getOpcode() == Instruction::Or) {
     287                        std::queue<Instruction *> disjunctions;
     288                        Instruction * disjunction = preceedingStream;
     289                        bool resolvedAllPredecessors = true;
     290                        for (;;) {
     291                            assert (disjunction->getNumOperands() == 2);
     292                            for (unsigned i = 0; i < 2; ++i) {
     293                                Instruction * const operand = dyn_cast<Instruction>(disjunction->getOperand(i));
     294                                if (operand && operand->getOpcode() == Instruction::Or) {
     295                                    AdvanceNode * predecessor = G.find(operand);
     296                                    if (predecessor) {
     297                                        node->addPrecessor(predecessor, negated);
     298                                    }
     299                                    else {
     300                                        disjunctions.push(operand);
     301                                    }
     302                                    continue;
     303                                }
     304                                resolvedAllPredecessors = false;
     305                            }
     306                            if (disjunctions.empty()) {
     307                                break;
     308                            }
     309                            disjunction = disjunctions.front();
     310                            disjunctions.pop();
     311                        }
     312                        if (resolvedAllPredecessors) {
     313                            continue;
     314                        }
     315                    }
     316                }
     317                #ifdef DEBUG_METADATA_ANNOTATIONS
     318                advance.setMetadata("unresolved", MDNode::get(bb.getContext(), &advance));
     319                #endif
     320            }
     321        }
     322    }
     323
     324    if (G.size() < 3) {
     325        return false;
     326    }
     327
     328    InstructionVector advances;
     329    advances.reserve(G.size());
     330    // Generate the initial suffix constraint graph for these advances.
     331    for (const AdvanceNode * v : G) {
     332        _suffixConstraints.add(v->advance());
     333        advances.push_back(const_cast<Instruction *>(v->advance()));
     334    }
     335    // Compute the dependency constraints for this graph.
     336    const auto M = getDependencyMatrixTC<DependencyMatrix>(bb, advances);
     337    for (auto i = G.begin(); ++i != G.end(); ) {
     338        const AdvanceNode * const a = *i;
     339        for (auto j = G.begin(); j != i; ++j) {
     340            const AdvanceNode * const b = *j;
     341            if (hasSuffixConstraint(a, b, M)) {
     342                _suffixConstraints.addConstraint(a->advance(), b->advance());
     343            }
     344        }
     345    }
     346
     347    return true;
    27348}
     349
     350
     351}
  • icGREP/icgrep-devel/icgrep/pablo/pe_metadata.h

    r4286 r4287  
    33
    44#include <pablo/pabloAST.h>
    5 #include <vector>
     5#include <llvm/ADT/DenseSet.h>
    66
    77namespace pablo {
     
    1010public:
    1111    enum class ClassTypeId : unsigned {
    12         PMDASTVector
     12        Set
    1313    };
    1414    inline ClassTypeId getClassTypeId() const {
     
    2828};
    2929
    30 class PMDVector : public PMDNode, public std::vector<PabloAST*> {
     30class PMDSet : public PMDNode, public llvm::DenseSet<PabloAST*> {
    3131public:
    32     inline static PMDVector * get(std::vector<PabloAST*> && vec) {
    33         return new PMDVector(std::move(vec));
     32    template<typename iterator>
     33    inline static PMDSet * get(iterator begin, iterator end) {
     34        return new PMDSet(begin, end);
    3435    }
    3536protected:
    36     PMDVector(std::vector<PabloAST*> && vec)
    37     : PMDNode(PMDNode::ClassTypeId::PMDASTVector)
    38     , std::vector<PabloAST*>(std::move(vec))
     37    template<typename iterator>
     38    PMDSet(iterator begin, iterator end)
     39    : PMDNode(PMDNode::ClassTypeId::Set)
     40    , llvm::DenseSet<PabloAST*>()
    3941    {
     42        insert(begin, end);
    4043    }
    4144};
     45
     46
    4247
    4348}
  • icGREP/icgrep-devel/icgrep/re/re_cc.cpp

    r4286 r4287  
    2626std::string CC::getName() const {
    2727    std::string name = "CC";
     28    char seperator = '_';
    2829    for (const CharSetItem & i : mSparseCharSet) {
    29         name += "_" + std::to_string(i.lo_codepoint);
    30         name += "." + std::to_string(i.hi_codepoint);
     30        name += seperator;
     31        if (i.lo_codepoint == i.hi_codepoint) {
     32            name += std::to_string(i.lo_codepoint);
     33        }
     34        else {
     35            name += std::to_string(i.lo_codepoint) + "-" + std::to_string(i.hi_codepoint);
     36        }
     37        seperator = ',';
    3138    }
    3239    return name;
     
    4754            // ranges overlap; expand the range to include the prior one and
    4855            // remove the old one from the list
    49             item.lo_codepoint = std::min(range.lo_codepoint, item.lo_codepoint);
    50             item.hi_codepoint = std::max(range.hi_codepoint, item.hi_codepoint);
    51             i = mSparseCharSet.erase(i);
     56            range.lo_codepoint = std::min(range.lo_codepoint, item.lo_codepoint);
     57            range.hi_codepoint = std::max(range.hi_codepoint, item.hi_codepoint);
     58            return;
    5259        }
    5360    }
     
    8491}
    8592
    86 CC::Relationship CC::compare(const CC * other) const {
     93CC::SetRelationship CC::compare(const CC * other) const {
    8794
    8895    if (LLVM_UNLIKELY(other == this)) {
    89         return Relationship::EQUIVALENT;
     96        return SetRelationship::EQUIVALENT;
    9097    }
    9198
     
    103110        const CharSetItem & rb = *bi;
    104111
     112        // _A_| ...
     113        //     |_B_
     114
     115        // A may be a superset of B but it cannot be a subset of B
     116
    105117        if (ra.hi_codepoint < rb.lo_codepoint) {
    106118            ++ai;
    107             nonSuperset = true;
     119            nonSubset = true;
    108120            continue;
    109121        }
     122
     123        //     |_A_
     124        // _B_| ...
     125
     126        // A may be a subset of B but it cannot be a superset of B
     127
     128
    110129        if (rb.hi_codepoint < ra.lo_codepoint) {
    111130            ++bi;
    112             nonSubset = true;
     131            nonSuperset = true;
    113132            continue;
    114133        }
     
    116135        disjoint = false;
    117136
     137        // |_A__
     138        //   |_B__
     139
     140        // A may be a superset of B but it cannot be a subset of B nor can it be disjoint
     141
    118142        if (ra.lo_codepoint < rb.lo_codepoint) {
    119143            nonSubset = true;
    120144        }
     145
     146        //   |_A__
     147        // |_B__
     148
     149        // A may be a subset of B but it cannot be a superset of B nor can it be disjoint
    121150
    122151        if (rb.lo_codepoint < ra.lo_codepoint) {
     
    124153        }
    125154
     155        // __A__| ...
     156        // __B______|
     157
     158        // SUCC(A) may overlap B in some way; only increment A
     159
    126160        if (ra.hi_codepoint <= rb.hi_codepoint) {
    127161            ++ai;
    128162        }
     163
     164        // __A______|
     165        // __B__| ...
     166
     167        // SUCC(B) may overlap A in some way; only increment B
     168
    129169        if (rb.hi_codepoint <= ra.hi_codepoint) {
    130170            ++bi;
     
    133173    }
    134174    if (disjoint) {
    135         return Relationship::DISJOINT;
     175        return SetRelationship::DISJOINT;
    136176    }
    137177
     
    144184
    145185    if (nonSubset && nonSuperset) {
    146         return Relationship::OVERLAPPING;
     186        return SetRelationship::OVERLAPPING;
    147187    }
    148188    else if (nonSubset) {
    149         return Relationship::SUPERSET;
     189        return SetRelationship::SUPERSET;
    150190    }
    151191    else if (nonSuperset) {
    152         return Relationship::SUBSET;
     192        return SetRelationship::SUBSET;
    153193    }
    154     return Relationship::EQUIVALENT;
     194    return SetRelationship::EQUIVALENT;
    155195}
    156196
  • icGREP/icgrep-devel/icgrep/re/re_cc.h

    r4286 r4287  
    3636    }
    3737
    38     enum class Relationship {
     38    enum class SetRelationship {
    3939        SUBSET
    40         , SUPERSET
     40        , SUPERSET       
     41        , OVERLAPPING
    4142        , DISJOINT
    42         , OVERLAPPING
    4343        , EQUIVALENT
    4444    };
     
    114114    }
    115115
    116     Relationship compare(const CC * other) const;
     116    SetRelationship compare(const CC * other) const;
    117117
    118118    virtual ~CC() {}
Note: See TracChangeset for help on using the changeset viewer.