summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2019-11-24 18:11:05 +0800
committerJohn Hodge <tpg@mutabah.net>2019-11-24 18:11:05 +0800
commit24a938e90bea5f54235ee938b684f090b2bf61ee (patch)
tree9933a6bba4e0f147b4d3d690066ac6dacef775a0
parent93f7d8e69489f26c0bc082be2f8b7bd511e37f6d (diff)
downloadmrust-24a938e90bea5f54235ee938b684f090b2bf61ee.tar.gz
tools - Add an experimental (and very incomplete) MIR optimisation tester
-rw-r--r--tools/mir_opt_test/main.cpp246
-rw-r--r--tools/mir_opt_test/parser.cpp318
-rw-r--r--tools/mir_opt_test/test_desc.h24
-rw-r--r--tools/mir_opt_test/tests/trivial.rs23
-rw-r--r--vsproject/mir_opt_test/mir_opt_test.vcxproj156
-rw-r--r--vsproject/mir_opt_test/mir_opt_test.vcxproj.filters30
6 files changed, 797 insertions, 0 deletions
diff --git a/tools/mir_opt_test/main.cpp b/tools/mir_opt_test/main.cpp
new file mode 100644
index 00000000..80a627f3
--- /dev/null
+++ b/tools/mir_opt_test/main.cpp
@@ -0,0 +1,246 @@
+/*
+ */
+#include <path.h>
+#include <target_version.hpp>
+#include "test_desc.h"
+#include <hir_conv/main_bindings.hpp>
+#include <mir/operations.hpp>
+#include <mir/main_bindings.hpp>
+#include <mir/mir.hpp>
+#include <trans/monomorphise.hpp> // used as a MIR clone
+#include <debug_inner.hpp>
+
+#ifdef _WIN32
+# define NOGDI // Don't include GDI functions (defines some macros that collide with mrustc ones)
+# include <Windows.h>
+#else
+# include <dirent.h>
+# include <sys/stat.h>
+#endif
+
+TargetVersion gTargetVersion = TargetVersion::Rustc1_29;
+
+struct Options
+{
+ helpers::path test_dir;
+
+ bool parse(int argc, char* argv[]);
+ void print_usage() const;
+ void print_help() const;
+};
+
+namespace {
+ MIR::FunctionPointer clone_mir(const StaticTraitResolve& resolve, const MIR::FunctionPointer& fcn);
+ bool compare_mir(const MIR::Function& exp, const MIR::Function& have, const HIR::SimplePath& path);
+}
+
+int main(int argc, char* argv[])
+{
+ debug_init_phases("MIRTEST_DEBUG", {
+ "Parse",
+ "Cleanup",
+ "Validate",
+ "Run Tests",
+ });
+
+ Options opts;
+ if( !opts.parse(argc, argv) )
+ {
+ return 1;
+ }
+
+ ::std::vector<MirOptTestFile> test_files;
+ {
+ auto ph = DebugTimedPhase("Parse");
+#ifdef _WIN32
+ WIN32_FIND_DATA find_data;
+ auto mask = opts.test_dir / "*.rs";
+ HANDLE find_handle = FindFirstFile( mask.str().c_str(), &find_data );
+ if( find_handle == INVALID_HANDLE_VALUE ) {
+ ::std::cerr << "Unable to find files matching " << mask << ::std::endl;
+ return 1;
+ }
+ do
+ {
+ auto test_file_path = opts.test_dir / find_data.cFileName;
+#else
+ auto* dp = opendir(opts.test_dir.str().c_str());
+ if( dp == nullptr ) {
+ ::std::cerr << "Unable to open directory " << opts.test_dir << ::std::endl;
+ }
+ while( const auto* dent = readdir(dp) )
+ {
+ if( dent->d_name[0] == '.' )
+ continue ;
+ auto test_file_path = opts.test_dir / dent->d_name;
+ struct stat sb;
+ stat(test_file_path.str().c_str(), &sb);
+ if( (sb.st_mode & S_IFMT) != S_IFREG) {
+ continue ;
+ }
+#endif
+ try
+ {
+ test_files.push_back( MirOptTestFile::load_from_file(test_file_path) );
+ }
+ catch(const ::std::exception& e)
+ {
+ ::std::cerr << "Exception: " << e.what() << " when loading test " << test_file_path << ::std::endl;
+ }
+#ifndef _WIN32
+ }
+ closedir(dp);
+#else
+ } while( FindNextFile(find_handle, &find_data) );
+ FindClose(find_handle);
+#endif
+ }
+
+ {
+ auto ph = DebugTimedPhase("Cleanup");
+ for(auto& f : test_files)
+ {
+ ConvertHIR_Bind(*f.m_crate);
+ }
+ }
+
+ {
+ auto ph = DebugTimedPhase("Validate");
+ for(auto& f : test_files)
+ {
+ MIR_CheckCrate(*f.m_crate);
+ }
+ }
+
+ for(auto& f : test_files)
+ {
+ auto ph = DebugTimedPhase("Run Tests");
+ for(const auto& test : f.m_tests)
+ {
+ const auto& in_fcn = f.m_crate->get_function_by_path(Span(), test.input_function);
+ const auto& exp_mir = *f.m_crate->get_function_by_path(Span(), test.output_template_function).m_code.m_mir;
+
+ StaticTraitResolve resolve(*f.m_crate);
+ // TODO: Generics?
+ auto cloned_mir = clone_mir(resolve, in_fcn.m_code.m_mir);
+
+ MIR_Optimise(resolve, test.input_function, *cloned_mir, in_fcn.m_args, in_fcn.m_return);
+
+ compare_mir(exp_mir, *cloned_mir, test.input_function);
+ }
+ }
+
+ return 0;
+}
+
+bool Options::parse(int argc, char* argv[])
+{
+ for(int i = 1; i < argc; i ++)
+ {
+ auto arg = helpers::string_view(argv[i], strlen(argv[i]));
+ if( arg[0] != '-' )
+ {
+ if( !this->test_dir.is_valid() )
+ {
+ this->test_dir = static_cast<std::string>(arg);
+ }
+ else
+ {
+ this->print_usage();
+ return false;
+ }
+ }
+ else if( arg[1] != '-' )
+ {
+ switch(arg[1])
+ {
+ case 'h':
+ this->print_help();
+ exit(0);
+ default:
+ this->print_usage();
+ return false;
+ }
+ }
+ else
+ {
+ if( arg == "--help" )
+ {
+ this->print_help();
+ exit(0);
+ }
+ else
+ {
+ this->print_usage();
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void Options::print_usage() const
+{
+}
+void Options::print_help() const
+{
+}
+
+namespace {
+ MIR::FunctionPointer clone_mir(const StaticTraitResolve& resolve, const MIR::FunctionPointer& fcn)
+ {
+ return Trans_Monomorphise(resolve, {}, fcn);
+ }
+ bool compare_mir(const MIR::Function& exp, const MIR::Function& have, const HIR::SimplePath& path)
+ {
+ if( exp.locals.size() != have.locals.size() ) {
+ std::cerr << path << " Mismatch in local count: exp " << exp.locals.size() << " != " << have.locals.size() << std::endl;
+ return false;
+ }
+ for(size_t i = 0; i < exp.locals.size(); i ++)
+ {
+ if( exp.locals[i] != have.locals[i] )
+ {
+ std::cerr << path << " Local " << i << " mismatch: exp " << exp.locals[i] << " != " << have.locals[i] << std::endl;
+ return false;
+ }
+ }
+
+ if( exp.drop_flags != have.drop_flags ) {
+ std::cerr << path << " Mismatch in drop flags" << std::endl;
+ return false;
+ }
+
+ if( exp.blocks.size() != have.blocks.size() ) {
+ std::cerr << path << " Mismatch in block count: exp " << exp.blocks.size() << " != " << have.blocks.size() << std::endl;
+ return false;
+ }
+ for(size_t bb_idx = 0; bb_idx < exp.blocks.size(); bb_idx ++)
+ {
+ const auto& bb_e = exp.blocks[bb_idx];
+ const auto& bb_h = have.blocks[bb_idx];
+
+ if( bb_e.statements.size() != bb_h.statements.size() ) {
+ std::cerr << path << " BB" << bb_idx << " Mismatch in statement count: exp " << bb_e.statements.size() << " != " << bb_h.statements.size() << std::endl;
+ return false;
+ }
+ for(size_t stmt_idx = 0; stmt_idx < bb_e.statements.size(); stmt_idx ++)
+ {
+ const auto& stmt_e = bb_e.statements[stmt_idx];
+ const auto& stmt_h = bb_h.statements[stmt_idx];
+ if( stmt_e != stmt_h ) {
+ std::cerr << path << " BB" << bb_idx << "/" << stmt_idx << " Mismatched statements: exp " << stmt_e << " != " << stmt_h << std::endl;
+ return false;
+ }
+ }
+
+ if( bb_e.terminator != bb_h.terminator )
+ {
+ std::cerr << path << " BB" << bb_idx << "/TERM Mismatched terminator: exp " << bb_e.terminator << " != " << bb_h.terminator << std::endl;
+ return false;
+ }
+ }
+ std::cerr << path << " EQUAL" << std::endl;
+ return true;
+ }
+} \ No newline at end of file
diff --git a/tools/mir_opt_test/parser.cpp b/tools/mir_opt_test/parser.cpp
new file mode 100644
index 00000000..70de7f9b
--- /dev/null
+++ b/tools/mir_opt_test/parser.cpp
@@ -0,0 +1,318 @@
+/*
+ */
+#include "test_desc.h"
+#include <parse/lex.hpp>
+#include <parse/common.hpp>
+#include <parse/parseerror.hpp>
+
+#include <hir/hir.hpp>
+#include <mir/mir.hpp>
+
+namespace {
+ HIR::Function parse_function(TokenStream& lex, RcString& out_name);
+ HIR::TypeRef parse_type(TokenStream& lex);
+ MIR::LValue parse_lvalue(TokenStream& lex, const ::std::map<RcString, MIR::LValue::Storage>& name_map);
+
+ bool consume_if(TokenStream& lex, eTokenType tok) {
+ if( lex.lookahead(0) == tok ) {
+ lex.getToken(); // eat token
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+MirOptTestFile MirOptTestFile::load_from_file(const helpers::path& p)
+{
+ Lexer lex(p.str());
+ Token tok;
+
+ MirOptTestFile rv;
+ rv.m_crate = HIR::CratePtr(::HIR::Crate());
+
+ while(lex.lookahead(0) != TOK_EOF)
+ {
+ std::map<RcString, std::string> attrs;
+ while( consume_if(lex, TOK_HASH) )
+ {
+ //bool is_outer = consume_if(lex, TOK_EXCLAM);
+ GET_CHECK_TOK(tok, lex, TOK_SQUARE_OPEN);
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ auto name = tok.istr();
+ GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+ GET_CHECK_TOK(tok, lex, TOK_STRING);
+ auto value = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_SQUARE_CLOSE);
+
+ attrs.insert( std::make_pair(name, value) );
+ }
+
+ if( consume_if(lex, TOK_RWORD_FN) )
+ {
+ RcString fcn_name;
+ auto fcn_decl = parse_function(lex, fcn_name);
+
+ auto vi = ::HIR::VisEnt<HIR::ValueItem> {
+ HIR::Publicity::new_global(), ::HIR::ValueItem(mv$(fcn_decl))
+ };
+ rv.m_crate->m_root_module.m_value_items.insert(::std::make_pair(fcn_name,
+ ::std::make_unique<decltype(vi)>(mv$(vi))
+ ));
+
+ // Attributes
+ for(const auto& attr : attrs)
+ {
+ if( attr.first == "test" )
+ {
+ MirOptTestFile::Test t;
+ t.input_function = ::HIR::SimplePath("", { fcn_name });
+ t.output_template_function = ::HIR::SimplePath("", { RcString(attr.second) });
+
+ rv.m_tests.push_back(mv$(t));
+ }
+ else
+ {
+ // Ignore?
+ }
+ }
+ }
+ //else if( lex.lookahead(0) == "INCLUDE" )
+ //{
+ // auto path = lex.check_consume(TokenClass::String).strval;
+ //}
+ else
+ {
+ TODO(lex.point_span(), "Error");
+ }
+ }
+
+ return rv;
+}
+namespace {
+ HIR::Function parse_function(TokenStream& lex, RcString& out_name)
+ {
+ Token tok;
+ ::std::map<RcString, MIR::LValue::Storage> val_name_map;
+ val_name_map.insert(::std::make_pair("retval", MIR::LValue::Storage::new_Return()));
+ ::std::map<RcString, unsigned> real_bb_name_map;
+ ::std::map<unsigned, RcString> lookup_bb_name_map;
+
+ ::HIR::Function fcn_decl;
+ fcn_decl.m_code.m_mir = ::MIR::FunctionPointer(new ::MIR::Function());
+ auto& mir_fcn = *fcn_decl.m_code.m_mir;
+
+ // Name
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ auto fcn_name = tok.istr();
+ DEBUG("fn " << fcn_name);
+
+ // Arguments
+ auto& args = fcn_decl.m_args;
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
+ while( lex.lookahead(0) != TOK_PAREN_CLOSE )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ auto name = tok.istr();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ auto var_ty = parse_type(lex);
+
+ auto arg_idx = static_cast<unsigned>(args.size());
+ val_name_map.insert( ::std::make_pair(name, ::MIR::LValue::Storage::new_Argument(arg_idx)) );
+ args.push_back( ::std::make_pair(HIR::Pattern(), mv$(var_ty)) );
+
+ if( !consume_if(lex, TOK_COMMA) )
+ break;
+ }
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
+ // Return type
+ if( consume_if(lex, TOK_THINARROW) )
+ {
+ // Parse return type
+ fcn_decl.m_return = parse_type(lex);
+ }
+ else
+ {
+ fcn_decl.m_return = HIR::TypeRef::new_unit();
+ }
+
+ // Body.
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
+
+ // 1. Variable list
+ while( consume_if(lex, TOK_RWORD_LET) )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ auto name = tok.istr();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ auto var_ty = parse_type(lex);
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+
+ auto var_idx = static_cast<unsigned>(mir_fcn.locals.size());
+ val_name_map.insert( ::std::make_pair(name, ::MIR::LValue::Storage::new_Local(var_idx)) );
+ mir_fcn.locals.push_back( mv$(var_ty) );
+ }
+ // 2. List of BBs arranged with 'ident: { STMTS; TERM }'
+ while( lex.lookahead(0) != TOK_BRACE_CLOSE )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ auto name = tok.istr();
+ real_bb_name_map.insert( ::std::make_pair(name, static_cast<unsigned>(mir_fcn.blocks.size())) );
+ mir_fcn.blocks.push_back(::MIR::BasicBlock());
+ auto& bb = mir_fcn.blocks.back();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
+ while( lex.lookahead(0) != TOK_BRACE_CLOSE )
+ {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ if( tok.istr() == "DROP" )
+ {
+ TODO(lex.point_span(), "MIR statement - " << tok);
+ }
+ else if( tok.istr() == "ASM" )
+ {
+ TODO(lex.point_span(), "MIR statement - " << tok);
+ }
+ else if( tok.istr() == "SETDROP" )
+ {
+ TODO(lex.point_span(), "MIR statement - " << tok);
+ }
+ else if( tok.istr() == "ASSIGN" )
+ {
+ // parse a lvalue
+ auto dst = parse_lvalue(lex, val_name_map);
+ GET_CHECK_TOK(tok, lex, TOK_EQUAL);
+
+ MIR::RValue src;
+ GET_TOK(tok, lex);
+ switch(tok.type())
+ {
+ case TOK_RWORD_TRUE: src = MIR::Constant::make_Bool({true }); break;
+ case TOK_RWORD_FALSE: src = MIR::Constant::make_Bool({false}); break;
+ case TOK_IDENT:
+ TODO(lex.point_span(), "MIR assign - " << tok);
+ break;
+ // Tuple literal
+ case TOK_PAREN_OPEN: {
+ src = MIR::RValue::make_Tuple({});
+ auto& vals = src.as_Tuple().vals;
+ while( lex.lookahead(0) != TOK_PAREN_CLOSE )
+ {
+ vals.push_back(parse_lvalue(lex, val_name_map));
+ if( !consume_if(lex, TOK_COMMA) )
+ break;
+ }
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
+ } break;
+ default:
+ TODO(lex.point_span(), "MIR assign - " << tok);
+ }
+
+ bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(dst), mv$(src) }));
+ }
+ else
+ {
+ TODO(lex.point_span(), "MIR statement - " << tok);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
+
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ if( tok.istr() == "RETURN" )
+ {
+ bb.terminator = ::MIR::Terminator::make_Return({});
+ }
+ else
+ {
+ TODO(lex.point_span(), "MIR terminator - " << tok);
+ }
+ }
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_CLOSE);
+
+ // 3. Convert BB names over
+ for(auto& blk : mir_fcn.blocks)
+ {
+ TU_MATCH_HDRA( (blk.terminator), {)
+ TU_ARMA(Goto, e) {
+ e = real_bb_name_map.at( lookup_bb_name_map[e] );
+ }
+ }
+ }
+
+ DEBUG(fcn_decl.m_args << " -> " << fcn_decl.m_return);
+ out_name = mv$(fcn_name);
+ return fcn_decl;
+ }
+
+ HIR::Path parse_path(TokenStream& lex)
+ {
+ TODO(lex.point_span(), "parse_path");
+ }
+ HIR::TypeRef parse_type(TokenStream& lex)
+ {
+ Token tok;
+ GET_TOK(tok, lex);
+ switch( tok.type() )
+ {
+ case TOK_PAREN_OPEN: {
+ ::std::vector<HIR::TypeRef> tys;
+ while( lex.lookahead(0) != TOK_PAREN_CLOSE )
+ {
+ tys.push_back( parse_type(lex) );
+ if( !consume_if(lex, TOK_COMMA) )
+ break;
+ }
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
+ return HIR::TypeRef(mv$(tys));
+ } break;
+ default:
+ TODO(lex.point_span(), "parse_type - " << tok);
+ }
+ }
+ MIR::LValue::Storage parse_lvalue_root(TokenStream& lex, const ::std::map<RcString, MIR::LValue::Storage>& name_map)
+ {
+ if( lex.lookahead(0) == TOK_DOUBLE_COLON )
+ {
+ // Static
+ return MIR::LValue::Storage::new_Static( parse_path(lex) );
+ }
+ else
+ {
+ Token tok;
+ GET_TOK(tok, lex);
+ CHECK_TOK(tok, TOK_IDENT);
+ return name_map.at(tok.istr()).clone();
+ }
+ }
+ MIR::LValue parse_lvalue(TokenStream& lex, const ::std::map<RcString, MIR::LValue::Storage>& name_map)
+ {
+ Token tok;
+ std::vector<MIR::LValue::Wrapper> wrappers;
+ auto root = parse_lvalue_root(lex, name_map);
+
+ while(true)
+ {
+ GET_TOK(tok, lex);
+ switch( tok.type() )
+ {
+ case TOK_SQUARE_OPEN:
+ TODO(lex.point_span(), "parse_lvalue - indexing");
+ break;
+ case TOK_DOT:
+ TODO(lex.point_span(), "parse_lvalue - field");
+ break;
+ case TOK_HASH:
+ TODO(lex.point_span(), "parse_lvalue - downcast");
+ break;
+ case TOK_STAR:
+ wrappers.push_back(::MIR::LValue::Wrapper::new_Deref());
+ break;
+ default:
+ lex.putback(mv$(tok));
+ return MIR::LValue(mv$(root), mv$(wrappers));
+ }
+ }
+ }
+}
diff --git a/tools/mir_opt_test/test_desc.h b/tools/mir_opt_test/test_desc.h
new file mode 100644
index 00000000..5e31830c
--- /dev/null
+++ b/tools/mir_opt_test/test_desc.h
@@ -0,0 +1,24 @@
+/*
+ * test_desc.h
+ * - Description of a MIR optimisation test
+ */
+#pragma once
+
+#include <hir/crate_ptr.hpp>
+#include <hir/type.hpp>
+#include <hir/path.hpp>
+#include <path.h>
+
+struct MirOptTestFile
+{
+ ::HIR::CratePtr m_crate;
+
+ struct Test
+ {
+ ::HIR::SimplePath input_function;
+ ::HIR::SimplePath output_template_function;
+ };
+ ::std::vector<Test> m_tests;
+
+ static MirOptTestFile load_from_file(const helpers::path& p);
+};
diff --git a/tools/mir_opt_test/tests/trivial.rs b/tools/mir_opt_test/tests/trivial.rs
new file mode 100644
index 00000000..eb818bfb
--- /dev/null
+++ b/tools/mir_opt_test/tests/trivial.rs
@@ -0,0 +1,23 @@
+#[test="test_trivial"]
+fn test_trivial()
+{
+ bb0: {
+ ASSIGN retval = ();
+ } RETURN
+}
+
+#[test="dce_local_exp"]
+fn dce_local()
+{
+ let useless: ();
+ bb0: {
+ ASSIGN useless = ();
+ ASSIGN retval = ();
+ } RETURN
+}
+fn dce_local_exp()
+{
+ bb0: {
+ ASSIGN retval = ();
+ } RETURN
+} \ No newline at end of file
diff --git a/vsproject/mir_opt_test/mir_opt_test.vcxproj b/vsproject/mir_opt_test/mir_opt_test.vcxproj
new file mode 100644
index 00000000..f7429dc9
--- /dev/null
+++ b/vsproject/mir_opt_test/mir_opt_test.vcxproj
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <VCProjectVersion>16.0</VCProjectVersion>
+ <ProjectGuid>{09D9A76F-51FF-4310-ABBE-CD7C52F3B6EA}</ProjectGuid>
+ <RootNamespace>miropttest</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\src;$(SolutionDir)..\src\include;$(SolutionDir)..\tools\mir_opt_test;$(SolutionDir)..\tools\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>common_lib.lib;mrustc_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\src;$(SolutionDir)..\src\include;$(SolutionDir)..\tools\mir_opt_test;$(SolutionDir)..\tools\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>common_lib.lib;mrustc_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\src;$(SolutionDir)..\src\include;$(SolutionDir)..\tools\mir_opt_test;$(SolutionDir)..\tools\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <AdditionalDependencies>common_lib.lib;mrustc_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\src;$(SolutionDir)..\src\include;$(SolutionDir)..\tools\mir_opt_test;$(SolutionDir)..\tools\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>common_lib.lib;mrustc_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(OutDir)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\tools\mir_opt_test\main.cpp" />
+ <ClCompile Include="..\..\tools\mir_opt_test\parser.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\tools\mir_opt_test\test_desc.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ <Import Project="..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
+ <Import Project="..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
+ </ImportGroup>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
+ <Error Condition="!Exists('..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
+ </Target>
+</Project> \ No newline at end of file
diff --git a/vsproject/mir_opt_test/mir_opt_test.vcxproj.filters b/vsproject/mir_opt_test/mir_opt_test.vcxproj.filters
new file mode 100644
index 00000000..30ca7cba
--- /dev/null
+++ b/vsproject/mir_opt_test/mir_opt_test.vcxproj.filters
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\tools\mir_opt_test\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\tools\mir_opt_test\parser.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\tools\mir_opt_test\test_desc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file