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

Last change on this file since 5045 was 5045, checked in by xuedongx, 3 years ago

Support over UTF-16 representation of Unicode

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