diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-23 19:16:49 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-23 19:16:49 +0000 |
| commit | b130fe7d316efb01870e99912d58ea7c5a11a329 (patch) | |
| tree | 4c4b0d9f45a07ef00c65f01b8a375ab693c7be77 /clang/lib/CodeGen | |
| parent | fe1397b97716de33571563c6e7b3bdf2d7a28148 (diff) | |
| download | bcm5719-llvm-b130fe7d316efb01870e99912d58ea7c5a11a329.tar.gz bcm5719-llvm-b130fe7d316efb01870e99912d58ea7c5a11a329.zip | |
Implement p0292r2 (constexpr if), a likely C++1z feature.
llvm-svn: 273602
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 8 |
3 files changed, 15 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index ff70bbc866f..9a93fce7b00 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -563,7 +563,8 @@ 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. bool CondConstant; - if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant)) { + if (ConstantFoldsToSimpleInteger(S.getCond(), CondConstant, + S.isConstexpr())) { // Figure out which block (then or else) is executed. const Stmt *Executed = S.getThen(); const Stmt *Skipped = S.getElse(); @@ -572,7 +573,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // If the skipped block has no labels in it, just emit the executed block. // This avoids emitting dead code and simplifies the CFG substantially. - if (!ContainsLabel(Skipped)) { + if (S.isConstexpr() || !ContainsLabel(Skipped)) { if (CondConstant) incrementProfileCounter(&S); if (Executed) { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1d46eea45fd..2dc4c12ce2e 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1107,9 +1107,10 @@ bool CodeGenFunction::containsBreak(const Stmt *S) { /// 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) { + bool &ResultBool, + bool AllowLabels) { llvm::APSInt ResultInt; - if (!ConstantFoldsToSimpleInteger(Cond, ResultInt)) + if (!ConstantFoldsToSimpleInteger(Cond, ResultInt, AllowLabels)) return false; ResultBool = ResultInt.getBoolValue(); @@ -1119,15 +1120,16 @@ bool 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 folded value. -bool CodeGenFunction:: -ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &ResultInt) { +bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, + llvm::APSInt &ResultInt, + bool AllowLabels) { // FIXME: Rename and handle conversion of other evaluatable things // to bool. llvm::APSInt Int; if (!Cond->EvaluateAsInt(Int, getContext())) return false; // Not foldable, not integer or not fully evaluatable. - if (CodeGenFunction::ContainsLabel(Cond)) + if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond)) return false; // Contains a label. ResultInt = Int; diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index b96e6bad8a1..af7e6114af6 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3051,13 +3051,15 @@ public: /// 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 ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result); + bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, + bool AllowLabels = false); /// 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 folded value. - bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result); - + bool ConstantFoldsToSimpleInteger(const Expr *Cond, llvm::APSInt &Result, + bool AllowLabels = false); + /// 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. |

