[cfe-commits] r59124 - /cfe/trunk/lib/CodeGen/CGExprScalar.cpp

Chris Lattner sabre at nondot.org
Wed Nov 12 00:55:54 PST 2008


Author: lattner
Date: Wed Nov 12 02:55:54 2008
New Revision: 59124

URL: http://llvm.org/viewvc/llvm-project?rev=59124&view=rev
Log:
Lower ?: into select when the selected values are cheap and side-effect-free.
This cuts another 200 lines off expr.ll, forming 23 selects.

Modified:
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=59124&r1=59123&r2=59124&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Nov 12 02:55:54 2008
@@ -1119,6 +1119,30 @@
 //                             Other Operators
 //===----------------------------------------------------------------------===//
 
+/// isCheapEnoughToEvaluateUnconditionally - Return true if the specified
+/// expression is cheap enough and side-effect-free enough to evaluate
+/// unconditionally instead of conditionally.  This is used to convert control
+/// flow into selects in some cases.
+static bool isCheapEnoughToEvaluateUnconditionally(const Expr *E) {
+  if (const ParenExpr *PE = dyn_cast<ParenExpr>(E))
+    return isCheapEnoughToEvaluateUnconditionally(PE->getSubExpr());
+  
+  // TODO: Allow anything we can constant fold to an integer or fp constant.
+  if (isa<IntegerLiteral>(E) || isa<CharacterLiteral>(E) ||
+      isa<FloatingLiteral>(E))
+    return true;
+  
+  // Non-volatile automatic variables too, to get "cond ? X : Y" where
+  // X and Y are local variables.
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+      if (VD->hasLocalStorage() && !VD->getType().isVolatileQualified())
+        return true;
+  
+  return false;
+}
+
+
 Value *ScalarExprEmitter::
 VisitConditionalOperator(const ConditionalOperator *E) {
   // If the condition constant folds and can be elided, try to avoid emitting
@@ -1136,6 +1160,19 @@
       return Visit(Live);
   }
   
+  
+  // If this is a really simple expression (like x ? 4 : 5), emit this as a
+  // select instead of as control flow.  We can only do this if it is cheap and
+  // safe to 
+  if (E->getLHS() && isCheapEnoughToEvaluateUnconditionally(E->getLHS()) &&
+      isCheapEnoughToEvaluateUnconditionally(E->getRHS())) {
+    llvm::Value *CondV = CGF.EvaluateExprAsBool(E->getCond());
+    llvm::Value *LHS = Visit(E->getLHS());
+    llvm::Value *RHS = Visit(E->getRHS());
+    return Builder.CreateSelect(CondV, LHS, RHS, "cond");
+  }
+  
+  
   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.?");
   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.:");
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.cont");





More information about the cfe-commits mailing list