source: icGREP/icgrep-devel/icgrep/pablo/builder.cpp

Last change on this file was 6215, checked in by cameron, 8 months ago

pablo.terminateAt

File size: 22.7 KB
Line 
1#include "builder.hpp"
2#include <pablo/boolean.h>
3#include <pablo/arithmetic.h>
4#include <pablo/branch.h>
5#include <pablo/pe_advance.h>
6#include <pablo/pe_lookahead.h>
7#include <pablo/pe_matchstar.h>
8#include <pablo/pe_scanthru.h>
9#include <pablo/pe_repeat.h>
10#include <pablo/pe_pack.h>
11#include <pablo/pe_infile.h>
12#include <pablo/pe_count.h>
13#include <pablo/pe_integer.h>
14#include <pablo/pe_string.h>
15#include <pablo/pe_zeroes.h>
16#include <pablo/pe_ones.h>
17#include <pablo/pe_var.h>
18#include <pablo/ps_assign.h>
19#include <pablo/ps_terminate.h>
20#include <boost/preprocessor/variadic/elem.hpp>
21#include <type_traits>
22
23using namespace llvm;
24
25namespace pablo {
26
27using TypeId = PabloAST::ClassTypeId;
28
29#define GET(I, ...) \
30    reinterpret_cast<decltype(BOOST_PP_VARIADIC_ELEM(I, __VA_ARGS__))>(arg##I)
31
32#define MAKE_UNARY(TYPE, ARGS...) \
33[&](){ /* immediately invoked lambda */ \
34struct __##NAME { \
35    inline PabloAST * operator()(void * const arg0) { \
36        return mPb->create##TYPE(GET(0, ARGS)); \
37    } \
38    inline __##NAME(PabloBlock * const pb) : mPb(pb) {} \
39private: \
40    PabloBlock * const mPb; \
41}; \
42__##NAME functor(mPb); \
43return cast<TYPE>(mExprTable.findUnaryOrCall(std::move(functor), TypeId::TYPE, ARGS)); \
44}()
45
46#define MAKE_NAMED_UNARY(TYPE, PREFIX, ARGS...) \
47[&](){ /* immediately invoked lambda */  \
48struct __##NAME { \
49    inline PabloAST * operator()(void * const arg0) { \
50        return mPb->create##TYPE(GET(0, ARGS), mPrefix); \
51    } \
52    inline __##NAME(PabloBlock * const pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
53private: \
54    PabloBlock * const mPb; \
55    const llvm::StringRef & mPrefix; \
56}; \
57__##NAME functor(mPb, prefix); \
58return cast<TYPE>(mExprTable.findUnaryOrCall(std::move(functor), TypeId::TYPE, ARGS)); \
59}()
60
61#define MAKE_BINARY(TYPE, ARGS...) \
62[&](){ /* immediately invoked lambda */  \
63struct __##NAME { \
64    inline PabloAST * operator()(void * const arg0, void * const arg1) { \
65        return mPb->create##TYPE(GET(0, ARGS), GET(1, ARGS)); \
66    } \
67    inline __##NAME(PabloBlock * const pb) : mPb(pb) {} \
68private: \
69    PabloBlock * const mPb; \
70}; \
71__##NAME functor(mPb); \
72return cast<TYPE>(mExprTable.findBinaryOrCall(std::move(functor), TypeId::TYPE, ARGS)); \
73}()
74
75#define MAKE_NAMED_BINARY(TYPE, PREFIX, ARGS...) \
76[&](){ /* immediately invoked lambda */  \
77struct __##NAME { \
78    inline PabloAST * operator()(void * const arg0, void * const arg1) { \
79        return mPb->create##TYPE(GET(0, ARGS), GET(1, ARGS), mPrefix); \
80    } \
81    inline __##NAME(PabloBlock * const pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
82private: \
83    PabloBlock * const mPb; \
84    const llvm::StringRef & mPrefix; \
85}; \
86__##NAME functor(mPb, PREFIX); \
87return cast<TYPE>(mExprTable.findBinaryOrCall(std::move(functor), TypeId::TYPE, ARGS)); \
88}()
89
90#define MAKE_TERNARY(TYPE, ARGS...) \
91[&](){ /* immediately invoked lambda */  \
92struct __##NAME { \
93    inline PabloAST * operator()(void * const arg0, void * const arg1, void * const arg2) { \
94        return mPb->create##TYPE(GET(0, ARGS), GET(1, ARGS), GET(2, ARGS)); \
95    } \
96    inline __##NAME(PabloBlock * const pb) : mPb(pb) {} \
97private: \
98    PabloBlock * const mPb; \
99}; \
100__##NAME functor(mPb); \
101return cast<TYPE>(mExprTable.findTernaryOrCall(std::move(functor), TypeId::TYPE, ARGS)); \
102}()
103
104#define MAKE_NAMED_TERNARY(TYPE, PREFIX, ARGS...) \
105[&](){ /* immediately invoked lambda */  \
106struct __##NAME { \
107    inline PabloAST * operator()(void * const arg0, void * const arg1, void * const arg2) { \
108        return mPb->create##TYPE(GET(0, ARGS), GET(1, ARGS), GET(2, ARGS), mPrefix); \
109    } \
110    inline __##NAME(PabloBlock * const pb, const llvm::StringRef & prefix) : mPb(pb), mPrefix(prefix) {} \
111private: \
112    PabloBlock * const mPb; \
113    const llvm::StringRef & mPrefix; \
114}; \
115__##NAME functor(mPb, PREFIX); \
116return cast<TYPE>(mExprTable.findTernaryOrCall(std::move(functor), TypeId::TYPE, ARGS)); \
117}()
118
119PabloAST * PabloBuilder::createAdvance(PabloAST * expr, not_null<Integer *> shiftAmount) {
120    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
121        return expr;
122    }
123    return MAKE_BINARY(Advance, expr, shiftAmount.get());
124}
125
126PabloAST * PabloBuilder::createAdvance(PabloAST * expr, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix) {
127    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
128        return expr;
129    }
130    return MAKE_NAMED_BINARY(Advance, prefix, expr, shiftAmount.get());
131}
132
133PabloAST * PabloBuilder::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, not_null<Integer *> shiftAmount) {
134    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
135        return expr;
136    }
137    else if (indexStream == nullptr || isa<Ones>(indexStream)) {
138        return createAdvance(expr, shiftAmount);
139    }
140    else if (cast<Integer>(shiftAmount.get())->value() == 1) {
141        return createAdvanceThenScanTo(createAnd(expr, indexStream), indexStream);
142    }
143    return MAKE_TERNARY(IndexedAdvance, expr, indexStream, shiftAmount.get());
144}
145
146PabloAST * PabloBuilder::createIndexedAdvance(PabloAST * expr, PabloAST * indexStream, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix) {
147    if (isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0) {
148        return expr;
149    }
150    else if (indexStream == nullptr || isa<Ones>(indexStream)) {
151        return createAdvance(expr, shiftAmount, prefix);
152    }
153    else if (cast<Integer>(shiftAmount.get())->value() == 1) {
154        return createAdvanceThenScanTo(expr, indexStream, prefix);
155    }
156    return MAKE_NAMED_TERNARY(IndexedAdvance, prefix, expr, indexStream, shiftAmount.get());
157}
158   
159Extract * PabloBuilder::createExtract(Var * array, not_null<Integer *> index) {
160    return MAKE_BINARY(Extract, array, index.get());
161}
162
163PabloAST * PabloBuilder::createLookahead(PabloAST * expr, not_null<Integer *> shiftAmount) {
164    if (LLVM_UNLIKELY(isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0)) {
165        return expr;
166    }
167    return MAKE_BINARY(Lookahead, expr, shiftAmount.get());
168}
169
170PabloAST * PabloBuilder::createLookahead(PabloAST * expr, not_null<Integer *> shiftAmount, const llvm::StringRef & prefix) {
171    if (LLVM_UNLIKELY(isa<Zeroes>(expr) || cast<Integer>(shiftAmount.get())->value() == 0)) {
172        return expr;
173    }
174    return MAKE_NAMED_BINARY(Lookahead, prefix, expr, shiftAmount.get());
175}
176
177PabloAST * PabloBuilder::createNot(PabloAST * expr) {
178    if (LLVM_UNLIKELY(isa<Ones>(expr))) {
179        return createZeroes(expr->getType());
180    }
181    else if (LLVM_UNLIKELY(isa<Zeroes>(expr))){
182        return createOnes(expr->getType());
183    }
184    else if (Not * not1 = dyn_cast<Not>(expr)) {
185        return not1->getOperand(0);
186    }
187    return MAKE_UNARY(Not, expr);
188}
189
190PabloAST * PabloBuilder::createNot(PabloAST * expr, const llvm::StringRef & prefix) {
191    if (LLVM_UNLIKELY(isa<Ones>(expr))) {
192        return createZeroes(expr->getType());
193    }
194    else if (LLVM_UNLIKELY(isa<Zeroes>(expr))){
195        return createOnes(expr->getType());
196    }
197    else if (Not * not1 = dyn_cast<Not>(expr)) {
198        return not1->getOperand(0);
199    }
200    return MAKE_NAMED_UNARY(Not, prefix, expr);
201}
202
203PabloAST * PabloBuilder::createCount(PabloAST * expr) {
204    return MAKE_UNARY(Count, expr);
205}
206
207PabloAST * PabloBuilder::createCount(PabloAST * expr, const llvm::StringRef & prefix) {
208    return MAKE_NAMED_UNARY(Count, prefix, expr);
209}
210
211PabloAST * PabloBuilder::createRepeat(not_null<Integer *> fieldWidth, PabloAST * value) {
212    return MAKE_BINARY(Repeat, fieldWidth.get(), value);
213}
214
215PabloAST * PabloBuilder::createRepeat(not_null<Integer *> fieldWidth, PabloAST * value, const llvm::StringRef & prefix) {
216    return MAKE_NAMED_BINARY(Repeat, prefix, fieldWidth.get(), value);
217}
218
219   
220PabloAST * PabloBuilder::createPackL(not_null<Integer *> fieldWidth, PabloAST * value) {
221    return MAKE_BINARY(PackL, fieldWidth.get(), value);
222}
223
224PabloAST * PabloBuilder::createPackH(not_null<Integer *> fieldWidth, PabloAST * value) {
225    return MAKE_BINARY(PackH, fieldWidth.get(), value);
226}
227
228
229PabloAST * PabloBuilder::createAnd(PabloAST * expr1, PabloAST * expr2) {
230    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
231        return expr2;
232    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
233        return expr1;
234    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
235        if (Not * not2 = dyn_cast<Not>(expr2)) {
236            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)));
237        } else if (equals(not1->getOperand(0), expr2)) {
238            return createZeroes(expr1->getType());
239        }
240    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
241        if (equals(expr1, not2->getOperand(0))) {
242            return createZeroes(expr1->getType());
243        }
244    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
245        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
246            return expr2;
247        }
248    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
249        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
250            return expr1;
251        }
252    }
253    if (expr1 > expr2) {
254        std::swap(expr1, expr2);
255    }
256    return MAKE_BINARY(And, expr1, expr2);
257}
258
259PabloAST * PabloBuilder::createAnd(PabloAST * expr1, PabloAST * expr2, const llvm::StringRef & prefix) {
260    if (isa<Zeroes>(expr2) || isa<Ones>(expr1)) {
261        return expr2;
262    } else if (isa<Zeroes>(expr1) || isa<Ones>(expr2) || equals(expr1, expr2)){
263        return expr1;
264    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
265        if (Not * not2 = dyn_cast<Not>(expr2)) {
266            return createNot(createOr(not1->getOperand(0), not2->getOperand(0)), prefix);
267        } else if (equals(not1->getOperand(0), expr2)) {
268            return createZeroes(expr1->getType());
269        }
270    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
271        if (equals(expr1, not2->getOperand(0))) {
272            return createZeroes(expr1->getType());
273        }
274    } else if (Or * or1 = dyn_cast<Or>(expr1)) {
275        if (equals(or1->getOperand(0), expr2) || equals(or1->getOperand(1), expr2)) {
276            return expr2;
277        }
278    } else if (Or * or2 = dyn_cast<Or>(expr2)) {
279        if (equals(or2->getOperand(0), expr1) || equals(or2->getOperand(1), expr1)) {
280            return expr1;
281        }
282    }
283    if (expr1 > expr2) {
284        std::swap(expr1, expr2);
285    }
286    return MAKE_NAMED_BINARY(And, prefix, expr1, expr2);
287}
288
289PabloAST * PabloBuilder::createOr(PabloAST * expr1, PabloAST * expr2) {
290    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
291        return expr2;
292    }
293    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
294        return expr1;
295    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
296        // ¬a√b = ¬¬(¬a √ b) = ¬(a ∧ ¬b)
297        return createNot(createAnd(not1->getOperand(0), createNot(expr2)));
298    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
299        // a√¬b = ¬¬(¬b √ a) = ¬(b ∧ ¬a)
300        return createNot(createAnd(not2->getOperand(0), createNot(expr1)));
301    } else if (equals(expr1, expr2)) {
302        return expr1;
303    } else if (And * and1 = dyn_cast<And>(expr1)) {
304        PabloAST * const expr1a = and1->getOperand(0);
305        PabloAST * const expr1b = and1->getOperand(1);
306        if (And * and2 = dyn_cast<And>(expr2)) {
307            PabloAST * const expr2a = and2->getOperand(0);
308            PabloAST * const expr2b = and2->getOperand(1);
309            //These optimizations factor out common components that can occur when sets are formed by union
310            //(e.g., union of [a-z] and [A-Z].
311            if (equals(expr1a, expr2a)) {
312                return createAnd(expr1a, createOr(expr1b, expr2b));
313            } else if (equals(expr1b, expr2b)) {
314                return createAnd(expr1b, createOr(expr1a, expr2a));
315            } else if (equals(expr1a, expr2b)) {
316                return createAnd(expr1a, createOr(expr1b, expr2a));
317            } else if (equals(expr1b, expr2a)) {
318                return createAnd(expr1b, createOr(expr1a, expr2b));
319            }
320        } else if (equals(expr1a, expr2) || equals(expr1b, expr2)) {
321            // (a ∧ b) √ a = a
322            return expr2;
323        }
324    } else if (And * and2 = dyn_cast<And>(expr2)) {
325        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
326            return expr1;
327        }
328    }
329    if (expr1 > expr2) {
330        std::swap(expr1, expr2);
331    }
332    return MAKE_BINARY(Or, expr1, expr2);
333}
334
335PabloAST * PabloBuilder::createOr(PabloAST * expr1, PabloAST * expr2, const llvm::StringRef & prefix) {
336    if (isa<Zeroes>(expr1) || isa<Ones>(expr2)){
337        return expr2;
338    }
339    if (isa<Zeroes>(expr2) || isa<Ones>(expr1) || equals(expr1, expr2)) {
340        return expr1;
341    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
342        // ¬a√b = ¬¬(¬a √ b) = ¬(a ∧ ¬b)
343        return createNot(createAnd(not1->getOperand(0), createNot(expr2)), prefix);
344    } else if (Not * not2 = dyn_cast<Not>(expr2)) {
345        // a√¬b = ¬¬(¬b √ a) = ¬(b ∧ ¬a)
346        return createNot(createAnd(not2->getOperand(0), createNot(expr1)), prefix);
347    } else if (equals(expr1, expr2)) {
348        return expr1;
349    } else if (And * and1 = dyn_cast<And>(expr1)) {
350        PabloAST * const expr1a = and1->getOperand(0);
351        PabloAST * const expr1b = and1->getOperand(1);
352        if (And * and2 = dyn_cast<And>(expr2)) {
353            PabloAST * const expr2a = and2->getOperand(0);
354            PabloAST * const expr2b = and2->getOperand(1);
355            //These optimizations factor out common components that can occur when sets are formed by union
356            //(e.g., union of [a-z] and [A-Z].
357            if (equals(expr1a, expr2a)) {
358                return createAnd(expr1a, createOr(expr1b, expr2b), prefix);
359            } else if (equals(expr1b, expr2b)) {
360                return createAnd(expr1b, createOr(expr1a, expr2a), prefix);
361            } else if (equals(expr1a, expr2b)) {
362                return createAnd(expr1a, createOr(expr1b, expr2a), prefix);
363            } else if (equals(expr1b, expr2a)) {
364                return createAnd(expr1b, createOr(expr1a, expr2b), prefix);
365            }
366        } else if (equals(expr1a, expr2) || equals(expr1b, expr2)) {
367            // (a ∧ b) √ a = a
368            return expr2;
369        }
370    } else if (And * and2 = dyn_cast<And>(expr2)) {
371        if (equals(and2->getOperand(0), expr1) || equals(and2->getOperand(1), expr1)) {
372            return expr1;
373        }
374    }
375    if (expr1 > expr2) {
376        std::swap(expr1, expr2);
377    }
378    return MAKE_NAMED_BINARY(Or, prefix, expr1, expr2);
379}
380
381PabloAST * PabloBuilder::createXor(PabloAST * expr1, PabloAST * expr2) {
382    if (expr1 == expr2) {
383        return createZeroes(expr1->getType());
384    } else if (isa<Ones>(expr1)) {
385        return createNot(expr2);
386    } else if (isa<Zeroes>(expr1)){
387        return expr2;
388    } else if (isa<Ones>(expr2)) {
389        return createNot(expr1);
390    } else if (isa<Zeroes>(expr2)){
391        return expr1;
392    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
393        if (Not * not2 = dyn_cast<Not>(expr2)) {
394            return createXor(not1->getOperand(0), not2->getOperand(0));
395        }
396    }
397    if (expr1 > expr2) {
398        std::swap(expr1, expr2);
399    }
400    return MAKE_BINARY(Xor, expr1, expr2);
401}
402
403PabloAST * PabloBuilder::createXor(PabloAST * expr1, PabloAST * expr2, const llvm::StringRef & prefix) {
404    if (expr1 == expr2) {
405        return createZeroes(expr1->getType());
406    } else if (isa<Ones>(expr1)) {
407        return createNot(expr2);
408    } else if (isa<Zeroes>(expr1)){
409        return expr2;
410    } else if (isa<Ones>(expr2)) {
411        return createNot(expr1);
412    } else if (isa<Zeroes>(expr2)){
413        return expr1;
414    } else if (Not * not1 = dyn_cast<Not>(expr1)) {
415        if (Not * not2 = dyn_cast<Not>(expr2)) {
416            return createXor(not1->getOperand(0), not2->getOperand(0), prefix);
417        }
418    }
419    if (expr1 > expr2) {
420        std::swap(expr1, expr2);
421    }
422    return MAKE_NAMED_BINARY(Xor, prefix, expr1, expr2);
423}
424
425PabloAST * PabloBuilder::createAdd(PabloAST * expr1, PabloAST * expr2) {
426    if (isa<Integer>(expr1) && isa<Integer>(expr2)) {
427        return getInteger(cast<Integer>(expr1)->value() + cast<Integer>(expr2)->value());
428    } else if (isa<Integer>(expr1)) {
429        if (cast<Integer>(expr1)->value() == 0) {
430            return expr2;
431        }
432    } else if (isa<Integer>(expr2)) {
433        if (cast<Integer>(expr2)->value() == 0) {
434            return expr1;
435        }
436    }
437    return MAKE_BINARY(Add, expr1, expr2);
438}
439
440PabloAST * PabloBuilder::createSubtract(PabloAST * expr1, PabloAST * expr2) {
441    if (isa<Integer>(expr1) && isa<Integer>(expr2)) {
442        return getInteger(cast<Integer>(expr1)->value() - cast<Integer>(expr2)->value());
443    } else if (isa<Integer>(expr1)) {
444        if (cast<Integer>(expr1)->value() == 0) {
445            return expr2;
446        }
447    } else if (isa<Integer>(expr2)) {
448        if (cast<Integer>(expr2)->value() == 0) {
449            return expr1;
450        }
451    }
452    return MAKE_BINARY(Subtract, expr1, expr2);
453}
454
455PabloAST * PabloBuilder::createLessThan(PabloAST * expr1, PabloAST * expr2) {
456    if (isa<Integer>(expr1) && isa<Integer>(expr2)) {
457        return getInteger(cast<Integer>(expr1)->value() < cast<Integer>(expr2)->value() ? 1 : 0);
458    }
459    return MAKE_BINARY(LessThan, expr1, expr2);
460}
461
462PabloAST * PabloBuilder::createEquals(PabloAST * expr1, PabloAST * expr2) {
463    if (isa<Integer>(expr1) && isa<Integer>(expr2)) {
464        return getInteger(cast<Integer>(expr1)->value() == cast<Integer>(expr2)->value() ? 1 : 0);
465    }
466    return MAKE_BINARY(Equals, expr1, expr2);
467}
468
469PabloAST * PabloBuilder::createInFile(PabloAST * expr) {
470    if (LLVM_UNLIKELY(isa<InFile>(expr) || isa<Zeroes>(expr))) {
471        return expr;
472    }
473    return MAKE_UNARY(InFile, expr);
474}
475
476PabloAST * PabloBuilder::createInFile(PabloAST * expr, const llvm::StringRef & prefix) {
477    if (LLVM_UNLIKELY(isa<InFile>(expr) || isa<Zeroes>(expr))) {
478        return expr;
479    }
480    return MAKE_NAMED_UNARY(InFile, prefix, expr);
481}
482
483PabloAST * PabloBuilder::createAtEOF(PabloAST * expr) {
484    return MAKE_UNARY(AtEOF, expr);
485}
486
487PabloAST * PabloBuilder::createAtEOF(PabloAST * expr, const llvm::StringRef & prefix) {
488    return MAKE_NAMED_UNARY(AtEOF, prefix, expr);
489}
490
491PabloAST * PabloBuilder::createTerminateAt(PabloAST * strm, not_null<Integer *> code) {
492    if (isa<Zeroes>(strm)) return strm;
493    return MAKE_BINARY(TerminateAt, strm, code.get());
494}
495
496PabloAST * PabloBuilder::createTerminateAt(PabloAST * strm, not_null<Integer *> code, const llvm::StringRef & prefix) {
497    if (isa<Zeroes>(strm)) return strm;
498    return MAKE_NAMED_BINARY(TerminateAt, prefix, strm, code.get());
499}
500
501PabloAST * PabloBuilder::createMatchStar(PabloAST * marker, PabloAST * charclass) {
502    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
503        return marker;
504    }
505    return MAKE_BINARY(MatchStar, marker, charclass);
506}
507   
508PabloAST * PabloBuilder::createMatchStar(PabloAST * marker, PabloAST * charclass, const llvm::StringRef & prefix) {
509    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
510        return marker;
511    }
512    return MAKE_NAMED_BINARY(MatchStar, prefix, marker, charclass);
513}
514
515PabloAST * PabloBuilder::createScanThru(PabloAST * from, PabloAST * thru) {
516    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
517        return from;
518    }
519    return MAKE_BINARY(ScanThru, from, thru);
520}
521
522PabloAST * PabloBuilder::createScanThru(PabloAST * from, PabloAST * thru, const llvm::StringRef & prefix) {
523    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
524        return from;
525    }
526    return MAKE_NAMED_BINARY(ScanThru, prefix, from, thru);
527}
528
529PabloAST * PabloBuilder::createScanTo(PabloAST * from, PabloAST * to) {
530    if (isa<Zeroes>(from)) {
531        return from;
532    }
533    return MAKE_BINARY(ScanTo, from, to);
534}
535
536PabloAST * PabloBuilder::createScanTo(PabloAST * from, PabloAST * to, const llvm::StringRef & prefix) {
537    if (isa<Zeroes>(from)) {
538        return from;
539    }
540    return MAKE_NAMED_BINARY(ScanTo, prefix, from, to);
541}
542
543PabloAST * PabloBuilder::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru) {
544    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
545        return from;
546    }
547    return MAKE_BINARY(AdvanceThenScanThru, from, thru);
548}
549
550PabloAST * PabloBuilder::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru, const llvm::StringRef & prefix) {
551    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
552        return from;
553    }
554    return MAKE_NAMED_BINARY(AdvanceThenScanThru, prefix, from, thru);
555}
556
557PabloAST * PabloBuilder::createAdvanceThenScanTo(PabloAST * from, PabloAST * to) {
558    if (isa<Zeroes>(from)) {
559        return from;
560    }
561    return MAKE_BINARY(AdvanceThenScanTo, from, to);
562}
563
564PabloAST * PabloBuilder::createAdvanceThenScanTo(PabloAST * from, PabloAST * to, const llvm::StringRef & prefix) {
565    if (isa<Zeroes>(from)) {
566        return from;
567    }
568    return MAKE_NAMED_BINARY(AdvanceThenScanTo, prefix, from, to);
569}
570
571PabloAST * PabloBuilder::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
572    if (isa<Ones>(condition)) {
573        return trueExpr;
574    } else if (isa<Zeroes>(condition)){
575        return falseExpr;
576    } else if (isa<Ones>(trueExpr)) {
577        return createOr(condition, falseExpr);
578    } else if (isa<Zeroes>(trueExpr)){
579        return createAnd(createNot(condition), falseExpr);
580    } else if (isa<Ones>(falseExpr)) {
581        return createOr(createNot(condition), trueExpr);
582    } else if (isa<Zeroes>(falseExpr)){
583        return createAnd(condition, trueExpr);
584    } else if (equals(trueExpr, falseExpr)) {
585        return trueExpr;
586    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
587        return createXor(condition, falseExpr);
588    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
589        return createXor(condition, trueExpr);
590    }
591    return MAKE_TERNARY(Sel, condition, trueExpr, falseExpr);
592}
593
594PabloAST * PabloBuilder::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const llvm::StringRef & prefix) {
595    if (isa<Ones>(condition)) {
596        return trueExpr;
597    } else if (isa<Zeroes>(condition)){
598        return falseExpr;
599    } else if (isa<Ones>(trueExpr)) {
600        return createOr(condition, falseExpr);
601    } else if (isa<Zeroes>(trueExpr)){
602        return createAnd(createNot(condition), falseExpr);
603    } else if (isa<Ones>(falseExpr)) {
604        return createOr(createNot(condition), trueExpr);
605    } else if (isa<Zeroes>(falseExpr)){
606        return createAnd(condition, trueExpr);
607    } else if (equals(trueExpr, falseExpr)) {
608        return trueExpr;
609    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
610        return createXor(condition, falseExpr);
611    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
612        return createXor(condition, trueExpr);
613    }
614    return MAKE_NAMED_TERNARY(Sel, prefix, condition, trueExpr, falseExpr);
615}
616
617}
Note: See TracBrowser for help on using the repository browser.