source: icGREP/icgrep-devel/icgrep/re/re_multiplex.cpp @ 5620

Last change on this file since 5620 was 5620, checked in by nmedfort, 22 months ago

Bug fixes for multigrep mode. Optional PabloKernel? branch hit counter added. Minor optimizations.

File size: 4.6 KB
Line 
1#include "re_multiplex.h"
2#include <re/re_name.h>
3#include <re/re_alt.h>
4#include <re/re_cc.h>
5#include <re/re_seq.h>
6#include <re/re_rep.h>
7#include <re/re_diff.h>
8#include <re/re_intersect.h>
9#include <re/re_assertion.h>
10#include <re/re_analysis.h>
11#include <re/re_memoizer.hpp>
12#include <UCD/ucd_compiler.hpp>
13#include <UCD/resolve_properties.h>
14#include <boost/container/flat_set.hpp>
15#include <cc/multiplex_CCs.h>
16#include <sstream>
17#include <iostream>
18#include <functional>
19
20using namespace boost::container;
21using namespace llvm;
22
23namespace re {
24 
25static inline CC * extractCC(RE * re) {
26    if (isa<CC>(re)) {
27        return cast<CC>(re);
28    } else if (isa<Name>(re)) {
29        return extractCC(cast<Name>(re)->getDefinition());
30    }
31    return nullptr;
32}
33
34RE * multiplex(RE * const re,
35               const std::vector<UCD::UnicodeSet> & UnicodeSets,
36               const std::vector<std::vector<unsigned>> & exclusiveSetIDs) {
37
38    Memoizer memoizer;
39
40    std::function<RE *(RE *)> multiplex = [&](RE * const re) -> RE * {
41        if (Name * name = dyn_cast<Name>(re)) {
42            auto f = memoizer.find(name);
43            if (f == memoizer.end()) {
44                if (LLVM_LIKELY(name->getDefinition() != nullptr)) {
45                    if (CC * cc = dyn_cast<CC>(name->getDefinition())) {
46                        UCD::UnicodeSet * sets = cast<UCD::UnicodeSet>(cc);
47                        auto index = find(UnicodeSets.begin(), UnicodeSets.end(), *sets) - UnicodeSets.begin();
48                        auto exclusive_IDs = exclusiveSetIDs[index];
49                        CC * CC_union = makeCC();
50                        for (auto i : exclusive_IDs) {
51                            CC_union = makeCC(CC_union, makeCC(i));
52                        }
53                        name->setDefinition(CC_union);
54                    } else {
55                        multiplex(name->getDefinition());
56                    }
57                } else {
58                    throw std::runtime_error("All non-unicode-property Name objects should have been defined prior to Unicode property resolution.");
59                }
60                return memoizer.memoize(name);
61            } else {
62                return *f;
63            }
64        } else if (Seq * seq = dyn_cast<Seq>(re)) {
65            for (auto si = seq->begin(); si != seq->end(); ++si) {
66                *si = multiplex(*si);
67            }
68        } else if (Alt * alt = dyn_cast<Alt>(re)) {
69            CC * unionCC = nullptr;
70            std::stringstream name;
71            for (auto ai = alt->begin(); ai != alt->end(); ) {
72                RE * re = multiplex(*ai);
73                if (CC * cc = extractCC(re)) {
74                    if (unionCC == nullptr) {
75                        unionCC = cc;
76                    } else {
77                        unionCC = makeCC(unionCC, cc);
78                        name << '+';
79                    }
80                    if (LLVM_LIKELY(isa<Name>(re))) {
81                        Name * n = cast<Name>(re);
82                        if (n->hasNamespace()) {
83                            name << n->getNamespace() << ':';
84                        }
85                        name << n->getName();
86                    } else if (isa<CC>(re)) {
87                        name << cast<CC>(re)->canonicalName(UnicodeClass);
88                    }
89                    ai = alt->erase(ai);
90                } else {
91                    *ai++ = re;
92                }
93            }
94            if (unionCC) {
95                alt->push_back(multiplex(makeName(name.str(), unionCC)));
96            }
97            if (alt->size() == 1) {
98                return alt->front();
99            }
100        } else if (Rep * rep = dyn_cast<Rep>(re)) {
101            rep->setRE(multiplex(rep->getRE()));
102        } else if (Assertion * a = dyn_cast<Assertion>(re)) {
103            a->setAsserted(multiplex(a->getAsserted()));
104        } else if (Diff * diff = dyn_cast<Diff>(re)) {
105            diff->setLH(multiplex(diff->getLH()));
106            diff->setRH(multiplex(diff->getRH()));
107            CC * lh = extractCC(diff->getLH());
108            CC * rh = extractCC(diff->getRH());
109            if (lh && rh) {
110                return multiplex(makeName("diff", subtractCC(lh, rh)));
111            }
112        } else if (Intersect * ix = dyn_cast<Intersect>(re)) {
113            ix->setLH(multiplex(ix->getLH()));
114            ix->setRH(multiplex(ix->getRH()));
115            CC * lh = extractCC(ix->getLH());
116            CC * rh = extractCC(ix->getRH());
117            if (lh && rh) {
118                return multiplex(makeName("intersect", intersectCC(lh, rh)));
119            }
120        }
121        return re;
122    };
123
124    return multiplex(re);
125}   
126
127}
Note: See TracBrowser for help on using the repository browser.