Make SCEVRewriteVisitor smarter about when it trys to create SCEVs
authorSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 14 Apr 2017 17:42:08 +0000 (17:42 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Fri, 14 Apr 2017 17:42:08 +0000 (17:42 +0000)
This change really saves just one foldingset lookup, but makes
SCEVRewriteVisitor "feature compatible" with the handwritten logic in
ScalarEvolutionNormalization, so that I can change
ScalarEvolutionNormalization to use SCEVRewriteVisitor in a next step.

This is a non-functional change, but _may_ improve performance in some
pathological cases, but that's unlikely.

llvm-svn: 300348

llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h

index fdcd8be..1cee5d0 100644 (file)
@@ -595,58 +595,82 @@ namespace llvm {
 
     const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
       const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
-      return SE.getTruncateExpr(Operand, Expr->getType());
+      return Operand == Expr->getOperand()
+                 ? Expr
+                 : SE.getTruncateExpr(Operand, Expr->getType());
     }
 
     const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
       const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
-      return SE.getZeroExtendExpr(Operand, Expr->getType());
+      return Operand == Expr->getOperand()
+                 ? Expr
+                 : SE.getZeroExtendExpr(Operand, Expr->getType());
     }
 
     const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
       const SCEV *Operand = ((SC*)this)->visit(Expr->getOperand());
-      return SE.getSignExtendExpr(Operand, Expr->getType());
+      return Operand == Expr->getOperand()
+                 ? Expr
+                 : SE.getSignExtendExpr(Operand, Expr->getType());
     }
 
     const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
       SmallVector<const SCEV *, 2> Operands;
-      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      bool Changed = false;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
         Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
-      return SE.getAddExpr(Operands);
+        Changed |= Expr->getOperand(i) != Operands.back();
+      }
+      return !Changed ? Expr : SE.getAddExpr(Operands);
     }
 
     const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
       SmallVector<const SCEV *, 2> Operands;
-      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      bool Changed = false;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
         Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
-      return SE.getMulExpr(Operands);
+        Changed |= Expr->getOperand(i) != Operands.back();
+      }
+      return !Changed ? Expr : SE.getMulExpr(Operands);
     }
 
     const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
-      return SE.getUDivExpr(((SC*)this)->visit(Expr->getLHS()),
-                            ((SC*)this)->visit(Expr->getRHS()));
+      auto *LHS = ((SC *)this)->visit(Expr->getLHS());
+      auto *RHS = ((SC *)this)->visit(Expr->getRHS());
+      bool Changed = LHS != Expr->getLHS() || RHS != Expr->getRHS();
+      return !Changed ? Expr : SE.getUDivExpr(LHS, RHS);
     }
 
     const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
       SmallVector<const SCEV *, 2> Operands;
-      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      bool Changed = false;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
         Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
-      return SE.getAddRecExpr(Operands, Expr->getLoop(),
-                              Expr->getNoWrapFlags());
+        Changed |= Expr->getOperand(i) != Operands.back();
+      }
+      return !Changed ? Expr
+                      : SE.getAddRecExpr(Operands, Expr->getLoop(),
+                                         Expr->getNoWrapFlags());
     }
 
     const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
       SmallVector<const SCEV *, 2> Operands;
-      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
-        Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
-      return SE.getSMaxExpr(Operands);
+      bool Changed = false;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
+        Operands.push_back(((SC *)this)->visit(Expr->getOperand(i)));
+        Changed |= Expr->getOperand(i) != Operands.back();
+      }
+      return !Changed ? Expr : SE.getSMaxExpr(Operands);
     }
 
     const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
       SmallVector<const SCEV *, 2> Operands;
-      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      bool Changed = false;
+      for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
         Operands.push_back(((SC*)this)->visit(Expr->getOperand(i)));
-      return SE.getUMaxExpr(Operands);
+        Changed |= Expr->getOperand(i) != Operands.back();
+      }
+      return !Changed ? Expr : SE.getUMaxExpr(Operands);
     }
 
     const SCEV *visitUnknown(const SCEVUnknown *Expr) {