Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
+ if (llvm::ConstantInt *LHSCst = dyn_cast<llvm::ConstantInt>(LHSCond)) {
+ // If we have 0 && RHS, see if we can elide RHS, if so, just return LHSCond.
+ if (LHSCst->getZExtValue() == 0) {
+ if (!CGF.ContainsLabel(E->getRHS()))
+ // Elide RHS, return 0
+ return llvm::Constant::getNullValue(CGF.LLVMIntTy);
+ } else {
+ // If we have 1 && X, just emit X without inserting the control flow.
+ Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+ // ZExt result to int.
+ return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "land.ext");
+ }
+ }
+
llvm::BasicBlock *ContBlock = llvm::BasicBlock::Create("land_cont");
llvm::BasicBlock *RHSBlock = llvm::BasicBlock::Create("land_rhs");
Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
Value *LHSCond = CGF.EvaluateExprAsBool(E->getLHS());
+ if (llvm::ConstantInt *LHSCst = dyn_cast<llvm::ConstantInt>(LHSCond)) {
+ // If we have 1 || RHS, see if we can elide RHS, if so, just return LHSCond.
+ if (LHSCst->getZExtValue() != 0) {
+ if (!CGF.ContainsLabel(E->getRHS()))
+ // Elide RHS, return 1
+ return llvm::ConstantInt::get(CGF.LLVMIntTy, 1);
+ } else {
+ // If we have 0 || X, just emit X without inserting the control flow.
+ Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
+ // ZExt result to int.
+ return Builder.CreateZExt(RHSCond, CGF.LLVMIntTy, "lor.ext");
+ }
+ }
+
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor_cont");
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor_rhs");
EmitDummyBlock();
}
-/// ContainsLabel - Return true if the statement contains a label in it. If
-/// this statement is not executed normally, it not containing a label means
-/// that we can just remove the code.
-static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false) {
- // If this is a label, we have to emit the code, consider something like:
- // if (0) { ... foo: bar(); } goto foo;
- if (isa<LabelStmt>(S))
- return true;
-
- // If this is a case/default statement, and we haven't seen a switch, we have
- // to emit the code.
- if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
- return true;
-
- // If this is a switch statement, we want to ignore cases below it.
- if (isa<SwitchStmt>(S))
- IgnoreCaseStmts = true;
-
- // Scan subexpressions for verboten labels.
- for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
- I != E; ++I)
- if (ContainsLabel(*I, IgnoreCaseStmts))
- return true;
-
- return false;
-}
-
-
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.
return false;
}
+/// ContainsLabel - Return true if the statement contains a label in it. If
+/// this statement is not executed normally, it not containing a label means
+/// that we can just remove the code.
+bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
+ // Null statement, not a label!
+ if (S == 0) return false;
+
+ // If this is a label, we have to emit the code, consider something like:
+ // if (0) { ... foo: bar(); } goto foo;
+ if (isa<LabelStmt>(S))
+ return true;
+
+ // If this is a case/default statement, and we haven't seen a switch, we have
+ // to emit the code.
+ if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
+ return true;
+
+ // If this is a switch statement, we want to ignore cases below it.
+ if (isa<SwitchStmt>(S))
+ IgnoreCaseStmts = true;
+
+ // Scan subexpressions for verboten labels.
+ for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
+ I != E; ++I)
+ if (ContainsLabel(*I, IgnoreCaseStmts))
+ return true;
+
+ return false;
+}
+
/// getCGRecordLayout - Return record layout info.
const CGRecordLayout *CodeGenFunction::getCGRecordLayout(CodeGenTypes &CGT,
QualType Ty) {
// Internal Helpers
//===--------------------------------------------------------------------===//
+ /// ContainsLabel - Return true if the statement contains a label in it. If
+ /// this statement is not executed normally, it not containing a label means
+ /// that we can just remove the code.
+ static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
+
private:
+
/// EmitIndirectSwitches - Emit code for all of the switch
/// instructions in IndirectSwitches.
void EmitIndirectSwitches();