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

Last change on this file since 5297 was 5283, checked in by nmedfort, 3 years ago

Optimized Symbol Generation (and fixed potential bug that could allow duplicate names being constructed); made PabloKernel? extend PabloAST (temporarily removed PabloAST::getName() to avoid diamond problem); added an internal scalar to PabloKernel? struct for each Count to avoid InOut? output scalar variable problem; allowed CodeMotionPass? to move code within the same scope but across a branch statement. Began work on separating Kernels into either Block-Oriented or Segment-Oriented kernels.

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