c2c/IRGenerator/CodeGenFunction.cpp
/// 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.
///
Emit a branch on a boolean condition  to the specified blocks.  Based on the condition, this might try
to simplify the codegen of the conditional based on the branch.
Emit a branch on a boolean condition 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) {
    LOG_FUNC
    if (const BinaryOperator *CondBOp = cast<BinaryOperator>(Cond)) {
        if (CondBOp->getOpcode() == BINOP_LAnd) {
#if 0
            bool ConstantBool = false;
            if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
                    ConstantBool) {
                return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
            }
            if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
                    ConstantBool) {
                return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
            }
#endif
            llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
            ConditionalEvaluation eval(*this);
            EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
            EmitBlock(LHSTrue);
            eval.begin(*this);
            EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
            eval.end(*this);
            return;
        }
        if (CondBOp->getOpcode() == BINOP_LOr) {
#if 0
            bool ConstantBool = false;
            if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
                    !ConstantBool) {
                return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
            }
            if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
                    !ConstantBool) {
                return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
            }
#endif
            llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
            ConditionalEvaluation eval(*this);
            EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
            EmitBlock(LHSFalse);
            eval.begin(*this);
            EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
            eval.end(*this);
            return;
        }
    }
#if 0
    if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
        if (CondUOp->getOpcode() == UO_LNot)
            return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
    }
#endif
#if 0
    if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
        llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
        llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
        ConditionalEvaluation cond(*this);
        EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
        cond.begin(*this);
        EmitBlock(LHSBlock);
        EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
        cond.end(*this);
        cond.begin(*this);
        EmitBlock(RHSBlock);
        EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
        cond.end(*this);
        return;
    }
#endif
    llvm::Value *CondV = EvaluateExprAsBool(Cond);
    Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
}
void CodeGenFunction :: EmitBranchOnBoolExpr ( const Expr * Cond , llvm :: BasicBlock * TrueBlock , llvm :: BasicBlock * FalseBlock ) { LOG_FUNC if ( const BinaryOperator * CondBOp = cast < BinaryOperator > ( Cond ) ) { if ( CondBOp -> getOpcode ( ) == BINOP_LAnd ) { #if 0 bool ConstantBool = false ; if ( ConstantFoldsToSimpleInteger ( CondBOp -> getLHS ( ) , ConstantBool ) && ConstantBool ) { return EmitBranchOnBoolExpr ( CondBOp -> getRHS ( ) , TrueBlock , FalseBlock ) ; } if ( ConstantFoldsToSimpleInteger ( CondBOp -> getRHS ( ) , ConstantBool ) && ConstantBool ) { return EmitBranchOnBoolExpr ( CondBOp -> getLHS ( ) , TrueBlock , FalseBlock ) ; } #endif llvm :: BasicBlock * LHSTrue = createBasicBlock ( " " ) ; ConditionalEvaluation eval ( * this ) ; EmitBranchOnBoolExpr ( CondBOp -> getLHS ( ) , LHSTrue , FalseBlock ) ; EmitBlock ( LHSTrue ) ; eval . begin ( * this ) ; EmitBranchOnBoolExpr ( CondBOp -> getRHS ( ) , TrueBlock , FalseBlock ) ; eval . end ( * this ) ; return ; } if ( CondBOp -> getOpcode ( ) == BINOP_LOr ) { #if 0 bool ConstantBool = false ; if ( ConstantFoldsToSimpleInteger ( CondBOp -> getLHS ( ) , ConstantBool ) && ! ConstantBool ) { return EmitBranchOnBoolExpr ( CondBOp -> getRHS ( ) , TrueBlock , FalseBlock ) ; } if ( ConstantFoldsToSimpleInteger ( CondBOp -> getRHS ( ) , ConstantBool ) && ! ConstantBool ) { return EmitBranchOnBoolExpr ( CondBOp -> getLHS ( ) , TrueBlock , FalseBlock ) ; } #endif llvm :: BasicBlock * LHSFalse = createBasicBlock ( " " ) ; ConditionalEvaluation eval ( * this ) ; EmitBranchOnBoolExpr ( CondBOp -> getLHS ( ) , TrueBlock , LHSFalse ) ; EmitBlock ( LHSFalse ) ; eval . begin ( * this ) ; EmitBranchOnBoolExpr ( CondBOp -> getRHS ( ) , TrueBlock , FalseBlock ) ; eval . end ( * this ) ; return ; } } #if 0 if ( const UnaryOperator * CondUOp = dyn_cast < UnaryOperator > ( Cond ) ) { if ( CondUOp -> getOpcode ( ) == UO_LNot ) return EmitBranchOnBoolExpr ( CondUOp -> getSubExpr ( ) , FalseBlock , TrueBlock ) ; } #endif #if 0 if ( const ConditionalOperator * CondOp = dyn_cast < ConditionalOperator > ( Cond ) ) { llvm :: BasicBlock * LHSBlock = createBasicBlock ( " " ) ; llvm :: BasicBlock * RHSBlock = createBasicBlock ( " " ) ; ConditionalEvaluation cond ( * this ) ; EmitBranchOnBoolExpr ( CondOp -> getCond ( ) , LHSBlock , RHSBlock ) ; cond . begin ( * this ) ; EmitBlock ( LHSBlock ) ; EmitBranchOnBoolExpr ( CondOp -> getLHS ( ) , TrueBlock , FalseBlock ) ; cond . end ( * this ) ; cond . begin ( * this ) ; EmitBlock ( RHSBlock ) ; EmitBranchOnBoolExpr ( CondOp -> getRHS ( ) , TrueBlock , FalseBlock ) ; cond . end ( * this ) ; return ; } #endif llvm :: Value * CondV = EvaluateExprAsBool ( Cond ) ; Builder . CreateCondBr ( CondV , TrueBlock , FalseBlock ) ; }
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
EmitBranchOnBoolExpr - Emit a branch on a boolean condition ( e . g .
//Cond = Cond->IgnoreParens(); // Handle X && Y in a condition. // If we have "1 && X", simplify the code.  "0 && X" would have constant // folded if the case was simple enough. // br(1 && X) -> br(X). // If we have "X && 1", simplify the code to use an uncond branch. // "X && 0" would have been constant folded to 0. // br(X && 1) -> br(X). // Emit the LHS as a conditional.  If the LHS conditional is false, we // want to jump to the FalseBlock. // Any temporaries created here are conditional. // If we have "0 || X", simplify the code.  "1 || X" would have constant // folded if the case was simple enough. // br(0 || X) -> br(X). // If we have "X || 0", simplify the code to use an uncond branch. // "X || 1" would have been constant folded to 1. // br(X || 0) -> br(X). // Emit the LHS as a conditional.  If the LHS conditional is true, we // want to jump to the TrueBlock. // Any temporaries created here are conditional. // br(!x, t, f) -> br(x, f, t) // br(c ? x : y, t, f) -> br(c, br(x, t, f), br(y, t, f)) // Emit the code with the fully general case.