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

Last change on this file since 6202 was 6202, checked in by cameron, 7 months ago

inFile optimization

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