diff mbox series

[115/125] gccrs: borrowck: BIR: emit moves

Message ID 20240801145809.366388-117-arthur.cohen@embecosm.com
State New
Headers show
Series [001/125] Rust: Make 'tree'-level 'MAIN_NAME_P' work | expand

Commit Message

Arthur Cohen Aug. 1, 2024, 2:57 p.m. UTC
From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit): Emit moves.
	* checks/errors/borrowck/rust-bir-builder-internal.h: Emit moves.
	* checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Emit moves.
	* checks/errors/borrowck/rust-bir-dump.cc (Dump::visit_move_place): Emit moves.
	(Dump::visit): Emit moves.
	* checks/errors/borrowck/rust-bir-place.h (struct Place): Emit moves.
	* checks/errors/borrowck/rust-bir-visitor.h: Emit moves.
	* checks/errors/borrowck/rust-bir.h (enum class): Emit moves.
	(class AbstractExpr): Emit moves.
	(BasicBlock::is_terminated): Emit moves.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 .../borrowck/rust-bir-builder-expr-stmt.cc    | 15 +++--
 .../borrowck/rust-bir-builder-internal.h      | 35 ++++------
 .../borrowck/rust-bir-builder-lazyboolexpr.h  |  2 +-
 .../checks/errors/borrowck/rust-bir-dump.cc   | 11 +++-
 .../checks/errors/borrowck/rust-bir-place.h   | 50 ++++++--------
 .../checks/errors/borrowck/rust-bir-visitor.h |  4 ++
 gcc/rust/checks/errors/borrowck/rust-bir.h    | 66 +++++++++++++------
 7 files changed, 103 insertions(+), 80 deletions(-)
diff mbox series

Patch

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 89352d84f6b..922894cc5d5 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -84,7 +84,7 @@  ExprStmtBuilder::visit (HIR::ClosureExpr &expr)
     {
       captures.push_back (ctx.place_db.lookup_variable (capture));
     }
-  make_args (captures);
+  move_all (captures);
 
   // Note: Not a coercion site for captures.
   return_expr (new InitializerExpr (std::move (captures)), lookup_type (expr));
@@ -96,7 +96,7 @@  ExprStmtBuilder::visit (HIR::StructExprStructFields &fields)
   auto struct_ty
     = lookup_type (fields)->as<TyTy::ADTType> ()->get_variants ().at (0);
   auto init_values = StructBuilder (ctx, struct_ty).build (fields);
-  make_args (init_values);
+  move_all (init_values);
   return_expr (new InitializerExpr (std::move (init_values)),
 	       lookup_type (fields));
 }
@@ -141,7 +141,7 @@  void
 ExprStmtBuilder::visit (HIR::NegationExpr &expr)
 {
   PlaceId operand = visit_expr (*expr.get_expr ());
-  return_expr (new Operator<1> ({make_arg (operand)}), lookup_type (expr));
+  return_expr (new Operator<1> ({move_place (operand)}), lookup_type (expr));
 }
 
 void
@@ -149,7 +149,7 @@  ExprStmtBuilder::visit (HIR::ArithmeticOrLogicalExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ());
-  return_expr (new Operator<2> ({make_arg (lhs), make_arg (rhs)}),
+  return_expr (new Operator<2> ({move_place (lhs), move_place (rhs)}),
 	       lookup_type (expr));
 }
 
@@ -158,7 +158,7 @@  ExprStmtBuilder::visit (HIR::ComparisonExpr &expr)
 {
   PlaceId lhs = visit_expr (*expr.get_lhs ());
   PlaceId rhs = visit_expr (*expr.get_rhs ());
-  return_expr (new Operator<2> ({make_arg (lhs), make_arg (rhs)}),
+  return_expr (new Operator<2> ({move_place (lhs), move_place (rhs)}),
 	       lookup_type (expr));
 }
 
@@ -208,7 +208,7 @@  ExprStmtBuilder::visit (HIR::ArrayExpr &expr)
       case HIR::ArrayElems::VALUES: {
 	auto &elem_vals = (static_cast<HIR::ArrayElemsValues &> (*elems));
 	auto init_values = visit_list (elem_vals.get_values ());
-	make_args (init_values);
+	move_all (init_values);
 	return_expr (new InitializerExpr (std::move (init_values)),
 		     lookup_type (expr));
 	break;
@@ -264,6 +264,7 @@  ExprStmtBuilder::visit (HIR::CallExpr &expr)
       coercion_site (arguments[i], fn_type->get_param_type_at (i));
     }
 
+  move_all (arguments);
   return_expr (new CallExpr (fn, std::move (arguments)), lookup_type (expr),
 	       true);
 }
