diff options
author | Chris Lattner <sabre@nondot.org> | 2008-11-12 08:55:54 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-11-12 08:55:54 +0000 |
commit | 9802a5173ffd403d9ede2d4b6b6107fa2e220544 (patch) | |
tree | 7c34da80b65d2b7a5b2428914a57034af56d965b /lib/CodeGen/CGExprScalar.cpp | |
parent | f7b5ea9de3d043fa900ab8a8976a4c0eefc233b7 (diff) |
Lower ?: into select when the selected values are cheap and side-effect-free.
This cuts another 200 lines off expr.ll, forming 23 selects.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59124 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index a3964ee2fc..918d3bbde8 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1119,6 +1119,30 @@ Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) { // 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 @@ VisitConditionalOperator(const ConditionalOperator *E) { 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"); |