From 0c7faa5fd118366c4b272e036e95625ebccf67ea Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 26 Feb 2017 18:15:35 +0800 Subject: Main - Add support for -g option --- src/main.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 3eb385f7..28889159 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -131,6 +131,9 @@ struct ProgramParams ::AST::Crate::Type crate_type = ::AST::Crate::Type::Unknown; ::std::string crate_name; + unsigned opt_level = 0; + bool emit_debug_info = false; + ::std::vector lib_search_dirs; ::std::vector libraries; @@ -450,6 +453,7 @@ int main(int argc, char *argv[]) for(const char* libdir : params.libraries ) { trans_opt.libraries.push_back( libdir ); } + trans_opt.emit_debug_info = params.emit_debug_info; // Generate code for non-generic public items (if requested) switch( crate_type ) @@ -579,6 +583,12 @@ ProgramParams::ProgramParams(int argc, char *argv[]) } this->outfile = argv[++i]; break; + case 'O': + this->opt_level = 2; + break; + case 'g': + this->emit_debug_info = true; + break; default: exit(1); } -- cgit v1.2.3 From 95ca7ba9049d378d602c0b44b7569c3276a013d5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 16 Mar 2017 11:54:47 +0800 Subject: Main - Set target_family --- src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 28889159..c534ff15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -174,6 +174,7 @@ int main(int argc, char *argv[]) Cfg_SetFlag("unix"); Cfg_SetFlag("linux"); Cfg_SetValue("target_os", "linux"); + Cfg_SetValue("target_family", "unix"); Cfg_SetValue("target_pointer_width", "64"); Cfg_SetValue("target_endian", "little"); Cfg_SetValue("target_arch", "x86_64"); @@ -437,6 +438,9 @@ int main(int argc, char *argv[]) CompilePhaseV("MIR Validate PO", [&]() { MIR_CheckCrate(*hir_crate); }); + CompilePhaseV("MIR Validate Full", [&]() { + //MIR_CheckCrate_Full(*hir_crate); + }); if( params.last_stage == ProgramParams::STAGE_MIR ) { return 0; -- cgit v1.2.3 From a223ffb9d0629e8b498f07dc67f056a7fb95385e Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 13 Apr 2017 12:46:01 +0800 Subject: All - Add rough support for #[test] (runs basic tests) --- Makefile | 1 + src/ast/crate.hpp | 21 ++++++++ src/expand/test.cpp | 14 ++++- src/expand/test_harness.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++ src/include/main_bindings.hpp | 1 + src/main.cpp | 24 ++++++++- src/trans/codegen_c.cpp | 1 + src/trans/main_bindings.hpp | 1 + 8 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 src/expand/test_harness.cpp (limited to 'src/main.cpp') diff --git a/Makefile b/Makefile index 17fbf665..2e907516 100644 --- a/Makefile +++ b/Makefile @@ -84,6 +84,7 @@ OBJ += expand/include.o OBJ += expand/env.o OBJ += expand/test.o OBJ += expand/rustc_diagnostics.o +OBJ += expand/test_harness.o OBJ += macro_rules/mod.o macro_rules/eval.o macro_rules/parse.o OBJ += resolve/use.o resolve/index.o resolve/absolute.o OBJ += hir/from_ast.o hir/from_ast_expr.o diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp index b74012a3..f9594a83 100644 --- a/src/ast/crate.hpp +++ b/src/ast/crate.hpp @@ -10,6 +10,23 @@ namespace AST { class ExternCrate; +class TestDesc +{ +public: + ::AST::Path path; + ::std::string name; + bool ignore = false; + bool is_benchmark = false; + + enum class ShouldPanic { + No, + Yes, + YesWithMessage, + } panic_type = ShouldPanic::No; + + ::std::string expected_panic_message; +}; + class Crate { public: @@ -22,6 +39,10 @@ public: // Mapping filled by searching for (?visible) macros with is_pub=true ::std::map< ::std::string, const MacroRules*> m_exported_macros; + // List of tests (populated in expand if --test is passed) + bool m_test_harness = false; + ::std::vector m_tests; + enum class Type { Unknown, RustLib, diff --git a/src/expand/test.cpp b/src/expand/test.cpp index fba6556f..26639203 100644 --- a/src/expand/test.cpp +++ b/src/expand/test.cpp @@ -7,6 +7,7 @@ */ #include #include +#include class CTestHandler: public ExpandDecorator @@ -18,8 +19,17 @@ class CTestHandler: ERROR(sp, E0000, "#[test] can only be put on functions - found on " << i.tag_str()); } - // TODO: Proper #[test] support, for now just remove them - i = AST::Item::make_None({}); + if( crate.m_test_harness ) + { + ::AST::TestDesc td; + td.name = path.nodes().back().name(); + td.path = ::AST::Path(path); + crate.m_tests.push_back( mv$(td) ); + } + else + { + i = AST::Item::make_None({}); + } } }; diff --git a/src/expand/test_harness.cpp b/src/expand/test_harness.cpp new file mode 100644 index 00000000..883bd2aa --- /dev/null +++ b/src/expand/test_harness.cpp @@ -0,0 +1,116 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * expand/mod.cpp + * - Expand pass core code + */ +#include +#include +#include +#include +#include // ABI_RUST + +#define NEWNODE(_ty, ...) ::AST::ExprNodeP(new ::AST::ExprNode##_ty(__VA_ARGS__)) + +void Expand_TestHarness(::AST::Crate& crate) +{ + // Create the following module: + // ``` + // mod `#test` { + // extern crate std; + // extern crate test; + // fn main() { + // self::test::test_main_static(&::`#test`::TESTS); + // } + // static TESTS: [test::TestDescAndFn; _] = [ + // test::TestDescAndFn { desc: test::TestDesc { name: "foo", ignore: false, should_panic: test::ShouldPanic::No }, testfn: ::path::to::foo }, + // ]; + // } + // ``` + + // ---- main function ---- + auto main_fn = ::AST::Function { Span(), {}, ABI_RUST, false, false, false, TypeRef(TypeRef::TagUnit(), Span()), {} }; + { + auto call_node = NEWNODE(_CallPath, + ::AST::Path("test", { ::AST::PathNode("test_main_static") }), + ::make_vec1( + NEWNODE(_UniOp, ::AST::ExprNode_UniOp::REF, + NEWNODE(_NamedValue, ::AST::Path("", { ::AST::PathNode("test#"), ::AST::PathNode("TESTS") })) + ) + ) + ); + main_fn.set_code( mv$(call_node) ); + } + + + // ---- test list ---- + ::std::vector< ::AST::ExprNodeP> test_nodes; + + for(const auto& test : crate.m_tests) + { + ::AST::ExprNode_StructLiteral::t_values desc_vals; + // `name: "foo",` + desc_vals.push_back( ::std::make_pair("name", NEWNODE(_CallPath, + ::AST::Path("test", { ::AST::PathNode("StaticTestName") }), + ::make_vec1( NEWNODE(_String, test.name) ) + ) )); + // `ignore: false,` + desc_vals.push_back( ::std::make_pair("ignore", NEWNODE(_Bool, test.ignore)) ); + // `should_panic: ShouldPanic::No,` + { + ::AST::ExprNodeP should_panic_val; + switch(test.panic_type) + { + case ::AST::TestDesc::ShouldPanic::No: + should_panic_val = NEWNODE(_NamedValue, ::AST::Path("test", { ::AST::PathNode("ShouldPanic"), ::AST::PathNode("No") })); + break; + case ::AST::TestDesc::ShouldPanic::Yes: + should_panic_val = NEWNODE(_NamedValue, ::AST::Path("test", { ::AST::PathNode("ShouldPanic"), ::AST::PathNode("Yes") })); + break; + case ::AST::TestDesc::ShouldPanic::YesWithMessage: + should_panic_val = NEWNODE(_CallPath, + ::AST::Path("test", { ::AST::PathNode("ShouldPanic"), ::AST::PathNode("YesWithMessage") }), + make_vec1( NEWNODE(_String, test.expected_panic_message) ) + ); + break; + } + desc_vals.push_back( ::std::make_pair("should_panic", mv$(should_panic_val)) ); + } + auto desc_expr = NEWNODE(_StructLiteral, ::AST::Path("test", { ::AST::PathNode("TestDesc")}), nullptr, mv$(desc_vals)); + + ::AST::ExprNode_StructLiteral::t_values descandfn_vals; + descandfn_vals.push_back( ::std::make_pair(::std::string("desc"), mv$(desc_expr)) ); + + auto test_type_var_name = test.is_benchmark ? "StaticBenchFn" : "StaticTestFn"; + descandfn_vals.push_back( ::std::make_pair(::std::string("testfn"), NEWNODE(_CallPath, + ::AST::Path("test", { ::AST::PathNode(test_type_var_name) }), + ::make_vec1( NEWNODE(_NamedValue, AST::Path(test.path)) ) + ) ) ); + + test_nodes.push_back( NEWNODE(_StructLiteral, ::AST::Path("test", { ::AST::PathNode("TestDescAndFn")}), nullptr, mv$(descandfn_vals) ) ); + } + auto* tests_array = new ::AST::ExprNode_Array(mv$(test_nodes)); + + size_t test_count = tests_array->m_values.size(); + auto tests_list = ::AST::Static { ::AST::Static::Class::STATIC, + TypeRef(TypeRef::TagSizedArray(), Span(), + TypeRef(Span(), ::AST::Path("test", { ::AST::PathNode("TestDescAndFn") })), + ::std::shared_ptr<::AST::ExprNode>( new ::AST::ExprNode_Integer(test_count, CORETYPE_UINT) ) + ), + ::AST::Expr( mv$(tests_array) ) + }; + + // ---- module ---- + auto newmod = ::AST::Module { ::AST::Path("", { ::AST::PathNode("test#") }) }; + // - TODO: These need to be loaded too. + // > They don't actually need to exist here, just be loaded (and use absolute paths) + newmod.add_ext_crate(false, "std", "std", {}); + newmod.add_ext_crate(false, "test", "test", {}); + + newmod.add_item(false, "main", mv$(main_fn), {}); + newmod.add_item(false, "TESTS", mv$(tests_list), {}); + + crate.m_root_module.add_item(false, "test#", mv$(newmod), {}); + crate.m_lang_items["mrustc-main"] = ::AST::Path("", { AST::PathNode("test#"), AST::PathNode("main") }); +} diff --git a/src/include/main_bindings.hpp b/src/include/main_bindings.hpp index c01ff86d..184f266f 100644 --- a/src/include/main_bindings.hpp +++ b/src/include/main_bindings.hpp @@ -16,6 +16,7 @@ extern AST::Crate Parse_Crate(::std::string mainfile); extern void Expand(::AST::Crate& crate); +extern void Expand_TestHarness(::AST::Crate& crate); /// Process #[] decorators extern void Process_Decorators(AST::Crate& crate); diff --git a/src/main.cpp b/src/main.cpp index c534ff15..0c181c29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -134,6 +134,8 @@ struct ProgramParams unsigned opt_level = 0; bool emit_debug_info = false; + bool test_harness = false; + ::std::vector lib_search_dirs; ::std::vector libraries; @@ -192,6 +194,11 @@ int main(int argc, char *argv[]) }); + if( params.test_harness ) + { + Cfg_SetFlag("test"); + } + try { @@ -199,6 +206,7 @@ int main(int argc, char *argv[]) AST::Crate crate = CompilePhase("Parse", [&]() { return Parse_Crate(params.infile); }); + crate.m_test_harness = params.test_harness; if( params.last_stage == ProgramParams::STAGE_PARSE ) { return 0; @@ -214,6 +222,12 @@ int main(int argc, char *argv[]) Expand(crate); }); + if( params.test_harness ) + { + // TODO: Generate harness main (and override the mrustc-main lang item) + Expand_TestHarness(crate); + } + // Extract the crate type and name from the crate attributes auto crate_type = params.crate_type; if( crate_type == ::AST::Crate::Type::Unknown ) { @@ -286,7 +300,7 @@ int main(int argc, char *argv[]) } // Allocator and panic strategies - if( crate.m_crate_type == ::AST::Crate::Type::Executable ) + if( crate.m_crate_type == ::AST::Crate::Type::Executable || params.test_harness ) { // TODO: Detect if an allocator crate is already present. crate.load_extern_crate(Span(), "alloc_system"); @@ -460,6 +474,11 @@ int main(int argc, char *argv[]) trans_opt.emit_debug_info = params.emit_debug_info; // Generate code for non-generic public items (if requested) + if( params.test_harness ) + { + // If the test harness is enabled, override crate type to "Executable" + crate_type = ::AST::Crate::Type::Executable; + } switch( crate_type ) { case ::AST::Crate::Type::Unknown: @@ -684,6 +703,9 @@ ProgramParams::ProgramParams(int argc, char *argv[]) exit(1); } } + else if( strcmp(arg, "--test") == 0 ) { + this->test_harness = true; + } else { ::std::cerr << "Unknown option '" << arg << "'" << ::std::endl; exit(1); diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index e74231e8..5d599dd5 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -123,6 +123,7 @@ namespace { << "(uint8_t*)" << Trans_Mangle( ::HIR::GenericPath(m_resolve.m_crate.get_lang_item_path(Span(), "mrustc-main")) ) << ", argc, (uint8_t**)argv" << ");\n"; } + // TODO: Test framework? else { m_of << "\t" << Trans_Mangle(::HIR::GenericPath(c_start_path)) << "(argc, argv);\n"; diff --git a/src/trans/main_bindings.hpp b/src/trans/main_bindings.hpp index 2878cc66..59933863 100644 --- a/src/trans/main_bindings.hpp +++ b/src/trans/main_bindings.hpp @@ -23,6 +23,7 @@ struct TransOptions }; extern TransList Trans_Enumerate_Main(const ::HIR::Crate& crate); +extern TransList Trans_Enumerate_Test(const ::HIR::Crate& crate); // NOTE: This also sets the saveout flags extern TransList Trans_Enumerate_Public(::HIR::Crate& crate); -- cgit v1.2.3 From ffaaf8047e615206e5eb27097a0b6e669f521b96 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 13 Apr 2017 15:35:06 +0800 Subject: Expand - Tweaks to test harness --- Makefile | 15 ++++++++++++++- src/expand/format_args.cpp | 1 + src/expand/mod.cpp | 2 +- src/main.cpp | 5 ++++- 4 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src/main.cpp') diff --git a/Makefile b/Makefile index 2e907516..9ae61cd0 100644 --- a/Makefile +++ b/Makefile @@ -146,7 +146,20 @@ output/lib%.hir: $(RUSTCSRC)src/lib%/src/lib.rs $(RUSTCSRC) $(BIN) $(DBG) $(ENV_$@) $(BIN) $< -o $@ $(RUST_FLAGS) $(ARGS_$@) $(PIPECMD) # # HACK: Work around gdb returning success even if the program crashed @test -e $@ - +output/lib%-test: $(RUSTCSRC)src/lib%/lib.rs $(RUSTCSRC) $(BIN) + @echo "--- [MRUSTC] --test -o $@" + @mkdir -p output/ + @rm -f $@ + $(DBG) $(ENV_$@) $(BIN) --test $< -o $@ -L output/libs $(RUST_FLAGS) $(ARGS_$@) $(PIPECMD) +# # HACK: Work around gdb returning success even if the program crashed + @test -e $@ +output/lib%-test: $(RUSTCSRC)src/lib%/src/lib.rs $(RUSTCSRC) $(BIN) + @echo "--- [MRUSTC] $@" + @mkdir -p output/ + @rm -f $@ + $(DBG) $(ENV_$@) $(BIN) --test $< -o $@ -L output/libs $(RUST_FLAGS) $(ARGS_$@) $(PIPECMD) +# # HACK: Work around gdb returning success even if the program crashed + @test -e $@ fcn_extcrate = $(patsubst %,output/lib%.hir,$(1)) fn_getdeps = \ diff --git a/src/expand/format_args.cpp b/src/expand/format_args.cpp index 0f881a6e..89503e0c 100644 --- a/src/expand/format_args.cpp +++ b/src/expand/format_args.cpp @@ -251,6 +251,7 @@ namespace { if( *s == '0' ) { args.zero_pad = true; + args.align_char = '0'; s ++; } else { diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index f152b1ab..df0a26f2 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -67,7 +67,7 @@ void Expand_Attrs(/*const */::AST::MetaItems& attrs, AttrStage stage, ::std::fu } void Expand_Attrs(::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, const ::AST::Path& path, ::AST::Module& mod, ::AST::Item& item) { - Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ d.handle(sp, a, crate, path, mod, item); }); + Expand_Attrs(attrs, stage, [&](const auto& sp, const auto& d, const auto& a){ if(!item.is_None()) d.handle(sp, a, crate, path, mod, item); }); } void Expand_Attrs(::AST::MetaItems& attrs, AttrStage stage, ::AST::Crate& crate, ::AST::Module& mod, ::AST::ImplDef& impl) { diff --git a/src/main.cpp b/src/main.cpp index 0c181c29..2f392bb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -224,7 +224,6 @@ int main(int argc, char *argv[]) if( params.test_harness ) { - // TODO: Generate harness main (and override the mrustc-main lang item) Expand_TestHarness(crate); } @@ -273,6 +272,10 @@ int main(int argc, char *argv[]) } } crate.m_crate_name = crate_name; + if( params.test_harness ) + { + crate.m_crate_name += "$test"; + } if( params.outfile == "" ) { switch( crate.m_crate_type ) -- cgit v1.2.3 From 2acb5a8ac29ddc6f6894802d255d686fdb18329d Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 16 Apr 2017 11:40:20 +0800 Subject: common - Expand FmtEscaped --- src/common.hpp | 15 ++------------- src/main.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 13 deletions(-) (limited to 'src/main.cpp') diff --git a/src/common.hpp b/src/common.hpp index 63125b0e..d3aca257 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -328,19 +328,8 @@ struct FmtEscaped { FmtEscaped(const ::std::string& s): s(s.c_str()) {} - friend ::std::ostream& operator<<(::std::ostream& os, const FmtEscaped& x) { - for(auto s = x.s; *s != '\0'; s ++) - { - switch(*s) - { - case '\n': os << "\\n"; break; - case '\\': os << "\\\\"; break; - case '"': os << "\\\""; break; - default: os << *s; break; - } - } - return os; - } + // See main.cpp + friend ::std::ostream& operator<<(::std::ostream& os, const FmtEscaped& x); }; // ------------------------------------------------------------------- diff --git a/src/main.cpp b/src/main.cpp index 2f392bb7..a9e4868b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -717,3 +717,54 @@ ProgramParams::ProgramParams(int argc, char *argv[]) } } + +::std::ostream& operator<<(::std::ostream& os, const FmtEscaped& x) +{ + os << ::std::hex; + for(auto s = x.s; *s != '\0'; s ++) + { + switch(*s) + { + case '\0': os << "\\0"; break; + case '\n': os << "\\n"; break; + case '\\': os << "\\\\"; break; + case '"': os << "\\\""; break; + default: + uint8_t v = *s; + if( v < 0x80 ) + { + if( v < ' ' || v > 0x7F ) + os << "\\u{" << ::std::hex << (unsigned int)v << "}"; + else + os << v; + } + else if( v < 0xC0 ) + ; + else if( v < 0xE0 ) + { + uint32_t val = (uint32_t)(v & 0x1F) << 6; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6; + os << "\\u{" << ::std::hex << val << "}"; + } + else if( v < 0xF0 ) + { + uint32_t val = (uint32_t)(v & 0x0F) << 12; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 12; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6; + os << "\\u{" << ::std::hex << val << "}"; + } + else if( v < 0xF8 ) + { + uint32_t val = (uint32_t)(v & 0x07) << 18; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 18; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 12; + v = (uint8_t)*++s; if( (v & 0xC0) != 0x80 ) { s--; continue ; } val |= (uint32_t)v << 6; + os << "\\u{" << ::std::hex << val << "}"; + } + break; + } + } + os << ::std::dec; + return os; +} + -- cgit v1.2.3 From 0ba0ca404dc1be824dcf71352ef6594952613189 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 23 Apr 2017 12:28:25 +0800 Subject: main - Annotation about why MIR Check Full is disabled --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index a9e4868b..0d1c208c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -455,6 +455,9 @@ int main(int argc, char *argv[]) CompilePhaseV("MIR Validate PO", [&]() { MIR_CheckCrate(*hir_crate); }); + // - Exhaustive MIR validation (follows every code path and checks variable validity) + // > DEBUGGING ONLY + // > DISBALED: Excessive memory usage on complex functions CompilePhaseV("MIR Validate Full", [&]() { //MIR_CheckCrate_Full(*hir_crate); }); -- cgit v1.2.3 From 4de1bdb03d48b2741ec1075a55f5d726facb6f91 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 28 Apr 2017 21:21:58 +0800 Subject: Main - Allow env var enabling of full MIR check --- src/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 0d1c208c..71b0f9ce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,6 +68,7 @@ void init_debug_list() g_debug_disable_map.insert( "MIR Cleanup" ); g_debug_disable_map.insert( "MIR Optimise" ); g_debug_disable_map.insert( "MIR Validate PO" ); + g_debug_disable_map.insert( "MIR Validate Full" ); g_debug_disable_map.insert( "HIR Serialise" ); g_debug_disable_map.insert( "Trans Enumerate" ); @@ -443,6 +444,7 @@ int main(int argc, char *argv[]) CompilePhaseV("MIR Cleanup", [&]() { MIR_CleanupCrate(*hir_crate); }); + // Optimise the MIR CompilePhaseV("MIR Optimise", [&]() { MIR_OptimiseCrate(*hir_crate); @@ -459,7 +461,8 @@ int main(int argc, char *argv[]) // > DEBUGGING ONLY // > DISBALED: Excessive memory usage on complex functions CompilePhaseV("MIR Validate Full", [&]() { - //MIR_CheckCrate_Full(*hir_crate); + if( getenv("MRUSTC_FULL_VALIDATE") ) + MIR_CheckCrate_Full(*hir_crate); }); if( params.last_stage == ProgramParams::STAGE_MIR ) { -- cgit v1.2.3 From a8deffa94ee7fe4223a54e127f8085b52531bc52 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 28 Apr 2017 22:48:49 +0800 Subject: Main - Support running full check before optimisation --- src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 71b0f9ce..cb506ffb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -444,6 +444,12 @@ int main(int argc, char *argv[]) CompilePhaseV("MIR Cleanup", [&]() { MIR_CleanupCrate(*hir_crate); }); + if( getenv("MRUSTC_FULL_VALIDATE_PREOPT") ) + { + CompilePhaseV("MIR Validate Full", [&]() { + MIR_CheckCrate_Full(*hir_crate); + }); + } // Optimise the MIR CompilePhaseV("MIR Optimise", [&]() { @@ -459,7 +465,6 @@ int main(int argc, char *argv[]) }); // - Exhaustive MIR validation (follows every code path and checks variable validity) // > DEBUGGING ONLY - // > DISBALED: Excessive memory usage on complex functions CompilePhaseV("MIR Validate Full", [&]() { if( getenv("MRUSTC_FULL_VALIDATE") ) MIR_CheckCrate_Full(*hir_crate); -- cgit v1.2.3 From 6a2d30690eb4e5c6c2801a6c340ccfb65a3875b9 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 29 Apr 2017 14:13:22 +0800 Subject: Add a custom intrinsic to reduce cost of [T]::len --- Makefile | 3 ++- rust_src.patch | 25 +++++++++++++++++++++++++ src/main.cpp | 1 + src/mir/optimise.cpp | 14 ++++++++------ 4 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 rust_src.patch (limited to 'src/main.cpp') diff --git a/Makefile b/Makefile index b2259641..7816f9ed 100644 --- a/Makefile +++ b/Makefile @@ -297,7 +297,7 @@ output/rustc: $(RUSTCSRC)src/rustc/rustc.rs output/librustc_driver.hir output/ru .PHONY: RUSTCSRC RUSTCSRC: $(RUSTCSRC) -$(RUSTCSRC): rust-nightly-date +$(RUSTCSRC): rust-nightly-date rust_src.patch @export DL_RUST_DATE=$$(cat rust-nightly-date); \ export DISK_RUST_DATE=$$([ -f $(RUSTC_SRC_DL) ] && cat $(RUSTC_SRC_DL)); \ if [ "$$DL_RUST_DATE" != "$$DISK_RUST_DATE" ]; then \ @@ -306,6 +306,7 @@ $(RUSTCSRC): rust-nightly-date rm -rf rustc-nightly; \ curl -sS https://static.rust-lang.org/dist/$${DL_RUST_DATE}/rustc-nightly-src.tar.gz -o rustc-nightly-src.tar.gz; \ tar -xf rustc-nightly-src.tar.gz --transform 's~^rustc-nightly-src~rustc-nightly~'; \ + patch -p0 < rust_src.patch; \ echo "$$DL_RUST_DATE" > $(RUSTC_SRC_DL); \ fi diff --git a/rust_src.patch b/rust_src.patch new file mode 100644 index 00000000..d782d16b --- /dev/null +++ b/rust_src.patch @@ -0,0 +1,25 @@ +--- rustc-nightly/src/libcore/intrinsics.rs ++++ rustc-nightly/src/libcore/intrinsics.rs +@@ -643,5 +643,8 @@ + pub fn drop_in_place(to_drop: *mut T); + ++ /// Obtain the length of a slice pointer ++ pub fn mrustc_slice_len(pointer: *const [T]) -> usize; ++ + /// Gets a static string slice containing the name of a type. + pub fn type_name() -> &'static str; + +--- rustc-nightly/src/libcore/slice.rs ++++ rustc-nightly/src/libcore/slice.rs +@@ -340,6 +340,8 @@ + #[inline] + fn len(&self) -> usize { +- unsafe { +- mem::transmute::<&[T], Repr>(self).len +- } ++ #[cfg(not(rust_compiler="mrustc"))] ++ let rv = unsafe { mem::transmute::<&[T], Repr>(self).len }; ++ #[cfg(rust_compiler="mrustc")] ++ let rv = unsafe { ::intrinsics::mrustc_slice_len(self) }; ++ rv + } diff --git a/src/main.cpp b/src/main.cpp index cb506ffb..f06ee545 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -173,6 +173,7 @@ int main(int argc, char *argv[]) ProgramParams params(argc, argv); // Set up cfg values + Cfg_SetValue("rust_compiler", "mrustc"); // TODO: Target spec Cfg_SetFlag("unix"); Cfg_SetFlag("linux"); diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp index b83a1169..81574afd 100644 --- a/src/mir/optimise.cpp +++ b/src/mir/optimise.cpp @@ -1396,12 +1396,14 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn) bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block); changed = true; } - //else if( tef.name == "get_dst_meta_slice" ) - //{ - // MIR_ASSERT(state, te.args.at(0).is_LValue(), "Argument to `get_dst_meta` must be a lvalue"); - // auto& e = te.args.at(0).as_LValue(); - // bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::RValue::make_DstMeta({ mv$(*e) }) })); - //} + else if( tef.name == "mrustc_slice_len" ) + { + MIR_ASSERT(state, te.args.at(0).is_LValue(), "Argument to `get_dst_meta` must be a lvalue"); + auto& e = te.args.at(0).as_LValue(); + bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::RValue::make_DstMeta({ mv$(e) }) })); + bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block); + changed = true; + } else { // Ignore any other intrinsics -- cgit v1.2.3 From ec1dc3542bd5122db57f4459f63a6040f5e3ab20 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 7 May 2017 14:52:28 +0800 Subject: Main - Load test crate when compiling a test --- src/main.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index f06ee545..83fd5ac3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -314,6 +314,10 @@ int main(int argc, char *argv[]) // - `mrustc-main` lang item default crate.m_lang_items.insert(::std::make_pair( ::std::string("mrustc-main"), ::AST::Path("", {AST::PathNode("main")}) )); } + if( params.test_harness ) + { + crate.load_extern_crate(Span(), "test"); + } // Resolve names to be absolute names (include references to the relevant struct/global/function) // - This does name checking on types and free functions. -- cgit v1.2.3