From: Lishin <[email protected]>
Connect the straight-line Drop analysis to the existing backend
cleanup.
Use the BIR analysis result to skip backend Drops for moved locals.
Static and unclassified Drops keep the existing cleanup behavior.
gcc/rust/ChangeLog:
* backend/rust-compile-drop.cc
(CompileDrop::build_current_scope_drop_cleanup): Skip definitely
dead Drop candidates.
* checks/errors/borrowck/rust-bir-drop-analysis.cc
(DropAnalysis::get): New function.
(DropAnalysis::clear): Likewise.
(DropAnalysis::is_definitely_dead): Likewise.
(DropAnalysis::analyze): Record dead whole-local HirIds.
* checks/errors/borrowck/rust-bir-drop-analysis.h
(DropAnalysis::get): New declaration.
(DropAnalysis::clear): Likewise.
(DropAnalysis::is_definitely_dead): Likewise.
(DropAnalysis::definitely_dead): New member.
* checks/errors/borrowck/rust-borrow-checker.cc
(BorrowChecker::go): Clear old Drop analysis results and analyze
each BIR function.
gcc/testsuite/ChangeLog:
* rust/execute/drop-whole-local-move.rs: New test.
Signed-off-by: Lishin <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github: https://github.com/Rust-GCC/gccrs/commit/cccddf6d4c7e56a0926efa7abf41a769d2057b7f
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4748
gcc/rust/backend/rust-compile-drop.cc | 4 ++
.../errors/borrowck/rust-bir-drop-analysis.cc | 36 +++++++++++
.../errors/borrowck/rust-bir-drop-analysis.h | 11 +++-
.../errors/borrowck/rust-borrow-checker.cc | 4 +-
.../rust/execute/drop-whole-local-move.rs | 59 +++++++++++++++++++
5 files changed, 112 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/rust/execute/drop-whole-local-move.rs
diff --git a/gcc/rust/backend/rust-compile-drop.cc b/gcc/rust/backend/rust-compile-drop.cc
index ab63e9751..d6bf79c07 100644
--- a/gcc/rust/backend/rust-compile-drop.cc
+++ b/gcc/rust/backend/rust-compile-drop.cc
@@ -21,6 +21,7 @@
#include "rust-compile-base.h"
#include "rust-compile-context.h"
#include "rust-compile-implitem.h"
+#include "rust-bir-drop-analysis.h"
#include "rust-hir-path-probe.h"
#include "rust-hir-trait-reference.h"
#include "rust-hir-type-bounds.h"
@@ -100,6 +101,9 @@ CompileDrop::build_current_scope_drop_cleanup ()
for (auto it = drop_candidates.rbegin (); it != drop_candidates.rend (); ++it)
{
+ if (BIR::DropAnalysis::get ().is_definitely_dead (it->hirid))
+ continue;
+
TyTy::BaseType *ty = nullptr;
Bvariable *var = nullptr;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc b/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc
index 006b07f22..09301d86e 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.cc
@@ -18,6 +18,7 @@
#include "rust-bir-drop-analysis.h"
#include "rust-bir.h"
+#include "rust-hir-map.h"
#include <unordered_set>
@@ -36,6 +37,25 @@ struct BasicBlockIdHash
} // namespace
+DropAnalysis &
+DropAnalysis::get ()
+{
+ static DropAnalysis instance;
+ return instance;
+}
+
+void
+DropAnalysis::clear ()
+{
+ definitely_dead.clear ();
+}
+
+bool
+DropAnalysis::is_definitely_dead (HirId id) const
+{
+ return definitely_dead.find (id) != definitely_dead.end ();
+}
+
void
DropAnalysis::analyze (Function &function)
{
@@ -106,6 +126,22 @@ DropAnalysis::analyze (Function &function)
? Statement::DropStyle::STATIC
: Statement::DropStyle::DEAD);
+ if (statement.get_drop_style () == Statement::DropStyle::DEAD)
+ {
+ const Place &dropped_place = function.place_db[place];
+
+ if (dropped_place.kind == Place::VARIABLE)
+ {
+ auto hir_id
+ = Analysis::Mappings::get ().lookup_node_to_hir (
+ static_cast<NodeId> (
+ dropped_place.variable_or_field_index));
+
+ if (hir_id.has_value ())
+ definitely_dead.insert (hir_id.value ());
+ }
+ }
+
initialized[place.value] = false;
break;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.h b/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.h
index c6298985a..2a52c1355 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-drop-analysis.h
@@ -20,6 +20,7 @@
#define RUST_BIR_DROP_ANALYSIS_H
#include "rust-bir.h"
+
namespace Rust {
namespace BIR {
@@ -32,7 +33,15 @@ namespace BIR {
class DropAnalysis
{
public:
- static void analyze (Function &function);
+ static DropAnalysis &get ();
+
+ void clear ();
+ void analyze (Function &function);
+
+ bool is_definitely_dead (HirId id) const;
+
+private:
+ std::set<HirId> definitely_dead;
};
} // namespace BIR
diff --git a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
index f93c5595e..ba2b7067d 100644
--- a/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-borrow-checker.cc
@@ -49,6 +49,8 @@ BorrowChecker::go (HIR::Crate &crate)
{
std::string crate_name;
+ BIR::DropAnalysis::get ().clear ();
+
if (enable_dump_bir)
{
mkdir ("bir_dump", 0755);
@@ -70,7 +72,7 @@ BorrowChecker::go (HIR::Crate &crate)
BIR::Builder builder (ctx);
auto bir = builder.build (*func);
- BIR::DropAnalysis::analyze (bir);
+ BIR::DropAnalysis::get ().analyze (bir);
if (enable_dump_bir)
{
diff --git a/gcc/testsuite/rust/execute/drop-whole-local-move.rs b/gcc/testsuite/rust/execute/drop-whole-local-move.rs
new file mode 100644
index 000000000..4bb8ca5bf
--- /dev/null
+++ b/gcc/testsuite/rust/execute/drop-whole-local-move.rs
@@ -0,0 +1,59 @@
+// { dg-output "^moved\r*\nstatic\r*\n$" }
+// { dg-additional-options "-frust-borrowcheck -w" }
+
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "drop"]
+pub trait Drop {
+ fn drop(&mut self);
+}
+
+struct Moved {
+ value: i32,
+}
+
+struct Static {
+ value: i32,
+}
+
+impl Drop for Moved {
+ fn drop(&mut self) {
+ let msg = "moved\n\0" as *const str as *const i8;
+ unsafe {
+ printf(msg);
+ }
+ }
+}
+
+impl Drop for Static {
+ fn drop(&mut self) {
+ let msg = "static\n\0" as *const str as *const i8;
+ unsafe {
+ printf(msg);
+ }
+ }
+}
+
+fn whole_move() {
+ let x = Moved { value: 1 };
+ let _y = x;
+}
+
+fn static_local() {
+ let _x = Static { value: 2 };
+}
+
+fn main() -> i32 {
+ whole_move();
+ static_local();
+ 0
+}
\ No newline at end of file
--
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.