[cfe-commits] r59113 - in /cfe/trunk/lib/CodeGen: CGExprScalar.cpp CGStmt.cpp CodeGenFunction.cpp CodeGenFunction.h
Chris Lattner
sabre at nondot.org
Wed Nov 12 00:04:59 PST 2008
Author: lattner
Date: Wed Nov 12 02:04:58 2008
New Revision: 59113
URL: http://llvm.org/viewvc/llvm-project?rev=59113&view=rev
Log:
Move EmitBranchOnBoolExpr and ConstantFoldsToSimpleInteger to
CodeGenFunction.cpp. Change VisitConditionalOperator to use
constant fold instead of codegen'ing a constant conditional.
Change ForStmt to use EmitBranchOnBoolExpr, this shrinks
expr.c very slightly to 40239 lines.
Modified:
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=59113&r1=59112&r2=59113&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Nov 12 02:04:58 2008
@@ -1111,31 +1111,29 @@
Value *ScalarExprEmitter::
VisitConditionalOperator(const ConditionalOperator *E) {
- // Evaluate the conditional, then convert it to bool. We do this explicitly
- // because we need the unconverted value if this is a GNU ?: expression with
- // missing middle value.
- Value *CondVal = CGF.EmitScalarExpr(E->getCond());
-
- // If the condition folded to a constant, try to elide the dead side. We
- // can't do this if the dead side contains a label.
- if (llvm::ConstantInt *CondCI = dyn_cast<llvm::ConstantInt>(CondVal)) {
+ // If the condition constant folds and can be elided, try to avoid emitting
+ // the condition and the dead arm.
+ if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getCond())){
Expr *Live = E->getLHS(), *Dead = E->getRHS();
- if (CondCI->isZero())
+ if (Cond == -1)
std::swap(Live, Dead);
- if (!Dead || !CGF.ContainsLabel(Dead)) {
- // Emit the live side.
- if (Live)
- return Visit(Live);
- // Perform promotions, to handle cases like "short ?: int"
- return EmitScalarConversion(CondVal, E->getCond()->getType(),
- E->getType());
- }
+
+ // If the dead side doesn't have labels we need, and if the Live side isn't
+ // the gnu missing ?: extension (which we could handle, but don't bother
+ // to), just emit the Live part.
+ if ((!Dead || !CGF.ContainsLabel(Dead)) && // No labels in dead part
+ Live) // Live part isn't missing.
+ return Visit(Live);
}
llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.?");
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.:");
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.cont");
-
+
+ // Evaluate the conditional, then convert it to bool. We do this explicitly
+ // because we need the unconverted value if this is a GNU ?: expression with
+ // missing middle value.
+ Value *CondVal = CGF.EmitScalarExpr(E->getCond());
Value *CondBoolVal =CGF.EmitScalarConversion(CondVal, E->getCond()->getType(),
CGF.getContext().BoolTy);
Builder.CreateCondBr(CondBoolVal, LHSBlock, RHSBlock);
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=59113&r1=59112&r2=59113&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Nov 12 02:04:58 2008
@@ -14,7 +14,6 @@
#include "CGDebugInfo.h"
#include "CodeGenModule.h"
#include "CodeGenFunction.h"
-#include "clang/AST/APValue.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/InlineAsm.h"
@@ -224,98 +223,13 @@
Builder.ClearInsertionPoint();
}
-
-/// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to
-/// a constant, or if it does but contains a label, return 0. If it constant
-/// folds to 'true' and does not contain a label, return 1, if it constant folds
-/// to 'false' and does not contain a label, return -1.
-static int ConstantFoldsToSimpleInteger(const Expr *Cond, ASTContext &Ctx) {
- APValue V;
- if (!Cond->tryEvaluate(V, Ctx))
- return 0; // Not foldable.
-
- if (CodeGenFunction::ContainsLabel(Cond))
- return 0; // Contains a label.
-
- return V.getInt().getBoolValue() ? 1 : -1;
-}
-
-
-/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
-/// statement) to the specified blocks. Based on the condition, this might try
-/// to simplify the codegen of the conditional based on the branch.
-///
-void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
- llvm::BasicBlock *TrueBlock,
- llvm::BasicBlock *FalseBlock) {
- if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
- return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
-
- if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
- // Handle X && Y in a condition.
- if (CondBOp->getOpcode() == BinaryOperator::LAnd) {
- // If we have "1 && X", simplify the code. "0 && X" would have constant
- // folded if the case was simple enough.
- if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), getContext()) == 1) {
- // br(1 && X) -> br(X).
- return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
- }
-
- // If we have "X && 1", simplify the code to use an uncond branch.
- // "X && 0" would have been constant folded to 0.
- if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), getContext()) == 1) {
- // br(X && 1) -> br(X).
- return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
- }
-
- // Emit the LHS as a conditional. If the LHS conditional is false, we
- // want to jump to the FalseBlock.
- llvm::BasicBlock *LHSTrue = createBasicBlock("land_lhs_true");
- EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
- EmitBlock(LHSTrue);
-
- EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
- return;
- } else if (CondBOp->getOpcode() == BinaryOperator::LOr) {
- // If we have "0 || X", simplify the code. "1 || X" would have constant
- // folded if the case was simple enough.
- if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), getContext()) == -1) {
- // br(0 || X) -> br(X).
- return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
- }
-
- // If we have "X || 0", simplify the code to use an uncond branch.
- // "X || 1" would have been constant folded to 1.
- if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), getContext()) == -1) {
- // br(X || 0) -> br(X).
- return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
- }
-
- // Emit the LHS as a conditional. If the LHS conditional is true, we
- // want to jump to the TrueBlock.
- llvm::BasicBlock *LHSFalse = createBasicBlock("lor_lhs_false");
- EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
- EmitBlock(LHSFalse);
-
- EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
- return;
- }
-
- }
-
- // Emit the code with the fully general case.
- llvm::Value *CondV = EvaluateExprAsBool(Cond);
- Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
-}
-
-
void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// C99 6.8.4.1: The first substatement is executed if the expression compares
// unequal to 0. The condition must be a scalar type.
// If the condition constant folds and can be elided, try to avoid emitting
// the condition and the dead arm of the if/else.
- if (int Cond = ConstantFoldsToSimpleInteger(S.getCond(), getContext())) {
+ if (int Cond = ConstantFoldsToSimpleInteger(S.getCond())) {
// Figure out which block (then or else) is executed.
const Stmt *Executed = S.getThen(), *Skipped = S.getElse();
if (Cond == -1) // Condition false?
@@ -382,7 +296,7 @@
// As long as the condition is true, go to the loop body.
if (EmitBoolCondBranch)
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
-
+
// Store the blocks to use for break and continue.
BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader));
@@ -476,13 +390,13 @@
// Evaluate the condition if present. If not, treat it as a non-zero-constant
// according to 6.8.5.3p2, aka, true.
if (S.getCond()) {
+ // As long as the condition is true, iterate the loop.
+ llvm::BasicBlock *ForBody = createBasicBlock("forbody");
+
// C99 6.8.5p2/p4: The first substatement is executed if the expression
// compares unequal to 0. The condition must be a scalar type.
- llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
+ EmitBranchOnBoolExpr(S.getCond(), ForBody, AfterFor);
- // As long as the condition is true, iterate the loop.
- llvm::BasicBlock *ForBody = createBasicBlock("forbody");
- Builder.CreateCondBr(BoolCondVal, ForBody, AfterFor);
EmitBlock(ForBody);
} else {
// Treat it as a non-zero constant. Don't even create a new block for the
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=59113&r1=59112&r2=59113&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Nov 12 02:04:58 2008
@@ -15,6 +15,7 @@
#include "CodeGenModule.h"
#include "CGDebugInfo.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "llvm/Support/CFG.h"
@@ -186,6 +187,90 @@
return false;
}
+
+/// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold to
+/// a constant, or if it does but contains a label, return 0. If it constant
+/// folds to 'true' and does not contain a label, return 1, if it constant folds
+/// to 'false' and does not contain a label, return -1.
+int CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond) {
+ APValue V;
+ if (!Cond->tryEvaluate(V, getContext()))
+ return 0; // Not foldable.
+
+ if (CodeGenFunction::ContainsLabel(Cond))
+ return 0; // Contains a label.
+
+ return V.getInt().getBoolValue() ? 1 : -1;
+}
+
+
+/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if
+/// statement) to the specified blocks. Based on the condition, this might try
+/// to simplify the codegen of the conditional based on the branch.
+///
+void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
+ llvm::BasicBlock *TrueBlock,
+ llvm::BasicBlock *FalseBlock) {
+ if (const ParenExpr *PE = dyn_cast<ParenExpr>(Cond))
+ return EmitBranchOnBoolExpr(PE->getSubExpr(), TrueBlock, FalseBlock);
+
+ if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
+ // Handle X && Y in a condition.
+ if (CondBOp->getOpcode() == BinaryOperator::LAnd) {
+ // If we have "1 && X", simplify the code. "0 && X" would have constant
+ // folded if the case was simple enough.
+ if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == 1) {
+ // br(1 && X) -> br(X).
+ return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+ }
+
+ // If we have "X && 1", simplify the code to use an uncond branch.
+ // "X && 0" would have been constant folded to 0.
+ if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == 1) {
+ // br(X && 1) -> br(X).
+ return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
+ }
+
+ // Emit the LHS as a conditional. If the LHS conditional is false, we
+ // want to jump to the FalseBlock.
+ llvm::BasicBlock *LHSTrue = createBasicBlock("land_lhs_true");
+ EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
+ EmitBlock(LHSTrue);
+
+ EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+ return;
+ } else if (CondBOp->getOpcode() == BinaryOperator::LOr) {
+ // If we have "0 || X", simplify the code. "1 || X" would have constant
+ // folded if the case was simple enough.
+ if (ConstantFoldsToSimpleInteger(CondBOp->getLHS()) == -1) {
+ // br(0 || X) -> br(X).
+ return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+ }
+
+ // If we have "X || 0", simplify the code to use an uncond branch.
+ // "X || 1" would have been constant folded to 1.
+ if (ConstantFoldsToSimpleInteger(CondBOp->getRHS()) == -1) {
+ // br(X || 0) -> br(X).
+ return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
+ }
+
+ // Emit the LHS as a conditional. If the LHS conditional is true, we
+ // want to jump to the TrueBlock.
+ llvm::BasicBlock *LHSFalse = createBasicBlock("lor_lhs_false");
+ EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
+ EmitBlock(LHSFalse);
+
+ EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+ return;
+ }
+
+ }
+
+ // Emit the code with the fully general case.
+ llvm::Value *CondV = EvaluateExprAsBool(Cond);
+ Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
+}
+
/// getCGRecordLayout - Return record layout info.
const CGRecordLayout *CodeGenFunction::getCGRecordLayout(CodeGenTypes &CGT,
QualType Ty) {
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=59113&r1=59112&r2=59113&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Nov 12 02:04:58 2008
@@ -563,9 +563,19 @@
/// that we can just remove the code.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
-private:
+ /// ConstantFoldsToSimpleInteger - If the sepcified expression does not fold
+ /// to a constant, or if it does but contains a label, return 0. If it
+ /// constant folds to 'true' and does not contain a label, return 1, if it
+ /// constant folds to 'false' and does not contain a label, return -1.
+ int ConstantFoldsToSimpleInteger(const Expr *Cond);
+
+ /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
+ /// if statement) to the specified blocks. Based on the condition, this might
+ /// try to simplify the codegen of the conditional based on the branch.
+ ///
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
- llvm::BasicBlock *FalseBlock);
+ llvm::BasicBlock *FalseBlock);
+private:
/// EmitIndirectSwitches - Emit code for all of the switch
/// instructions in IndirectSwitches.
More information about the cfe-commits
mailing list