Skip to content

Commit 7061664

Browse files
committed
---
yaml --- r: 3763 b: refs/heads/master c: 182c413 h: refs/heads/master i: 3761: 7057ca4 3759: 6ba8d8b v: v3
1 parent 46962b7 commit 7061664

File tree

4 files changed

+443
-134
lines changed

4 files changed

+443
-134
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: be6febb46d541ebe8cb0f3e0585ffb8bafb39762
2+
refs/heads/master: 182c413af199196155d4d82716988b2f5886e892

trunk/src/comp/middle/tstate/auxiliary.rs

Lines changed: 258 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import std::vec;
12
import std::ivec;
3+
import std::int::str;
24
import std::str;
35
import std::option;
4-
import std::option::none;
5-
import std::option::some;
6-
import std::option::maybe;
6+
import std::option::*;
77
import std::int;
88
import std::uint;
99
import syntax::ast::*;
@@ -26,19 +26,32 @@ import tstate::ann::empty_states;
2626
import tstate::ann::pps_len;
2727
import tstate::ann::set_prestate;
2828
import tstate::ann::set_poststate;
29+
import tstate::ann::set_in_poststate_;
2930
import tstate::ann::extend_prestate;
3031
import tstate::ann::extend_poststate;
3132
import tstate::ann::set_precondition;
3233
import tstate::ann::set_postcondition;
34+
import tstate::ann::set_in_postcond_;
3335
import tstate::ann::ts_ann;
3436
import tstate::ann::clear_in_postcond;
3537
import tstate::ann::clear_in_poststate;
3638
import tstate::ann::clear_in_poststate_;
3739
import tritv::*;
40+
import bitvectors::promises_;
3841

3942
import syntax::print::pprust::constr_args_to_str;
43+
import syntax::print::pprust::constr_arg_to_str;
4044
import syntax::print::pprust::lit_to_str;
4145

46+
// Used to communicate which operands should be invalidated
47+
// to helper functions
48+
tag oper_type {
49+
oper_move;
50+
oper_swap;
51+
oper_assign;
52+
oper_assign_op;
53+
oper_pure;
54+
}
4255

