14ExprBuilder::ExprBuilder() {
22 virtual ref<Expr> Constant(
const llvm::APInt &Value) {
50 return ZExtExpr::alloc(LHS, W);
54 return SExtExpr::alloc(LHS, W);
58 return AddExpr::alloc(LHS, RHS);
62 return SubExpr::alloc(LHS, RHS);
66 return MulExpr::alloc(LHS, RHS);
70 return UDivExpr::alloc(LHS, RHS);
74 return SDivExpr::alloc(LHS, RHS);
78 return URemExpr::alloc(LHS, RHS);
82 return SRemExpr::alloc(LHS, RHS);
90 return AndExpr::alloc(LHS, RHS);
94 return OrExpr::alloc(LHS, RHS);
98 return XorExpr::alloc(LHS, RHS);
102 return ShlExpr::alloc(LHS, RHS);
106 return LShrExpr::alloc(LHS, RHS);
110 return AShrExpr::alloc(LHS, RHS);
114 return EqExpr::alloc(LHS, RHS);
118 return NeExpr::alloc(LHS, RHS);
122 return UltExpr::alloc(LHS, RHS);
126 return UleExpr::alloc(LHS, RHS);
130 return UgtExpr::alloc(LHS, RHS);
134 return UgeExpr::alloc(LHS, RHS);
138 return SltExpr::alloc(LHS, RHS);
142 return SleExpr::alloc(LHS, RHS);
146 return SgtExpr::alloc(LHS, RHS);
150 return SgeExpr::alloc(LHS, RHS);
157 class ChainedBuilder {
168 : Builder(_Builder), Base(_Base) {}
169 ~ChainedBuilder() {
delete Base; }
171 ref<Expr> Constant(
const llvm::APInt &Value) {
181 return Base->
Read(Updates, Index);
186 return Base->
Select(Cond, LHS, RHS);
190 return Base->
Concat(LHS, RHS);
195 return Base->
Extract(LHS, Offset, W);
199 return Base->
ZExt(LHS, W);
203 return Base->
SExt(LHS, W);
207 return Base->
Add(LHS, RHS);
211 return Base->
Sub(LHS, RHS);
215 return Base->
Mul(LHS, RHS);
219 return Base->
UDiv(LHS, RHS);
223 return Base->
SDiv(LHS, RHS);
227 return Base->
URem(LHS, RHS);
231 return Base->
SRem(LHS, RHS);
235 return Base->
Not(LHS);
239 return Base->
And(LHS, RHS);
243 return Base->
Or(LHS, RHS);
247 return Base->
Xor(LHS, RHS);
251 return Base->
Shl(LHS, RHS);
255 return Base->
LShr(LHS, RHS);
259 return Base->
AShr(LHS, RHS);
263 return Base->
Eq(LHS, RHS);
267 return Base->
Ne(LHS, RHS);
271 return Base->
Ult(LHS, RHS);
275 return Base->
Ule(LHS, RHS);
279 return Base->
Ugt(LHS, RHS);
283 return Base->
Uge(LHS, RHS);
287 return Base->
Slt(LHS, RHS);
291 return Base->
Sle(LHS, RHS);
295 return Base->
Sgt(LHS, RHS);
299 return Base->
Sge(LHS, RHS);
310 template<
typename SpecializedBuilder>
311 class ConstantSpecializedExprBuilder :
public ExprBuilder {
312 SpecializedBuilder Builder;
315 ConstantSpecializedExprBuilder(
ExprBuilder *Base) : Builder(this, Base) {}
316 ~ConstantSpecializedExprBuilder() {}
318 virtual ref<Expr> Constant(
const llvm::APInt &Value) {
319 return Builder.Constant(Value);
323 return Builder.NotOptimized(Index);
329 auto UN = Updates.
head;
330 while (UN && Eq(Index, UN->index)->isFalse())
342 return CE->
isTrue() ? LHS : RHS;
344 return Builder.Select(cast<NonConstantExpr>(Cond), LHS, RHS);
351 return Builder.Concat(LCE, cast<NonConstantExpr>(RHS));
352 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
353 return Builder.Concat(cast<NonConstantExpr>(LHS), RCE);
356 return Builder.Concat(cast<NonConstantExpr>(LHS),
357 cast<NonConstantExpr>(RHS));
365 return Builder.Extract(cast<NonConstantExpr>(LHS), Offset, W);
372 return Builder.ZExt(cast<NonConstantExpr>(LHS), W);
379 return Builder.SExt(cast<NonConstantExpr>(LHS), W);
385 return LCE->
Add(RCE);
386 return Builder.Add(LCE, cast<NonConstantExpr>(RHS));
387 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
388 return Builder.Add(cast<NonConstantExpr>(LHS), RCE);
391 return Builder.Add(cast<NonConstantExpr>(LHS),
392 cast<NonConstantExpr>(RHS));
398 return LCE->
Sub(RCE);
399 return Builder.Sub(LCE, cast<NonConstantExpr>(RHS));
400 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
401 return Builder.Sub(cast<NonConstantExpr>(LHS), RCE);
404 return Builder.Sub(cast<NonConstantExpr>(LHS),
405 cast<NonConstantExpr>(RHS));
411 return LCE->
Mul(RCE);
412 return Builder.Mul(LCE, cast<NonConstantExpr>(RHS));
413 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
414 return Builder.Mul(cast<NonConstantExpr>(LHS), RCE);
417 return Builder.Mul(cast<NonConstantExpr>(LHS),
418 cast<NonConstantExpr>(RHS));
424 return LCE->
UDiv(RCE);
425 return Builder.UDiv(LCE, cast<NonConstantExpr>(RHS));
426 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
427 return Builder.UDiv(cast<NonConstantExpr>(LHS), RCE);
430 return Builder.UDiv(cast<NonConstantExpr>(LHS),
431 cast<NonConstantExpr>(RHS));
437 return LCE->
SDiv(RCE);
438 return Builder.SDiv(LCE, cast<NonConstantExpr>(RHS));
439 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
440 return Builder.SDiv(cast<NonConstantExpr>(LHS), RCE);
443 return Builder.SDiv(cast<NonConstantExpr>(LHS),
444 cast<NonConstantExpr>(RHS));
450 return LCE->
URem(RCE);
451 return Builder.URem(LCE, cast<NonConstantExpr>(RHS));
452 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
453 return Builder.URem(cast<NonConstantExpr>(LHS), RCE);
456 return Builder.URem(cast<NonConstantExpr>(LHS),
457 cast<NonConstantExpr>(RHS));
463 return LCE->
SRem(RCE);
464 return Builder.SRem(LCE, cast<NonConstantExpr>(RHS));
465 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
466 return Builder.SRem(cast<NonConstantExpr>(LHS), RCE);
469 return Builder.SRem(cast<NonConstantExpr>(LHS),
470 cast<NonConstantExpr>(RHS));
475 if (
NotExpr *DblNot = dyn_cast<NotExpr>(LHS))
481 return Builder.Not(cast<NonConstantExpr>(LHS));
487 return LCE->
And(RCE);
488 return Builder.And(LCE, cast<NonConstantExpr>(RHS));
489 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
490 return Builder.And(cast<NonConstantExpr>(LHS), RCE);
493 return Builder.And(cast<NonConstantExpr>(LHS),
494 cast<NonConstantExpr>(RHS));
501 return Builder.Or(LCE, cast<NonConstantExpr>(RHS));
502 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
503 return Builder.Or(cast<NonConstantExpr>(LHS), RCE);
506 return Builder.Or(cast<NonConstantExpr>(LHS),
507 cast<NonConstantExpr>(RHS));
513 return LCE->
Xor(RCE);
514 return Builder.Xor(LCE, cast<NonConstantExpr>(RHS));
515 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
516 return Builder.Xor(cast<NonConstantExpr>(LHS), RCE);
519 return Builder.Xor(cast<NonConstantExpr>(LHS),
520 cast<NonConstantExpr>(RHS));
526 return LCE->
Shl(RCE);
527 return Builder.Shl(LCE, cast<NonConstantExpr>(RHS));
528 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
529 return Builder.Shl(cast<NonConstantExpr>(LHS), RCE);
532 return Builder.Shl(cast<NonConstantExpr>(LHS),
533 cast<NonConstantExpr>(RHS));
539 return LCE->
LShr(RCE);
540 return Builder.LShr(LCE, cast<NonConstantExpr>(RHS));
541 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
542 return Builder.LShr(cast<NonConstantExpr>(LHS), RCE);
545 return Builder.LShr(cast<NonConstantExpr>(LHS),
546 cast<NonConstantExpr>(RHS));
552 return LCE->
AShr(RCE);
553 return Builder.AShr(LCE, cast<NonConstantExpr>(RHS));
554 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
555 return Builder.AShr(cast<NonConstantExpr>(LHS), RCE);
558 return Builder.AShr(cast<NonConstantExpr>(LHS),
559 cast<NonConstantExpr>(RHS));
566 return Builder.Eq(LCE, cast<NonConstantExpr>(RHS));
567 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
568 return Builder.Eq(cast<NonConstantExpr>(LHS), RCE);
571 return Builder.Eq(cast<NonConstantExpr>(LHS),
572 cast<NonConstantExpr>(RHS));
579 return Builder.Ne(LCE, cast<NonConstantExpr>(RHS));
580 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
581 return Builder.Ne(cast<NonConstantExpr>(LHS), RCE);
584 return Builder.Ne(cast<NonConstantExpr>(LHS),
585 cast<NonConstantExpr>(RHS));
591 return LCE->
Ult(RCE);
592 return Builder.Ult(LCE, cast<NonConstantExpr>(RHS));
593 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
594 return Builder.Ult(cast<NonConstantExpr>(LHS), RCE);
597 return Builder.Ult(cast<NonConstantExpr>(LHS),
598 cast<NonConstantExpr>(RHS));
604 return LCE->
Ule(RCE);
605 return Builder.Ule(LCE, cast<NonConstantExpr>(RHS));
606 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
607 return Builder.Ule(cast<NonConstantExpr>(LHS), RCE);
610 return Builder.Ule(cast<NonConstantExpr>(LHS),
611 cast<NonConstantExpr>(RHS));
617 return LCE->
Ugt(RCE);
618 return Builder.Ugt(LCE, cast<NonConstantExpr>(RHS));
619 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
620 return Builder.Ugt(cast<NonConstantExpr>(LHS), RCE);
623 return Builder.Ugt(cast<NonConstantExpr>(LHS),
624 cast<NonConstantExpr>(RHS));
630 return LCE->
Uge(RCE);
631 return Builder.Uge(LCE, cast<NonConstantExpr>(RHS));
632 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
633 return Builder.Uge(cast<NonConstantExpr>(LHS), RCE);
636 return Builder.Uge(cast<NonConstantExpr>(LHS),
637 cast<NonConstantExpr>(RHS));
643 return LCE->
Slt(RCE);
644 return Builder.Slt(LCE, cast<NonConstantExpr>(RHS));
645 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
646 return Builder.Slt(cast<NonConstantExpr>(LHS), RCE);
649 return Builder.Slt(cast<NonConstantExpr>(LHS),
650 cast<NonConstantExpr>(RHS));
656 return LCE->
Sle(RCE);
657 return Builder.Sle(LCE, cast<NonConstantExpr>(RHS));
658 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
659 return Builder.Sle(cast<NonConstantExpr>(LHS), RCE);
662 return Builder.Sle(cast<NonConstantExpr>(LHS),
663 cast<NonConstantExpr>(RHS));
669 return LCE->
Sgt(RCE);
670 return Builder.Sgt(LCE, cast<NonConstantExpr>(RHS));
671 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
672 return Builder.Sgt(cast<NonConstantExpr>(LHS), RCE);
675 return Builder.Sgt(cast<NonConstantExpr>(LHS),
676 cast<NonConstantExpr>(RHS));
682 return LCE->
Sge(RCE);
683 return Builder.Sge(LCE, cast<NonConstantExpr>(RHS));
684 }
else if (
ConstantExpr *RCE = dyn_cast<ConstantExpr>(RHS)) {
685 return Builder.Sge(cast<NonConstantExpr>(LHS), RCE);
688 return Builder.Sge(cast<NonConstantExpr>(LHS),
689 cast<NonConstantExpr>(RHS));
693 class ConstantFoldingBuilder :
694 public ChainedBuilder {
697 : ChainedBuilder(Builder, Base) {}
705 switch (RHS->getKind()) {
712 return Builder->Add(LHS->Add(CE), BE->
right);
715 return Builder->Add(LHS->Add(CE), BE->
left);
723 return Builder->Sub(LHS->Add(CE), BE->
right);
726 return Builder->Add(LHS->Sub(CE), BE->
left);
731 return Base->
Add(LHS, RHS);
736 return Add(RHS, LHS);
741 switch (LHS->getKind()) {
747 return Builder->Add(BE->
left,
754 return Builder->Add(BE->
left,
759 switch (RHS->getKind()) {
766 return Builder->Add(CE, Builder->Add(LHS, BE->
right));
769 return Builder->Add(CE, Builder->Add(LHS, BE->
left));
777 return Builder->Add(CE, Builder->Sub(LHS, BE->
right));
780 return Builder->Add(CE->Neg(), Builder->Add(LHS, BE->
left));
785 return Base->
Add(LHS, RHS);
790 switch (RHS->getKind()) {
797 return Builder->Sub(LHS->Sub(CE), BE->
right);
800 return Builder->Sub(LHS->Sub(CE), BE->
left);
808 return Builder->Add(LHS->Sub(CE), BE->
right);
811 return Builder->Sub(LHS->Add(CE), BE->
left);
816 return Base->
Sub(LHS, RHS);
822 return Add(RHS->Neg(), LHS);
827 switch (LHS->getKind()) {
833 return Builder->Add(BE->
left, Builder->
Sub(BE->
right, RHS));
839 return Builder->Sub(BE->
left, Builder->
Add(BE->
right, RHS));
843 switch (RHS->getKind()) {
850 return Builder->Add(CE->Neg(), Builder->Sub(LHS, BE->
right));
853 return Builder->Add(CE->Neg(), Builder->Sub(LHS, BE->
left));
861 return Builder->Add(CE->Neg(), Builder->Add(LHS, BE->
right));
864 return Builder->Add(CE, Builder->Sub(LHS, BE->
left));
869 return Base->
Sub(LHS, RHS);
880 return Base->
Mul(LHS, RHS);
885 return Mul(RHS, LHS);
890 return Base->
Mul(LHS, RHS);
897 if (LHS->isAllOnes())
901 return Base->
And(LHS, RHS);
906 return And(RHS, LHS);
911 return Base->
And(LHS, RHS);
918 if (LHS->isAllOnes())
922 return Base->
Or(LHS, RHS);
932 return Base->
Or(LHS, RHS);
941 return Base->
Xor(LHS, RHS);
946 return Xor(RHS, LHS);
951 return Base->
Xor(LHS, RHS);
964 return Base->
Not(RHS);
967 return Base->
Eq(LHS, RHS);
977 return Base->
Eq(LHS, RHS);
981 typedef ConstantSpecializedExprBuilder<ConstantFoldingBuilder>
982 ConstantFoldingExprBuilder;
984 class SimplifyingBuilder :
public ChainedBuilder {
987 : ChainedBuilder(Builder, Base) {}
999 return Base->
Not(RHS);
1002 return Base->
Eq(LHS, RHS);
1007 return Eq(RHS, LHS);
1014 return Builder->True();
1016 return Base->
Eq(LHS, RHS);
1021 if (
const OrExpr *OE = dyn_cast<OrExpr>(LHS))
1022 return Builder->
And(Builder->Not(OE->left),
1023 Builder->Not(OE->right));
1024 return Base->
Not(LHS);
1029 return Builder->
Not(Builder->Eq(LHS, RHS));
1034 return Builder->
Ult(RHS, LHS);
1039 return Builder->
Ule(RHS, LHS);
1044 return Builder->
Slt(RHS, LHS);
1049 return Builder->
Sle(RHS, LHS);
1053 typedef ConstantSpecializedExprBuilder<SimplifyingBuilder>
1054 SimplifyingExprBuilder;
1058 return new DefaultExprBuilder();
1062 return new ConstantFoldingExprBuilder(Base);
1066 return new SimplifyingExprBuilder(Base);
static ref< Expr > alloc(const ref< Expr > &l, const ref< Expr > &r)
static ref< ConstantExpr > alloc(const llvm::APInt &v)
ExprBuilder - Base expression builder class.
virtual ref< Expr > Ule(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > URem(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Xor(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sle(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Eq(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Or(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Not(const ref< Expr > &LHS)=0
virtual ref< Expr > ZExt(const ref< Expr > &LHS, Expr::Width W)=0
virtual ref< Expr > UDiv(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Uge(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Extract(const ref< Expr > &LHS, unsigned Offset, Expr::Width W)=0
virtual ref< Expr > And(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sge(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > LShr(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > SExt(const ref< Expr > &LHS, Expr::Width W)=0
virtual ref< Expr > Mul(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Select(const ref< Expr > &Cond, const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Slt(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Ne(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Concat(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > SRem(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > AShr(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Shl(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Sub(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > SDiv(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Ult(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Read(const UpdateList &Updates, const ref< Expr > &Index)=0
virtual ref< Expr > Ugt(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > NotOptimized(const ref< Expr > &Index)=0
virtual ref< Expr > Sgt(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
virtual ref< Expr > Constant(const llvm::APInt &Value)=0
virtual ref< Expr > Add(const ref< Expr > &LHS, const ref< Expr > &RHS)=0
@ Sge
Not used in canonical form.
@ Ne
Not used in canonical form.
@ Ugt
Not used in canonical form.
@ Sgt
Not used in canonical form.
@ Uge
Not used in canonical form.
unsigned Width
The type of an expression is simply its width, in bits.
bool isTrue() const
isTrue - Is this the true expression.
virtual ref< Expr > getKid(unsigned i) const =0
static ref< Expr > alloc(const ref< Expr > &e)
static ref< Expr > alloc(const ref< Expr > &src)
static ref< Expr > alloc(const UpdateList &updates, const ref< Expr > &index)
static ref< Expr > alloc(const ref< Expr > &c, const ref< Expr > &t, const ref< Expr > &f)
Class representing a complete list of updates into an array.
ref< UpdateNode > head
pointer to the most recent update node
ExprBuilder * createDefaultExprBuilder()
ExprBuilder * createConstantFoldingExprBuilder(ExprBuilder *Base)
ExprBuilder * createSimplifyingExprBuilder(ExprBuilder *Base)