efriedma created this revision. efriedma added a reviewer: nickdesaulniers. Herald added a project: clang.
Just a proof of concept to show this works. Handles all the examples from D76096 <https://reviews.llvm.org/D76096>, as far as I can tell. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D76169 Files: clang/lib/AST/ExprConstant.cpp clang/lib/CodeGen/CGExprConstant.cpp Index: clang/lib/CodeGen/CGExprConstant.cpp =================================================================== --- clang/lib/CodeGen/CGExprConstant.cpp +++ clang/lib/CodeGen/CGExprConstant.cpp @@ -2084,8 +2084,7 @@ case APValue::Union: return ConstStructBuilder::BuildStruct(*this, Value, DestType); case APValue::Array: { - const ConstantArrayType *CAT = - CGM.getContext().getAsConstantArrayType(DestType); + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); unsigned NumElements = Value.getArraySize(); unsigned NumInitElts = Value.getArrayInitializedElts(); @@ -2093,7 +2092,7 @@ llvm::Constant *Filler = nullptr; if (Value.hasArrayFiller()) { Filler = tryEmitAbstractForMemory(Value.getArrayFiller(), - CAT->getElementType()); + AT->getElementType()); if (!Filler) return nullptr; } @@ -2108,7 +2107,7 @@ llvm::Type *CommonElementType = nullptr; for (unsigned I = 0; I < NumInitElts; ++I) { llvm::Constant *C = tryEmitPrivateForMemory( - Value.getArrayInitializedElt(I), CAT->getElementType()); + Value.getArrayInitializedElt(I), AT->getElementType()); if (!C) return nullptr; if (I == 0) @@ -2120,6 +2119,8 @@ // This means that the array type is probably "IncompleteType" or some // type that is not ConstantArray. + const ConstantArrayType *CAT = + CGM.getContext().getAsConstantArrayType(DestType); if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -13740,14 +13740,6 @@ return true; } - // FIXME: Evaluating values of large array and record types can cause - // performance problems. Only do so in C++11 for now. - if (Exp->isRValue() && (Exp->getType()->isArrayType() || - Exp->getType()->isRecordType()) && - !Ctx.getLangOpts().CPlusPlus11) { - IsConst = false; - return true; - } return false; } @@ -13913,12 +13905,6 @@ assert(!isValueDependent() && "Expression evaluator can't be called on a dependent expression."); - // FIXME: Evaluating initializers for large array and record types can cause - // performance problems. Only do so in C++11 for now. - if (isRValue() && (getType()->isArrayType() || getType()->isRecordType()) && - !Ctx.getLangOpts().CPlusPlus11) - return false; - Expr::EvalStatus EStatus; EStatus.Diag = &Notes;
Index: clang/lib/CodeGen/CGExprConstant.cpp =================================================================== --- clang/lib/CodeGen/CGExprConstant.cpp +++ clang/lib/CodeGen/CGExprConstant.cpp @@ -2084,8 +2084,7 @@ case APValue::Union: return ConstStructBuilder::BuildStruct(*this, Value, DestType); case APValue::Array: { - const ConstantArrayType *CAT = - CGM.getContext().getAsConstantArrayType(DestType); + const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); unsigned NumElements = Value.getArraySize(); unsigned NumInitElts = Value.getArrayInitializedElts(); @@ -2093,7 +2092,7 @@ llvm::Constant *Filler = nullptr; if (Value.hasArrayFiller()) { Filler = tryEmitAbstractForMemory(Value.getArrayFiller(), - CAT->getElementType()); + AT->getElementType()); if (!Filler) return nullptr; } @@ -2108,7 +2107,7 @@ llvm::Type *CommonElementType = nullptr; for (unsigned I = 0; I < NumInitElts; ++I) { llvm::Constant *C = tryEmitPrivateForMemory( - Value.getArrayInitializedElt(I), CAT->getElementType()); + Value.getArrayInitializedElt(I), AT->getElementType()); if (!C) return nullptr; if (I == 0) @@ -2120,6 +2119,8 @@ // This means that the array type is probably "IncompleteType" or some // type that is not ConstantArray. + const ConstantArrayType *CAT = + CGM.getContext().getAsConstantArrayType(DestType); if (CAT == nullptr && CommonElementType == nullptr && !NumInitElts) { const ArrayType *AT = CGM.getContext().getAsArrayType(DestType); CommonElementType = CGM.getTypes().ConvertType(AT->getElementType()); Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -13740,14 +13740,6 @@ return true; } - // FIXME: Evaluating values of large array and record types can cause - // performance problems. Only do so in C++11 for now. - if (Exp->isRValue() && (Exp->getType()->isArrayType() || - Exp->getType()->isRecordType()) && - !Ctx.getLangOpts().CPlusPlus11) { - IsConst = false; - return true; - } return false; } @@ -13913,12 +13905,6 @@ assert(!isValueDependent() && "Expression evaluator can't be called on a dependent expression."); - // FIXME: Evaluating initializers for large array and record types can cause - // performance problems. Only do so in C++11 for now. - if (isRValue() && (getType()->isArrayType() || getType()->isRecordType()) && - !Ctx.getLangOpts().CPlusPlus11) - return false; - Expr::EvalStatus EStatus; EStatus.Diag = &Notes;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits