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

Last change on this file since 5792 was 5782, checked in by nmedfort, 20 months ago

Initial check-in of LookAhead? support; modified LineBreakKernel? to compute CR+LF using LookAhead?(1) + misc. fixes.

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