@@ -502,7 +503,7 @@  ExprStmtBuilder::visit (HIR::IfExpr &expr)
 void
 ExprStmtBuilder::visit (HIR::IfExprConseqElse &expr)
 {
-  push_switch (make_arg (visit_expr (*expr.get_if_condition ())));
+  push_switch (move_place (visit_expr (*expr.get_if_condition ())));
   BasicBlockId if_end_bb = ctx.current_bb;
 
   PlaceId result = take_or_create_return_place (lookup_type (expr));
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
index 55f00aa50ac..b421ba43fba 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h
@@ -230,10 +230,15 @@  protected: // Helpers to add BIR statements
     push_assignment (tmp, rhs);
   }
 
+  void push_tmp_assignment (PlaceId rhs)
+  {
+    push_tmp_assignment (new Assignment (rhs), ctx.place_db[rhs].tyty);
+  }
+
   void push_switch (PlaceId switch_val,
 		    std::initializer_list<BasicBlockId> destinations = {})
   {
-    auto copy = make_arg (switch_val);
+    auto copy = move_place (switch_val);
     ctx.get_current_bb ().statements.emplace_back (Statement::Kind::SWITCH,
 						   copy);
     ctx.get_current_bb ().successors.insert (
@@ -259,33 +264,21 @@  protected: // Helpers to add BIR statements
       Statement::Kind::STORAGE_DEAD, place);
   }
 
-  PlaceId declare_rvalue (PlaceId place)
+  PlaceId move_place (PlaceId arg)
   {
-    ctx.place_db[place].is_rvalue = true;
-    return place;
-  }
-
-  void declare_rvalues (std::vector<PlaceId> &places)
-  {
-    for (auto &place : places)
-      declare_rvalue (place);
-  }
-
-  PlaceId make_arg (PlaceId arg)
-  {
-    auto copy = ctx.place_db.into_rvalue (arg);
-    if (copy != arg)
+    if (ctx.place_db[arg].is_lvalue ())
       {
-	push_storage_live (copy);
-	push_assignment (copy, arg);
+	push_tmp_assignment (arg);
+	arg = translated;
       }
-    return copy;
+
+    return arg;
   }
 
-  void make_args (std::vector<PlaceId> &args)
+  template <typename T> void move_all (T &args)
   {
     std::transform (args.begin (), args.end (), args.begin (),
-		    [this] (PlaceId arg) { return make_arg (arg); });
+		    [this] (PlaceId arg) { return move_place (arg); });
   }
 
 protected: // CFG helpers
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index fb0c75b4f72..1cc55569c7c 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -62,7 +62,7 @@  protected:
   void visit (HIR::LazyBooleanExpr &expr) override
   {
     auto lhs = visit_expr (*expr.get_lhs ());
-    push_switch (make_arg (lhs), {short_circuit_bb});
+    push_switch (move_place (lhs), {short_circuit_bb});
 
     start_new_consecutive_bb ();
     return_place (visit_expr (*expr.get_rhs ()));
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
index 4dea27e3038..320b653f830 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-dump.cc
@@ -241,7 +241,7 @@  void
 Dump::visit_move_place (PlaceId place_id)
 {
   const Place &place = func.place_db[place_id];
-  if (place.is_rvalue || !place.is_copy)
+  if (!place.is_constant ())
     stream << "move ";
   visit_place (place_id);
 }
@@ -325,7 +325,14 @@  Dump::visit (Operator<2> &expr)
 void
 Dump::visit (Assignment &expr)
 {
-  visit_move_place (expr.get_rhs ());
+  if (func.place_db[expr.get_rhs ()].is_rvalue ())
+    {
+      visit_move_place (expr.get_rhs ());
+    }
+  else
+    {
+      visit_place (expr.get_rhs ());
+    }
 }
 
 std::ostream &
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-place.h b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
index 61e90d58d26..546890d797c 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-place.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-place.h
@@ -91,18 +91,26 @@  struct Place
   } path;
   /** Copy trait */
   bool is_copy;
-  /** This place can be moved from safety. */
-  bool is_rvalue;
+  bool has_drop = false;
   Lifetime lifetime;
   TyTy::BaseType *tyty;
 
