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

Last change on this file since 5585 was 5565, checked in by xuedongx, 2 years ago

Separate name resolve and gather for future use. Add re_colloect_unicodesets and re_multiplex.

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