source: icGREP/icgrep-devel/icgrep/re/re_name_resolve.cpp

Last change on this file was 5646, checked in by nmedfort, 13 hours ago

Minor clean up. Bug fix for object cache when the same cached kernel is used twice in a single run. Improvement to RE Minimizer.

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