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

Last change on this file since 6129 was 6129, checked in by cameron, 11 months ago

pablo.Infile(0) optimization

File size: 23.2 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    if (isa<Zeroes>(expr)) return expr;
482    MAKE_UNARY(createInFile, TypeId::InFile, expr);
483    return result;
484}
485
486PabloAST * PabloBuilder::createInFile(PabloAST * expr, const llvm::StringRef & prefix) {
487    MAKE_NAMED_UNARY(createInFile, TypeId::InFile, prefix, expr);
488    return result;
489}
490
491PabloAST * PabloBuilder::createAtEOF(PabloAST * expr) {
492    MAKE_UNARY(createAtEOF, TypeId::AtEOF, expr);
493    return result;
494}
495
496PabloAST * PabloBuilder::createAtEOF(PabloAST * expr, const llvm::StringRef & prefix) {
497    MAKE_NAMED_UNARY(createAtEOF, TypeId::AtEOF, prefix, expr);
498    return result;
499}
500
501PabloAST * PabloBuilder::createMatchStar(PabloAST * marker, PabloAST * charclass) {
502    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
503        return marker;
504    }
505    MAKE_BINARY(createMatchStar, TypeId::MatchStar, marker, charclass);
506    return result;
507}
508
509PabloAST * PabloBuilder::createMatchStar(PabloAST * marker, PabloAST * charclass, const llvm::StringRef & prefix) {
510    if (isa<Zeroes>(marker) || isa<Zeroes>(charclass)) {
511        return marker;
512    }
513    MAKE_NAMED_BINARY(createMatchStar, TypeId::MatchStar, prefix, marker, charclass);
514    return result;
515}
516
517PabloAST * PabloBuilder::createScanThru(PabloAST * from, PabloAST * thru) {
518    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
519        return from;
520    }
521    MAKE_BINARY(createScanThru, TypeId::ScanThru, from, thru);
522    return result;
523}
524
525PabloAST * PabloBuilder::createScanThru(PabloAST * from, PabloAST * thru, const llvm::StringRef & prefix) {
526    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
527        return from;
528    }
529    MAKE_NAMED_BINARY(createScanThru, TypeId::ScanThru, prefix, from, thru);
530    return result;
531}
532
533PabloAST * PabloBuilder::createScanTo(PabloAST * from, PabloAST * to) {
534    if (isa<Zeroes>(from)) {
535        return from;
536    }
537    MAKE_BINARY(createScanTo, TypeId::ScanTo, from, to);
538    return result;
539}
540
541PabloAST * PabloBuilder::createScanTo(PabloAST * from, PabloAST * to, const llvm::StringRef & prefix) {
542    if (isa<Zeroes>(from)) {
543        return from;
544    }
545    MAKE_NAMED_BINARY(createScanTo, TypeId::ScanTo, prefix, from, to);
546    return result;
547}
548
549PabloAST * PabloBuilder::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru) {
550    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
551        return from;
552    }
553    MAKE_BINARY(createAdvanceThenScanThru, TypeId::AdvanceThenScanThru, from, thru);
554    return result;
555}
556
557PabloAST * PabloBuilder::createAdvanceThenScanThru(PabloAST * from, PabloAST * thru, const llvm::StringRef & prefix) {
558    if (isa<Zeroes>(from) || isa<Zeroes>(thru)) {
559        return from;
560    }
561    MAKE_NAMED_BINARY(createAdvanceThenScanThru, TypeId::AdvanceThenScanThru, prefix, from, thru);
562    return result;
563}
564
565PabloAST * PabloBuilder::createAdvanceThenScanTo(PabloAST * from, PabloAST * to) {
566    if (isa<Zeroes>(from)) {
567        return from;
568    }
569    MAKE_BINARY(createAdvanceThenScanTo, TypeId::ScanTo, from, to);
570    return result;
571}
572
573PabloAST * PabloBuilder::createAdvanceThenScanTo(PabloAST * from, PabloAST * to, const llvm::StringRef & prefix) {
574    if (isa<Zeroes>(from)) {
575        return from;
576    }
577    MAKE_NAMED_BINARY(createAdvanceThenScanTo, TypeId::ScanTo, prefix, from, to);
578    return result;
579}
580
581PabloAST * PabloBuilder::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr) {
582    if (isa<Ones>(condition)) {
583        return trueExpr;
584    } else if (isa<Zeroes>(condition)){
585        return falseExpr;
586    } else if (isa<Ones>(trueExpr)) {
587        return createOr(condition, falseExpr);
588    } else if (isa<Zeroes>(trueExpr)){
589        return createAnd(createNot(condition), falseExpr);
590    } else if (isa<Ones>(falseExpr)) {
591        return createOr(createNot(condition), trueExpr);
592    } else if (isa<Zeroes>(falseExpr)){
593        return createAnd(condition, trueExpr);
594    } else if (equals(trueExpr, falseExpr)) {
595        return trueExpr;
596    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
597        return createXor(condition, falseExpr);
598    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
599        return createXor(condition, trueExpr);
600    }
601    MAKE_TERNARY(createSel, TypeId::Sel, condition, trueExpr, falseExpr);
602    return result;
603}
604
605PabloAST * PabloBuilder::createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr, const llvm::StringRef & prefix) {
606    if (isa<Ones>(condition)) {
607        return trueExpr;
608    } else if (isa<Zeroes>(condition)){
609        return falseExpr;
610    } else if (isa<Ones>(trueExpr)) {
611        return createOr(condition, falseExpr);
612    } else if (isa<Zeroes>(trueExpr)){
613        return createAnd(createNot(condition), falseExpr);
614    } else if (isa<Ones>(falseExpr)) {
615        return createOr(createNot(condition), trueExpr);
616    } else if (isa<Zeroes>(falseExpr)){
617        return createAnd(condition, trueExpr);
618    } else if (equals(trueExpr, falseExpr)) {
619        return trueExpr;
620    } else if (isa<Not>(trueExpr) && equals(cast<Not>(trueExpr)->getOperand(0), falseExpr)) {
621        return createXor(condition, falseExpr);
622    } else if (isa<Not>(falseExpr) && equals(trueExpr, cast<Not>(falseExpr)->getOperand(0))){
623        return createXor(condition, trueExpr);
624    }
625    MAKE_NAMED_TERNARY(createSel, TypeId::Sel, prefix, condition, trueExpr, falseExpr);
626    return result;
627}
628
629}
Note: See TracBrowser for help on using the repository browser.