https://gcc.gnu.org/g:a438e47eeddb5e56dbcb3387417f334a582b5764

commit r15-8343-ga438e47eeddb5e56dbcb3387417f334a582b5764
Author: badumbatish <tanghocle...@gmail.com>
Date:   Sun Jul 7 22:03:12 2024 -0700

    gccrs: Refactor compile-asm for first round review
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-asm.cc (strip_double_quotes):
            Refactor compile-asm for first round review
            (CompileAsm::asm_build_asm_stmt): Likewise.
            (CompileAsm::asm_build_expr): Likewise.
            (CompileAsm::asm_get_locus): Likewise.
            (CompileAsm::asm_construct_string_tree): Likewise.
            (CompileAsm::asm_construct_outputs): Likewise.
            (CompileAsm::asm_construct_inputs): Likewise.
            (CompileAsm::asm_construct_clobber_tree): Likewise.
            (CompileAsm::asm_construct_label_tree): Likewise.
            (CompileAsm::asm_is_simple): Likewise.
            (CompileAsm::asm_is_inline): Likewise.
            * backend/rust-compile-asm.h (strip_double_quotes): Likewise.
            (class CompileAsm): Likewise.

Diff:
---
 gcc/rust/backend/rust-compile-asm.cc | 251 +++++++----------------------------
 gcc/rust/backend/rust-compile-asm.h  | 127 +++++++++---------
 2 files changed, 107 insertions(+), 271 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-asm.cc 
b/gcc/rust/backend/rust-compile-asm.cc
index fe080f6aa6b9..8fd62dd48c9d 100644
--- a/gcc/rust/backend/rust-compile-asm.cc
+++ b/gcc/rust/backend/rust-compile-asm.cc
@@ -1,72 +1,57 @@
 #include "rust-compile-asm.h"
 
-#include "rust-tree.h"
 #include "rust-system.h"
