summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2019-11-26 19:18:16 +0800
committerJohn Hodge <tpg@mutabah.net>2019-11-26 19:18:16 +0800
commit6b7f855f9e8c50be2cddcb3126e25f4986daa46e (patch)
tree419ec42f5bfbb9a1a81a6180c4537d62d806fa3b
parent916bfed2c597446c79831aaf29c83dd1e893e853 (diff)
downloadmrust-6b7f855f9e8c50be2cddcb3126e25f4986daa46e.tar.gz
mir_opt_test - Add tests for SingleSetAndUse (includes one that caused bad codegen at one point)
-rw-r--r--tools/mir_opt_test/parser.cpp36
-rw-r--r--tools/mir_opt_test/tests/single-set-and-use.rs53
2 files changed, 87 insertions, 2 deletions
diff --git a/tools/mir_opt_test/parser.cpp b/tools/mir_opt_test/parser.cpp
index 72441db7..6d298d60 100644
--- a/tools/mir_opt_test/parser.cpp
+++ b/tools/mir_opt_test/parser.cpp
@@ -115,6 +115,11 @@ namespace {
auto fcn_name = tok.istr();
DEBUG("fn " << fcn_name);
+ if(consume_if(lex, TOK_LT) )
+ {
+ TODO(lex.point_span(), "Generic functions");
+ }
+
// Arguments
auto& args = fcn_decl.m_args;
GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
@@ -187,7 +192,15 @@ namespace {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
if( tok.istr() == "DROP" )
{
- TODO(lex.point_span(), "MIR statement - " << tok);
+ auto slot = parse_lvalue(lex, val_name_map);
+ if( consume_if(lex, TOK_RWORD_IF) )
+ {
+ TODO(lex.point_span(), "MIR statement - DROP if");
+ }
+ else
+ {
+ bb.statements.push_back(::MIR::Statement::make_Drop({ MIR::eDropKind::DEEP, mv$(slot), ~0u }));
+ }
}
else if( tok.istr() == "ASM" )
{
@@ -207,10 +220,29 @@ namespace {
GET_TOK(tok, lex);
switch(tok.type())
{
- // Cnstant boolean
+ // Constant boolean
case TOK_RWORD_TRUE: src = MIR::Constant::make_Bool({true }); break;
case TOK_RWORD_FALSE: src = MIR::Constant::make_Bool({false}); break;
+ case TOK_PLUS:
+ case TOK_DASH: {
+ bool is_neg = (tok.type() == TOK_DASH);
+ GET_TOK(tok, lex);
+ switch(tok.type())
+ {
+ case TOK_INTEGER:
+ TODO(lex.point_span(), "MIR assign - " << (is_neg ? "-" : "+") << tok.intval());
+ //src = MIR::Constant::make_Int({ tok.intval(), ct });
+ case TOK_FLOAT:
+ TODO(lex.point_span(), "MIR assign - " << (is_neg ? "-" : "+") << tok.floatval());
+ //src = MIR::Constant::make_Float({ tok.floatval(), ct });
+ default:
+ throw ParseError::Unexpected(lex, tok, { TOK_INTEGER, TOK_FLOAT });
+ }
+ } break;
+ case TOK_INTEGER:
+ TODO(lex.point_span(), "MIR assign - " << tok.intval());
+
case TOK_AMP:
if( consume_if(lex, TOK_RWORD_MOVE) )
src = MIR::RValue::make_Borrow({ 0, HIR::BorrowType::Owned, parse_lvalue(lex, val_name_map) });
diff --git a/tools/mir_opt_test/tests/single-set-and-use.rs b/tools/mir_opt_test/tests/single-set-and-use.rs
new file mode 100644
index 00000000..1cd5e542
--- /dev/null
+++ b/tools/mir_opt_test/tests/single-set-and-use.rs
@@ -0,0 +1,53 @@
+//
+// Tests for single-use-variable elimination
+//
+
+// Check forward movement of values
+#[test="simple_fwd_exp"]
+fn simple_fwd(a: i32) -> (i32,)
+{
+ let v: i32;
+ bb0: {
+ ASSIGN v = a;
+ ASSIGN retval = (v,);
+ } RETURN;
+}
+fn simple_fwd_exp(a: i32) -> (i32,)
+{
+ bb0: {
+ ASSIGN retval = (a,);
+ } RETURN;
+}
+
+// Reverse (upwards) movement
+#[test="simple_rev_exp"]
+fn simple_rev(a: i32) -> (i32,)
+{
+ let v: (i32,);
+ bb0: {
+ ASSIGN v = (a,);
+ ASSIGN retval = v;
+ } RETURN;
+}
+fn simple_rev_exp(a: i32) -> (i32,)
+{
+ bb0: {
+ ASSIGN retval = (a,);
+ } RETURN;
+}
+
+// Check that if there's a mutable borrow of the source, that the source isn't propagated forwards
+// - NOTE: This relies on the optimiser not being smart enough to move the `retval` construction up
+#[test="nomut"]
+fn nomut(a: i32) -> (i32,)
+{
+ let v: i32;
+ let ba: &mut i32;
+ bb0: {
+ ASSIGN v = a;
+ ASSIGN ba = &mut a;
+ //ASSIGN a* = +0;
+ ASSIGN retval = (v,);
+ DROP ba;
+ } RETURN;
+}