4356
/* logging funs */
4457
fn def_id_to_str(def_id d) -> str {
@@ -195,6 +208,8 @@ type pred_desc_ = rec((@constr_arg_use)[] args, uint bit_num);
195208
196209
type pred_desc = spanned[pred_desc_];
197210
211+
// FIXME: Should be node_id, since we can only talk
212+
// about locals.
198213
type constr_arg_use = constr_arg_general[tup(ident, def_id)];
199214
200215
tag constraint {
@@ -564,9 +579,13 @@ fn expr_to_constr_arg(ty::ctxt tcx, &@expr e) -> @constr_arg_use {
564579
}
565580

566581
fn exprs_to_constr_args(ty::ctxt tcx, &(@expr)[] args)
567-
-> (@constr_arg_use)[] {
582+
-> (@constr_arg_use)[] {
568583
auto f = bind expr_to_constr_arg(tcx, _);
569-
ret ivec::map(f, args);
584+
let (@constr_arg_use)[] rslt = ~[];
585+
for (@expr e in args) {
586+
rslt += ~[f(e)];
587+
}
588+
rslt
570589
}
571590

572591
fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
@@ -602,14 +621,9 @@ fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
602621
}
603622

604623
fn pred_desc_to_str(&pred_desc p) -> str {
605-
// FIXME: Remove this vec->ivec conversion.
606-
let (@constr_arg_use)[] cau_ivec = ~[];
607-
for (@constr_arg_use cau in p.node.args) {
608-
cau_ivec += ~[cau];
609-
}
610-
611-
ret "<" + uint::str(p.node.bit_num) + ", " +
612-
constr_args_to_str(std::util::fst[ident, def_id], cau_ivec) + ">";
624+
"<" + uint::str(p.node.bit_num) + ", " +
625+
constr_args_to_str(std::util::fst[ident, def_id],
626+
p.node.args) + ">"
613627
}
614628

615629
fn substitute_constr_args(&ty::ctxt cx, &(@expr)[] actuals,
@@ -621,8 +635,6 @@ fn substitute_constr_args(&ty::ctxt cx, &(@expr)[] actuals,
621635
ret npred(c.node.path, rslt);
622636
}
623637

624-
type subst = tup(arg, @expr)[];
625-
626638
fn substitute_arg(&ty::ctxt cx, &(@expr)[] actuals, @constr_arg a) ->
627639
@constr_arg_use {
628640
auto num_actuals = ivec::len(actuals);
@@ -640,6 +652,144 @@ fn substitute_arg(&ty::ctxt cx, &(@expr)[] actuals, @constr_arg a) ->
640652
}
641653
}
642654

655+
fn pred_desc_matches(&(constr_arg_general_[tup(ident, def_id)])[] pattern,
656+
&pred_desc desc) -> bool {
657+
auto i = 0u;
658+
for (@constr_arg_use c in desc.node.args) {
659+
auto n = pattern.(i);
660+
alt (c.node) {
661+
case (carg_ident(?p)) {
662+
alt (n) {
663+
case (carg_ident(?q)) {
664+
if (p._1 != q._1) {
665+
ret false;
666+
}
667+
}
668+
case (_) { ret false; }
669+
}
670+
}
671+
case (carg_base) {
672+
if (n != carg_base) {
673+
ret false;
674+
}
675+
}
676+
case (carg_lit(?l)) {
677+
alt (n) {
678+
case (carg_lit(?m)) {
679+
if (!lit_eq(l, m)) {
680+
ret false;
681+
}
682+
}
683+
case (_) { ret false; }
684+
}
685+
}
686+
}
687+
i += 1u;
688+
}
689+
ret true;
690+
}
691+
692+
fn find_instance_(&(constr_arg_general_[tup(ident, def_id)])[] pattern,
693+
&pred_desc[] descs) -> option::t[uint] {
694+
for (pred_desc d in descs) {
695+
if (pred_desc_matches(pattern, d)) {
696+
ret some(d.node.bit_num);
697+
}
698+
}
699+
ret none;
700+
}
701+
702+
type inst = tup(ident, def_id);
703+
type subst = tup(inst, inst)[];
704+
705+
fn find_instances(&fn_ctxt fcx, &subst subst, &constraint c)
706+
-> vec[tup(uint, uint)] {
707+
708+
let vec[tup(uint, uint)] rslt = [];
709+
if (ivec::len(subst) == 0u) {
710+
ret rslt;
711+
}
712+
713+
alt (c) {
714+
case (cinit(_,_,_)) { /* this is dealt with separately */ }
715+
case (cpred(?p, ?descs)) {
716+
for (pred_desc d in *descs) {
717+
if (args_mention(d.node.args, find_in_subst_bool, subst)) {
718+
auto old_bit_num = d.node.bit_num;
719+
auto new = replace(subst, d);
720+
alt (find_instance_(new, *descs)) {
721+
case (some(?d1)) {
722+
rslt += [tup(old_bit_num, d1)];
723+
}
724+
case (_) { }
725+
}
726+
}
727+
}
728+
}
729+
}
730+
rslt
731+
}
732+
733+
fn find_in_subst(def_id id, &subst s) -> option::t[inst] {
734+
for (tup(inst, inst) p in s) {
735+
if (id == p._0._1) {
736+
ret some(p._1);
737+
}
738+
}
739+
ret none;
740+
}
741+
742+
fn find_in_subst_bool(&subst s, def_id id) -> bool {
743+
is_some(find_in_subst(id, s))
744+
}
745+
746+
fn insts_to_str(&(constr_arg_general_[inst])[] stuff) -> str {
747+
auto rslt = "<";
748+
for (constr_arg_general_[inst] i in stuff) {
749+
rslt += " " + alt(i) {
750+
case (carg_ident(?p)) { p._0 }
751+
case (carg_base) { "*" }
752+
case (carg_lit(_)) { "[lit]" } } + " ";
753+
}
754+
rslt += ">";
755+
rslt
756+
}
757+
758+
fn replace(subst subst, pred_desc d) -> (constr_arg_general_[inst])[] {
759+
let (constr_arg_general_[inst])[] rslt = ~[];
760+
for (@constr_arg_use c in d.node.args) {
761+
alt (c.node) {
762+
case (carg_ident(?p)) {
763+
alt (find_in_subst(p._1, subst)) {
764+
case (some(?new)) {
765+
rslt += ~[carg_ident(new)];
766+
}
767+
case (_) {
768+
rslt += ~[c.node];
769+
}
770+
}
771+
}
772+
case (_) {
773+
// log_err "##";
774+
rslt += ~[c.node];
775+
}
776+
}
777+
}
778+
779+
/*
780+
for (constr_arg_general_[tup(ident, def_id)] p in rslt) {
781+
alt (p) {
782+
case (carg_ident(?p)) {
783+
log_err p._0;
784+
}
785+
case (_) {}
786+
}
787+
}
788+
*/
789+
790+
ret rslt;
791+
}
792+
643793
fn path_to_ident(&ty::ctxt cx, &path p) -> ident {
644794
alt (ivec::last(p.node.idents)) {
645795
case (none) { cx.sess.span_fatal(p.span, "Malformed path"); }
@@ -684,6 +834,56 @@ fn local_node_id_to_def_id(&fn_ctxt fcx, &node_id i) -> option::t[def_id] {
684834
}
685835
}
686836

837+
fn copy_in_postcond(&fn_ctxt fcx, node_id parent_exp, inst dest, inst src,
838+
oper_type ty) {
839+
auto post = node_id_to_ts_ann(fcx.ccx, parent_exp).conditions.
840+
postcondition;
841+
copy_in_poststate_two(fcx, post, post, dest, src, ty);
842+
}
843+
844+
// FIXME refactor
845+
fn copy_in_poststate(&fn_ctxt fcx, &poststate post, inst dest, inst src,
846+
oper_type ty) {
847+
copy_in_poststate_two(fcx, post, post, dest, src, ty);
848+
}
849+
850+
// In target_post, set the bits corresponding to copies of any
851+
// constraints mentioning src that are set in src_post, with
852+
// dest substituted for src.
853+
// (This doesn't create any new constraints. If a new, substituted
854+
// constraint isn't already in the bit vector, it's ignored.)
855+
fn copy_in_poststate_two(&fn_ctxt fcx, &poststate src_post,
856+
&poststate target_post, inst dest, inst src,
857+
oper_type ty) {
858+
auto subst;
859+
alt (ty) {
860+
case (oper_swap) {
861+
subst = ~[tup(dest, src),
862+
tup(src, dest)];
863+
}
864+
case (oper_assign_op) {
865+
ret; // Don't do any propagation
866+
}
867+
case (_) {
868+
subst = ~[tup(src, dest)];
869+
}
870+
}
871+
872+
for each (@tup(node_id, constraint) p in
873+
fcx.enclosing.constrs.items()) {
874+
// replace any occurrences of the src def_id with the
875+
// dest def_id
876+
auto instances = find_instances(fcx, subst, p._1);
877+
878+
for (tup(uint,uint) p in instances) {
879+
if (promises_(p._0, src_post)) {
880+
set_in_poststate_(p._1, target_post);
881+
}
882+
}
883+
}
884+
}
885+
886+
687887
/* FIXME should refactor this better */
688888
fn forget_in_postcond(&fn_ctxt fcx, node_id parent_exp, node_id dead_v) {
689889
// In the postcondition given by parent_exp, clear the bits
@@ -757,13 +957,20 @@ fn forget_in_poststate_still_init(&fn_ctxt fcx, &poststate p, node_id dead_v)
757957
ret changed;
758958
}
759959

760-
fn constraint_mentions(&fn_ctxt fcx, &norm_constraint c, &def_id v) -> bool {
960+
fn any_eq(&(def_id)[] v, def_id d) -> bool {
961+
for (def_id i in v) {
962+
if (i == d) { ret true; }
963+
}
964+
false
965+
}
966+
967+
fn constraint_mentions(&fn_ctxt fcx, &norm_constraint c, def_id v) -> bool {
761968
ret (alt (c.c.node.c) {
762969
case (ninit(_)) {
763970
v == local_def(c.c.node.id)
764971
}
765972
case (npred(_, ?args)) {
766-
args_mention(args, v)
973+
args_mention(args, any_eq, ~[v])
767974
}
768975
});
769976
}
@@ -775,20 +982,42 @@ fn non_init_constraint_mentions(&fn_ctxt fcx, &norm_constraint c,
775982
false
776983
}
777984
case (npred(_, ?args)) {
778-
args_mention(args, v)
985+
args_mention(args, any_eq, ~[v])
779986
}
780987
});
781988
}
782989

783-
784-
fn args_mention(&(@constr_arg_use)[] args, &def_id v) -> bool {
785-
fn mentions(&def_id v, &@constr_arg_use a) -> bool {
990+
fn args_mention[T](&(@constr_arg_use)[] args, fn(&(T)[], def_id) -> bool q,
991+
&(T)[] s) -> bool {
992+
/*
993+
FIXME
994+
The following version causes an assertion in trans to fail
995+
(something about type_is_tup_like)
996+
fn mentions[T](&(T)[] s, &fn(&(T)[], def_id) -> bool q,
997+
&@constr_arg_use a) -> bool {
786998
alt (a.node) {
787-
case (carg_ident(?p1)) { p1._1 == v }
999+
case (carg_ident(?p1)) {
1000+
auto res = q(s, p1._1);
1001+
log_err (res);
1002+
res
1003+
}
7881004
case (_) { false }
7891005
}
7901006
}
791-
ret ivec::any[@constr_arg_use](bind mentions(v,_), args);
1007+
ret ivec::any(bind mentions(s,q,_), args);
1008+
*/
1009+
1010+
for (@constr_arg_use a in args) {
1011+
alt (a.node) {
1012+
case (carg_ident(?p1)) {
1013+
if (q(s, p1._1)) {
1014+
ret true;
1015+
}
1016+
}
1017+
case (_) {}
1018+
}
1019+
}
1020+
ret false;
7921021
}
7931022

7941023
fn use_var(&fn_ctxt fcx, &node_id v) {
@@ -803,6 +1032,12 @@ fn vec_contains(&@mutable (node_id[]) v, &node_id i) -> bool {
8031032
ret false;
8041033
}
8051034

1035+
fn op_to_oper_ty(init_op io) -> oper_type {
1036+
alt (io) {
1037+
case (init_move) { oper_move }
1038+
case (_) { oper_assign }
1039+
}
1040+
}
8061041
//
8071042
// Local Variables:
8081043
// mode: rust

0 commit comments

Comments
 (0)