-#include <cstddef>
 namespace Rust {
 namespace Compile {
 
+std::string
+strip_double_quotes (const std::string &str)
+{
+  // Helper function strips the beginning and ending double quotes from a
+  // string.
+  std::string result = str;
+
+  rust_assert (result.size () >= 3);
+  result.erase (0, 1);
+  result.erase (result.size () - 1, 1);
+  return result;
+}
+
 CompileAsm::CompileAsm (Context *ctx)
   : HIRCompileBase (ctx), translated (error_mark_node)
 {}
 void
 CompileAsm::visit (HIR::InlineAsm &expr)
 {
-  return ctx->add_statement (asm_build_expr (expr));
-}
-tree
-CompileAsm::asm_build_asm_stmt (HIR::InlineAsm &expr)
-{
-  // From the implementation of c-typeck.cc
-  // tree
-  // build_asm_stmt (bool is_volatile, tree args)
-  //{
-  //   if (is_volatile)
-  //     ASM_VOLATILE_P (args) = 1;
-  //   return add_stmt (args);
-  // }
-  //
-  return NULL_TREE;
+  ctx->add_statement (asm_build_expr (expr));
 }
+
 tree
 CompileAsm::asm_build_expr (HIR::InlineAsm &expr)
 {
-  auto asm_expr = asm_build_stmt (asm_get_locus (expr), ASM_EXPR,
-                                 {asm_construct_string_tree (expr),
-                                  asm_construct_outputs (expr),
-                                  asm_construct_inputs (expr),
-                                  asm_construct_clobber_tree (expr),
-                                  asm_construct_label_tree (expr)});
+  auto asm_expr
+    = asm_build_stmt (expr.get_locus (), {asm_construct_string_tree (expr),
+                                         asm_construct_outputs (expr),
+                                         asm_construct_inputs (expr),
+                                         asm_construct_clobber_tree (expr),
+                                         asm_construct_label_tree (expr)});
 
   ASM_BASIC_P (asm_expr) = CompileAsm::asm_is_simple (expr);
-  ASM_VOLATILE_P (asm_expr) = (false);
+  ASM_VOLATILE_P (asm_expr) = false;
   ASM_INLINE_P (asm_expr) = CompileAsm::asm_is_inline (expr);
   return asm_expr;
-  // return build_asm_expr (CompileAsm::asm_get_locus (expr),
-  //                    CompileAsm::asm_construct_string_tree (expr),
-  //                    CompileAsm::asm_construct_outputs (expr),
-  //                    CompileAsm::asm_construct_inputs (expr),
-  //                    CompileAsm::asm_construct_clobber_tree (expr),
-  //                    CompileAsm::asm_construct_label_tree (expr),
-  //                    CompileAsm::asm_is_simple (expr),
-  //                    CompileAsm::asm_is_inline (expr));
 }
 
 tree
 CompileAsm::asm_build_stmt (
-  location_t loc, enum tree_code code,
+  location_t loc,
   const std::array<tree, CompileAsm::ASM_TREE_ARRAY_LENGTH> &trees)
 {
+  // Prototype functiion for building an ASM_EXPR tree.
   tree ret;
-  //  va_list p;
   bool side_effects;
 
-  /* This function cannot be used to construct variably-sized nodes.  */
-  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
-
-  // va_start (p, code);
-
-  ret = make_node (code);
+  ret = make_node (ASM_EXPR);
   TREE_TYPE (ret) = void_type_node;
   SET_EXPR_LOCATION (ret, loc);
 
@@ -75,6 +60,8 @@ CompileAsm::asm_build_stmt (
      expressions by checking whether the parameters have side
      effects.  */
 
+  // This is here because of c-typeck.cc's code
+  // I'm not sure what kind of effects it has
   side_effects = false;
   for (size_t i = 0; i < trees.size (); i++)
     {
@@ -86,213 +73,65 @@ CompileAsm::asm_build_stmt (
 
   TREE_SIDE_EFFECTS (ret) |= side_effects;
 
-  // va_end (p);
   return ret;
 }
-location_t
-CompileAsm::asm_get_locus (HIR::InlineAsm &expr)
-{
-  return expr.get_locus ();
-}
+
 tree
 CompileAsm::asm_construct_string_tree (HIR::InlineAsm &expr)
 {
-  if (expr.template_strs.empty ())
-    return build_string (1, "");
-  else
-    return build_string (4, "nop");
-  // Initialize to NULL_TREE
-  tree string_chain = NULL_TREE;
-
+  // To construct an ASM_EXPR tree, we need to build a STRING_CST tree.
+  //
+  // We do this by concatenating all the template strings in the InlineAsm
+  // into one big std::string seperated by tabs and newlines. (For easier
+  // debugging and reading)
+  std::stringstream ss;
   for (const auto &template_str : expr.template_strs)
-    {
-      auto str = template_str.symbol;
-      auto string_tree = build_string (str.size () + 1, str.c_str ());
-
-      string_chain = tree_cons (NULL_TREE, string_tree, string_chain);
-    }
-  // Reverse the chain before returning
+    ss << strip_double_quotes (template_str.symbol) << "\n\t";
 
-  string_chain = nreverse (string_chain);
-
-  return nreverse (string_chain);
+  std::string result = ss.str ();
+  return build_string (result.size () + 1, result.c_str ());
 }
+
 tree
 CompileAsm::asm_construct_outputs (HIR::InlineAsm &expr)
 {
+  // TODO: Do i need to do this?
   return NULL_TREE;
 }
 
 tree
 CompileAsm::asm_construct_inputs (HIR::InlineAsm &expr)
 {
+  // TODO: Do i need to do this?
   return NULL_TREE;
 }
 
 tree
 CompileAsm::asm_construct_clobber_tree (HIR::InlineAsm &expr)
 {
+  // TODO: Do i need to do this?
   return NULL_TREE;
 }
+
 tree
 CompileAsm::asm_construct_label_tree (HIR::InlineAsm &expr)
 {
+  // TODO: Do i need to do this?
   return NULL_TREE;
 }
 
 bool
 CompileAsm::asm_is_simple (HIR::InlineAsm &expr)
 {
+  // TODO: Check back later to determine how an InlineAsm is simple.
   return true;
 }
 
 bool
 CompileAsm::asm_is_inline (HIR::InlineAsm &expr)
 {
+  // TODO: Check back later to determine how an InlineAsm is inline.
   return true;
 }
 } // namespace Compile
 } // namespace Rust
-  //
-  //
-  // The following section serves as documentation for PR revieweres and future
-  // asm developers. It documents the inspriation for the implementation of the
-  // CompileAsm class
-
-// From the implementation of c-typeck.cc
-// tree
-// build_asm_stmt (bool is_volatile, tree args)
-//{
-//   if (is_volatile)
-//     ASM_VOLATILE_P (args) = 1;
-//   return add_stmt (args);
-// }
-//
-///* Build an asm-expr, whose components are a STRING, some OUTPUTS,
-//   some INPUTS, and some CLOBBERS.  The latter three may be NULL.
-//   SIMPLE indicates whether there was anything at all after the
-//   string in the asm expression -- asm("blah") and asm("blah" : )
-//   are subtly different.  We use a ASM_EXPR node to represent this.
-//   LOC is the location of the asm, and IS_INLINE says whether this
-//   is asm inline.  */
-// tree
-// build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
-//             tree clobbers, tree labels, bool simple, bool is_inline)
-//{
-//  tree tail;
-//  tree args;
-//  int i;
-//  const char *constraint;
-//  const char **oconstraints;
-//  bool allows_mem, allows_reg, is_inout;
-//  int ninputs, noutputs;
-//
-//  ninputs = list_length (inputs);
-//  noutputs = list_length (outputs);
-//  oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
-//
-//  string = resolve_asm_operand_names (string, outputs, inputs, labels);
-//
-//  /* Remove output conversions that change the type but not the mode.  */
-//  for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
-//    {
-//      tree output = TREE_VALUE (tail);
-//
-//      output = c_fully_fold (output, false, NULL, true);
-//
-//      /* ??? Really, this should not be here.  Users should be using a
-//      proper lvalue, dammit.  But there's a long history of using casts
-//      in the output operands.  In cases like longlong.h, this becomes a
-//      primitive form of typechecking -- if the cast can be removed, then
-//      the output operand had a type of the proper width; otherwise we'll
-//      get an error.  Gross, but ...  */
-//      STRIP_NOPS (output);
-//
-//      if (!lvalue_or_else (loc, output, lv_asm))
-//     output = error_mark_node;
-//
-//      if (output != error_mark_node
-//       && (TREE_READONLY (output)
-//           || TYPE_READONLY (TREE_TYPE (output))
-//           || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (output))
-//               && C_TYPE_FIELDS_READONLY (TREE_TYPE (output)))))
-//     readonly_error (loc, output, lv_asm);
-//
-//      constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
-//      oconstraints[i] = constraint;
-//
-//      if (parse_output_constraint (&constraint, i, ninputs, noutputs,
-//                                &allows_mem, &allows_reg, &is_inout))
-//     {
-//       /* If the operand is going to end up in memory,
-//          mark it addressable.  */
-//       if (!allows_reg && !c_mark_addressable (output))
-//         output = error_mark_node;
-//       if (!(!allows_reg && allows_mem)
-//           && output != error_mark_node
-//           && VOID_TYPE_P (TREE_TYPE (output)))
-//         {
-//           error_at (loc, "invalid use of void expression");
-//           output = error_mark_node;
-//         }
-//     }
-//      else
-//     output = error_mark_node;
-//
-//      TREE_VALUE (tail) = output;
-//    }
-//
-//  for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
-//    {
-//      tree input;
-//
-//      constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
-//      input = TREE_VALUE (tail);
-//
-//      if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
-//                               oconstraints, &allows_mem, &allows_reg))
-//     {
-//       /* If the operand is going to end up in memory,
-//          mark it addressable.  */
-//       if (!allows_reg && allows_mem)
-//         {
-//           input = c_fully_fold (input, false, NULL, true);
-//
-//           /* Strip the nops as we allow this case.  FIXME, this really
-//              should be rejected or made deprecated.  */
-//           STRIP_NOPS (input);
-//           if (!c_mark_addressable (input))
-//             input = error_mark_node;
-//         }
-//       else
-//         {
-//           struct c_expr expr;
-//           memset (&expr, 0, sizeof (expr));
-//           expr.value = input;
-//           expr = convert_lvalue_to_rvalue (loc, expr, true, false);
-//           input = c_fully_fold (expr.value, false, NULL);
-//
-//           if (input != error_mark_node && VOID_TYPE_P (TREE_TYPE (input)))
-//             {
-//               error_at (loc, "invalid use of void expression");
-//               input = error_mark_node;
-//             }
-//         }
-//     }
-//      else
-//     input = error_mark_node;
-//
-//      TREE_VALUE (tail) = input;
-//    }
-//
-//  args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers,
-//  labels);
-//
-//  /* asm statements without outputs, including simple ones, are treated
-//     as volatile.  */
-//  ASM_INPUT_P (args) = simple;
-//  ASM_VOLATILE_P (args) = (noutputs == 0);
-//  ASM_INLINE_P (args) = is_inline;
-//
-//  return args;
-//}
diff --git a/gcc/rust/backend/rust-compile-asm.h 
b/gcc/rust/backend/rust-compile-asm.h
index d7967bc7fdb5..15ffc707986f 100644
--- a/gcc/rust/backend/rust-compile-asm.h
+++ b/gcc/rust/backend/rust-compile-asm.h
@@ -26,78 +26,25 @@
 namespace Rust {
 namespace Compile {
 
+std::string
+strip_double_quotes (const std::string &);
+
 class CompileAsm : private HIRCompileBase, protected HIR::HIRExpressionVisitor
 {
+private:
+  tree translated;
+
 public:
+  // WE WILL OPEN THIS UP WHEN WE WANT TO ADD A DEDICATED PASS OF HIR'S ASM
+  // translation.
   // static tree Compile (HIR::Expr *expr, Context *ctx);
 
-  void visit (HIR::InlineAsm &expr) override;
-
-  void visit (HIR::TupleIndexExpr &expr) override {}
-  void visit (HIR::TupleExpr &expr) override {}
-  void visit (HIR::ReturnExpr &expr) override {}
-  void visit (HIR::CallExpr &expr) override {}
-  void visit (HIR::MethodCallExpr &expr) override {}
-  void visit (HIR::LiteralExpr &expr) override {}
-  void visit (HIR::AssignmentExpr &expr) override {}
-  void visit (HIR::CompoundAssignmentExpr &expr) override {}
-  void visit (HIR::ArrayIndexExpr &expr) override {}
-  void visit (HIR::ArrayExpr &expr) override {}
-  void visit (HIR::ArithmeticOrLogicalExpr &expr) override {}
-  void visit (HIR::ComparisonExpr &expr) override {}
-  void visit (HIR::LazyBooleanExpr &expr) override {}
-  void visit (HIR::NegationExpr &expr) override {}
-  void visit (HIR::TypeCastExpr &expr) override {}
-  void visit (HIR::IfExpr &expr) override {}
-  void visit (HIR::IfExprConseqElse &expr) override {}
-  void visit (HIR::BlockExpr &expr) override {}
-  void visit (HIR::UnsafeBlockExpr &expr) override {}
-  void visit (HIR::StructExprStruct &struct_expr) override {}
-  void visit (HIR::StructExprStructFields &struct_expr) override {}
-  void visit (HIR::GroupedExpr &expr) override {}
-  void visit (HIR::FieldAccessExpr &expr) override {}
-  void visit (HIR::QualifiedPathInExpression &expr) override {}
-  void visit (HIR::PathInExpression &expr) override {}
-  void visit (HIR::LoopExpr &expr) override {}
-  void visit (HIR::WhileLoopExpr &expr) override {}
-  void visit (HIR::BreakExpr &expr) override {}
-  void visit (HIR::ContinueExpr &expr) override {}
-  void visit (HIR::BorrowExpr &expr) override {}
-  void visit (HIR::DereferenceExpr &expr) override {}
-  void visit (HIR::MatchExpr &expr) override {}
-  void visit (HIR::RangeFromToExpr &expr) override {}
-  void visit (HIR::RangeFromExpr &expr) override {}
-  void visit (HIR::RangeToExpr &expr) override {}
-  void visit (HIR::RangeFullExpr &expr) override {}
-  void visit (HIR::RangeFromToInclExpr &expr) override {}
-  void visit (HIR::ClosureExpr &expr) override {}
-
-  // TODO
-  void visit (HIR::ErrorPropagationExpr &) override {}
-  void visit (HIR::RangeToInclExpr &) override {}
-
-  // TODO
-  // these need to be sugared in the HIR to if statements and a match
-  void visit (HIR::WhileLetLoopExpr &) override {}
-  void visit (HIR::IfLetExpr &) override {}
-  void visit (HIR::IfLetExprConseqElse &) override {}
-
-  // lets not worry about async yet....
-  void visit (HIR::AwaitExpr &) override {}
-  void visit (HIR::AsyncBlockExpr &) override {}
-
-  // nothing to do for these
-  void visit (HIR::StructExprFieldIdentifier &) override {}
-  void visit (HIR::StructExprFieldIdentifierValue &) override {}
-  void visit (HIR::StructExprFieldIndexValue &) override {}
-
+  // RELEVANT MEMBER FUNCTIONS
   static const int ASM_TREE_ARRAY_LENGTH = 5;
-  static tree asm_build_asm_stmt (HIR::InlineAsm &);
   static tree asm_build_expr (HIR::InlineAsm &);
-  static tree asm_build_stmt (location_t, enum tree_code,
+  static tree asm_build_stmt (location_t,
                              const std::array<tree, ASM_TREE_ARRAY_LENGTH> &);
 
-  static location_t asm_get_locus (HIR::InlineAsm &);
   static tree asm_construct_string_tree (HIR::InlineAsm &);
   static tree asm_construct_outputs (HIR::InlineAsm &);
   static tree asm_construct_inputs (HIR::InlineAsm &);
@@ -108,8 +55,58 @@ public:
 
   CompileAsm (Context *ctx);
 
-private:
-  tree translated;
+  void visit (HIR::InlineAsm &) override;
+
+  // NON RELEVANT MEMBER FUNCTIONS
+
+  void visit (HIR::TupleIndexExpr &) override {}
+  void visit (HIR::TupleExpr &) override {}
+  void visit (HIR::ReturnExpr &) override {}
+  void visit (HIR::CallExpr &) override {}
+  void visit (HIR::MethodCallExpr &) override {}
+  void visit (HIR::LiteralExpr &) override {}
+  void visit (HIR::AssignmentExpr &) override {}
+  void visit (HIR::CompoundAssignmentExpr &) override {}
+  void visit (HIR::ArrayIndexExpr &) override {}
+  void visit (HIR::ArrayExpr &) override {}
+  void visit (HIR::ArithmeticOrLogicalExpr &) override {}
+  void visit (HIR::ComparisonExpr &) override {}
+  void visit (HIR::LazyBooleanExpr &) override {}
+  void visit (HIR::NegationExpr &) override {}
+  void visit (HIR::TypeCastExpr &) override {}
+  void visit (HIR::IfExpr &) override {}
+  void visit (HIR::IfExprConseqElse &) override {}
+  void visit (HIR::BlockExpr &) override {}
+  void visit (HIR::UnsafeBlockExpr &) override {}
+  void visit (HIR::StructExprStruct &struct_) override {}
+  void visit (HIR::StructExprStructFields &struct_) override {}
+  void visit (HIR::GroupedExpr &) override {}
+  void visit (HIR::FieldAccessExpr &) override {}
+  void visit (HIR::QualifiedPathInExpression &) override {}
+  void visit (HIR::PathInExpression &) override {}
+  void visit (HIR::LoopExpr &) override {}
+  void visit (HIR::WhileLoopExpr &) override {}
+  void visit (HIR::BreakExpr &) override {}
+  void visit (HIR::ContinueExpr &) override {}
+  void visit (HIR::BorrowExpr &) override {}
+  void visit (HIR::DereferenceExpr &) override {}
+  void visit (HIR::MatchExpr &) override {}
+  void visit (HIR::RangeFromToExpr &) override {}
+  void visit (HIR::RangeFromExpr &) override {}
+  void visit (HIR::RangeToExpr &) override {}
+  void visit (HIR::RangeFullExpr &) override {}
+  void visit (HIR::RangeFromToInclExpr &) override {}
+  void visit (HIR::ClosureExpr &) override {}
+  void visit (HIR::ErrorPropagationExpr &) override {}
+  void visit (HIR::RangeToInclExpr &) override {}
+  void visit (HIR::WhileLetLoopExpr &) override {}
+  void visit (HIR::IfLetExpr &) override {}
+  void visit (HIR::IfLetExprConseqElse &) override {}
+  void visit (HIR::AwaitExpr &) override {}
+  void visit (HIR::AsyncBlockExpr &) override {}
+  void visit (HIR::StructExprFieldIdentifier &) override {}
+  void visit (HIR::StructExprFieldIdentifierValue &) override {}
+  void visit (HIR::StructExprFieldIndexValue &) override {}
 };
 } // namespace Compile
 } // namespace Rust

Reply via email to