From: Owen Avery <[email protected]>

gcc/rust/ChangeLog:

        * backend/rust-compile-asm.cc: Include "rust-ggc.h".
        (chain_asm_operand): Use GGC::ChainList.
        (CompileAsm::asm_construct_outputs): Likewise.
        (CompileAsm::asm_construct_inputs): Likewise.
        (CompileLlvmAsm::construct_operands): Likewise.
        (CompileLlvmAsm::construct_clobbers): Likewise.
        * util/rust-ggc.h (class ChainList): New class.

Signed-off-by: Owen Avery <[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/6211b044aa5192c737ced7e2aa1fad2ff1423293

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4508

 gcc/rust/backend/rust-compile-asm.cc | 34 ++++++++++++-------------
 gcc/rust/util/rust-ggc.h             | 38 ++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index be0305a6e..2ac65bd65 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,16 +1,16 @@
 #include "rust-compile-asm.h"
 #include "rust-compile-expr.h"
 #include "rust-system.h"
+#include "rust-ggc.h"
 
 namespace Rust {
 namespace Compile {
 
-static tree
-chain_asm_operand (tree head, const char *constraint, tree value)
+static void
+chain_asm_operand (GGC::ChainList &ls, const char *constraint, tree value)
 {
   auto name = build_string (strlen (constraint) + 1, constraint);
-  return chainon (head,
-                 build_tree_list (build_tree_list (NULL_TREE, name), value));
+  ls.push_back (build_tree_list (build_tree_list (NULL_TREE, name), value));
 }
 
 CompileAsm::CompileAsm (Context *ctx) : HIRCompileBase (ctx) {}
@@ -107,7 +107,7 @@ CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
 
-  tree head = NULL_TREE;
+  GGC::ChainList ls;
   for (auto &operand : expr.get_operands ())
     {
       tl::optional<std::reference_wrapper<HIR::Expr>> out_expr
@@ -118,9 +118,9 @@ CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
       tree out_tree = CompileExpr::Compile (*out_expr, this->ctx);
       // expects a tree list
       // TODO: This assumes that the output is a register
-      head = chain_asm_operand (head, "=r", out_tree);
+      chain_asm_operand (ls, "=r", out_tree);
     }
-  return head;
+  return ls.get_head ();
 }
 
 tl::optional<std::reference_wrapper<HIR::Expr>>
@@ -147,7 +147,8 @@ tree
 CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
 {
   // TODO: Do i need to do this?
-  tree head = NULL_TREE;
+
+  GGC::ChainList ls;
   for (auto &operand : expr.get_operands ())
     {
       tl::optional<std::reference_wrapper<HIR::Expr>> in_expr
@@ -158,9 +159,9 @@ CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
       tree in_tree = CompileExpr::Compile (*in_expr, this->ctx);
       // expects a tree list
       // TODO: This assumes that the input is a register
-      head = chain_asm_operand (head, "r", in_tree);
+      chain_asm_operand (ls, "r", in_tree);
     }
-  return head;
+  return ls.get_head ();
 }
 
 tree
@@ -182,29 +183,28 @@ CompileLlvmAsm::CompileLlvmAsm (Context *ctx) : 
HIRCompileBase (ctx) {}
 tree
 CompileLlvmAsm::construct_operands (std::vector<HIR::LlvmOperand> operands)
 {
-  tree head = NULL_TREE;
+  GGC::ChainList ls;
   for (auto &operand : operands)
     {
       tree t = CompileExpr::Compile (*operand.expr, this->ctx);
       auto name = build_string (operand.constraint.size () + 1,
                                operand.constraint.c_str ());
-      head = chainon (head,
-                     build_tree_list (build_tree_list (NULL_TREE, name), t));
+      ls.push_back (build_tree_list (build_tree_list (NULL_TREE, name), t));
     }
-  return head;
+  return ls.get_head ();
 }
 
 tree
 CompileLlvmAsm::construct_clobbers (std::vector<AST::TupleClobber> clobbers)
 {
-  tree head = NULL_TREE;
+  GGC::ChainList ls;
   for (auto &clobber : clobbers)
     {
       auto name
        = build_string (clobber.symbol.size () + 1, clobber.symbol.c_str ());
-      head = chainon (head, build_tree_list (NULL_TREE, name));
+      ls.push_back (build_tree_list (NULL_TREE, name));
     }
-  return head;
+  return ls.get_head ();
 }
 
 tree
diff --git a/gcc/rust/util/rust-ggc.h b/gcc/rust/util/rust-ggc.h
index e4ebabd41..eb4b327fb 100644
--- a/gcc/rust/util/rust-ggc.h
+++ b/gcc/rust/util/rust-ggc.h
@@ -60,6 +60,44 @@ operator== (const std::string &a, const Ident &b)
   return b == a;
 }
 
+class ChainList
+{
+  tree head;
+  tree *tail_cdr;
+
+public:
+  ChainList () : head (NULL_TREE), tail_cdr (&head) {}
+
+  ChainList (ChainList &&oth)
+  {
+    head = oth.head;
+    if (oth.tail_cdr == &oth.head)
+      tail_cdr = &oth.head;
+    else
+      tail_cdr = oth.tail_cdr;
+    oth.head = NULL_TREE;
+    oth.tail_cdr = &oth.head;
+  }
+
+  ChainList &operator= (ChainList &&oth)
+  {
+    this->~ChainList ();
+    new (this) ChainList (std::move (oth));
+    return *this;
+  }
+
+  tree get_head () const { return head; }
+
+  // TREE_CHAIN (ent) will be modified
+  // making ent a node in this list
+  // do not push a single tree to multiple ChainList objects
+  void push_back (tree ent)
+  {
+    *tail_cdr = ent;
+    tail_cdr = &TREE_CHAIN (ent);
+  }
+};
+
 } // namespace GGC
 
 } // namespace Rust

base-commit: 732732618557f25d87885d816d75f456fe3b03a3
-- 
2.53.0

Reply via email to