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

Last change on this file since 5889 was 5889, checked in by cameron, 19 months ago

BitByteGrepKernel? initial check-in

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