+public:
   Place (Kind kind, uint32_t variable_or_field_index, const Path &path,
-	 bool is_copy, bool is_rvalue, const Lifetime &lifetime,
-	 TyTy::BaseType *tyty)
+	 bool is_copy, const Lifetime &lifetime, TyTy::BaseType *tyty)
     : kind (kind), variable_or_field_index (variable_or_field_index),
-      path (path), is_copy (is_copy), is_rvalue (is_rvalue),
-      lifetime (lifetime), tyty (tyty)
+      path (path), is_copy (is_copy), lifetime (lifetime), tyty (tyty)
   {}
+
+public:
+  [[nodiscard]] bool is_lvalue () const
+  {
+    return kind == VARIABLE || kind == FIELD || kind == INDEX || kind == DEREF;
+  }
+
+  [[nodiscard]] bool is_rvalue () const { return kind == TEMPORARY; }
+
+  bool is_constant () const { return kind == CONSTANT; }
 };
 
 using ScopeId = uint32_t;
@@ -134,8 +142,7 @@  public:
   PlaceDB ()
   {
     // Reserved index for invalid place.
-    places.push_back (
-      {Place::INVALID, 0, {}, false, false, NO_LIFETIME, nullptr});
+    places.push_back ({Place::INVALID, 0, {}, false, NO_LIFETIME, nullptr});
 
     scopes.emplace_back (); // Root scope.
   }
@@ -193,8 +200,7 @@  public:
   PlaceId add_variable (NodeId id, TyTy::BaseType *tyty)
   {
     return add_place (
-      {Place::VARIABLE, id, {}, is_type_copy (tyty), false, NO_LIFETIME, tyty},
-      0);
+      {Place::VARIABLE, id, {}, is_type_copy (tyty), NO_LIFETIME, tyty}, 0);
   }
 
   WARN_UNUSED_RESULT PlaceId lookup_or_add_path (Place::Kind kind,
@@ -217,15 +223,14 @@  public:
 	  }
       }
     return add_place ({kind, id, Place::Path{parent, 0, 0}, is_type_copy (tyty),
-		       false, NO_LIFETIME, tyty},
+		       NO_LIFETIME, tyty},
 		      current);
   }
 
   PlaceId add_temporary (TyTy::BaseType *tyty)
   {
     return add_place (
-      {Place::TEMPORARY, 0, {}, is_type_copy (tyty), false, NO_LIFETIME, tyty},
-      0);
+      {Place::TEMPORARY, 0, {}, is_type_copy (tyty), NO_LIFETIME, tyty}, 0);
   }
 
   PlaceId get_constant (TyTy::BaseType *tyty)
@@ -235,8 +240,7 @@  public:
       return lookup->second;
     Lifetime lifetime
       = tyty->get_kind () == TyTy::REF ? STATIC_LIFETIME : NO_LIFETIME;
-    Place place
-      = {Place::CONSTANT, 0, {}, is_type_copy (tyty), false, lifetime, tyty};
+    Place place = {Place::CONSTANT, 0, {}, is_type_copy (tyty), lifetime, tyty};
     places.push_back (place);
     return places.size () - 1;
   }
@@ -261,24 +265,10 @@  public:
     if (lookup != INVALID_PLACE)
       return lookup;
     add_place (
-      {Place::VARIABLE, id, {}, is_type_copy (tyty), false, NO_LIFETIME, tyty});
+      {Place::VARIABLE, id, {}, is_type_copy (tyty), NO_LIFETIME, tyty});
     return places.size () - 1;
   };
 
