aboutsummaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
authorRoman Rusyaev <rusyaev.rm@gmail.com>2022-07-26 18:56:04 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2022-07-26 18:57:10 +0800
commitfec5ff2a3230ac9214891879e97b67dd6db833ed (patch)
tree73900b3b45ffc0c4095544f4b5a8563de27fbc60 /clang/include
parentbf759e3b10386adc6734f4def5e3c343f8fbbd50 (diff)
downloadllvm-fec5ff2a3230ac9214891879e97b67dd6db833ed.zip
llvm-fec5ff2a3230ac9214891879e97b67dd6db833ed.tar.gz
llvm-fec5ff2a3230ac9214891879e97b67dd6db833ed.tar.bz2
[Clang] [P2025] Analyze only potential scopes for NRVO
Before the patch we calculated the NRVO candidate looking at the variable's whole enclosing scope. The research in [P2025] shows that looking at the variable's potential scope is better and covers more cases where NRVO would be safe and desirable. Many thanks to @Izaron for the original implementation. Reviewed By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D119792
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/Sema/Scope.h38
1 files changed, 19 insertions, 19 deletions
diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h
index f4c5086..3749d92 100644
--- a/clang/include/clang/Sema/Scope.h
+++ b/clang/include/clang/Sema/Scope.h
@@ -210,9 +210,19 @@ private:
/// Used to determine if errors occurred in this scope.
DiagnosticErrorTrap ErrorTrap;
- /// A lattice consisting of undefined, a single NRVO candidate variable in
- /// this scope, or over-defined. The bit is true when over-defined.
- llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
+ /// A single NRVO candidate variable in this scope.
+ /// There are three possible values:
+ /// 1) pointer to VarDecl that denotes NRVO candidate itself.
+ /// 2) nullptr value means that NRVO is not allowed in this scope
+ /// (e.g. return a function parameter).
+ /// 3) None value means that there is no NRVO candidate in this scope
+ /// (i.e. there are no return statements in this scope).
+ Optional<VarDecl *> NRVO;
+
+ /// Represents return slots for NRVO candidates in the current scope.
+ /// If a variable is present in this set, it means that a return slot is
+ /// available for this variable in the current scope.
+ llvm::SmallPtrSet<VarDecl *, 8> ReturnSlots;
void setFlags(Scope *Parent, unsigned F);
@@ -304,6 +314,10 @@ public:
bool decl_empty() const { return DeclsInScope.empty(); }
void AddDecl(Decl *D) {
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ if (!isa<ParmVarDecl>(VD))
+ ReturnSlots.insert(VD);
+
DeclsInScope.insert(D);
}
@@ -527,23 +541,9 @@ public:
UsingDirectives.end());
}
- void addNRVOCandidate(VarDecl *VD) {
- if (NRVO.getInt())
- return;
- if (NRVO.getPointer() == nullptr) {
- NRVO.setPointer(VD);
- return;
- }
- if (NRVO.getPointer() != VD)
- setNoNRVO();
- }
-
- void setNoNRVO() {
- NRVO.setInt(true);
- NRVO.setPointer(nullptr);
- }
+ void updateNRVOCandidate(VarDecl *VD);
- void mergeNRVOIntoParent();
+ void applyNRVO();
/// Init - This is used by the parser to implement scope caching.
void Init(Scope *parent, unsigned flags);