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

Last change on this file was 6208, checked in by cameron, 7 months ago

Unneeded capture removal

File size: 2.7 KB
Line 
1#include "re_simplifier.h"
2#include <re/re_name.h>
3#include <re/re_alt.h>
4#include <re/re_seq.h>
5#include <re/re_rep.h>
6#include <re/re_range.h>
7#include <re/re_diff.h>
8#include <re/re_intersect.h>
9#include <re/re_assertion.h>
10#include <re/re_toolchain.h>
11#include <re/re_toolchain.h>
12#include <boost/container/flat_set.hpp>
13
14using namespace llvm;
15
16namespace re {
17
18using Set = boost::container::flat_set<RE *>;
19using List = std::vector<RE *>;
20
21struct RE_Simplifier final : public RE_Transformer {
22
23    RE * transformAlt(Alt * alt) override {
24        Set set;
25        set.reserve(alt->size());
26        for (RE * item : *alt) {
27            item = transform(item);
28            if (LLVM_UNLIKELY(isa<Alt>(item))) {
29                for (RE * innerAlt : *cast<Alt>(item)) {
30                    set.insert(innerAlt);
31                }
32            }  else {
33                set.insert(item);
34            }
35        }
36        return makeAlt(set.begin(), set.end());
37    }
38
39    RE * transformSeq(Seq * seq) override {
40        List list;
41        list.reserve(seq->size());
42        for (RE * item : *seq) {
43            item = transform(item);
44            if (LLVM_UNLIKELY(isa<Seq>(item) && cast<Seq>(item)->empty())) {
45                continue;
46            }
47            list.push_back(item);
48        }
49        return makeSeq(list.begin(), list.end());
50    }
51
52    RE * transformName(Name * nm) override {
53        nm->setDefinition(transform(nm->getDefinition()));
54        return nm;
55    }
56
57    RE_Simplifier() : RE_Transformer("Simplifier", NameTransformationMode::TransformDefinition) { }
58
59};
60
61RE * simplifyRE(RE * re) {
62    return RE_Simplifier().transformRE(re);
63}
64
65using ReferenceSet = boost::container::flat_set<std::string>;
66
67struct ReferenceCollector  final : public RE_Inspector {
68    ReferenceCollector(ReferenceSet & references)
69    : RE_Inspector(InspectionMode::IgnoreNonUnique), mReferences(references) {}
70   
71    void inspectName(Name * n) final {
72        if (n->getType() == Name::Type::Reference) {
73            mReferences.insert(n->getName());
74        }
75    }
76   
77private:
78    ReferenceSet & mReferences;
79};
80
81struct UnneededCaptureRemoval final : public RE_Transformer {
82    UnneededCaptureRemoval(ReferenceSet & references)
83    : RE_Transformer("UnneededCaptureRemoval"), mReferences(references) {}
84   
85    RE * transformName(Name * n) final {
86        if (n->getType() == Name::Type::Capture) {
87            if (mReferences.count(n->getName()) == 0) {
88                return n->getDefinition();
89            }
90        }
91        return n;
92    }
93   
94private:
95    ReferenceSet & mReferences;
96};
97
98RE * removeUnneededCaptures(RE * r) {
99    ReferenceSet refs;
100    ReferenceCollector(refs).inspectRE(r);
101    return UnneededCaptureRemoval(refs).transformRE(r);
102}
103}
Note: See TracBrowser for help on using the repository browser.