source: icGREP/icgrep-devel/icgrep/UCD/ucd_compiler.cpp @ 4841

Last change on this file since 4841 was 4841, checked in by nmedfort, 4 years ago

Update for grapheme cluster mode and boundaries.

File size: 23.8 KB
Line 
1#include "ucd_compiler.hpp"
2#include <cc/cc_compiler.h>
3#include <UCD/unicode_set.h>
4#include <re/re_name.h>
5#include <utf8_encoder.h>
6
7using namespace cc;
8using namespace re;
9using namespace pablo;
10
11namespace UCD {
12
13const UCDCompiler::RangeList UCDCompiler::defaultIfHierachy = {
14    // Non-ASCII
15    {0x80, 0x10FFFF},
16    // Two-byte sequences
17    {0x80, 0x7FF},
18    {0x100, 0x3FF},
19    // 0100..017F; Latin Extended-A
20    // 0180..024F; Latin Extended-B
21    // 0250..02AF; IPA Extensions
22    // 02B0..02FF; Spacing Modifier Letters
23    {0x100, 0x2FF}, {0x100, 0x24F}, {0x100, 0x17F}, {0x180, 0x24F}, {0x250, 0x2AF}, {0x2B0, 0x2FF},
24    // 0300..036F; Combining Diacritical Marks
25    // 0370..03FF; Greek and Coptic
26    {0x300, 0x36F}, {0x370, 0x3FF},
27    // 0400..04FF; Cyrillic
28    // 0500..052F; Cyrillic Supplement
29    // 0530..058F; Armenian
30    // 0590..05FF; Hebrew
31    // 0600..06FF; Arabic
32    {0x400, 0x5FF}, {0x400, 0x4FF}, {0x500, 0x058F}, {0x500, 0x52F}, {0x530, 0x58F}, {0x590, 0x5FF}, {0x600, 0x6FF},
33    // 0700..074F; Syriac
34    // 0750..077F; Arabic Supplement
35    // 0780..07BF; Thaana
36    // 07C0..07FF; NKo
37    {0x700, 0x77F}, {0x700, 0x74F}, {0x750, 0x77F}, {0x780, 0x7FF}, {0x780, 0x7BF}, {0x7C0, 0x7FF},
38    // Three-byte sequences
39    {0x800, 0xFFFF}, {0x800, 0x4DFF}, {0x800, 0x1FFF}, {0x800, 0x0FFF},
40    // 0800..083F; Samaritan
41    // 0840..085F; Mandaic
42    // 08A0..08FF; Arabic Extended-A
43    // 0900..097F; Devanagari
44    // 0980..09FF; Bengali
45    // 0A00..0A7F; Gurmukhi
46    // 0A80..0AFF; Gujarati
47    // 0B00..0B7F; Oriya
48    // 0B80..0BFF; Tamil
49    // 0C00..0C7F; Telugu
50    // 0C80..0CFF; Kannada
51    // 0D00..0D7F; Malayalam
52    // 0D80..0DFF; Sinhala
53    // 0E00..0E7F; Thai
54    // 0E80..0EFF; Lao
55    // 0F00..0FFF; Tibetan
56    {0x1000, 0x1FFF},
57    // 1000..109F; Myanmar
58    // 10A0..10FF; Georgian
59    // 1100..11FF; Hangul Jamo
60    // 1200..137F; Ethiopic
61    // 1380..139F; Ethiopic Supplement
62    // 13A0..13FF; Cherokee
63    // 1400..167F; Unified Canadian Aboriginal Syllabics
64    // 1680..169F; Ogham
65    // 16A0..16FF; Runic
66    // 1700..171F; Tagalog
67    // 1720..173F; Hanunoo
68    // 1740..175F; Buhid
69    // 1760..177F; Tagbanwa
70    // 1780..17FF; Khmer
71    // 1800..18AF; Mongolian
72    // 18B0..18FF; Unified Canadian Aboriginal Syllabics Extended
73    // 1900..194F; Limbu
74    // 1950..197F; Tai Le
75    // 1980..19DF; New Tai Lue
76    // 19E0..19FF; Khmer Symbols
77    // 1A00..1A1F; Buginese
78    // 1A20..1AAF; Tai Tham
79    // 1AB0..1AFF; Combining Diacritical Marks Extended
80    // 1B00..1B7F; Balinese
81    // 1B80..1BBF; Sundanese
82    // 1BC0..1BFF; Batak
83    // 1C00..1C4F; Lepcha
84    // 1C50..1C7F; Ol Chiki
85    // 1CC0..1CCF; Sundanese Supplement
86    // 1CD0..1CFF; Vedic Extensions
87    // 1D00..1D7F; Phonetic Extensions
88    // 1D80..1DBF; Phonetic Extensions Supplement
89    // 1DC0..1DFF; Combining Diacritical Marks Supplement
90    // 1E00..1EFF; Latin Extended Additional
91    // 1F00..1FFF; Greek Extended
92    {0x2000, 0x4DFF}, {0x2000, 0x2FFF},
93    {0x3000, 0x4DFF},
94    {0x4E00, 0x9FFF},
95    // 4E00..9FFF; CJK Unified Ideographs
96    {0xA000, 0xFFFF},
97
98    {0x10000, 0x10FFFF}};
99
100const UCDCompiler::RangeList UCDCompiler::noIfHierachy = {{0x10000, 0x10FFFF}};
101
102/** ------------------------------------------------------------------------------------------------------------- *
103 * @brief generateRange
104 ** ------------------------------------------------------------------------------------------------------------- */
105void UCDCompiler::generateRange(const RangeList & ifRanges, PabloBuilder & entry) {
106    // Pregenerate the suffix var outside of the if ranges. The DCE pass will either eliminate it if it's not used or the
107    // code sinking pass will move appropriately into an inner if block.
108    CC *  suffix = makeCC(0x80, 0xBF);
109    assert (!suffix->empty());
110    mSuffixVar = mCharacterClassCompiler.compileCC(suffix, entry);
111    generateRange(ifRanges, 0, UNICODE_MAX, entry);
112}
113
114/** ------------------------------------------------------------------------------------------------------------- *
115 * @brief generateRange
116 * @param ifRangeList
117 ** ------------------------------------------------------------------------------------------------------------- */
118void UCDCompiler::generateRange(const RangeList & ifRanges, const codepoint_t lo, const codepoint_t hi, PabloBuilder & builder) {
119
120    // Codepoints in unenclosed ranges will be computed unconditionally.
121    // Generate them first so that computed subexpressions may be shared
122    // with calculations within the if hierarchy.
123    const auto enclosed = rangeIntersect(ifRanges, lo, hi);
124    for (const auto rg : rangeGaps(enclosed, lo, hi)) {
125        generateSubRanges(lo_codepoint(rg), hi_codepoint(rg), builder);
126    }
127
128    const auto outer = outerRanges(enclosed);
129    const auto inner = innerRanges(enclosed);
130    for (const auto range : outer) {
131
132        TargetVector intersectingTargets;
133        TargetVector nonIntersectingTargets;
134
135        // Split our current target list into two sets: the intersecting and non-intersecting ones. Any non-
136        // intersecting set will be removed from the current map to eliminate the possibility of it being
137        // considered until after we leave the current range. The intersecting sets are also stored to ensure
138        // that we know what the original target value was going into this range block so tha we can OR the
139        // inner value with the outer value.
140
141        for (auto ti = mTargetMap.begin(); ti != mTargetMap.end(); ) {           
142            if (ti->first->intersects(range.first, range.second)) {
143                intersectingTargets.emplace_back(ti->first, ti->second);
144                ++ti;
145            } else {
146                nonIntersectingTargets.emplace_back(ti->first, ti->second);
147                ti = mTargetMap.erase(ti);
148            }
149        }
150        if (mTargetMap.size() > 0) {
151
152            PabloBuilder inner_block = PabloBuilder::Create(builder);
153
154            generateRange(inner, range.first, range.second, inner_block);
155
156            std::vector<Assign *> targets;
157            for (auto ti = intersectingTargets.begin(); ti != intersectingTargets.end(); ) {
158                auto f = mTargetMap.find(ti->first);
159                assert (f != mTargetMap.end());
160                if (LLVM_UNLIKELY(isa<Zeroes>(f->second))) {
161                    ti = intersectingTargets.erase(ti);
162                    continue;
163                }
164                Assign * escapedValue = inner_block.createAssign("m", f->second);
165                targets.push_back(escapedValue);
166                f->second = escapedValue;
167                ++ti;
168            }
169
170            // If this range is empty, just skip creating the if block
171            if (targets.size() > 0) {
172                builder.createIf(ifTestCompiler(range.first, range.second, builder), std::move(targets), inner_block);
173                for (const auto ti : intersectingTargets) {
174                    auto f = mTargetMap.find(ti.first);
175                    assert (f != mTargetMap.end());
176                    assert (isa<Assign>(f->second));
177                    f->second = builder.createOr(ti.second, f->second);
178                }
179            }
180        }
181        for (const Target t : nonIntersectingTargets) {
182            mTargetMap.emplace(t.first, t.second);
183        }
184    }
185}
186
187/** ------------------------------------------------------------------------------------------------------------- *
188 * @brief generateSubRanges
189 ** ------------------------------------------------------------------------------------------------------------- */
190void UCDCompiler::generateSubRanges(const codepoint_t lo, const codepoint_t hi, PabloBuilder & builder) {
191    for (auto & t : mTargetMap) {
192        const auto range = rangeIntersect(*t.first, lo, hi);
193        PabloAST * target = t.second;
194        // Divide by UTF-8 length, separating out E0, ED, F0 and F4 ranges
195        const std::array<interval_t, 9> ranges =
196            {{{0, 0x7F}, {0x80, 0x7FF}, {0x800, 0xFFF}, {0x1000, 0xD7FF}, {0xD800, 0xDFFF},
197             {0xE000, 0xFFFF}, {0x10000, 0x3FFFF}, {0x40000, 0xFFFFF}, {0x100000, 0x10FFFF}}};
198        for (auto r : ranges) {
199            const auto subrange = rangeIntersect(range, lo_codepoint(r), hi_codepoint(r));
200            target = sequenceGenerator(std::move(subrange), 1, builder, target, nullptr);
201        }
202        t.second = target;
203    }
204}
205
206/** ------------------------------------------------------------------------------------------------------------- *
207 * @brief sequenceGenerator
208 * @param ifRangeList
209 *
210 *
211 * Generate remaining code to match UTF-8 code sequences within the codepoint set cpset, assuming that the code
212 * matching the sequences up to byte number byte_no have been generated.
213 ** ------------------------------------------------------------------------------------------------------------- */
214PabloAST * UCDCompiler::sequenceGenerator(const RangeList && ranges, const unsigned byte_no, PabloBuilder & builder, PabloAST * target, PabloAST * prefix) {
215
216    if (LLVM_LIKELY(ranges.size() > 0)) {
217
218        codepoint_t lo, hi;
219        std::tie(lo, hi) = ranges[0];
220
221        const auto min = UTF8_Encoder::length(lo_codepoint(ranges.front()));
222        const auto max = UTF8_Encoder::length(hi_codepoint(ranges.back()));
223
224        if (min != max) {
225            const auto mid = UTF8_Encoder::maxCodePoint(min);
226            target = sequenceGenerator(std::move(rangeIntersect(ranges, lo, mid)), byte_no, builder, target, prefix);
227            target = sequenceGenerator(std::move(rangeIntersect(ranges, mid + 1, hi)), byte_no, builder, target, prefix);
228        } else if (min == byte_no) {
229            // We have a single byte remaining to match for all code points in this CC.
230            // Use the byte class compiler to generate matches for these codepoints.
231            const auto bytes = byteDefinitions(ranges, byte_no);
232            PabloAST * var = mCharacterClassCompiler.compileCC(makeCC(bytes), builder);
233            if (byte_no > 1) {
234                var = builder.createAnd(var, builder.createAdvance(makePrefix(lo, byte_no, builder, prefix), 1));
235            }
236            target = builder.createOr(target, var);
237        } else {
238            for (auto rg : ranges) {
239                codepoint_t lo, hi;
240                std::tie(lo, hi) = rg;
241                const auto lo_byte = UTF8_Encoder::encodingByte(lo, byte_no);
242                const auto hi_byte = UTF8_Encoder::encodingByte(hi, byte_no);
243                if (lo_byte != hi_byte) {
244                    if (!UTF8_Encoder::isLowCodePointAfterByte(lo, byte_no)) {
245                        const codepoint_t mid = lo | ((1 << (6 * (min - byte_no))) - 1);
246                        target = sequenceGenerator(lo, mid, byte_no, builder, target, prefix);
247                        target = sequenceGenerator(mid + 1, hi, byte_no, builder, target, prefix);
248                    } else if (!UTF8_Encoder::isHighCodePointAfterByte(hi, byte_no)) {
249                        const codepoint_t mid = hi & ~((1 << (6 * (min - byte_no))) - 1);
250                        target = sequenceGenerator(lo, mid - 1, byte_no, builder, target, prefix);
251                        target = sequenceGenerator(mid, hi, byte_no, builder, target, prefix);
252                    } else { // we have a prefix group of type (a)
253                        PabloAST * var = mCharacterClassCompiler.compileCC(makeCC(lo_byte, hi_byte), builder);
254                        if (byte_no > 1) {
255                            var = builder.createAnd(builder.createAdvance(prefix, 1), var);
256                        }
257                        for (unsigned i = byte_no; i != UTF8_Encoder::length(lo); ++i) {
258                            var = builder.createAnd(mSuffixVar, builder.createAdvance(var, 1));
259                        }
260                        target = builder.createOr(target, var);
261                    }
262                }
263                else { // lbyte == hbyte
264                    PabloAST * var = mCharacterClassCompiler.compileCC(makeCC(lo_byte, hi_byte), builder);
265                    if (byte_no > 1) {
266                        var = builder.createAnd(builder.createAdvance(prefix ? prefix : var, 1), var);
267                    }
268                    if (byte_no < UTF8_Encoder::length(lo)) {
269                        target = sequenceGenerator(lo, hi, byte_no + 1, builder, target, var);
270                    }
271                }
272            }
273        }
274    }
275    return target;
276}
277
278/** ------------------------------------------------------------------------------------------------------------- *
279 * @brief sequenceGenerator
280 ** ------------------------------------------------------------------------------------------------------------- */
281inline PabloAST * UCDCompiler::sequenceGenerator(const codepoint_t lo, const codepoint_t hi, const unsigned byte_no, PabloBuilder & builder, PabloAST * target, PabloAST * prefix) {
282    return sequenceGenerator({{ lo, hi }}, byte_no, builder, target, prefix);
283}
284
285/** ------------------------------------------------------------------------------------------------------------- *
286 * @brief ifTestCompiler
287 ** ------------------------------------------------------------------------------------------------------------- */
288inline PabloAST * UCDCompiler::ifTestCompiler(const codepoint_t lo, const codepoint_t hi, PabloBuilder & builder) {
289    return ifTestCompiler(lo, hi, 1, builder, builder.createOnes());
290}
291
292/** ------------------------------------------------------------------------------------------------------------- *
293 * @brief ifTestCompiler
294 ** ------------------------------------------------------------------------------------------------------------- */
295PabloAST * UCDCompiler::ifTestCompiler(const codepoint_t lo, const codepoint_t hi, const unsigned byte_no, PabloBuilder & builder, PabloAST * target) {
296
297    codepoint_t lo_byte = UTF8_Encoder::encodingByte(lo, byte_no);
298    codepoint_t hi_byte = UTF8_Encoder::encodingByte(hi, byte_no);
299    const bool at_lo_boundary = (lo == 0 || UTF8_Encoder::encodingByte(lo - 1, byte_no) != lo_byte);
300    const bool at_hi_boundary = (hi == 0x10FFFF || UTF8_Encoder::encodingByte(hi + 1, byte_no) != hi_byte);
301
302    if (at_lo_boundary && at_hi_boundary) {
303        if (lo_byte != hi_byte) {
304            if (lo == 0x80) lo_byte = 0xC0;
305            if (hi == 0x10FFFF) hi_byte = 0xFF;
306        }
307        PabloAST * cc = mCharacterClassCompiler.compileCC(makeCC(lo_byte, hi_byte), builder);
308        target = builder.createAnd(cc, target);
309    } else if (lo_byte == hi_byte) {
310        PabloAST * cc = mCharacterClassCompiler.compileCC(makeCC(lo_byte, hi_byte), builder);
311        target = builder.createAnd(cc, target);
312        target = builder.createAdvance(target, 1);
313        target = ifTestCompiler(lo, hi, byte_no + 1, builder, target);
314    } else if (!at_hi_boundary) {
315        const auto mid = UTF8_Encoder::minCodePointWithCommonBytes(hi, byte_no);
316        PabloAST * e1 = ifTestCompiler(lo, mid - 1, byte_no, builder, target);
317        PabloAST * e2 = ifTestCompiler(mid, hi, byte_no, builder, target);
318        target = builder.createOr(e1, e2);
319    } else {
320        const auto mid = UTF8_Encoder::maxCodePointWithCommonBytes(lo, byte_no);
321        PabloAST * e1 = ifTestCompiler(lo, mid, byte_no, builder, target);
322        PabloAST * e2 = ifTestCompiler(mid + 1, hi, byte_no, builder, target);
323        target = builder.createOr(e1, e2);
324    }
325    return target;
326}
327
328/** ------------------------------------------------------------------------------------------------------------- *
329 * @brief definePrecedingPrefix
330 * @param ifRangeList
331 *
332 *
333 * Ensure the sequence of preceding bytes is defined, up to, but not including the given byte_no
334 ** ------------------------------------------------------------------------------------------------------------- */
335PabloAST * UCDCompiler::makePrefix(const codepoint_t cp, const unsigned byte_no, PabloBuilder & builder, PabloAST * prefix) {
336    assert (byte_no >= 1 && byte_no <= 4);
337    assert (byte_no == 1 || prefix != nullptr);
338    for (unsigned i = 1; i != byte_no; ++i) {
339        const CC * const cc = makeCC(UTF8_Encoder::encodingByte(cp, i));
340        PabloAST * var = mCharacterClassCompiler.compileCC(cc, builder);
341        if (i > 1) {
342            var = builder.createAnd(var, builder.createAdvance(prefix, 1));
343        }
344        prefix = var;
345    }
346    return prefix;
347}
348
349/** ------------------------------------------------------------------------------------------------------------- *
350 * @brief definePrecedingPrefix
351 * @param ifRangeList
352 *
353 *
354 * Ensure the sequence of preceding bytes is defined, up to, but not including the given byte_no
355 ** ------------------------------------------------------------------------------------------------------------- */
356UCDCompiler::RangeList UCDCompiler::byteDefinitions(const RangeList & list, const unsigned byte_no) {
357    RangeList result;
358    result.reserve(list.size());
359    for (const auto & i : list) {
360        result.emplace_back(UTF8_Encoder::encodingByte(lo_codepoint(i), byte_no), UTF8_Encoder::encodingByte(hi_codepoint(i), byte_no));
361    }
362    return result;
363}
364
365/** ------------------------------------------------------------------------------------------------------------- *
366 * @brief rangeIntersect
367 * @param list
368 * @param lo
369 * @param hi
370 ** ------------------------------------------------------------------------------------------------------------- */
371template <typename RangeListOrUnicodeSet>
372UCDCompiler::RangeList UCDCompiler::rangeIntersect(const RangeListOrUnicodeSet & list, const codepoint_t lo, const codepoint_t hi) {
373    RangeList result;
374    for (const auto i : list) {
375        if ((lo_codepoint(i) <= hi) && (hi_codepoint(i) >= lo)) {
376            result.emplace_back(std::max(lo, lo_codepoint(i)), std::min(hi, hi_codepoint(i)));
377        }
378    }
379    return result;
380}
381
382/** ------------------------------------------------------------------------------------------------------------- *
383 * @brief rangeGaps
384 * @param cc
385 * @param lo
386 * @param hi
387 ** ------------------------------------------------------------------------------------------------------------- */
388UCDCompiler::RangeList UCDCompiler::rangeGaps(const RangeList & list, const codepoint_t lo, const codepoint_t hi) {
389    RangeList gaps;
390    if (LLVM_LIKELY(lo < hi)) {
391        if (LLVM_UNLIKELY(list.empty())) {
392            gaps.emplace_back(lo, hi);
393        } else {
394            codepoint_t cp = lo;
395            for (const auto & i : list) {
396                if (hi_codepoint(i) < cp) {
397                    continue;
398                } else if (lo_codepoint(i) > cp) {
399                    gaps.emplace_back(cp, lo_codepoint(i) - 1);
400                } else if (hi_codepoint(i) >= hi) {
401                    continue;
402                }
403                cp = hi_codepoint(i) + 1;
404            }
405        }
406    }
407    return gaps;
408}
409
410/** ------------------------------------------------------------------------------------------------------------- *
411 * @brief outerRanges
412 * @param list
413 ** ------------------------------------------------------------------------------------------------------------- */
414UCDCompiler::RangeList UCDCompiler::outerRanges(const RangeList & list) {
415    RangeList ranges;
416    if (LLVM_LIKELY(list.size() > 0)) {
417        auto i = list.cbegin();
418        for (auto j = i + 1; j != list.cend(); ++j) {
419            if (hi_codepoint(*j) > hi_codepoint(*i)) {
420                ranges.emplace_back(lo_codepoint(*i), hi_codepoint(*i));
421                i = j;
422            }
423        }
424        if (LLVM_LIKELY(i != list.end())) {
425            ranges.emplace_back(lo_codepoint(*i), hi_codepoint(*i));
426        }
427    }
428    return ranges;
429}
430
431/** ------------------------------------------------------------------------------------------------------------- *
432 * @brief innerRanges
433 ** ------------------------------------------------------------------------------------------------------------- */
434UCDCompiler::RangeList UCDCompiler::innerRanges(const RangeList & list) {
435    RangeList ranges;
436    if (LLVM_LIKELY(list.size() > 0)) {
437        for (auto i = list.cbegin(), j = i + 1; j != list.cend(); ++j) {
438            if (hi_codepoint(*j) <= hi_codepoint(*i)) {
439                ranges.emplace_back(lo_codepoint(*j), hi_codepoint(*j));
440            } else {
441                i = j;
442            }
443        }
444    }
445    return ranges;
446}
447
448/** ------------------------------------------------------------------------------------------------------------- *
449 * @brief generateWithDefaultIfHierarchy
450 ** ------------------------------------------------------------------------------------------------------------- */
451void UCDCompiler::generateWithDefaultIfHierarchy(NameMap & names, PabloBuilder & entry) {
452    addTargets(names);
453    generateRange(defaultIfHierachy, entry);
454    updateNames(names, entry);
455}
456
457/** ------------------------------------------------------------------------------------------------------------- *
458 * @brief generateWithDefaultIfHierarchy
459 ** ------------------------------------------------------------------------------------------------------------- */
460PabloAST * UCDCompiler::generateWithDefaultIfHierarchy(const UnicodeSet * set, PabloBuilder & entry) {
461    // mTargetMap.insert(std::make_pair<const UnicodeSet *, PabloAST *>(set, PabloBlock::createZeroes()));
462    mTargetMap.emplace(set, PabloBlock::createZeroes());
463    generateRange(defaultIfHierachy, entry);
464    return mTargetMap.begin()->second;
465}
466
467/** ------------------------------------------------------------------------------------------------------------- *
468 * @brief generateWithoutIfHierarchy
469 ** ------------------------------------------------------------------------------------------------------------- */
470void UCDCompiler::generateWithoutIfHierarchy(NameMap & names, PabloBuilder & entry) {
471    addTargets(names);
472    generateRange(noIfHierachy, entry);
473    updateNames(names, entry);
474}
475
476/** ------------------------------------------------------------------------------------------------------------- *
477 * @brief generateWithoutIfHierarchy
478 ** ------------------------------------------------------------------------------------------------------------- */
479PabloAST * UCDCompiler::generateWithoutIfHierarchy(const UnicodeSet * set, PabloBuilder & entry) {
480    mTargetMap.emplace(set, PabloBlock::createZeroes());
481    generateRange(noIfHierachy, entry);
482    return mTargetMap.begin()->second;
483}
484
485/** ------------------------------------------------------------------------------------------------------------- *
486 * @brief addTargets
487 ** ------------------------------------------------------------------------------------------------------------- */
488inline void UCDCompiler::addTargets(const NameMap & names) {
489    for (const auto t : names) {
490        if (LLVM_LIKELY(isa<CC>(t.first->getDefinition()))) {
491            mTargetMap.emplace(cast<CC>(t.first->getDefinition()), t.second ? t.second : PabloBlock::createZeroes());
492        } else {
493            throw std::runtime_error(t.first->getName() + " is not defined by a CC!");
494        }
495    }
496    assert (mTargetMap.size() > 0);
497}
498
499/** ------------------------------------------------------------------------------------------------------------- *
500 * @brief updateNames
501 ** ------------------------------------------------------------------------------------------------------------- */
502inline void UCDCompiler::updateNames(NameMap & names, PabloBuilder & entry) {
503    for (auto & t : names) {
504        auto f = mTargetMap.find(cast<CC>(t.first->getDefinition()));
505        if (f != mTargetMap.end()) {
506            std::string name = t.first->getName();
507            if (Statement * result = dyn_cast<Statement>(f->second)) {
508                result->setName(entry.getName(name, false));
509                t.second = result;
510            } else {
511                t.second = entry.createAssign(std::move(name), f->second);
512            }
513        }
514    }
515    mTargetMap.clear();
516}
517
518/** ------------------------------------------------------------------------------------------------------------- *
519 * @brief constructor
520 ** ------------------------------------------------------------------------------------------------------------- */
521UCDCompiler::UCDCompiler(cc::CC_Compiler & ccCompiler)
522: mCharacterClassCompiler(ccCompiler)
523, mSuffixVar(nullptr) { }
524
525}
Note: See TracBrowser for help on using the repository browser.