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

Last change on this file since 5828 was 5828, checked in by nmedfort, 17 months ago

Pablo support for byte comparisions; LineFeed? kernel processes byte streams directly. Some clean up of PabloBuilder? functionality.

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