aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/hir
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2025-04-15 11:38:29 +0200
committerP-E-P <32375388+P-E-P@users.noreply.github.com>2025-04-17 18:05:17 +0000
commit3e8955884cd816e43a52a0dda31399c01d2d8761 (patch)
tree6eae6fa978d9cabc0f4e6a41aa33d47a3feb8ccf /gcc/rust/hir
parent435b346f47ffa467bb6cfa1717ab9f2283b18d46 (diff)
downloadgcc-3e8955884cd816e43a52a0dda31399c01d2d8761.zip
gcc-3e8955884cd816e43a52a0dda31399c01d2d8761.tar.gz
gcc-3e8955884cd816e43a52a0dda31399c01d2d8761.tar.bz2
Parse and lower llvm asm node
Add a new HIR LlvmInlineAsm HIR node as well as some structures to represent it's options and operands. Lower AST::LlvmInlineAsm node to it and then create a tree from that node. gcc/rust/ChangeLog: * ast/rust-ast-collector.cc (TokenCollector::visit): Remove unreachable code. * ast/rust-expr.h (struct LlvmOperand): Add LlvmOperand struct to represent input and outputs. (class LlvmInlineAsm): Add input, output and clobber operands. (struct TupleTemplateStr): Add locus getter. * backend/rust-compile-block.h: Add visit for LlvmInlineAsm. * backend/rust-compile-expr.cc (CompileExpr::visit): Add llvm inline asm stmt compilation. * backend/rust-compile-expr.h: Add function prototype. * backend/rust-compile-asm.h (class CompileLlvmAsm): Add llvm asm hir not to gimple. * backend/rust-compile-asm.cc (CompileLlvmAsm::CompileLlvmAsm): Add constructor. (CompileLlvmAsm::construct_operands): Add function to construct operand tree. (CompileLlvmAsm::construct_clobbers): Add function to construct clobber tree. (CompileLlvmAsm::tree_codegen_asm): Generate the whole tree for a given llvm inline assembly node. * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit): Add visit function. * checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Add function prototype. * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Add visit function. * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise. * checks/errors/borrowck/rust-function-collector.h: Likewise. * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit): Likewise. * checks/errors/privacy/rust-privacy-reporter.h: Add visit function prototype. * checks/errors/rust-const-checker.cc (ConstChecker::visit): Add visit function. * checks/errors/rust-const-checker.h: Add visit function prototype. * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): Add visit function. * checks/errors/rust-hir-pattern-analysis.h: Add visit function prototype. * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Add visit function. * checks/errors/rust-unsafe-checker.h: Add function prototype. * expand/rust-macro-builtins-asm.cc (parse_llvm_templates): Parse templates. (parse_llvm_arguments): Add function to parse non template tokens. (parse_llvm_operands): Add function to parse operands, either input or output. (parse_llvm_outputs): Add function to parse and collect llvm asm outputs. (parse_llvm_inputs): Likewise with inputs. (parse_llvm_clobbers): Add function to parse llvm asm clobbers. (parse_llvm_options): Add function to parse llvm asm options. (parse_llvm_asm): Add function to parse llvm asm. * expand/rust-macro-builtins-asm.h (class LlvmAsmContext): Add context for llvm asm parser. (parse_llvm_outputs): Add function prototype. (parse_llvm_inputs): Likewise. (parse_llvm_clobbers): Likewise. (parse_llvm_options): Likewise. * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Lower AST llvm asm node to HIR. * hir/rust-ast-lower-expr.h: Add function prototype. * hir/rust-hir-dump.cc (Dump::visit): Add visit function. * hir/rust-hir-dump.h: Add function prototype. * hir/tree/rust-hir-expr-abstract.h: Add HIR llvm asm node kind. * hir/tree/rust-hir-expr.h (struct LlvmOperand): Add LlvmOperand type to represent input and outputs. (class LlvmInlineAsm): Add LlvmInlineAsm hir node. * hir/tree/rust-hir-full-decls.h (class LlvmInlineAsm): Add LlvmInlineAsm hir node forward declaration. * hir/tree/rust-hir-visitor.h: Add visit functions for LlvmInlineAsm hir node. * hir/tree/rust-hir.cc (LlvmInlineAsm::accept_vis): Add hir node visitor related functions. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Type check input and output operands. * typecheck/rust-hir-type-check-expr.h: Add function prototype. * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Visit input and output operand expressions. * resolve/rust-ast-resolve-expr.cc (ResolveExpr::visit): Resolve input and output expressions. * resolve/rust-ast-resolve-expr.h: Add function prototypes. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Diffstat (limited to 'gcc/rust/hir')
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.cc44
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h1
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc4
-rw-r--r--gcc/rust/hir/rust-hir-dump.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr-abstract.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h74
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc11
9 files changed, 140 insertions, 0 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc
index 3f040d4..e9e3b4e 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -955,6 +955,50 @@ ASTLoweringExpr::visit (AST::InlineAsm &expr)
hir_operands, expr.get_clobber_abi (),
expr.get_options (), mapping);
}
+
+void
+ASTLoweringExpr::visit (AST::LlvmInlineAsm &expr)
+{
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ mappings.get_next_localdef_id (crate_num));
+
+ std::vector<LlvmOperand> inputs;
+ std::vector<LlvmOperand> outputs;
+
+ for (auto i : expr.get_inputs ())
+ {
+ std::unique_ptr<Expr> inner_expr
+ = std::unique_ptr<Expr> (translate (*i.expr.get ()));
+ inputs.emplace_back (i.constraint, std::move (inner_expr));
+ }
+
+ for (auto o : expr.get_outputs ())
+ {
+ std::unique_ptr<Expr> inner_expr
+ = std::unique_ptr<Expr> (translate (*o.expr.get ()));
+ outputs.emplace_back (o.constraint, std::move (inner_expr));
+ }
+
+ HIR::LlvmInlineAsm::Options options{expr.is_volatile (),
+ expr.is_stack_aligned (),
+ expr.get_dialect ()};
+
+ // We're not really supporting llvm_asm, only the bare minimum
+ // we're quite conservative here as the current code support more usecase.
+ rust_assert (outputs.size () == 0);
+ rust_assert (inputs.size () <= 1);
+ rust_assert (expr.get_clobbers ().size () <= 1);
+ rust_assert (expr.get_templates ().size () == 1);
+ rust_assert (expr.get_templates ()[0].symbol == "");
+
+ translated
+ = new HIR::LlvmInlineAsm (expr.get_locus (), inputs, outputs,
+ expr.get_templates (), expr.get_clobbers (),
+ options, expr.get_outer_attrs (), mapping);
+}
+
void
ASTLoweringExpr::visit (AST::FormatArgs &fmt)
{
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index dd903a0..b8681fb 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -122,6 +122,7 @@ public:
void visit (AST::ClosureExprInner &expr) override;
void visit (AST::ClosureExprInnerTyped &expr) override;
void visit (AST::InlineAsm &expr) override;
+ void visit (AST::LlvmInlineAsm &expr) override;
// Extra visitor for FormatArgs nodes
void visit (AST::FormatArgs &fmt) override;
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index c4523e6..156bd81 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1510,6 +1510,10 @@ Dump::visit (InlineAsm &e)
{}
void
+Dump::visit (LlvmInlineAsm &e)
+{}
+
+void
Dump::visit (TypeParam &e)
{
begin ("TypeParam");
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index 49ac405..b3015c6 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -166,6 +166,7 @@ private:
virtual void visit (AwaitExpr &) override;
virtual void visit (AsyncBlockExpr &) override;
virtual void visit (InlineAsm &) override;
+ virtual void visit (LlvmInlineAsm &) override;
virtual void visit (TypeParam &) override;
virtual void visit (ConstGenericParam &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
index ecf9bd1..5bc5d89 100644
--- a/gcc/rust/hir/tree/rust-hir-expr-abstract.h
+++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
@@ -71,6 +71,7 @@ public:
AsyncBlock,
Path,
InlineAsm,
+ LlvmInlineAsm,
};
BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; }
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 20287b8..6400cb9 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -3118,6 +3118,80 @@ public:
AST::AttrVec outer_attribs = AST::AttrVec ());
};
+struct LlvmOperand
+{
+ std::string constraint;
+ std::unique_ptr<Expr> expr;
+
+ LlvmOperand (std::string constraint, std::unique_ptr<Expr> &&expr)
+ : constraint (constraint), expr (std::move (expr))
+ {}
+
+ LlvmOperand (const LlvmOperand &other)
+ : constraint (other.constraint), expr (other.expr->clone_expr ())
+ {}
+ LlvmOperand &operator= (const LlvmOperand &other)
+ {
+ constraint = other.constraint;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+ }
+};
+
+class LlvmInlineAsm : public ExprWithoutBlock
+{
+public:
+ struct Options
+ {
+ bool is_volatile;
+ bool align_stack;
+ AST::LlvmInlineAsm::Dialect dialect;
+ };
+
+ location_t locus;
+ AST::AttrVec outer_attrs;
+ std::vector<LlvmOperand> inputs;
+ std::vector<LlvmOperand> outputs;
+ std::vector<AST::TupleTemplateStr> templates;
+ std::vector<AST::TupleClobber> clobbers;
+ Options options;
+
+ LlvmInlineAsm (location_t locus, std::vector<LlvmOperand> inputs,
+ std::vector<LlvmOperand> outputs,
+ std::vector<AST::TupleTemplateStr> templates,
+ std::vector<AST::TupleClobber> clobbers, Options options,
+ AST::AttrVec outer_attrs, Analysis::NodeMapping mappings)
+ : ExprWithoutBlock (mappings, std::move (outer_attrs)), locus (locus),
+ inputs (std::move (inputs)), outputs (std::move (outputs)),
+ templates (std::move (templates)), clobbers (std::move (clobbers)),
+ options (options)
+ {}
+
+ AST::LlvmInlineAsm::Dialect get_dialect () { return options.dialect; }
+
+ location_t get_locus () const override { return locus; }
+
+ std::vector<AST::Attribute> &get_outer_attrs () { return outer_attrs; }
+
+ void accept_vis (HIRFullVisitor &vis) override;
+ void accept_vis (HIRExpressionVisitor &vis) override;
+
+ LlvmInlineAsm *clone_expr_without_block_impl () const override
+ {
+ return new LlvmInlineAsm (*this);
+ }
+
+ std::vector<AST::TupleTemplateStr> &get_templates () { return templates; }
+
+ Expr::ExprType get_expression_type () const override
+ {
+ return Expr::ExprType::LlvmInlineAsm;
+ }
+
+ std::vector<AST::TupleClobber> get_clobbers () { return clobbers; }
+};
+
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 6eae99d..a1722b0 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -126,6 +126,7 @@ class InlineAsmRegClass;
struct AnonConst;
class InlineAsmOperand;
class InlineAsm;
+class LlvmInlineAsm;
// rust-stmt.h
class EmptyStmt;
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index b14547b..c934484 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -84,6 +84,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;
virtual void visit (TypeParam &param) = 0;
virtual void visit (ConstGenericParam &param) = 0;
virtual void visit (LifetimeWhereClauseItem &item) = 0;
@@ -220,6 +221,7 @@ public:
virtual void visit (AwaitExpr &) override {}
virtual void visit (AsyncBlockExpr &) override {}
virtual void visit (InlineAsm &) override {}
+ virtual void visit (LlvmInlineAsm &) override {}
virtual void visit (TypeParam &) override {}
virtual void visit (ConstGenericParam &) override {}
@@ -441,6 +443,7 @@ public:
virtual void visit (IfExpr &expr) = 0;
virtual void visit (IfExprConseqElse &expr) = 0;
virtual void visit (InlineAsm &expr) = 0;
+ virtual void visit (LlvmInlineAsm &expr) = 0;
virtual void visit (MatchExpr &expr) = 0;
virtual void visit (AwaitExpr &expr) = 0;
virtual void visit (AsyncBlockExpr &expr) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index 4fc6b1a..c943357 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -3822,6 +3822,17 @@ InlineAsm::accept_vis (HIRFullVisitor &vis)
}
void
+LlvmInlineAsm::accept_vis (HIRFullVisitor &vis)
+{
+ vis.visit (*this);
+}
+void
+LlvmInlineAsm::accept_vis (HIRExpressionVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
BorrowExpr::accept_vis (HIRExpressionVisitor &vis)
{
vis.visit (*this);