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

Last change on this file since 6173 was 6173, checked in by nmedfort, 7 months ago

Added RE_Inspector.

Migrated RE passes to RE_Transformer.

Incorporated Memoizer functionality into RE_Transformer/Inspector.

Removed Memoizer.

Bug fix for unicode_set.

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