-  PlaceId into_rvalue (PlaceId place)
-  {
-    if (places[place].is_rvalue || places[place].kind == Place::CONSTANT
-	|| places[place].tyty->get_kind () == TyTy::REF)
-      return place;
-    return add_place ({Place::TEMPORARY,
-		       0,
-		       {},
-		       places[place].is_copy,
-		       true,
-		       NO_LIFETIME,
-		       places[place].tyty});
-  }
-
   template <typename FN> void for_each_path_from_root (PlaceId var, FN fn) const
   {
     PlaceId current = var;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h b/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h
index 0b3a4bddbec..7ad62f700db 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-visitor.h
@@ -50,6 +50,10 @@  public:
 template <typename BASE, typename T> class VisitableImpl : public BASE
 {
 public:
+  template <typename... Args>
+  explicit VisitableImpl (Args &&... args) : BASE (std::forward<Args> (args)...)
+  {}
+
   void accept_vis (Visitor &visitor) override
   {
     visitor.visit (static_cast<T &> (*this));
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir.h b/gcc/rust/checks/errors/borrowck/rust-bir.h
index 746b2dc7e38..f8a2151aaf8 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir.h
@@ -97,20 +97,7 @@  struct BasicBlock
   std::vector<BasicBlockId> successors;
 
 public:
-  WARN_UNUSED_RESULT bool is_terminated () const
-  {
-    if (statements.empty ())
-      return false;
-    switch (statements.back ().get_kind ())
-      {
-      case Statement::Kind::GOTO:
-      case Statement::Kind::RETURN:
-      case Statement::Kind::SWITCH:
-	return true;
-      default:
-	return false;
-      }
-  }
+  WARN_UNUSED_RESULT bool is_terminated () const;
 
   WARN_UNUSED_RESULT bool is_goto_terminated () const
   {
@@ -119,9 +106,23 @@  public:
   }
 };
 
+enum class ExprKind
+{
+  INITIALIZER,
+  OPERATOR,
+  BORROW,
+  ASSIGNMENT,
+  CALL,
+};
+
 // Rhs expression of BIR assignment statements (abstract).
 class AbstractExpr : public Visitable
 {
+  ExprKind kind;
+
+public:
+  explicit AbstractExpr (ExprKind kind) : kind (kind) {}
+  [[nodiscard]] ExprKind get_kind () const { return kind; }
 };
 
 class InitializerExpr : public VisitableImpl<AbstractExpr, InitializerExpr>
@@ -129,7 +130,10 @@  class InitializerExpr : public VisitableImpl<AbstractExpr, InitializerExpr>
   std::vector<PlaceId> values;
 
 public:
-  explicit InitializerExpr (std::vector<PlaceId> &&values) : values (values) {}
+  explicit InitializerExpr (std::vector<PlaceId> &&values)
+    : VisitableImpl<AbstractExpr, InitializerExpr> (ExprKind::INITIALIZER),
+      values (values)
+  {}
 
 public:
   std::vector<PlaceId> &get_values () { return values; }
@@ -142,7 +146,8 @@  class Operator : public VisitableImpl<AbstractExpr, Operator<ARITY>>
 
 public:
   explicit Operator (std::array<PlaceId, ARITY> &&operands)
-    : operands (operands)
+    : VisitableImpl<AbstractExpr, Operator<ARITY>> (ExprKind::OPERATOR),
+      operands (operands)
   {}
 
 public:
@@ -158,7 +163,9 @@  class BorrowExpr : public VisitableImpl<AbstractExpr, BorrowExpr>
   PlaceId place;
 
 public:
-  explicit BorrowExpr (PlaceId place) : place (place) {}
+  explicit BorrowExpr (PlaceId place)
+    : VisitableImpl<AbstractExpr, BorrowExpr> (ExprKind::BORROW), place (place)
+  {}
   WARN_UNUSED_RESULT PlaceId get_place () const { return place; }
 };
 
@@ -172,7 +179,9 @@  class Assignment : public VisitableImpl<AbstractExpr, Assignment>
   PlaceId rhs;
 
 public:
-  explicit Assignment (PlaceId rhs) : rhs (rhs) {}
+  explicit Assignment (PlaceId rhs)
+    : VisitableImpl<AbstractExpr, Assignment> (ExprKind::ASSIGNMENT), rhs (rhs)
+  {}
 
 public:
   WARN_UNUSED_RESULT PlaceId get_rhs () const { return rhs; }
@@ -185,7 +194,8 @@  class CallExpr : public VisitableImpl<AbstractExpr, CallExpr>
 
 public:
   explicit CallExpr (PlaceId callable, std::vector<PlaceId> &&arguments)
-    : arguments (arguments), callable (callable)
+    : VisitableImpl<AbstractExpr, CallExpr> (ExprKind::CALL),
+      arguments (arguments), callable (callable)
   {}
 
 public:
@@ -193,6 +203,24 @@  public:
   WARN_UNUSED_RESULT PlaceId get_callable () const { return callable; }
 };
 
+inline bool
+BasicBlock::is_terminated () const
+{
+  if (statements.empty ())
+    return false;
+  switch (statements.back ().get_kind ())
+    {
+    case Statement::Kind::GOTO:
+    case Statement::Kind::RETURN:
+    case Statement::Kind::SWITCH:
+      return true;
+    case Statement::Kind::ASSIGNMENT:
+      return statements.back ().get_expr ().get_kind () == ExprKind::CALL;
+    default:
+      return false;
+    }
+}
+
 } // namespace BIR
 
 } // namespace Rust