зеркало из https://github.com/microsoft/clang-1.git
Change the interface to ConstantFoldsToSimpleInteger to not encode
a bool + success into one tri-state integer, simplifying things. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126592 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a02411e4d5
Коммит
c2c90011a6
|
@ -1715,10 +1715,10 @@ EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
|
|||
}
|
||||
|
||||
const Expr *condExpr = expr->getCond();
|
||||
|
||||
if (int condValue = ConstantFoldsToSimpleInteger(condExpr)) {
|
||||
bool CondExprBool;
|
||||
if (ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
|
||||
const Expr *live = expr->getTrueExpr(), *dead = expr->getFalseExpr();
|
||||
if (condValue == -1) std::swap(live, dead);
|
||||
if (!CondExprBool) std::swap(live, dead);
|
||||
|
||||
if (!ContainsLabel(dead))
|
||||
return EmitLValue(live);
|
||||
|
|
|
@ -2257,8 +2257,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
|
|||
|
||||
// If we have 0 && RHS, see if we can elide RHS, if so, just return 0.
|
||||
// If we have 1 && X, just emit X without inserting the control flow.
|
||||
if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) {
|
||||
if (Cond == 1) { // If we have 1 && X, just emit X.
|
||||
bool LHSCondVal;
|
||||
if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
|
||||
if (LHSCondVal) { // If we have 1 && X, just emit X.
|
||||
Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
|
||||
// ZExt result to int or bool.
|
||||
return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
|
||||
|
@ -2309,8 +2310,9 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
|
|||
|
||||
// If we have 1 || RHS, see if we can elide RHS, if so, just return 1.
|
||||
// If we have 0 || X, just emit X without inserting the control flow.
|
||||
if (int Cond = CGF.ConstantFoldsToSimpleInteger(E->getLHS())) {
|
||||
if (Cond == -1) { // If we have 0 || X, just emit X.
|
||||
bool LHSCondVal;
|
||||
if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
|
||||
if (!LHSCondVal) { // If we have 0 || X, just emit X.
|
||||
Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
|
||||
// ZExt result to int or bool.
|
||||
return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
|
||||
|
@ -2409,9 +2411,10 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
|
|||
|
||||
// If the condition constant folds and can be elided, try to avoid emitting
|
||||
// the condition and the dead arm.
|
||||
if (int Cond = CGF.ConstantFoldsToSimpleInteger(condExpr)){
|
||||
bool CondExprBool;
|
||||
if (CGF.ConstantFoldsToSimpleInteger(condExpr, CondExprBool)) {
|
||||
Expr *live = lhsExpr, *dead = rhsExpr;
|
||||
if (Cond == -1) std::swap(live, dead);
|
||||
if (!CondExprBool) std::swap(live, dead);
|
||||
|
||||
// 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
|
||||
|
|
|
@ -359,10 +359,12 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
|
|||
|
||||
// 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())) {
|
||||
bool CondConstant;
|
||||
if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant)) {
|
||||
// Figure out which block (then or else) is executed.
|
||||
const Stmt *Executed = S.getThen(), *Skipped = S.getElse();
|
||||
if (Cond == -1) // Condition false?
|
||||
const Stmt *Executed = S.getThen();
|
||||
const Stmt *Skipped = S.getElse();
|
||||
if (!CondConstant) // Condition false?
|
||||
std::swap(Executed, Skipped);
|
||||
|
||||
// If the skipped block has no labels in it, just emit the executed block.
|
||||
|
|
|
@ -408,22 +408,23 @@ bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
|
|||
}
|
||||
|
||||
|
||||
/// 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) {
|
||||
/// ConstantFoldsToSimpleInteger - If the specified expression does not fold
|
||||
/// to a constant, or if it does but contains a label, return false. If it
|
||||
/// constant folds return true and set the boolean result in Result.
|
||||
bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
|
||||
bool &ResultBool) {
|
||||
// FIXME: Rename and handle conversion of other evaluatable things
|
||||
// to bool.
|
||||
Expr::EvalResult Result;
|
||||
if (!Cond->Evaluate(Result, getContext()) || !Result.Val.isInt() ||
|
||||
Result.HasSideEffects)
|
||||
return 0; // Not foldable, not integer or not fully evaluatable.
|
||||
return false; // Not foldable, not integer or not fully evaluatable.
|
||||
|
||||
if (CodeGenFunction::ContainsLabel(Cond))
|
||||
return 0; // Contains a label.
|
||||
return false; // Contains a label.
|
||||
|
||||
return Result.Val.getInt().getBoolValue() ? 1 : -1;
|
||||
ResultBool = Result.Val.getInt().getBoolValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -442,14 +443,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
|
|||
if (CondBOp->getOpcode() == BO_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) {
|
||||
bool ConstantBool;
|
||||
if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
|
||||
ConstantBool) {
|
||||
// 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) {
|
||||
if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
|
||||
ConstantBool) {
|
||||
// br(X && 1) -> br(X).
|
||||
return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
|
||||
}
|
||||
|
@ -468,17 +472,22 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
|
|||
eval.end(*this);
|
||||
|
||||
return;
|
||||
} else if (CondBOp->getOpcode() == BO_LOr) {
|
||||
}
|
||||
|
||||
if (CondBOp->getOpcode() == BO_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) {
|
||||
bool ConstantBool;
|
||||
if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
|
||||
!ConstantBool) {
|
||||
// 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) {
|
||||
if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
|
||||
!ConstantBool) {
|
||||
// br(X || 0) -> br(X).
|
||||
return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
|
||||
}
|
||||
|
|
|
@ -2045,10 +2045,9 @@ public:
|
|||
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts = false);
|
||||
|
||||
/// ConstantFoldsToSimpleInteger - If the specified 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);
|
||||
/// to a constant, or if it does but contains a label, return false. If it
|
||||
/// constant folds return true and set the boolean result in Result.
|
||||
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result);
|
||||
|
||||
/// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
|
||||
/// if statement) to the specified blocks. Based on the condition, this might
|
||||
|
|
Загрузка…
Ссылка в новой задаче