https://gcc.gnu.org/g:400324882aaa45772930d2266c9241d45f64d251

commit 400324882aaa45772930d2266c9241d45f64d251
Author: Jakub Dupak <d...@jakubdupak.com>
Date:   Fri Feb 2 14:47:14 2024 +0100

    borrowck: BIR: emit moves
    
    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 <d...@jakubdupak.com>

Diff:
---
 .../errors/borrowck/rust-bir-builder-expr-stmt.cc  | 15 ++---
 .../errors/borrowck/rust-bir-builder-internal.h    | 35 +++++-------
 .../borrowck/rust-bir-builder-lazyboolexpr.h       |  2 +-
 gcc/rust/checks/errors/borrowck/rust-bir-dump.cc   | 11 +++-
 gcc/rust/checks/errors/borrowck/rust-bir-place.h   | 50 +++++++---------
 gcc/rust/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 --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 89352d84f6b8..922894cc5d50 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 55f00aa50ac9..b421ba43fbae 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 fb0c75b4f729..1cc55569c7ca 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 4dea27e30383..320b653f830a 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 61e90d58d263..546890d797cc 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 0b3a4bddbecf..7ad62f700dbc 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 746b2dc7e38c..f8a2151aaf8c 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

Reply via email to