summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2020-01-22 02:50:12 +0200
committerSaar Raz <saar@raz.email>2020-01-24 02:28:26 +0200
commit62709e7e49aacfc591c5f4e05be8216a0111c159 (patch)
tree5882a18509dc84cf25cbc710cad555196a559c03 /clang/lib/Sema
parentb597c9e46cb5993edbb872586022dd9ca36cfd8d (diff)
downloadbcm5719-llvm-62709e7e49aacfc591c5f4e05be8216a0111c159.tar.gz
bcm5719-llvm-62709e7e49aacfc591c5f4e05be8216a0111c159.zip
[Concepts] Constraint Satisfaction Caching
Add a simple cache for constraint satisfaction results. Whether or not this simple caching would be permitted in final C++2a is currently being discussed but it is required for acceptable performance so we use it in the meantime, with the possibility of adding some cache invalidation mechanisms later. Differential Revision: https://reviews.llvm.org/D72552 (cherry picked from commit b933d37cd3774e5431b35e82187eebb59b1ff59e)
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/Sema.cpp16
-rwxr-xr-xclang/lib/Sema/SemaConcept.cpp76
2 files changed, 60 insertions, 32 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index f8da1cb89b9..7eb8c8d2f76 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -153,10 +153,10 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TUKind(TUKind), NumSFINAEErrors(0),
FullyCheckedComparisonCategories(
static_cast<unsigned>(ComparisonCategoryType::Last) + 1),
- AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
- NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
- CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
- TyposCorrected(0), AnalysisWarnings(*this),
+ SatisfactionCache(Context), AccessCheckingSFINAE(false),
+ InNonInstantiationSFINAEContext(false), NonInstantiationEntries(0),
+ ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(nullptr),
+ DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this),
ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr),
CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) {
TUScope = nullptr;
@@ -379,6 +379,14 @@ Sema::~Sema() {
if (isMultiplexExternalSource)
delete ExternalSource;
+ // Delete cached satisfactions.
+ std::vector<ConstraintSatisfaction *> Satisfactions;
+ Satisfactions.reserve(Satisfactions.size());
+ for (auto &Node : SatisfactionCache)
+ Satisfactions.push_back(&Node);
+ for (auto *Node : Satisfactions)
+ delete Node;
+
threadSafety::threadSafetyCleanup(ThreadSafetyDeclCache);
// Destroys data sharing attributes stack for OpenMP
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 93e5b4511da..81601b09ce0 100755
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -272,36 +272,56 @@ static bool CheckConstraintSatisfaction(Sema &S, TemplateDeclT *Template,
return false;
}
-bool Sema::CheckConstraintSatisfaction(TemplateDecl *Template,
- ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange,
- ConstraintSatisfaction &Satisfaction) {
- return ::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
- TemplateArgs, TemplateIDRange,
- Satisfaction);
-}
+bool Sema::CheckConstraintSatisfaction(
+ NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs,
+ ArrayRef<TemplateArgument> TemplateArgs, SourceRange TemplateIDRange,
+ ConstraintSatisfaction &OutSatisfaction) {
+ if (ConstraintExprs.empty()) {
+ OutSatisfaction.IsSatisfied = true;
+ return false;
+ }
-bool
-Sema::CheckConstraintSatisfaction(ClassTemplatePartialSpecializationDecl* Part,
- ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange,
- ConstraintSatisfaction &Satisfaction) {
- return ::CheckConstraintSatisfaction(*this, Part, ConstraintExprs,
- TemplateArgs, TemplateIDRange,
- Satisfaction);
-}
+ llvm::FoldingSetNodeID ID;
+ void *InsertPos;
+ ConstraintSatisfaction *Satisfaction = nullptr;
+ if (LangOpts.ConceptSatisfactionCaching) {
+ ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
+ Satisfaction = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos);
+ if (Satisfaction) {
+ OutSatisfaction = *Satisfaction;
+ return false;
+ }
+ Satisfaction = new ConstraintSatisfaction(Template, TemplateArgs);
+ } else {
+ Satisfaction = &OutSatisfaction;
+ }
+ bool Failed;
+ if (auto *T = dyn_cast<TemplateDecl>(Template))
+ Failed = ::CheckConstraintSatisfaction(*this, T, ConstraintExprs,
+ TemplateArgs, TemplateIDRange,
+ *Satisfaction);
+ else if (auto *P =
+ dyn_cast<ClassTemplatePartialSpecializationDecl>(Template))
+ Failed = ::CheckConstraintSatisfaction(*this, P, ConstraintExprs,
+ TemplateArgs, TemplateIDRange,
+ *Satisfaction);
+ else
+ Failed = ::CheckConstraintSatisfaction(
+ *this, cast<VarTemplatePartialSpecializationDecl>(Template),
+ ConstraintExprs, TemplateArgs, TemplateIDRange, *Satisfaction);
+ if (Failed) {
+ if (LangOpts.ConceptSatisfactionCaching)
+ delete Satisfaction;
+ return true;
+ }
-bool
-Sema::CheckConstraintSatisfaction(VarTemplatePartialSpecializationDecl* Partial,
- ArrayRef<const Expr *> ConstraintExprs,
- ArrayRef<TemplateArgument> TemplateArgs,
- SourceRange TemplateIDRange,
- ConstraintSatisfaction &Satisfaction) {
- return ::CheckConstraintSatisfaction(*this, Partial, ConstraintExprs,
- TemplateArgs, TemplateIDRange,
- Satisfaction);
+ if (LangOpts.ConceptSatisfactionCaching) {
+ // We cannot use InsertNode here because CheckConstraintSatisfaction might
+ // have invalidated it.
+ SatisfactionCache.InsertNode(Satisfaction);
+ OutSatisfaction = *Satisfaction;
+ }
+ return false;
}
bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
OpenPOWER on IntegriCloud