On Mon, Apr 28, 2025 at 8:48 AM <arthur.co...@embecosm.com> wrote:
>
> From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
>
> InlineAsm node does not support memory clobbers.

A few review on this.
I think this should just be called extended rather than referencing LLVM here.

>
> gcc/rust/ChangeLog:
>
>         * ast/rust-ast-collector.cc (TokenCollector::visit): Make visitor
>         unreachable.
>         * ast/rust-ast-collector.h: Add visit for LlvmInlineAsmNode.
>         * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Add visit
>         function for the default ast visitor.
>         * ast/rust-ast-visitor.h: Add function prototype.
>         * ast/rust-ast.cc (LlvmInlineAsm::accept_vis): Add accept_vis to
>         LlvmInlineAsm node.
>         * ast/rust-ast.h: Add LlvmInlineAsm node kind.
>         * ast/rust-expr.h (class LlvmInlineAsm): Add LlvmInlineAsm node.
>         * expand/rust-derive.h: Add visit function for LlvmInlineAsm node.
>         * expand/rust-macro-builtins-asm.cc (MacroBuiltin::llvm_asm_handler):
>         Add handler for llvm inline assembly nodes.
>         (parse_llvm_asm): Add function to parse llvm assembly nodes.
>         * expand/rust-macro-builtins-asm.h (parse_llvm_asm): Add function
>         prototypes.
>         * expand/rust-macro-builtins.cc (inline_llvm_asm_maker): Add macro
>         transcriber.
>         * expand/rust-macro-builtins.h: Add transcriber function prototype.
>         * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Add visit
>         function for LlvmInlineAsm node.
>         * hir/rust-ast-lower-base.h: Add visit function prototype.
>         * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Add visit
>         function for LlvmInlineAsm node.
>         * resolve/rust-ast-resolve-base.h: Add visit function prototype.
>
> Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
> ---
>  gcc/rust/ast/rust-ast-collector.cc         | 10 ++++-
>  gcc/rust/ast/rust-ast-collector.h          |  1 +
>  gcc/rust/ast/rust-ast-visitor.cc           |  4 ++
>  gcc/rust/ast/rust-ast-visitor.h            |  2 +
>  gcc/rust/ast/rust-ast.cc                   |  6 +++
>  gcc/rust/ast/rust-ast.h                    |  1 +
>  gcc/rust/ast/rust-expr.h                   | 48 ++++++++++++++++++++++
>  gcc/rust/expand/rust-derive.h              |  1 +
>  gcc/rust/expand/rust-macro-builtins-asm.cc | 21 ++++++++++
>  gcc/rust/expand/rust-macro-builtins-asm.h  |  7 ++++
>  gcc/rust/expand/rust-macro-builtins.cc     | 11 ++++-
>  gcc/rust/expand/rust-macro-builtins.h      |  4 ++
>  gcc/rust/hir/rust-ast-lower-base.cc        |  4 ++
>  gcc/rust/hir/rust-ast-lower-base.h         |  1 +
>  gcc/rust/resolve/rust-ast-resolve-base.cc  |  4 ++
>  gcc/rust/resolve/rust-ast-resolve-base.h   |  1 +
>  16 files changed, 124 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/rust/ast/rust-ast-collector.cc 
> b/gcc/rust/ast/rust-ast-collector.cc
> index 8ee63752f32..90ff2e36251 100644
> --- a/gcc/rust/ast/rust-ast-collector.cc
> +++ b/gcc/rust/ast/rust-ast-collector.cc
> @@ -1520,7 +1520,15 @@ TokenCollector::visit (AsyncBlockExpr &expr)
>
>  void
>  TokenCollector::visit (InlineAsm &expr)
> -{}
> +{
> +  rust_unreachable ();
> +}
> +
> +void
> +TokenCollector::visit (LlvmInlineAsm &expr)
> +{
> +  rust_unreachable ();
> +}
>
>  // rust-item.h
>
> diff --git a/gcc/rust/ast/rust-ast-collector.h 
> b/gcc/rust/ast/rust-ast-collector.h
> index b014c23ed0b..f45e3cc51ae 100644
> --- a/gcc/rust/ast/rust-ast-collector.h
> +++ b/gcc/rust/ast/rust-ast-collector.h
> @@ -303,6 +303,7 @@ public:
>    void visit (AwaitExpr &expr);
>    void visit (AsyncBlockExpr &expr);
>    void visit (InlineAsm &expr);
> +  void visit (LlvmInlineAsm &expr);
>    // rust-item.h
>    void visit (TypeParam &param);
>    void visit (LifetimeWhereClauseItem &item);
> diff --git a/gcc/rust/ast/rust-ast-visitor.cc 
> b/gcc/rust/ast/rust-ast-visitor.cc
> index 9d524c3cc4c..beb3360c4e1 100644
> --- a/gcc/rust/ast/rust-ast-visitor.cc
> +++ b/gcc/rust/ast/rust-ast-visitor.cc
> @@ -713,6 +713,10 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr)
>      }
>  }
>
> +void
> +DefaultASTVisitor::visit (AST::LlvmInlineAsm &expr)
> +{}
> +
>  void
>  DefaultASTVisitor::visit (AST::TypeParam &param)
>  {
> diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
> index 51661df76b4..6d243e7b063 100644
> --- a/gcc/rust/ast/rust-ast-visitor.h
> +++ b/gcc/rust/ast/rust-ast-visitor.h
> @@ -131,6 +131,7 @@ public:
>    virtual void visit (AwaitExpr &expr) = 0;
>    virtual void visit (AsyncBlockExpr &expr) = 0;
>    virtual void visit (InlineAsm &expr) = 0;
> +  virtual void visit (LlvmInlineAsm &expr) = 0;
>
>    // rust-item.h
>    virtual void visit (TypeParam &param) = 0;
> @@ -314,6 +315,7 @@ public:
>    virtual void visit (AST::AwaitExpr &expr) override;
>    virtual void visit (AST::AsyncBlockExpr &expr) override;
>    virtual void visit (InlineAsm &expr) override;
> +  virtual void visit (LlvmInlineAsm &expr) override;
>
>    virtual void visit (AST::TypeParam &param) override;
>    virtual void visit (AST::LifetimeWhereClauseItem &item) override;
> diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
> index 06e0e7b0fbc..4e82be420fe 100644
> --- a/gcc/rust/ast/rust-ast.cc
> +++ b/gcc/rust/ast/rust-ast.cc
> @@ -4650,6 +4650,12 @@ InlineAsm::accept_vis (ASTVisitor &vis)
>    vis.visit (*this);
>  }
>
> +void
> +LlvmInlineAsm::accept_vis (ASTVisitor &vis)
> +{
> +  vis.visit (*this);
> +}
> +
>  void
>  TypeParam::accept_vis (ASTVisitor &vis)
>  {
> diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
> index 91611ec6a62..55f178d782c 100644
> --- a/gcc/rust/ast/rust-ast.h
> +++ b/gcc/rust/ast/rust-ast.h
> @@ -1264,6 +1264,7 @@ public:
>      Await,
>      AsyncBlock,
>      InlineAsm,
> +    LlvmInlineAsm,
>      Identifier,
>      FormatArgs,
>      MacroInvocation,
> diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
> index 69538df63e5..0dfb4e5fd60 100644
> --- a/gcc/rust/ast/rust-expr.h
> +++ b/gcc/rust/ast/rust-expr.h
> @@ -5330,6 +5330,54 @@ public:
>    Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; 
> }
>  };
>
> +class LlvmInlineAsm : public ExprWithoutBlock
> +{
> +  // llvm_asm!("" :         : "r"(&mut dummy) : "memory" : "volatile");
> +  //           Asm, Outputs, Inputs,            Clobbers, Options,
> +
> +private:
> +  location_t locus;
> +  std::vector<Attribute> outer_attrs;
> +
> +  std::vector<TupleClobber> clobber_abi;
> +  bool is_volatile;
> +  bool align_stack;
> +  enum class Dialect
> +  {
> +    Att,
> +    Intel,
> +  } dialect;

Asm Dialect is target specific so this should just be an integer which
gets translated via target hooks instead of a full on enum.

Note GCC's extended asm dialects support up a full 32bit #:
#ifdef ASSEMBLER_DIALECT

/* Number of the assembler dialect to use, starting at 0.  */
static int dialect_number;
#endif
X86 is not the only target which supports an asm dialect: sh, pa,
pdp11 and bpf are other targets which support one.

Thanks,
Andew Pinski

> +
> +public:
> +  LlvmInlineAsm (location_t locus) : locus (locus) {}
> +
> +  Dialect get_dialect () { return dialect; }
> +
> +  location_t get_locus () const override { return locus; }
> +
> +  void mark_for_strip () override {}
> +
> +  bool is_marked_for_strip () const override { return false; }
> +
> +  std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
> +
> +  void accept_vis (ASTVisitor &vis) override;
> +
> +  std::string as_string () const override { return "InlineAsm AST Node"; }
> +
> +  void set_outer_attrs (std::vector<Attribute> v) override { outer_attrs = 
> v; }
> +
> +  LlvmInlineAsm *clone_expr_without_block_impl () const override
> +  {
> +    return new LlvmInlineAsm (*this);
> +  }
> +
> +  Expr::Kind get_expr_kind () const override
> +  {
> +    return Expr::Kind::LlvmInlineAsm;
> +  }
> +};
> +
>  } // namespace AST
>  } // namespace Rust
>
> diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
> index d8cc0a480ab..5fca49ca1f3 100644
> --- a/gcc/rust/expand/rust-derive.h
> +++ b/gcc/rust/expand/rust-derive.h
> @@ -171,6 +171,7 @@ private:
>    virtual void visit (AwaitExpr &expr) override final{};
>    virtual void visit (AsyncBlockExpr &expr) override final{};
>    virtual void visit (InlineAsm &expr) override final{};
> +  virtual void visit (LlvmInlineAsm &expr) override final{};
>    virtual void visit (TypeParam &param) override final{};
>    virtual void visit (LifetimeWhereClauseItem &item) override final{};
>    virtual void visit (TypeBoundWhereClauseItem &item) override final{};
> diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
> b/gcc/rust/expand/rust-macro-builtins-asm.cc
> index 97f7e3cff77..8bee4524d49 100644
> --- a/gcc/rust/expand/rust-macro-builtins-asm.cc
> +++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
> @@ -660,6 +660,15 @@ MacroBuiltin::asm_handler (location_t invoc_locus, 
> AST::MacroInvocData &invoc,
>    return parse_asm (invoc_locus, invoc, semicolon, is_global_asm);
>  }
>
> +tl::optional<AST::Fragment>
> +MacroBuiltin::llvm_asm_handler (location_t invoc_locus,
> +                               AST::MacroInvocData &invoc,
> +                               AST::InvocKind semicolon,
> +                               AST::AsmKind is_global_asm)
> +{
> +  return parse_llvm_asm (invoc_locus, invoc, semicolon, is_global_asm);
> +}
> +
>  tl::expected<InlineAsmContext, InlineAsmParseError>
>  parse_asm_arg (InlineAsmContext inline_asm_ctx)
>  {
> @@ -970,4 +979,16 @@ validate (InlineAsmContext inline_asm_ctx)
>  {
>    return tl::expected<InlineAsmContext, InlineAsmParseError> 
> (inline_asm_ctx);
>  }
> +
> +tl::optional<AST::Fragment>
> +parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
> +               AST::InvocKind semicolon, AST::AsmKind is_global_asm)
> +{
> +  MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
> +  Parser<MacroInvocLexer> parser (lex);
> +  auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
> +
> +  AST::LlvmInlineAsm llvm_asm{invoc_locus};
> +}
> +
>  } // namespace Rust
> diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h 
> b/gcc/rust/expand/rust-macro-builtins-asm.h
> index 8081dae5140..e13ee25a935 100644
> --- a/gcc/rust/expand/rust-macro-builtins-asm.h
> +++ b/gcc/rust/expand/rust-macro-builtins-asm.h
> @@ -172,4 +172,11 @@ tl::optional<std::string>
>  parse_label (Parser<MacroInvocLexer> &parser, TokenId last_token_id,
>              InlineAsmContext &inline_asm_ctx);
>
> +// LLVM ASM bits
> +
> +WARN_UNUSED_RESULT
> +tl::optional<AST::Fragment>
> +parse_llvm_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
> +               AST::InvocKind semicolon, AST::AsmKind is_global_asm);
> +
>  } // namespace Rust
> diff --git a/gcc/rust/expand/rust-macro-builtins.cc 
> b/gcc/rust/expand/rust-macro-builtins.cc
> index 8b406fff9e6..b58ed71ba4e 100644
> --- a/gcc/rust/expand/rust-macro-builtins.cc
> +++ b/gcc/rust/expand/rust-macro-builtins.cc
> @@ -103,6 +103,15 @@ inline_asm_maker (AST::AsmKind global_asm)
>    };
>  }
>
> +AST::MacroTranscriberFunc
> +inline_llvm_asm_maker (AST::AsmKind global_asm)
> +{
> +  return [global_asm] (location_t loc, AST::MacroInvocData &invoc,
> +                      AST::InvocKind semicolon) {
> +    return MacroBuiltin::llvm_asm_handler (loc, invoc, semicolon, 
> global_asm);
> +  };
> +}
> +
>  std::unordered_map<std::string, AST::MacroTranscriberFunc>
>    MacroBuiltin::builtin_transcribers = {
>      {"assert", MacroBuiltin::assert_handler},
> @@ -121,7 +130,7 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
>      {"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
>      {"asm", inline_asm_maker (AST::AsmKind::Inline)},
>      // FIXME: Is that okay?
> -    {"llvm_asm", inline_asm_maker (AST::AsmKind::Inline)},
> +    {"llvm_asm", inline_llvm_asm_maker (AST::AsmKind::Inline)},
>      {"global_asm", inline_asm_maker (AST::AsmKind::Global)},
>      {"option_env", MacroBuiltin::option_env_handler},
>      /* Unimplemented macro builtins */
> diff --git a/gcc/rust/expand/rust-macro-builtins.h 
> b/gcc/rust/expand/rust-macro-builtins.h
> index ff06ebf2289..541e95636b1 100644
> --- a/gcc/rust/expand/rust-macro-builtins.h
> +++ b/gcc/rust/expand/rust-macro-builtins.h
> @@ -180,6 +180,10 @@ public:
>                                                   AST::InvocKind semicolon,
>                                                   AST::AsmKind is_global_asm);
>
> +  static tl::optional<AST::Fragment>
> +  llvm_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
> +                   AST::InvocKind semicolon, AST::AsmKind is_global_asm);
> +
>    static tl::optional<AST::Fragment>
>    format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
>                        AST::InvocKind semicolon, AST::FormatArgs::Newline nl);
> diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
> b/gcc/rust/hir/rust-ast-lower-base.cc
> index 5039798a810..2d9a4450c90 100644
> --- a/gcc/rust/hir/rust-ast-lower-base.cc
> +++ b/gcc/rust/hir/rust-ast-lower-base.cc
> @@ -267,6 +267,10 @@ void
>  ASTLoweringBase::visit (AST::InlineAsm &)
>  {}
>
> +void
> +ASTLoweringBase::visit (AST::LlvmInlineAsm &)
> +{}
> +
>  //  void ASTLoweringBase::visit(MatchCasematch_case) {}
>  // void ASTLoweringBase:: (AST::MatchCaseBlockExpr &) {}
>  // void ASTLoweringBase:: (AST::MatchCaseExpr &) {}
> diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
> b/gcc/rust/hir/rust-ast-lower-base.h
> index b3bb174babf..31161810c6f 100644
> --- a/gcc/rust/hir/rust-ast-lower-base.h
> +++ b/gcc/rust/hir/rust-ast-lower-base.h
> @@ -152,6 +152,7 @@ public:
>    virtual void visit (AST::IfLetExpr &expr) override;
>    virtual void visit (AST::IfLetExprConseqElse &expr) override;
>    virtual void visit (AST::InlineAsm &expr) override;
> +  virtual void visit (AST::LlvmInlineAsm &expr) override;
>    //  virtual void visit(MatchCase& match_case) override;
>    // virtual void visit (AST::MatchCaseBlockExpr &match_case) override;
>    // virtual void visit (AST::MatchCaseExpr &match_case) override;
> diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc 
> b/gcc/rust/resolve/rust-ast-resolve-base.cc
> index 6c35a22b7f6..b781ce33f3f 100644
> --- a/gcc/rust/resolve/rust-ast-resolve-base.cc
> +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
> @@ -327,6 +327,10 @@ void
>  ResolverBase::visit (AST::InlineAsm &)
>  {}
>
> +void
> +ResolverBase::visit (AST::LlvmInlineAsm &)
> +{}
> +
>  void
>  ResolverBase::visit (AST::TypeParam &)
>  {}
> diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h 
> b/gcc/rust/resolve/rust-ast-resolve-base.h
> index ab74e84f079..5bb9e4f1822 100644
> --- a/gcc/rust/resolve/rust-ast-resolve-base.h
> +++ b/gcc/rust/resolve/rust-ast-resolve-base.h
> @@ -110,6 +110,7 @@ public:
>    void visit (AST::AwaitExpr &);
>    void visit (AST::AsyncBlockExpr &);
>    void visit (AST::InlineAsm &);
> +  void visit (AST::LlvmInlineAsm &);
>
>    void visit (AST::TypeParam &);
>
> --
> 2.49.0
>

Reply via email to