diff options
author | Roman Rusyaev <rusyaev.rm@gmail.com> | 2022-07-26 18:56:04 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2022-07-26 18:57:10 +0800 |
commit | fec5ff2a3230ac9214891879e97b67dd6db833ed (patch) | |
tree | 73900b3b45ffc0c4095544f4b5a8563de27fbc60 /clang/include | |
parent | bf759e3b10386adc6734f4def5e3c343f8fbbd50 (diff) | |
download | llvm-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.h | 38 |
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); |