summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-06-23 19:16:49 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-06-23 19:16:49 +0000
commitb130fe7d316efb01870e99912d58ea7c5a11a329 (patch)
tree4c4b0d9f45a07ef00c65f01b8a375ab693c7be77 /clang/lib/CodeGen
parentfe1397b97716de33571563c6e7b3bdf2d7a28148 (diff)
downloadbcm5719-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.cpp5
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp12
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h8
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.
OpenPOWER on IntegriCloud