From 467141184aa274126ff7e2a41d08bb621b7a3fdf Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 24 Dec 2020 21:26:26 +0000 Subject: Implement constant expressions --- gcc/rust/backend/rust-compile-context.h | 16 ++++++++++++++++ gcc/rust/backend/rust-compile-expr.h | 5 +++++ gcc/rust/backend/rust-compile-item.h | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 5736bf2..288dbda 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -141,6 +141,21 @@ public: return true; } + void insert_const_decl (HirId id, ::Bexpression *expr) + { + compiled_consts[id] = expr; + } + + bool lookup_const_decl (HirId id, ::Bexpression **expr) + { + auto it = compiled_consts.find (id); + if (it == compiled_consts.end ()) + return false; + + *expr = it->second; + return true; + } + void push_fn (::Bfunction *fn, ::Bvariable *ret_addr) { fn_stack.push_back (fncontext{fn, ret_addr}); @@ -183,6 +198,7 @@ private: std::map compiled_var_decls; std::map compiled_type_map; std::map compiled_fn_map; + std::map compiled_consts; std::vector< ::std::vector > statements; std::vector< ::Bblock *> scope_stack; diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 5c3206a..871b4ba 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -105,6 +105,11 @@ public: return; } + // this could be a constant reference + if (ctx->lookup_const_decl (ref, &translated)) + return; + + // must be an identifier Bvariable *var = nullptr; if (!ctx->lookup_var_decl (ref, &var)) { diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index f131a89..10bdce0 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -23,6 +23,7 @@ #include "rust-compile-tyty.h" #include "rust-compile-var-decl.h" #include "rust-compile-stmt.h" +#include "rust-compile-expr.h" namespace Rust { namespace Compile { @@ -38,6 +39,24 @@ public: virtual ~CompileItem () {} + void visit (HIR::ConstantItem &constant) + { + TyTy::TyBase *resolved_type = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (), + &resolved_type); + rust_assert (ok); + + ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type); + Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx); + + Bexpression *const_expr = ctx->get_backend ()->named_constant_expression ( + type, constant.get_identifier (), value, constant.get_locus ()); + + ctx->push_const (const_expr); + ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); + } + void visit (HIR::Function &function) { // items can be forward compiled which means we may not need to invoke this -- cgit v1.1 From 36ebe9a0380694c8517536eb37c7134f1323a30b Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 30 Dec 2020 22:13:41 +0000 Subject: This brings structs back in post HIR changes. It supports structs where no base struct is referenced and the constructor is in order. --- gcc/rust/backend/rust-compile-context.h | 8 ++++ gcc/rust/backend/rust-compile-expr.h | 22 +++++++++- gcc/rust/backend/rust-compile-item.h | 29 +++++++++++++ gcc/rust/backend/rust-compile-resolve-path.cc | 30 ++++++++++++- gcc/rust/backend/rust-compile-resolve-path.h | 27 +++++++++--- gcc/rust/backend/rust-compile-struct-field-expr.h | 52 +++++++++++++++++++++++ gcc/rust/backend/rust-compile.cc | 9 ++++ 7 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 gcc/rust/backend/rust-compile-struct-field-expr.h (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 288dbda..9f1475a 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -227,6 +227,14 @@ public: void visit (TyTy::FnType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override + { + ::Btype *compiled_type = nullptr; + bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); + rust_assert (ok); + translated = compiled_type; + } + void visit (TyTy::ArrayType &type) override { mpz_t ival; diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 871b4ba..7b01e0e 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -23,6 +23,7 @@ #include "rust-compile-tyty.h" #include "rust-compile-resolve-path.h" #include "rust-compile-block.h" +#include "rust-compile-struct-field-expr.h" namespace Rust { namespace Compile { @@ -56,7 +57,7 @@ public: void visit (HIR::CallExpr &expr) { - Bexpression *fn = ResolvePath::Compile (expr.get_fnexpr (), ctx); + Bexpression *fn = ResolvePathRef::Compile (expr.get_fnexpr (), ctx); rust_assert (fn != nullptr); std::vector args; @@ -355,6 +356,25 @@ public: ctx->add_statement (block_stmt); } + void visit (HIR::StructExprStructFields &struct_expr) + { + Btype *type + = ResolvePathType::Compile (&struct_expr.get_struct_name (), ctx); + + // this assumes all fields are in order from type resolution and if a base + // struct was specified those fields are filed via accesors + std::vector vals; + struct_expr.iterate ([&] (HIR::StructExprField *field) mutable -> bool { + Bexpression *expr = CompileStructExprField::Compile (field, ctx); + vals.push_back (expr); + return true; + }); + + translated + = ctx->get_backend ()->constructor_expression (type, vals, + struct_expr.get_locus ()); + } + private: CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index 10bdce0..aa65962 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -39,6 +39,35 @@ public: virtual ~CompileItem () {} + void visit (HIR::StructStruct &struct_decl) + { + std::vector fields; + struct_decl.iterate ([&] (HIR::StructField &field) mutable -> bool { + TyTy::TyBase *resolved_type = nullptr; + bool ok + = ctx->get_tyctx ()->lookup_type (field.get_mappings ().get_hirid (), + &resolved_type); + rust_assert (ok); + + Btype *compiled_field_ty + = TyTyCompile::compile (ctx->get_backend (), resolved_type); + + Backend::Btyped_identifier f (field.field_name, compiled_field_ty, + field.get_locus ()); + fields.push_back (std::move (f)); + return true; + }); + + Btype *struct_type_record = ctx->get_backend ()->struct_type (fields); + Btype *named_struct + = ctx->get_backend ()->named_type (struct_decl.get_identifier (), + struct_type_record, + struct_decl.get_locus ()); + ctx->push_type (named_struct); + ctx->insert_compiled_type (struct_decl.get_mappings ().get_hirid (), + named_struct); + } + void visit (HIR::ConstantItem &constant) { TyTy::TyBase *resolved_type = nullptr; diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index c5c646d..c24005e 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -25,7 +25,7 @@ namespace Rust { namespace Compile { void -ResolvePath::visit (HIR::PathInExpression &expr) +ResolvePathRef::visit (HIR::PathInExpression &expr) { // need to look up the reference for this identifier NodeId ref_node_id; @@ -70,5 +70,33 @@ ResolvePath::visit (HIR::PathInExpression &expr) = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ()); } +void +ResolvePathType::visit (HIR::PathInExpression &expr) +{ + // need to look up the reference for this identifier + NodeId ref_node_id; + if (!ctx->get_resolver ()->lookup_resolved_name ( + expr.get_mappings ().get_nodeid (), &ref_node_id)) + { + rust_fatal_error (expr.get_locus (), "failed to look up resolved name"); + return; + } + + HirId ref; + if (!ctx->get_mappings ()->lookup_node_to_hir ( + expr.get_mappings ().get_crate_num (), ref_node_id, &ref)) + { + rust_fatal_error (expr.get_locus (), "reverse lookup failure"); + return; + } + + // assumes paths are functions for now + if (!ctx->lookup_compiled_types (ref, &resolved)) + { + rust_fatal_error (expr.get_locus (), "forward decl was not compiled"); + return; + } +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h index d8f393d..a5543d2 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.h +++ b/gcc/rust/backend/rust-compile-resolve-path.h @@ -25,27 +25,44 @@ namespace Rust { namespace Compile { -class ResolvePath : public HIRCompileBase +class ResolvePathRef : public HIRCompileBase { public: static Bexpression *Compile (HIR::Expr *expr, Context *ctx) { - ResolvePath resolver (ctx); + ResolvePathRef resolver (ctx); expr->accept_vis (resolver); rust_assert (resolver.resolved != nullptr); return resolver.resolved; } - virtual ~ResolvePath () {} - void visit (HIR::PathInExpression &expr); private: - ResolvePath (Context *ctx) : HIRCompileBase (ctx), resolved (nullptr) {} + ResolvePathRef (Context *ctx) : HIRCompileBase (ctx), resolved (nullptr) {} Bexpression *resolved; }; +class ResolvePathType : public HIRCompileBase +{ +public: + static Btype *Compile (HIR::Expr *expr, Context *ctx) + { + ResolvePathType resolver (ctx); + expr->accept_vis (resolver); + rust_assert (resolver.resolved != nullptr); + return resolver.resolved; + } + + void visit (HIR::PathInExpression &expr); + +private: + ResolvePathType (Context *ctx) : HIRCompileBase (ctx), resolved (nullptr) {} + + Btype *resolved; +}; + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h new file mode 100644 index 0000000..a394f7a --- /dev/null +++ b/gcc/rust/backend/rust-compile-struct-field-expr.h @@ -0,0 +1,52 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// . + +#ifndef RUST_COMPILE_STRUCT_FIELD_EXPR +#define RUST_COMPILE_STRUCT_FIELD_EXPR + +#include "rust-compile-base.h" +#include "rust-compile-tyty.h" + +namespace Rust { +namespace Compile { + +class CompileStructExprField : public HIRCompileBase +{ +public: + static Bexpression *Compile (HIR::StructExprField *field, Context *ctx) + { + CompileStructExprField compiler (ctx); + field->accept_vis (compiler); + rust_assert (compiler.translated != nullptr); + return compiler.translated; + } + + void visit (HIR::StructExprFieldIdentifierValue &field); + +private: + CompileStructExprField (Context *ctx) + : HIRCompileBase (ctx), translated (nullptr) + {} + + Bexpression *translated; +}; + +} // namespace Compile +} // namespace Rust + +#endif // RUST_COMPILE_STRUCT_FIELD_EXPR diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 02fa3a0..24b45ee 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -19,6 +19,7 @@ #include "rust-compile.h" #include "rust-compile-item.h" #include "rust-compile-expr.h" +#include "rust-compile-struct-field-expr.h" namespace Rust { namespace Compile { @@ -152,5 +153,13 @@ CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr) else_block, expr.get_locus ()); } +// rust-compile-struct-field-expr.h + +void +CompileStructExprField::visit (HIR::StructExprFieldIdentifierValue &field) +{ + translated = CompileExpr::Compile (field.get_value (), ctx); +} + } // namespace Compile } // namespace Rust -- cgit v1.1 From 1a97dbc6b54cd77ba7c3f00cb8dd2e870017a83c Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Tue, 5 Jan 2021 17:49:01 +0000 Subject: Examine the Suffix hint on integers to apply apropriate TyTy type. This change propagates the PrimitiveCoreType to AST and HIR so the suffix can be examined. --- gcc/rust/backend/rust-compile-tyty.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index 66d2472..f4e467a 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -111,6 +111,18 @@ public: = backend->named_type ("i32", backend->integer_type (false, 32), Linemap::predeclared_location ()); return; + + case TyTy::IntType::I64: + translated + = backend->named_type ("i64", backend->integer_type (false, 64), + Linemap::predeclared_location ()); + return; + + case TyTy::IntType::I128: + translated + = backend->named_type ("i128", backend->integer_type (false, 128), + Linemap::predeclared_location ()); + return; } gcc_unreachable (); } @@ -135,6 +147,18 @@ public: = backend->named_type ("i32", backend->integer_type (true, 32), Linemap::predeclared_location ()); return; + + case TyTy::UintType::U64: + translated + = backend->named_type ("u64", backend->integer_type (true, 64), + Linemap::predeclared_location ()); + return; + + case TyTy::UintType::U128: + translated + = backend->named_type ("u128", backend->integer_type (true, 128), + Linemap::predeclared_location ()); + return; } gcc_unreachable (); } -- cgit v1.1 From aef9821d9b04fffadb4c0f9796652cec58da8902 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Tue, 5 Jan 2021 15:51:46 +0000 Subject: Add in F32 and F64 types builtin types. We need to ensure all suffix of literals are handled in a subsequent PR. --- gcc/rust/backend/rust-compile-context.h | 8 ++++++++ gcc/rust/backend/rust-compile-expr.h | 30 ++++++++++++++++++++++++++++++ gcc/rust/backend/rust-compile-tyty.h | 18 ++++++++++++++++++ 3 files changed, 56 insertions(+) (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index 9f1475a..d241921 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -272,6 +272,14 @@ public: translated = compiled_type; } + void visit (TyTy::FloatType &type) override + { + ::Btype *compiled_type = nullptr; + bool ok = ctx->lookup_compiled_types (type.get_ref (), &compiled_type); + rust_assert (ok); + translated = compiled_type; + } + private: TyTyResolveCompile (Context *ctx) : ctx (ctx) {} diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 7b01e0e..9081000 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -155,6 +155,36 @@ public: } return; + case HIR::Literal::FLOAT: { + printf ("FLOATY BOYO: [%s]\n", expr.as_string ().c_str ()); + + mpfr_t fval; + if (mpfr_init_set_str (fval, expr.as_string ().c_str (), 10, + MPFR_RNDN) + != 0) + { + rust_fatal_error (expr.get_locus (), + "bad float number in literal"); + return; + } + + TyTy::TyBase *tyty = nullptr; + if (!ctx->get_tyctx ()->lookup_type ( + expr.get_mappings ().get_hirid (), &tyty)) + { + rust_fatal_error (expr.get_locus (), + "did not resolve type for this literal expr"); + return; + } + + printf ("tyty float is [%s]\n", tyty->as_string ().c_str ()); + + Btype *type = TyTyResolveCompile::compile (ctx, tyty); + translated + = ctx->get_backend ()->float_constant_expression (type, fval); + } + return; + default: rust_fatal_error (expr.get_locus (), "unknown literal"); return; diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index f4e467a..e3c8a73 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -163,6 +163,24 @@ public: gcc_unreachable (); } + void visit (TyTy::FloatType &type) override + { + switch (type.get_kind ()) + { + case TyTy::FloatType::F32: + translated = backend->named_type ("f32", backend->float_type (32), + Linemap::predeclared_location ()); + return; + + case TyTy::FloatType::F64: + translated = backend->named_type ("f32", backend->float_type (64), + Linemap::predeclared_location ()); + return; + } + + gcc_unreachable (); + } + private: TyTyCompile (::Backend *backend) : backend (backend), translated (nullptr), -- cgit v1.1 From 82d80bf20ec46fc9a1e5b44a5f1231b584bcb28e Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 6 Jan 2021 10:21:20 +0000 Subject: Fix bad naming of f64 named type in GIMPLE. --- gcc/rust/backend/rust-compile-tyty.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index e3c8a73..528f90e 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -173,7 +173,7 @@ public: return; case TyTy::FloatType::F64: - translated = backend->named_type ("f32", backend->float_type (64), + translated = backend->named_type ("f64", backend->float_type (64), Linemap::predeclared_location ()); return; } -- cgit v1.1 From c2cc8df0b5aacd448f464e5a927d03730698aba8 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Tue, 5 Jan 2021 13:26:47 +0000 Subject: Add in support to compile static variables. Still requires name mangling for the ASM name similar to functions. --- gcc/rust/backend/rust-compile-item.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'gcc/rust/backend') diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index aa65962..90630bb 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -68,6 +68,34 @@ public: named_struct); } + void visit (HIR::StaticItem &var) + { + TyTy::TyBase *resolved_type = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type (var.get_mappings ().get_hirid (), + &resolved_type); + rust_assert (ok); + + Btype *type = TyTyResolveCompile::compile (ctx, resolved_type); + Bexpression *value = CompileExpr::Compile (var.get_expr (), ctx); + + std::string name = var.get_identifier (); + // FIXME need name mangling + std::string asm_name = "__" + var.get_identifier (); + + bool is_external = false; + bool is_hidden = false; + bool in_unique_section = true; + + Bvariable *static_global + = ctx->get_backend ()->global_variable (name, asm_name, type, is_external, + is_hidden, in_unique_section, + var.get_locus ()); + ctx->get_backend ()->global_variable_set_init (static_global, value); + + ctx->insert_var_decl (var.get_mappings ().get_hirid (), static_global); + ctx->push_var (static_global); + } + void visit (HIR::ConstantItem &constant) { TyTy::TyBase *resolved_type = nullptr; -- cgit v1.1