diff --git a/Cargo.lock b/Cargo.lock
index 9acb4cbef6941..c5e093079ba40 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10870,6 +10870,7 @@ dependencies = [
"move-symbol-pool",
"num 0.4.1",
"once_cell",
+ "petgraph 0.6.4",
"serde",
]
@@ -11170,6 +11171,7 @@ dependencies = [
"move-binary-format",
"move-command-line-common",
"move-compiler",
+ "move-compiler-v2",
"move-core-types",
"move-docgen",
"move-errmapgen",
@@ -11318,6 +11320,7 @@ dependencies = [
"codespan-reporting",
"move-command-line-common",
"move-compiler",
+ "move-compiler-v2",
"move-model",
"move-prover-test-utils",
"move-stackless-bytecode",
diff --git a/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md b/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md
index 231ce0b060283..f64d57763b192 100644
--- a/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md
+++ b/aptos-move/framework/aptos-framework/doc/reconfiguration_with_dkg.md
@@ -164,8 +164,10 @@ Abort if no DKG is in progress.
requires chain_status::is_operating();
include stake::ResourceRequirement;
include stake::GetReconfigStartTimeRequirement;
-include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
+include features::spec_periodical_reward_rate_decrease_enabled(
+) ==> staking_config::StakingRewardsConfigEnabledRequirement;
aborts_if false;
+pragma verify_duration_estimate = 600;
diff --git a/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move b/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
index fd5709dd53e28..d03da00335adc 100644
--- a/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
+++ b/aptos-move/framework/aptos-framework/sources/reconfiguration_with_dkg.spec.move
@@ -12,8 +12,10 @@ spec aptos_framework::reconfiguration_with_dkg {
requires chain_status::is_operating();
include stake::ResourceRequirement;
include stake::GetReconfigStartTimeRequirement;
- include features::spec_periodical_reward_rate_decrease_enabled() ==> staking_config::StakingRewardsConfigEnabledRequirement;
+ include features::spec_periodical_reward_rate_decrease_enabled(
+ ) ==> staking_config::StakingRewardsConfigEnabledRequirement;
aborts_if false;
+ pragma verify_duration_estimate = 600; // TODO: set because of timeout (property proved).
}
spec finish(account: &signer) {
@@ -59,5 +61,4 @@ spec aptos_framework::reconfiguration_with_dkg {
requires dkg::has_incomplete_session();
aborts_if false;
}
-
}
diff --git a/aptos-move/framework/src/prover.rs b/aptos-move/framework/src/prover.rs
index 58be654d76f46..5614c273b435b 100644
--- a/aptos-move/framework/src/prover.rs
+++ b/aptos-move/framework/src/prover.rs
@@ -123,7 +123,7 @@ impl ProverOptions {
) -> anyhow::Result<()> {
let now = Instant::now();
let for_test = self.for_test;
- let model = build_model(
+ let mut model = build_model(
dev_mode,
package_path,
named_addresses,
@@ -162,7 +162,7 @@ impl ProverOptions {
)],
});
let mut writer = StandardStream::stderr(ColorChoice::Auto);
- move_prover::run_move_prover_with_model(&model, &mut writer, options, Some(now))?;
+ move_prover::run_move_prover_with_model(&mut model, &mut writer, options, Some(now))?;
Ok(())
}
diff --git a/third_party/move/evm/move-to-yul/tests/TestABIStructs.exp b/third_party/move/evm/move-to-yul/tests/TestABIStructs.exp
index 36eeeb174da2d..49a3eb0ea4782 100644
--- a/third_party/move/evm/move-to-yul/tests/TestABIStructs.exp
+++ b/third_party/move/evm/move-to-yul/tests/TestABIStructs.exp
@@ -2446,7 +2446,7 @@ object "test_A2_M_test_abi_String" {
case 2 {
// label L5
// assert Le($t1, $t4)
- // assert forall j: num: Range(0, $t1): ascii::$is_valid_char(Index($t0, j))
+ // assert forall j: num: Range(0, $t1): ascii::is_valid_char(Index($t0, j))
// $t6 := <($t1, $t4)
$t6 := $Lt(i, $t4)
// if ($t6) goto L1 else goto L0
@@ -2474,7 +2474,7 @@ object "test_A2_M_test_abi_String" {
case 5 {
// label L0
// assert Eq($t1, $t4)
- // assert forall j: num: Range(0, $t4): ascii::$is_valid_char(Index($t0, j))
+ // assert forall j: num: Range(0, $t4): ascii::is_valid_char(Index($t0, j))
// $t14 := move($t0)
$t14 := mload($locals)
// $t15 := pack ascii::String($t14)
diff --git a/third_party/move/move-compiler-v2/Cargo.toml b/third_party/move/move-compiler-v2/Cargo.toml
index 010da0fffa448..3e4c679baddfd 100644
--- a/third_party/move/move-compiler-v2/Cargo.toml
+++ b/third_party/move/move-compiler-v2/Cargo.toml
@@ -37,7 +37,7 @@ log = { version = "0.4.14", features = ["serde"] }
num = "0.4.0"
once_cell = "1.7.2"
#paste = "1.0.5"
-#petgraph = "0.5.1"
+petgraph = "0.6.4"
serde = { version = "1.0.124", features = ["derive"] }
[dev-dependencies]
diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs b/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs
index a8c591459f576..6fc17c75f266b 100644
--- a/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs
+++ b/third_party/move/move-compiler-v2/src/env_pipeline/mod.rs
@@ -6,11 +6,14 @@
// TODO: move all other `&mut GlobalEnv` processors into this module.
-use log::debug;
+use log::trace;
use move_model::model::GlobalEnv;
use std::io::Write;
pub mod lambda_lifter;
+pub mod rewrite_target;
+pub mod spec_checker;
+pub mod spec_rewriter;
/// Represents a pipeline of processors working on the global environment.
#[derive(Default)]
@@ -32,10 +35,10 @@ impl<'a> EnvProcessorPipeline<'a> {
/// Runs the pipeline. Running will be ended if any of the steps produces an error.
/// The function returns true if all steps succeeded without errors.
pub fn run(&self, env: &mut GlobalEnv) -> bool {
- debug!("before env processor pipeline: {}", env.dump_env());
+ trace!("before env processor pipeline: {}", env.dump_env());
for (name, proc) in &self.processors {
proc(env);
- debug!("after env processor {}", name);
+ trace!("after env processor {}", name);
if env.has_errors() {
return false;
}
@@ -47,13 +50,13 @@ impl<'a> EnvProcessorPipeline<'a> {
/// only.
pub fn run_and_record(&self, env: &mut GlobalEnv, w: &mut impl Write) -> anyhow::Result {
let msg = format!("before env processor pipeline:\n{}\n", env.dump_env());
- debug!("{}", msg);
+ trace!("{}", msg);
writeln!(w, "// -- Model dump {}", msg)?;
for (name, proc) in &self.processors {
proc(env);
if !env.has_errors() {
let msg = format!("after env processor {}:\n{}\n", name, env.dump_env());
- debug!("{}", msg);
+ trace!("{}", msg);
writeln!(w, "// -- Model dump {}", msg)?;
} else {
return Ok(false);
diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/rewrite_target.rs b/third_party/move/move-compiler-v2/src/env_pipeline/rewrite_target.rs
new file mode 100644
index 0000000000000..2851f5c2b79c3
--- /dev/null
+++ b/third_party/move/move-compiler-v2/src/env_pipeline/rewrite_target.rs
@@ -0,0 +1,206 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+use move_model::{
+ ast::{Exp, Spec, SpecBlockTarget},
+ model::{FunId, GlobalEnv, NodeId, QualifiedId, SpecFunId},
+};
+use std::{
+ collections::{BTreeMap, BTreeSet},
+ mem,
+};
+
+/// Represents a target for rewriting.
+#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
+pub enum RewriteTarget {
+ /// A Move function
+ MoveFun(QualifiedId),
+ /// A specification function
+ SpecFun(QualifiedId),
+ /// A specification block, which can be attached to a Move function, struct, or module.
+ SpecBlock(SpecBlockTarget),
+}
+
+/// Represents the state of a rewriting target.
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum RewriteState {
+ /// The target has not been changed
+ Unchanged,
+ /// The definition of a Move or spec function has changed
+ Def(Exp),
+ /// A specification block has changed.
+ Spec(Spec),
+ /// The target is 'abstract', i.e. does have a definition.
+ Abstract,
+}
+
+/// Scope for collecting targets.
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
+pub enum RewritingScope {
+ /// Including only targets for which `module.is_target()` is true.
+ CompilationTarget,
+ /// Include everything.
+ Everything,
+}
+
+/// Represents a set of rewriting targets in the given state.
+#[derive(Clone)]
+pub struct RewriteTargets {
+ pub targets: BTreeMap,
+}
+
+impl RewriteTargets {
+ /// Create a new set of rewrite targets, collecting them as specified by `scope`.
+ /// Those targets are initially associated with `Unchanged` state.
+ pub fn create(env: &GlobalEnv, scope: RewritingScope) -> Self {
+ let mut targets = vec![];
+ let add_spec =
+ |targets: &mut Vec, sb_target: SpecBlockTarget, spec: &Spec| {
+ if !spec.is_empty() {
+ targets.push(RewriteTarget::SpecBlock(sb_target))
+ }
+ };
+ for module in env.get_modules() {
+ if scope == RewritingScope::Everything || module.is_target() {
+ for func in module.get_functions() {
+ let id = func.get_qualified_id();
+ targets.push(RewriteTarget::MoveFun(id));
+ add_spec(
+ &mut targets,
+ SpecBlockTarget::Function(id.module_id, id.id),
+ &func.get_spec(),
+ );
+ }
+ for (spec_fun_id, _) in module.get_spec_funs() {
+ targets.push(RewriteTarget::SpecFun(
+ module.get_id().qualified(*spec_fun_id),
+ ));
+ }
+ for struct_env in module.get_structs() {
+ add_spec(
+ &mut targets,
+ SpecBlockTarget::Struct(module.get_id(), struct_env.get_id()),
+ &struct_env.get_spec(),
+ )
+ }
+ if !module.get_spec().is_empty() {
+ add_spec(
+ &mut targets,
+ SpecBlockTarget::Module(module.get_id()),
+ &module.get_spec(),
+ );
+ }
+ }
+ }
+ Self {
+ targets: targets
+ .into_iter()
+ .map(|target| (target, RewriteState::Unchanged))
+ .collect(),
+ }
+ }
+
+ /// Filters the targets according to the predicate.
+ pub fn filter(&mut self, pred: impl Fn(&RewriteTarget, &RewriteState) -> bool) {
+ self.targets = mem::take(&mut self.targets)
+ .into_iter()
+ .filter(|(t, s)| pred(t, s))
+ .collect();
+ }
+
+ /// Iterates all targets.
+ pub fn iter(&self) -> impl Iterator- + '_ {
+ self.targets.iter()
+ }
+
+ /// Returns an iteration of the target keys.
+ pub fn keys(&self) -> impl Iterator
- + '_ {
+ self.targets.keys().cloned()
+ }
+
+ /// Adds a new rewrite target in state `Unchanged` if it doesn't exist yet. Returns
+ /// a boolean whether the entry is new and a mutable reference to the state.
+ pub fn entry(&mut self, target: RewriteTarget) -> (bool, &mut RewriteState) {
+ let mut is_new = false;
+ let state = self.targets.entry(target).or_insert_with(|| {
+ is_new = true;
+ RewriteState::Unchanged
+ });
+ (is_new, state)
+ }
+
+ /// Gets the current state of the target.
+ pub fn state(&self, target: &RewriteTarget) -> &RewriteState {
+ self.targets.get(target).expect("state defined")
+ }
+
+ /// Gets the mutable current state of the target.
+ pub fn state_mut(&mut self, target: &RewriteTarget) -> &mut RewriteState {
+ self.targets.get_mut(target).expect("state defined")
+ }
+
+ /// Updates the global env based on the current state. This consumes
+ /// the rewrite targets.
+ pub fn write_to_env(self, env: &mut GlobalEnv) {
+ for (target, state) in self.targets {
+ use RewriteState::*;
+ use RewriteTarget::*;
+ match (target, state) {
+ (_, Unchanged) => {},
+ (MoveFun(fnid), Def(def)) => env.set_function_def(fnid, def),
+ (SpecFun(fnid), Def(def)) => env.get_spec_fun_mut(fnid).body = Some(def),
+ (SpecBlock(sb_target), Spec(spec)) => {
+ *env.get_spec_block_mut(&sb_target) = spec;
+ },
+ _ => panic!("unexpected rewrite target and result combination"),
+ }
+ }
+ }
+}
+
+impl RewriteTarget {
+ /// Gets the call sites for the target.
+ pub fn called_funs_with_call_sites(
+ &self,
+ env: &GlobalEnv,
+ ) -> BTreeMap, BTreeSet> {
+ use RewriteTarget::*;
+ match self {
+ MoveFun(id) => env
+ .get_function(*id)
+ .get_def()
+ .map(|e| e.called_funs_with_callsites())
+ .unwrap_or_default(),
+ SpecFun(id) => env
+ .get_spec_fun(*id)
+ .body
+ .as_ref()
+ .map(|e| e.called_funs_with_callsites())
+ .unwrap_or_default(),
+ SpecBlock(target) => {
+ let spec = env.get_spec_block(target);
+ spec.called_funs_with_callsites()
+ },
+ }
+ }
+
+ /// Get the environment state of this target in form of a RewriteState.
+ pub fn get_env_state(&self, env: &GlobalEnv) -> RewriteState {
+ use RewriteState::*;
+ use RewriteTarget::*;
+ match self {
+ MoveFun(fid) => env
+ .get_function(*fid)
+ .get_def()
+ .map(|e| Def(e.clone()))
+ .unwrap_or(Abstract),
+ SpecFun(fid) => env
+ .get_spec_fun(*fid)
+ .body
+ .clone()
+ .map(Def)
+ .unwrap_or(Abstract),
+ SpecBlock(sb_target) => Spec(env.get_spec_block(sb_target).clone()),
+ }
+ }
+}
diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs b/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs
new file mode 100644
index 0000000000000..e400eac2c6cde
--- /dev/null
+++ b/third_party/move/move-compiler-v2/src/env_pipeline/spec_checker.rs
@@ -0,0 +1,128 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+//! The spec checker runs over the specifications of the target modules:
+//!
+//! - It checks whether the constructs they use are pure. If a specification
+//! expression calls a Move function it checks that for pureness as well.
+//! - It checks whether struct invariants do not depend on global state.
+
+use crate::env_pipeline::rewrite_target::{
+ RewriteState, RewriteTarget, RewriteTargets, RewritingScope,
+};
+use codespan_reporting::diagnostic::Severity;
+use log::info;
+use move_model::{
+ ast::{Exp, Spec},
+ model::{FunId, GlobalEnv, NodeId, QualifiedId},
+ pureness_checker::{FunctionPurenessChecker, FunctionPurenessCheckerMode},
+};
+
+pub fn run_spec_checker(env: &GlobalEnv) {
+ info!("checking specifications");
+
+ // Targets are all spec functions and spec blocks, as well as functions to
+ // process inline specs.
+ let mut targets = RewriteTargets::create(env, RewritingScope::CompilationTarget);
+ targets.filter(|target, _| {
+ matches!(
+ target,
+ RewriteTarget::SpecFun(_) | RewriteTarget::SpecBlock(_) | RewriteTarget::MoveFun(_)
+ )
+ });
+
+ // Walk over those targets and check them for pureness.
+ for target in targets.keys() {
+ match (target.clone(), target.get_env_state(env)) {
+ (RewriteTarget::MoveFun(_), RewriteState::Def(exp)) => {
+ exp.visit_inline_specs(&mut |s| {
+ check_spec(env, s);
+ true
+ })
+ },
+ (RewriteTarget::SpecFun(_), RewriteState::Def(exp)) => check_exp(env, &exp),
+ (RewriteTarget::SpecBlock(_), RewriteState::Spec(spec)) => check_spec(env, &spec),
+ _ => {},
+ }
+ }
+}
+
+fn check_exp(env: &GlobalEnv, exp: &Exp) {
+ let mut error_reported = false;
+ let mut checker = FunctionPurenessChecker::new(
+ FunctionPurenessCheckerMode::Specification,
+ |node_id, msg, call_chain| report_error(env, &mut error_reported, node_id, msg, call_chain),
+ );
+ checker.check_exp(env, exp);
+}
+
+fn check_spec(env: &GlobalEnv, spec: &Spec) {
+ let mut error_reported = false;
+ let mut checker = FunctionPurenessChecker::new(
+ FunctionPurenessCheckerMode::Specification,
+ |node_id, msg, call_chain| report_error(env, &mut error_reported, node_id, msg, call_chain),
+ );
+ checker.check_spec(env, spec);
+}
+
+fn report_error(
+ env: &GlobalEnv,
+ error_reported: &mut bool,
+ id: NodeId,
+ msg: &str,
+ call_chain: &[(QualifiedId, NodeId)],
+) {
+ // We report the first error only because otherwise the error messages can be
+ // overwhelming, if the user e.g. accidentally calls a complex system function.
+ if *error_reported {
+ return;
+ }
+ // The first call in call_chain is the one from the specification function to
+ // a Move function. We take this as the primary anchor for the error message
+ let print_fun = |f: QualifiedId| env.get_function(f).get_name_str();
+ if call_chain.is_empty() {
+ // Direct report
+ env.diag_with_primary_and_labels(
+ Severity::Error,
+ &env.get_node_loc(id),
+ "specification expression cannot use impure construct",
+ msg,
+ vec![],
+ );
+ } else {
+ let (first_fun, first_id) = call_chain[0];
+ let mut call_chain_info = vec![];
+ // First print the sequence of calls leading us to the issue
+ for i in 1..call_chain.len() {
+ let previous_fun = print_fun(call_chain[i - 1].0);
+ let this_fun = print_fun(call_chain[1].0);
+ let this_loc = env.get_node_loc(call_chain[1].1);
+ call_chain_info.push((
+ this_loc,
+ format!(
+ "transitively calling `{}` from `{}` here",
+ this_fun, previous_fun
+ ),
+ ))
+ }
+ // Next print the particular issue detected
+ let last_fun = call_chain.last().unwrap().0;
+ call_chain_info.push((
+ env.get_node_loc(id),
+ format!("in `{}`: {}", print_fun(last_fun), msg),
+ ));
+
+ env.diag_with_primary_and_labels(
+ Severity::Error,
+ &env.get_node_loc(first_id),
+ &format!(
+ "specification expression cannot call impure \
+ Move function `{}`",
+ env.get_function(first_fun).get_name_str()
+ ),
+ "called here",
+ call_chain_info,
+ );
+ }
+ *error_reported = true;
+}
diff --git a/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs b/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs
new file mode 100644
index 0000000000000..269e3c83b9e2f
--- /dev/null
+++ b/third_party/move/move-compiler-v2/src/env_pipeline/spec_rewriter.rs
@@ -0,0 +1,502 @@
+// Copyright © Aptos Foundation
+// SPDX-License-Identifier: Apache-2.0
+
+//! The spec rewriter runs on the whole model after inlining and after check for pureness
+//! and does the following:
+//!
+//! - For every transitively used Move function in specs, it derives
+//! a spec function version of it.
+//! - It rewrites all specification expressions to call the derived spec
+//! function instead of the Move function.
+//! - It also rewrites expression to replace Move constructs with spec
+//! constructs where possible. This includes replacing references
+//! with values. This transformation assumes that expressions
+//! are already checked for pureness.
+//! - For all spec functions (including the derived ones) it computes
+//! transitive memory usage and callee functions.
+//! - It checks that data invariants do not depend on memory, and flags
+//! errors if not. This can only be done after transitive memory
+//! usage is known.
+//! - It collects all global invariants and attaches them, together
+//! with their memory usage, to the model.
+
+use crate::env_pipeline::rewrite_target::{
+ RewriteState, RewriteTarget, RewriteTargets, RewritingScope,
+};
+use itertools::Itertools;
+use log::info;
+use move_model::{
+ ast::{ConditionKind, Exp, ExpData, GlobalInvariant, Operation, SpecFunDecl},
+ exp_rewriter::ExpRewriterFunctions,
+ model::{FunId, GlobalEnv, NodeId, Parameter, QualifiedId, SpecFunId, StructEnv},
+ symbol::Symbol,
+ ty::ReferenceKind,
+};
+use petgraph::prelude::DiGraphMap;
+use std::{
+ cell::RefCell,
+ collections::{BTreeMap, BTreeSet},
+};
+
+pub fn run_spec_rewriter(env: &mut GlobalEnv) {
+ info!("rewriting specifications");
+
+ // Collect all spec blocks and spec functions in the whole program, plus
+ // functions in compilation scope. For the later we need to process
+ // inline spec blocks.
+ // TODO: we may want to optimize this to only rewrite specs involved in
+ // a verification problem, but we need to have a precise definition
+ // what this entails. For example, pre/post conditions need to be present
+ // only if the function spec is marked as opaque.
+ let mut targets = RewriteTargets::create(env, RewritingScope::Everything);
+ targets.filter(|target, _| match target {
+ RewriteTarget::MoveFun(fid) => {
+ let fun = env.get_function(*fid);
+ fun.module_env.is_target() && !fun.is_inline() && !fun.is_native()
+ },
+ RewriteTarget::SpecFun(fid) => {
+ let fun = env.get_spec_fun(*fid);
+ !fun.is_native
+ },
+ RewriteTarget::SpecBlock(_) => true,
+ });
+
+ // Identify the Move functions transitively called by those targets. They need to be
+ // converted to spec functions.
+ let mut called_funs = BTreeSet::new();
+ for target in targets.keys() {
+ let callees: BTreeSet<_> = match target {
+ RewriteTarget::MoveFun(_) => {
+ if let RewriteState::Def(def) = target.get_env_state(env) {
+ let mut spec_callees = BTreeSet::new();
+ def.visit_inline_specs(&mut |spec| {
+ spec_callees.extend(spec.called_funs_with_callsites().into_keys());
+ true // keep going
+ });
+ spec_callees
+ } else {
+ BTreeSet::new()
+ }
+ },
+ RewriteTarget::SpecFun(_) | RewriteTarget::SpecBlock(_) => target
+ .called_funs_with_call_sites(env)
+ .into_keys()
+ .collect(),
+ };
+ for callee in callees {
+ called_funs.insert(callee);
+ let mut transitive = env
+ .get_function(callee)
+ .get_transitive_closure_of_called_functions();
+ called_funs.append(&mut transitive);
+ }
+ }
+
+ // For compatibility reasons with the v1 way how to compile spec
+ // blocks of inline functions, we also need to add all 'lambda'
+ // lifted functions.
+
+ // Derive spec functions for all called Move functions,
+ // building a mapping between function ids. Also add
+ // those new spec functions to `targets` for subsequent
+ // processing.
+ let mut function_mapping = BTreeMap::new();
+ for fun_id in called_funs {
+ let spec_fun_id = derive_spec_fun(env, fun_id);
+ function_mapping.insert(fun_id, spec_fun_id);
+ // Add new spec fun to targets for later processing
+ targets.entry(RewriteTarget::SpecFun(spec_fun_id));
+ // Mark spec fun to be used in environment
+ env.add_used_spec_fun(spec_fun_id)
+ }
+
+ // Based on the mapping above, now visit all targets and convert them.
+ for target in targets.keys().collect_vec() {
+ use RewriteState::*;
+ use RewriteTarget::*;
+ let get_param_names =
+ |params: &[Parameter]| params.iter().map(|Parameter(name, ..)| *name).collect_vec();
+ match (&target, target.get_env_state(env)) {
+ (MoveFun(_), Def(exp)) => {
+ let mut converter = SpecConverter::new(env, &function_mapping, false);
+ let new_exp = converter.rewrite_exp(exp.clone());
+ if !ExpData::ptr_eq(&new_exp, &exp) {
+ *targets.state_mut(&target) = Def(new_exp)
+ }
+ },
+ (SpecFun(id), Def(exp)) => {
+ let mut converter = SpecConverter::new(env, &function_mapping, true)
+ .symbolized_parameters(get_param_names(&env.get_spec_fun(*id).params));
+ let new_exp = converter.rewrite_exp(exp.clone());
+ if !ExpData::ptr_eq(&new_exp, &exp) {
+ *targets.state_mut(&target) = Def(new_exp)
+ }
+ },
+ (SpecBlock(sb_target), Spec(spec)) => {
+ let mut converter = SpecConverter::new(env, &function_mapping, true);
+ let (changed, new_spec) = converter.rewrite_spec_descent(sb_target, &spec);
+ if changed {
+ *targets.state_mut(&target) = Spec(new_spec)
+ }
+ },
+ _ => {},
+ }
+ }
+ targets.write_to_env(env);
+
+ // Now that all functions are defined, compute transitive callee and used memory.
+ // Since specification functions can be recursive we compute the strongly-connected
+ // components first and then process each in bottom-up order.
+ let mut graph: DiGraphMap, ()> = DiGraphMap::new();
+ let spec_funs = env
+ .get_modules()
+ .flat_map(|m| {
+ m.get_spec_funs()
+ .map(|(id, _)| m.get_id().qualified(*id))
+ .collect_vec()
+ })
+ .collect_vec();
+ for qid in spec_funs {
+ graph.add_node(qid);
+ let (initial_callees, initial_usage) = if let Some(def) = &env.get_spec_fun(qid).body {
+ let callees = def.called_spec_funs(env);
+ for callee in &callees {
+ graph.add_edge(qid, callee.to_qualified_id(), ());
+ }
+ (callees, def.directly_used_memory(env))
+ } else {
+ Default::default()
+ };
+ let decl_mut = env.get_spec_fun_mut(qid);
+ (decl_mut.callees, decl_mut.used_memory) = (initial_callees, initial_usage);
+ }
+ for scc in petgraph::algo::kosaraju_scc(&graph) {
+ // Within each cycle, the transitive usage is the union of the transitive
+ // usage of each member.
+ let mut transitive_callees = BTreeSet::new();
+ let mut transitive_usage = BTreeSet::new();
+ for qid in &scc {
+ let decl = env.get_spec_fun(*qid);
+ // Add direct usage.
+ transitive_callees.extend(decl.callees.iter().cloned());
+ transitive_usage.extend(decl.used_memory.iter().cloned());
+ // Add indirect usage
+ for callee in &decl.callees {
+ let decl = env.get_spec_fun(callee.to_qualified_id());
+ transitive_callees.extend(
+ decl.callees
+ .iter()
+ .map(|id| id.clone().instantiate(&callee.inst)),
+ );
+ transitive_usage.extend(
+ decl.used_memory
+ .iter()
+ .map(|mem| mem.clone().instantiate(&callee.inst)),
+ );
+ }
+ }
+ // Store result back
+ for qid in scc {
+ let decl_mut = env.get_spec_fun_mut(qid);
+ decl_mut.callees = transitive_callees.clone();
+ decl_mut.used_memory = transitive_usage.clone();
+ }
+ }
+
+ // Last, process invariants
+ for module in env.get_modules() {
+ if module.is_target() {
+ for str in module.get_structs() {
+ check_data_invariants(&str)
+ }
+ }
+ }
+ collect_global_invariants_to_env(env)
+}
+
+// -------------------------------------------------------------------------------------------
+// Deriving Specification Functions
+
+// Derive a specification function from a Move function. Initially the body is the
+// original one, not yet converted to the specification representation.
+fn derive_spec_fun(env: &mut GlobalEnv, fun_id: QualifiedId) -> QualifiedId {
+ let fun = env.get_function(fun_id);
+ let (is_native, body) = if fun.is_native() {
+ (true, None)
+ } else {
+ let exp = fun.get_def().expect("function body").clone();
+ (false, Some(exp))
+ };
+
+ // For historical reasons, those names are prefixed with `$` even though there
+ // is no name clash allowed.
+ let name = env
+ .symbol_pool()
+ .make(&format!("${}", fun.get_name().display(env.symbol_pool())));
+ // Eliminate references in parameters and result type
+ let params = fun
+ .get_parameters()
+ .into_iter()
+ .map(|Parameter(sym, ty, loc)| Parameter(sym, ty.skip_reference().clone(), loc))
+ .collect();
+ let result_type = fun.get_result_type().skip_reference().clone();
+
+ let decl = SpecFunDecl {
+ loc: fun.get_loc(),
+ name,
+ type_params: fun.get_type_parameters(),
+ params,
+ context_params: None,
+ result_type,
+ used_memory: BTreeSet::new(),
+ uninterpreted: false,
+ is_move_fun: true,
+ is_native,
+ body,
+ callees: BTreeSet::new(),
+ is_recursive: RefCell::new(None),
+ };
+ env.add_spec_function_def(fun_id.module_id, decl)
+}
+
+// -------------------------------------------------------------------------------------------
+// Expressions Conversion
+
+/// The expression converter takes a Move expression and converts it to a
+/// specification expression. It expects the expression to be checked to be pure.
+struct SpecConverter<'a> {
+ env: &'a GlobalEnv,
+ /// Whether we are in a specification expression. Conversion applies only if.
+ in_spec: bool,
+ /// The mapping from Move function to spec function ids.
+ function_mapping: &'a BTreeMap, QualifiedId>,
+ /// If non-empty, Temporary expressions should be mapped to symbolic LocalVar
+ /// expressions. This is the convention for specification function parameters.
+ symbolized_parameters: Vec,
+ /// NodeIds which are exempted from stripping references. For compatibility
+ /// reasons nodes which fetch temporaries should not be stripped as the reference
+ /// info is needed for correct treatment of the `old(..)` expression.
+ reference_strip_exempted: BTreeSet,
+}
+
+impl<'a> SpecConverter<'a> {
+ fn new(
+ env: &'a GlobalEnv,
+ function_mapping: &'a BTreeMap, QualifiedId>,
+ in_spec: bool,
+ ) -> Self {
+ Self {
+ env,
+ in_spec,
+ function_mapping,
+ symbolized_parameters: vec![],
+ reference_strip_exempted: Default::default(),
+ }
+ }
+
+ fn symbolized_parameters(self, symbolized_parameters: Vec) -> Self {
+ Self {
+ symbolized_parameters,
+ ..self
+ }
+ }
+}
+
+impl<'a> ExpRewriterFunctions for SpecConverter<'a> {
+ fn rewrite_exp(&mut self, exp: Exp) -> Exp {
+ use ExpData::*;
+ use Operation::*;
+ if !self.in_spec {
+ // If not in spec mode, check whether we need to switch to it,
+ // and descent
+ if matches!(exp.as_ref(), ExpData::SpecBlock(..)) {
+ self.in_spec = true;
+ let result = self.rewrite_exp_descent(exp);
+ self.in_spec = false;
+ result
+ } else {
+ self.rewrite_exp_descent(exp)
+ }
+ } else {
+ // Simplification which need to be done before descent
+ let exp = match exp.as_ref() {
+ IfElse(id, _, if_true, if_false)
+ if matches!(if_true.as_ref(), Call(_, Tuple, _))
+ && matches!(if_false.as_ref(), Call(_, Abort, _)) =>
+ {
+ // The code pattern produced by an `assert!`: `if (c) () else abort`.
+ // Reduce to unit
+ Call(*id, Tuple, vec![]).into_exp()
+ },
+ Temporary(id, _) => {
+ self.reference_strip_exempted.insert(*id);
+ exp
+ },
+ _ => exp,
+ };
+
+ let exp = self.rewrite_exp_descent(exp);
+
+ // Simplification after descent
+ match exp.as_ref() {
+ Temporary(id, idx) => {
+ // For specification functions, parameters are represented as LocalVar,
+ // so apply mapping if present.
+ if let Some(sym) = self.symbolized_parameters.get(*idx) {
+ LocalVar(*id, *sym).into_exp()
+ } else {
+ exp.clone()
+ }
+ },
+ Call(id, BorrowGlobal(ReferenceKind::Immutable), args) => {
+ // Map borrow_global to specification global
+ Call(*id, Global(None), args.clone()).into_exp()
+ },
+ Call(_, Borrow(_), args) | Call(_, Deref, args) => {
+ // Skip local borrow
+ args[0].clone()
+ },
+ Call(id, MoveFunction(mid, fid), args) => {
+ // Rewrite to associated spec function
+ let spec_fun_id = self
+ .function_mapping
+ .get(&mid.qualified(*fid))
+ .unwrap_or_else(|| {
+ panic!(
+ "associated spec fun for {}",
+ self.env.get_function(mid.qualified(*fid)).get_name_str()
+ )
+ });
+
+ Call(
+ *id,
+ SpecFunction(spec_fun_id.module_id, spec_fun_id.id, None),
+ args.clone(),
+ )
+ .into_exp()
+ },
+ // Deal with removing various occurrences of Abort and spec blocks
+ Call(id, Abort, _) | SpecBlock(id, ..) => {
+ // Replace direct call by unit
+ Call(*id, Tuple, vec![]).into_exp()
+ },
+ IfElse(id, _, if_true, if_false)
+ if matches!(if_true.as_ref(), Call(_, Tuple, _))
+ && matches!(if_false.as_ref(), Call(_, Abort, _)) =>
+ {
+ // The code pattern produced by an `assert!`: `if (c) () else abort`.
+ // Reduce to unit as well
+ Call(*id, Tuple, vec![]).into_exp()
+ },
+ Sequence(id, exps) => {
+ // Remove aborts, units, and spec blocks
+ let mut reduced_exps = exps
+ .iter()
+ .take(exps.len() - 1)
+ .flat_map(|e| {
+ if matches!(
+ e.as_ref(),
+ SpecBlock(..) | Call(_, Abort, _) | Call(_, Tuple, _)
+ ) {
+ None
+ } else {
+ Some(e.clone())
+ }
+ })
+ .collect_vec();
+ reduced_exps.push(exps.last().unwrap().clone());
+ if reduced_exps.len() != exps.len() {
+ if reduced_exps.len() == 1 {
+ reduced_exps.pop().unwrap()
+ } else {
+ Sequence(*id, reduced_exps).into_exp()
+ }
+ } else {
+ exp.clone()
+ }
+ },
+ _ => exp.clone(),
+ }
+ }
+ }
+
+ fn rewrite_node_id(&mut self, id: NodeId) -> Option {
+ if !self.in_spec || self.reference_strip_exempted.contains(&id) {
+ // Skip the processing below
+ return None;
+ }
+ if let Some(new_ty) = self
+ .env
+ .get_node_type_opt(id)
+ .map(|ty| ty.skip_reference().clone())
+ {
+ let new_id = self.env.new_node(self.env.get_node_loc(id), new_ty);
+ if let Some(new_inst) = self.env.get_node_instantiation_opt(id).map(|inst| {
+ inst.into_iter()
+ .map(|ty| ty.skip_reference().clone())
+ .collect_vec()
+ }) {
+ self.env.set_node_instantiation(new_id, new_inst);
+ }
+ Some(new_id)
+ } else {
+ None
+ }
+ }
+}
+
+// -------------------------------------------------------------------------------------------
+// Processing Invariants
+
+fn collect_global_invariants_to_env(env: &mut GlobalEnv) {
+ let mut invariants = vec![];
+ for module_env in env.get_modules() {
+ for cond in &module_env.get_spec().conditions {
+ if matches!(
+ cond.kind,
+ ConditionKind::GlobalInvariant(..) | ConditionKind::GlobalInvariantUpdate(..)
+ ) {
+ let id = env.new_global_id();
+ invariants.push(GlobalInvariant {
+ id,
+ loc: cond.loc.clone(),
+ kind: cond.kind.clone(),
+ mem_usage: cond
+ .exp
+ .used_memory(env)
+ .into_iter()
+ .map(|(mem, _)| mem.clone())
+ .collect(),
+ declaring_module: module_env.get_id(),
+ cond: cond.exp.clone(),
+ properties: cond.properties.clone(),
+ });
+ }
+ }
+ }
+ for invariant in invariants {
+ env.add_global_invariant(invariant)
+ }
+}
+
+fn check_data_invariants(struct_env: &StructEnv) {
+ let env = struct_env.module_env.env;
+ for cond in &struct_env.get_spec().conditions {
+ if matches!(cond.kind, ConditionKind::StructInvariant) {
+ let usage = cond.exp.used_memory(env);
+ if !usage.is_empty() {
+ env.error(
+ &cond.loc,
+ &format!(
+ "data invariants cannot depend on global state \
+ but found dependency to `{}`",
+ usage
+ .into_iter()
+ .map(|(sid, _)| env.display(&sid).to_string())
+ .join(",")
+ ),
+ )
+ }
+ }
+ }
+}
diff --git a/third_party/move/move-compiler-v2/src/inliner.rs b/third_party/move/move-compiler-v2/src/inliner.rs
index 9ec37cf047661..fdc62aa217928 100644
--- a/third_party/move/move-compiler-v2/src/inliner.rs
+++ b/third_party/move/move-compiler-v2/src/inliner.rs
@@ -1,46 +1,49 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0
-/// Inlining Overview:
-/// - We visit function calling inline functions reachable from compilation targets in a bottom-up
-/// fashion, storing rewritten functions in a map to simplify further processing.
-/// - Change to the program happens at the end.
-///
-/// Summary of structs/impls in this file. Note that these duplicate comments in the body of this file,
-/// and ideally should be updated if those are changed significantly.
-/// - function `run_inlining` is the main entry point for the inlining pass
-///
-/// - struct `Inliner`
-/// - holds the map recording function bodies which are rewritten due to inlining so that we don't
-/// need to modify the program until the end.
-/// - `do_inlining_in` function is the entry point for each function needing inlining.
-///
-/// - struct `OuterInlinerRewriter` uses trait `ExpRewriterFunctions` to rewrite each call in the
-/// target.
-///
-/// - struct `InlinedRewriter` rewrites a call to an inlined function
-/// - `inline_call` is the external entry point for rewriting a call to an inline function.
-///
-/// - `construct_inlined_call_expression` is a helper to build the `Block` expression corresponding
-/// to { let params=actuals; body } used for both lambda inlining and inline function inlining.
-///
-/// - struct `InlinedRewriter` uses trait `ExpRewriterFunctions` to rewrite the inlined function
-/// body.
-/// - `rewrite_exp` is the entry point to rewrite the body of an inline function.
-///
-/// - struct ShadowStack implements the free variable shadowing stack:
-/// For a given set of "free" variables, the `ShadowStack` tracks which variables are
-/// still directly visible, and which variables have been hidden by local variable
-/// declarations with the same symbol. In the latter case, the ShadowStack provides
-/// a "shadow" symbol which can be used in place of the original.
-///
-/// - TODO(10858): add an anchor AST node so we can implement `Return` for inline functions and
-/// `Lambda`.
+//! Inlining Overview:
+//! - We visit function calling inline functions reachable from compilation targets in a bottom-up
+//! fashion, storing rewritten functions in a map to simplify further processing.
+//! - Change to the program happens at the end.
+//!
+//! Summary of structs/impls in this file. Note that these duplicate comments in the body of this file,
+//! and ideally should be updated if those are changed significantly.
+//! - function `run_inlining` is the main entry point for the inlining pass
+//!
+//! - struct `Inliner`
+//! - holds the map recording function bodies which are rewritten due to inlining so that we don't
+//! need to modify the program until the end.
+//! - `do_inlining_in` function is the entry point for each function needing inlining.
+//!
+//! - struct `OuterInlinerRewriter` uses trait `ExpRewriterFunctions` to rewrite each call in the
+//! target.
+//!
+//! - struct `InlinedRewriter` rewrites a call to an inlined function
+//! - `inline_call` is the external entry point for rewriting a call to an inline function.
+//!
+//! - `construct_inlined_call_expression` is a helper to build the `Block` expression corresponding
+//! to { let params=actuals; body } used for both lambda inlining and inline function inlining.
+//!
+//! - struct `InlinedRewriter` uses trait `ExpRewriterFunctions` to rewrite the inlined function
+//! body.
+//! - `rewrite_exp` is the entry point to rewrite the body of an inline function.
+//!
+//! - struct ShadowStack implements the free variable shadowing stack:
+//! For a given set of "free" variables, the `ShadowStack` tracks which variables are
+//! still directly visible, and which variables have been hidden by local variable
+//! declarations with the same symbol. In the latter case, the ShadowStack provides
+//! a "shadow" symbol which can be used in place of the original.
+//!
+//! - TODO(10858): add an anchor AST node so we can implement `Return` for inline functions and
+//! `Lambda`.
+
+use crate::env_pipeline::rewrite_target::{
+ RewriteState, RewriteTarget, RewriteTargets, RewritingScope,
+};
use codespan_reporting::diagnostic::Severity;
-use itertools::chain;
use log::{debug, trace};
use move_model::{
- ast::{Exp, ExpData, Operation, Pattern, TempIndex},
+ ast::{Exp, ExpData, Operation, Pattern, Spec, SpecBlockTarget, TempIndex},
exp_rewriter::ExpRewriterFunctions,
model::{FunId, GlobalEnv, Loc, NodeId, Parameter, QualifiedId},
symbol::Symbol,
@@ -55,142 +58,150 @@ use std::{
};
type QualifiedFunId = QualifiedId;
-type CallSiteLocations = BTreeMap<(QualifiedFunId, QualifiedFunId), BTreeSet>;
+type CallSiteLocations = BTreeMap<(RewriteTarget, QualifiedFunId), BTreeSet>;
// ======================================================================================
// Entry
/// Run inlining on current program's AST. For each function which is target of the compilation,
/// visit that function body and inline any calls to functions marked as "inline".
-pub fn run_inlining(env: &mut GlobalEnv) {
+pub fn run_inlining(env: &mut GlobalEnv, scope: RewritingScope, keep_inline_functions: bool) {
debug!("Inlining");
// Get non-inline function roots for running inlining.
// Also generate an error for any target inline functions lacking a body to inline.
- let mut todo = get_targets(env);
+ let mut targets = RewriteTargets::create(env, scope);
+ filter_targets(env, &mut targets);
+ let mut todo: BTreeSet<_> = targets.keys().collect();
// Only look for inlining sites if we have targets to inline into.
if !todo.is_empty() {
// Recursively find callees of each target with a function body.
- // The call graph reachable from targets, represented by a map from each function to the set
+ // The call graph reachable from targets, represented by a map from each target to the set
// of functions it calls. The domain is limited to functions with function bodies.
- let mut call_graph: BTreeMap> = BTreeMap::new();
+ let mut call_graph: BTreeMap> = BTreeMap::new();
// For each function `caller` calling an inline function `callee`, we record the set of all
// call sites where `caller` calls `callee` (for error messages).
let mut inline_function_call_site_locations: CallSiteLocations = CallSiteLocations::new();
// Update call_graph and inline_function_call_site_locations for all reachable calls.
- let mut visited_functions = BTreeSet::new();
- while let Some(id) = todo.pop_first() {
- if visited_functions.insert(id) {
- if let Some(def) = env.get_function(id).get_def() {
- let callees_with_sites = def.called_funs_with_callsites();
- for (callee, sites) in callees_with_sites {
- todo.insert(callee);
- call_graph.entry(id).or_default().insert(callee);
- if env.get_function(callee).is_inline() {
- inline_function_call_site_locations.insert((id, callee), sites);
- }
+ let mut visited_targets = BTreeSet::new();
+ while let Some(target) = todo.pop_first() {
+ if visited_targets.insert(target.clone()) {
+ let callees_with_sites = target.called_funs_with_call_sites(env);
+ for (callee, sites) in callees_with_sites {
+ todo.insert(RewriteTarget::MoveFun(callee));
+ targets.entry(RewriteTarget::MoveFun(callee));
+ call_graph.entry(target.clone()).or_default().insert(callee);
+ if env.get_function(callee).is_inline() {
+ inline_function_call_site_locations.insert((target.clone(), callee), sites);
}
}
}
}
- // Get a list of all reachable functions calling inline functions, in bottom-up order.
+ // Get a list of all reachable targets calling inline functions, in bottom-up order.
// If there are any cycles, this call displays an error to the user and returns None.
- if let Ok(functions_needing_inlining) = functions_needing_inlining_in_order(
- env,
- &call_graph,
- inline_function_call_site_locations,
- ) {
+ if let Ok(targets_needing_inlining) =
+ targets_needing_inlining_in_order(env, &call_graph, inline_function_call_site_locations)
+ {
// We inline functions bottom-up, so that any inline function which itself has calls to
// inline functions has already had its stuff inlined.
- let mut inliner = Inliner::new(env);
- for fid in functions_needing_inlining.iter() {
- inliner.do_inlining_in(*fid);
+ let mut inliner = Inliner::new(env, targets);
+ for target in targets_needing_inlining.into_iter() {
+ inliner.do_inlining_in(target);
}
- // Now that all inlining finished, actually update function bodies in env.
- for (fun_id, funexpr_after_inlining) in inliner.funexprs_after_inlining {
- if let Some(changed_funexpr) = funexpr_after_inlining {
- env.set_function_def(fun_id, changed_funexpr)
- }
- }
+ // Now that all inlining finished, actually update definitions in env.
+ inliner.inline_targets.write_to_env(env);
}
}
// Delete all inline functions with bodies from the program rep, even if none were inlined,
// since (1) they are no longer needed, and (2) they may have code constructs that codegen can't
// deal with.
-
- // First construct a list of functions to remove.
- let mut inline_funs = BTreeSet::new();
- for module in env.get_modules() {
- for func in module.get_functions() {
- let id = func.get_qualified_id();
- if func.is_inline() && func.get_def().is_some() {
- // Only delete functions with a body.
- inline_funs.insert(id);
+ //
+ // This can be overridden by `keep_inline_functions`, which maybe helpful in debugging
+ // scenarios since env dumping crashes if the functions are removed but still referenced
+ // from somewhere.
+ if !keep_inline_functions {
+ // First construct a list of functions to remove.
+ let mut inline_funs = BTreeSet::new();
+ for module in env.get_modules() {
+ for func in module.get_functions() {
+ let id = func.get_qualified_id();
+ if func.is_inline() && func.get_def().is_some() {
+ // Only delete functions with a body.
+ inline_funs.insert(id);
+ }
}
}
+ env.filter_functions(|fun_id: &QualifiedFunId| !inline_funs.contains(fun_id));
}
- // Modify the model to delete of the functions and references to them.
- env.filter_functions(|fun_id: &QualifiedFunId| inline_funs.contains(fun_id));
}
-/// Helper functions for inlining driver
-
-/// Get all target functions which are not themselves inline functions.
-/// While we're iterating, produce an error on every target inline function lacking a body to
-/// inline.
-fn get_targets(env: &mut GlobalEnv) -> BTreeSet {
- let mut targets = BTreeSet::new();
- for module in env.get_modules() {
- if module.is_target() {
- for func in module.get_functions() {
- let id = func.get_qualified_id();
- if func.is_inline() {
- if func.get_def().is_none() {
- let func_loc = func.get_loc();
- let func_name = func.get_name_str();
- if func.is_native() {
- let msg = format!("Inline function `{}` must not be native", func_name);
- env.error(&func_loc, &msg);
- } else {
- let msg = format!(
- "No body found for non-native inline function `{}`",
- func_name
- );
- env.diag(Severity::Bug, &func_loc, &msg);
- }
+/// Filter out inline functions from targets since we only process them when they are
+/// called from other functions. While we're iterating, produce an error
+/// on every inline function lacking a body to inline.
+fn filter_targets(env: &GlobalEnv, targets: &mut RewriteTargets) {
+ targets.filter(|target: &RewriteTarget, _| {
+ if let RewriteTarget::MoveFun(fnid) = target {
+ let func = env.get_function(*fnid);
+ if func.is_inline() {
+ if func.get_def().is_none() {
+ let func_loc = func.get_loc();
+ let func_name = func.get_name_str();
+ if func.is_native() {
+ let msg = format!("Inline function `{}` must not be native", func_name);
+ env.error(&func_loc, &msg);
+ } else {
+ let msg = format!(
+ "No body found for non-native inline function `{}`",
+ func_name
+ );
+ env.diag(Severity::Bug, &func_loc, &msg);
}
- } else {
- targets.insert(id);
}
+ false
+ } else {
+ true
}
+ } else {
+ true
}
- }
- targets
+ });
}
-/// Return a list of all functions calling inline functions, in bottom-up order,
+/// Return a list of all inline functions calling inline functions, in bottom-up order,
/// so that any inline function will be processed before any function calling it.
-fn functions_needing_inlining_in_order(
+fn targets_needing_inlining_in_order(
env: &GlobalEnv,
- call_graph: &BTreeMap>,
+ call_graph: &BTreeMap>,
inline_function_call_site_locations: CallSiteLocations,
-) -> Result, ()> {
+) -> Result, ()> {
+ let is_inline_fun = |fnid: &QualifiedFunId| env.get_function(*fnid).is_inline();
+ let inline_fun_target_opt = |target: &RewriteTarget| {
+ if let RewriteTarget::MoveFun(fnid) = target {
+ if is_inline_fun(fnid) {
+ Some(*fnid)
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ };
// Subset of the call graph limited to inline functions.
let inline_function_call_graph: BTreeMap> = call_graph
.iter()
- .filter(|&(caller_fnid, _)| env.get_function(*caller_fnid).is_inline())
+ .filter_map(|(target, callees)| inline_fun_target_opt(target).map(|fid| (fid, callees)))
.map(|(caller_fnid, callees)| {
(
- *caller_fnid,
+ caller_fnid,
callees
.iter()
- .filter(|&callee_fnid| env.get_function(*callee_fnid).is_inline())
+ .filter(|callee_fnid| is_inline_fun(callee_fnid))
.cloned()
.collect(),
)
@@ -220,7 +231,9 @@ fn functions_needing_inlining_in_order(
.iter()
.zip(cycle.iter().skip(1).chain(iter::once(start_fnid)))
.flat_map(|(f, g)| {
- let sites_ids = inline_function_call_site_locations.get(&(*f, *g)).unwrap();
+ let sites_ids = inline_function_call_site_locations
+ .get(&(RewriteTarget::MoveFun(*f), *g))
+ .unwrap();
let f_str = env.get_function(*f).get_full_name_str();
let g_str = env.get_function(*g).get_full_name_str();
let msg = format!("call from `{}` to `{}`", f_str, g_str);
@@ -246,23 +259,22 @@ fn functions_needing_inlining_in_order(
&inline_functions_calling_others,
&inline_function_call_graph,
);
-
- // Identify subset of non-inline functions which call inline functions. Order doesn't matter
- // here.
- let non_inline_functions_needing_inlining: Vec = call_graph
- .iter()
- .filter(|(caller_fnid, callees)| {
- !env.get_function(**caller_fnid).is_inline()
- && callees
- .iter()
- .any(|callee_fnid| env.get_function(*callee_fnid).is_inline())
- })
- .map(|(caller_fnid, _)| caller_fnid)
- .cloned()
+ let mut result: Vec = po_inline_functions
+ .into_iter()
+ .map(RewriteTarget::MoveFun)
.collect();
- let result: Vec =
- chain(po_inline_functions, non_inline_functions_needing_inlining).collect();
+ // Add subset of non-inline function targets which call inline functions. Order
+ // doesn't matter here.
+ result.extend(
+ call_graph
+ .iter()
+ .filter(|(target, callees)| {
+ inline_fun_target_opt(target).is_none() && callees.iter().any(is_inline_fun)
+ })
+ .map(|(target, _)| target.clone()),
+ );
+
Ok(result)
}
@@ -348,47 +360,76 @@ fn check_for_cycles(
struct Inliner<'env> {
env: &'env GlobalEnv,
- /// Functions already processed all get an entry here, with a new function body after inline
- /// calls are substituted here. Functions which are unchanged (no calls to inline functions)
- /// bind to None.
- funexprs_after_inlining: BTreeMap>,
+ /// The set of rewrite targets the inliner works on.
+ inline_targets: RewriteTargets,
}
impl<'env> Inliner<'env> {
- fn new(env: &'env GlobalEnv) -> Self {
- let funexprs_after_inlining = BTreeMap::new();
+ fn new(env: &'env GlobalEnv, inline_targets: RewriteTargets) -> Self {
Self {
env,
- funexprs_after_inlining,
+ inline_targets,
}
}
- /// If the body of function `func_id` contains calls to inline functions, then
- /// - makes a copy of the body with every call to any inline function `callee` replaced by
+ /// If the target has expressions containing calls to inline functions, then
+ /// - makes a copy of the target with every call to any inline function `callee` replaced by
/// either
- /// - the mapping found in `self.funexprs_after_inlining` for `callee`, or
+ /// - the mapping found in `self.inline_results` for `callee`, or
/// - the original body of `callee` (as obtained from `self.env: &GlobalEnv`)
- /// - stores a mapping from `func_id` to the inlined body `self.funexprs_after_inlining`
- /// Otherwise, stores a mapping from `func_id` to `None` in `self.funexprs_after_inlining`
+ /// - stores a mapping from `target` to inlining result in `self.inline_results`
+ /// Otherwise, stores a mapping from `target` to `InlineResult::Unchanged` in
+ /// `self.inline_results`
///
- /// This should be called on `func_id` only after all inline functions it calls are processed.
- /// It must not be called more than once for any given `func_id`.
- fn do_inlining_in(&mut self, func_id: QualifiedFunId) {
- assert!(!self.funexprs_after_inlining.contains_key(&func_id));
- let func_env = self.env.get_function(func_id);
- if let Some(def) = func_env.get_def() {
- let mut rewriter = OuterInlinerRewriter::new(self.env, self);
-
- let rewritten = rewriter.rewrite_exp(def.clone());
- let changed = !ExpData::ptr_eq(&rewritten, def);
- if changed {
- self.funexprs_after_inlining
- .insert(func_id, Some(rewritten));
- } else {
- self.funexprs_after_inlining.insert(func_id, None);
- }
+ /// This should be called on `target` only after all inline functions it calls are processed.
+ /// It must not be called more than once for any given `target`.
+ fn do_inlining_in(&mut self, target: RewriteTarget) {
+ use RewriteState::*;
+ use RewriteTarget::*;
+ assert_eq!(self.inline_targets.entry(target.clone()).1, &Unchanged);
+ match &target {
+ MoveFun(func_id) => {
+ let func_env = self.env.get_function(*func_id);
+ if let Some(new_def) = func_env.get_def().and_then(|def| self.do_rewrite_exp(def)) {
+ *self.inline_targets.state_mut(&target) = Def(new_def)
+ }
+ },
+ SpecFun(func_id) => {
+ let func_env = self.env.get_spec_fun(*func_id);
+ if let Some(new_def) = func_env
+ .body
+ .as_ref()
+ .and_then(|def| self.do_rewrite_exp(def))
+ {
+ *self.inline_targets.state_mut(&target) = Def(new_def);
+ }
+ },
+ SpecBlock(sb_target) => {
+ let spec = self.env.get_spec_block(sb_target);
+ if let Some(new_spec) = self.do_rewrite_spec(sb_target, &spec) {
+ *self.inline_targets.state_mut(&target) = Spec(new_spec)
+ }
+ },
+ }
+ }
+
+ fn do_rewrite_exp(&mut self, exp: &Exp) -> Option {
+ let mut rewriter = OuterInlinerRewriter::new(self.env, self);
+ let rewritten = rewriter.rewrite_exp(exp.clone());
+ if !ExpData::ptr_eq(&rewritten, exp) {
+ Some(rewritten)
+ } else {
+ None
+ }
+ }
+
+ fn do_rewrite_spec(&mut self, target: &SpecBlockTarget, spec: &Spec) -> Option {
+ let mut rewriter = OuterInlinerRewriter::new(self.env, self);
+ let (changed, new_spec) = rewriter.rewrite_spec_descent(target, spec);
+ if changed {
+ Some(new_spec)
} else {
- // Ignore missing body. Error is flagged elsewhere.
+ None
}
}
}
@@ -421,15 +462,18 @@ impl<'env, 'inliner> ExpRewriterFunctions for OuterInlinerRewriter<'env, 'inline
let type_args = self.env.get_node_instantiation(call_id);
let parameters = func_env.get_parameters();
let func_loc = func_env.get_id_loc();
- let body_expr =
- if let Some(Some(expr)) = self.inliner.funexprs_after_inlining.get(&qfid) {
- // `qfid` was previously inlined into, use the post-inlining copy of body.
- Some(expr.clone())
- } else {
- // `qfid` was not previously inlined into, look for the original body expr.
- let func_env_def = func_env.get_def();
- func_env_def.cloned()
- };
+ let body_expr = if let RewriteState::Def(expr) = self
+ .inliner
+ .inline_targets
+ .state(&RewriteTarget::MoveFun(qfid))
+ {
+ // `qfid` was previously inlined into, use the post-inlining copy of body.
+ Some(expr.clone())
+ } else {
+ // `qfid` was not previously inlined into, look for the original body expr.
+ let func_env_def = func_env.get_def();
+ func_env_def.cloned()
+ };
// inline here
if let Some(expr) = body_expr {
trace!(
diff --git a/third_party/move/move-compiler-v2/src/lib.rs b/third_party/move/move-compiler-v2/src/lib.rs
index 785f2cb6e9df3..7d4fe6bd41273 100644
--- a/third_party/move/move-compiler-v2/src/lib.rs
+++ b/third_party/move/move-compiler-v2/src/lib.rs
@@ -15,7 +15,7 @@ pub mod options;
pub mod pipeline;
use crate::{
- env_pipeline::EnvProcessorPipeline,
+ env_pipeline::{rewrite_target::RewritingScope, spec_checker, EnvProcessorPipeline},
pipeline::{
ability_processor::AbilityProcessor, avail_copies_analysis::AvailCopiesAnalysisProcessor,
copy_propagation::CopyPropagation, dead_store_elimination::DeadStoreElimination,
@@ -51,7 +51,6 @@ use move_stackless_bytecode::function_target_pipeline::{
use move_symbol_pool::Symbol;
pub use options::*;
use std::{collections::BTreeSet, io::Write, path::Path};
-
/// Run Move compiler and print errors to stderr.
pub fn run_move_compiler_to_stderr(
options: Options,
@@ -70,25 +69,11 @@ where
{
logging::setup_logging();
info!("Move Compiler v2");
- // Run context check.
- let mut env = run_checker(options.clone())?;
- check_errors(&env, error_writer, "checking errors")?;
-
- debug!("After context check, GlobalEnv=\n{}", env.dump_env());
- let env_pipeline = create_env_processor_pipeline(&env);
- if log_enabled!(Level::Debug) {
- env_pipeline.run_and_record(&mut env, error_writer)?;
- } else {
- env_pipeline.run(&mut env);
- }
+ // Run context check.
+ let mut env = run_checker_and_rewriters(options.clone(), RewritingScope::CompilationTarget)?;
check_errors(&env, error_writer, "checking errors")?;
- debug!(
- "After flow-insensitive checks, GlobalEnv=\n{}",
- env.dump_env()
- );
-
// Run code generator
let mut targets = run_bytecode_gen(&env);
check_errors(&env, error_writer, "code generation errors")?;
@@ -167,6 +152,21 @@ pub fn run_checker(options: Options) -> anyhow::Result {
Ok(env)
}
+/// Run the type checker as well as the AST rewriting pipeline and related additional
+/// checks, returning the global env (with errors if encountered). The result
+/// fails not on context checking errors, but possibly on i/o errors.
+pub fn run_checker_and_rewriters(
+ options: Options,
+ scope: RewritingScope,
+) -> anyhow::Result {
+ let env_pipeline = check_and_rewrite_pipeline(&options, false, scope);
+ let mut env = run_checker(options)?;
+ if !env.has_errors() {
+ env_pipeline.run(&mut env);
+ }
+ Ok(env)
+}
+
// Run the (stackless) bytecode generator. For each function which is target of the
// compilation, create an entry in the functions target holder which encapsulate info
// like the generated bytecode.
@@ -205,29 +205,46 @@ pub fn run_file_format_gen(env: &GlobalEnv, targets: &FunctionTargetsHolder) ->
file_format_generator::generate_file_format(env, targets)
}
-/// Returns the standard env_processor_pipeline
-pub fn create_env_processor_pipeline<'b>(env: &GlobalEnv) -> EnvProcessorPipeline<'b> {
- let options = env.get_extension::().expect("options");
+/// Constructs the env checking and rewriting processing pipeline. `inlining_scope` can be set to
+/// `Everything` for use with the Move Prover, otherwise `CompilationTarget`
+/// should be used.
+pub fn check_and_rewrite_pipeline<'a>(
+ options: &Options,
+ for_v1_model: bool,
+ inlining_scope: RewritingScope,
+) -> EnvProcessorPipeline<'a> {
let optimize_on = options.experiment_on(Experiment::OPTIMIZE);
+ // The default transformation pipeline on the GlobalEnv
let mut env_pipeline = EnvProcessorPipeline::default();
env_pipeline.add(
- "unused vars and params checks",
+ "unused checks",
flow_insensitive_checkers::check_for_unused_vars_and_params,
);
env_pipeline.add(
- "function typed parameter check",
+ "type parameter check",
function_checker::check_for_function_typed_parameters,
);
- env_pipeline.add(
- "access and use check before inlining",
- |env: &mut GlobalEnv| function_checker::check_access_and_use(env, true),
- );
- env_pipeline.add("inlining", inliner::run_inlining);
- env_pipeline.add(
- "access and use check after inlining",
- |env: &mut GlobalEnv| function_checker::check_access_and_use(env, false),
- );
+ if !for_v1_model {
+ // Currently when coming via the v1 model building path friend info is
+ // not populated, so skip those tests. They are anyway run already by
+ // the v1 compiler.
+ env_pipeline.add(
+ "access and use check before inlining",
+ |env: &mut GlobalEnv| function_checker::check_access_and_use(env, true),
+ );
+ }
+ env_pipeline.add("inlining", {
+ move |env| {
+ inliner::run_inlining(env, inlining_scope, /*keep_inline_functions*/ false)
+ }
+ });
+ if !for_v1_model {
+ env_pipeline.add(
+ "access and use check after inlining",
+ |env: &mut GlobalEnv| function_checker::check_access_and_use(env, false),
+ );
+ }
env_pipeline.add("simplifier", {
move |env: &mut GlobalEnv| {
ast_simplifier::run_simplifier(
@@ -236,6 +253,10 @@ pub fn create_env_processor_pipeline<'b>(env: &GlobalEnv) -> EnvProcessorPipelin
)
}
});
+ env_pipeline.add("specification checker", |env| {
+ let env: &GlobalEnv = env;
+ spec_checker::run_spec_checker(env)
+ });
env_pipeline
}
diff --git a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp
index c73eab8577e2e..3910bd4b361dc 100644
--- a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp
+++ b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.exp
@@ -1,75 +1,21 @@
Diagnostics:
-error: type `ability::Impotent` does not have the `key` ability
- ┌─ tests/ability-check/ability_violation.move:4:3
- │
- 4 │ move_from(addr);
- │ ^^^^^^^^^^^^^^^^^^ required because of storage operation here
- ·
-14 │ move_from_no_key(addr);
- │ -------------------------------- from a call inlined at this callsite
-
-error: value of type `ability::Impotent` does not have the `drop` ability
- ┌─ tests/ability-check/ability_violation.move:4:3
- │
- 4 │ move_from(addr);
- │ ^^^^^^^^^^^^^^^^^^ implicitly dropped here since it is no longer used
- ·
-14 │ move_from_no_key(addr);
- │ -------------------------------- from a call inlined at this callsite
-
-error: type `ability::S` does not have the `key` ability
- ┌─ tests/ability-check/ability_violation.move:15:3
- │
-15 │ move_from
>(addr);
- │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
-error: value of type `ability::S` does not have the `drop` ability
- ┌─ tests/ability-check/ability_violation.move:15:3
- │
-15 │ move_from>(addr);
- │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implicitly dropped here since it is no longer used
-
-error: type `ability::Impotent` does not have the `key` ability
- ┌─ tests/ability-check/ability_violation.move:16:3
- │
-16 │ borrow_global_mut(addr);
- │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
-error: type `ability::Impotent` does not have the `key` ability
- ┌─ tests/ability-check/ability_violation.move:17:3
- │
-17 │ borrow_global(addr);
- │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
-error: type `ability::Impotent` does not have the `key` ability
- ┌─ tests/ability-check/ability_violation.move:18:3
- │
-18 │ exists(addr);
- │ ^^^^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
-error: type `ability::Impotent` does not have the `key` ability
- ┌─ tests/ability-check/ability_violation.move:22:3
- │
-22 │ move_to(signer, Impotent {})
- │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
error: local `x` of type `ability::Impotent` does not have the `copy` ability
- ┌─ tests/ability-check/ability_violation.move:27:4
- │
-27 │ (x, x);
- │ ^ - used here
- │ │
- │ copy needed here because value is still in use
+ ┌─ tests/ability-check/ability_violation.move:7:10
+ │
+7 │ (x, x);
+ │ ^ - used here
+ │ │
+ │ copy needed here because value is still in use
error: value of type `ability::Impotent` does not have the `drop` ability
- ┌─ tests/ability-check/ability_violation.move:27:4
- │
-27 │ (x, x);
- │ ^ implicitly dropped here since it is no longer used
+ ┌─ tests/ability-check/ability_violation.move:7:10
+ │
+7 │ (x, x);
+ │ ^ implicitly dropped here since it is no longer used
error: value of type `ability::Impotent` does not have the `drop` ability
- ┌─ tests/ability-check/ability_violation.move:27:7
- │
-27 │ (x, x);
- │ ^ implicitly dropped here since it is no longer used
+ ┌─ tests/ability-check/ability_violation.move:7:13
+ │
+7 │ (x, x);
+ │ ^ implicitly dropped here since it is no longer used
diff --git a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.move b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.move
index 4e0fcc75c2e42..869dcef1b16c0 100644
--- a/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.move
+++ b/third_party/move/move-compiler-v2/tests/ability-check/ability_violation.move
@@ -1,29 +1,9 @@
module 0x42::ability {
- inline fun move_from_no_key(addr: address) {
- move_from(addr);
- }
+ struct Impotent {}
- struct Impotent {}
-
- struct S has key {
- x: T
- }
-
- fun no_key(addr: address) {
- move_from_no_key(addr);
- move_from>(addr);
- borrow_global_mut(addr);
- borrow_global(addr);
- exists(addr);
- }
-
- fun invalid_move_to(signer: &signer) {
- move_to(signer, Impotent {})
- }
-
- fun invalid_copy() {
- let x = Impotent {};
- (x, x);
- }
+ fun invalid_copy() {
+ let x = Impotent {};
+ (x, x);
+ }
}
diff --git a/third_party/move/move-compiler-v2/tests/ability-check/globals.exp b/third_party/move/move-compiler-v2/tests/ability-check/globals.exp
deleted file mode 100644
index bc37a081b87d4..0000000000000
--- a/third_party/move/move-compiler-v2/tests/ability-check/globals.exp
+++ /dev/null
@@ -1,33 +0,0 @@
-
-Diagnostics:
-warning: Unused parameter `x`. Consider removing or prefixing with an underscore: `_x`
- ┌─ tests/ability-check/globals.move:18:27
- │
-18 │ fun write(a: address, x: u64): u64 {
- │ ^
-
-
-Diagnostics:
-error: type `globals::R` does not have the `key` ability
- ┌─ tests/ability-check/globals.move:6:9
- │
-6 │ move_to(s, R{f: 1});
- │ ^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
-error: type `globals::R` does not have the `key` ability
- ┌─ tests/ability-check/globals.move:10:9
- │
-10 │ exists(a)
- │ ^^^^^^^^^^^^ required because of storage operation here
-
-error: type `globals::R` does not have the `key` ability
- ┌─ tests/ability-check/globals.move:14:17
- │
-14 │ let r = borrow_global(a);
- │ ^^^^^^^^^^^^^^^^^^^ required because of storage operation here
-
-error: type `globals::R` does not have the `key` ability
- ┌─ tests/ability-check/globals.move:19:17
- │
-19 │ let r = borrow_global_mut(a);
- │ ^^^^^^^^^^^^^^^^^^^^^^^ required because of storage operation here
diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp b/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp
index ec4289d86565f..369bf46f052e3 100644
--- a/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp
+++ b/third_party/move/move-compiler-v2/tests/ability-transform/by_reference.exp
@@ -4,143 +4,127 @@
fun _0::check() {
var $t0: bool
var $t1: u64
- var $t2: u64
+ var $t2: bool
var $t3: u64
var $t4: bool
- var $t5: vector
- var $t6: vector
+ var $t5: u64
+ var $t6: &u64
var $t7: u64
- var $t8: bool
+ var $t8: u64
var $t9: u64
- var $t10: &u64
- var $t11: u64
- var $t12: u64
- var $t13: u64
- var $t14: bool
- var $t15: vector
- var $t16: &vector
- var $t17: vector
- var $t18: vector
+ var $t10: bool
+ var $t11: vector
+ var $t12: &vector
+ var $t13: vector
+ var $t14: vector
+ var $t15: u64
+ var $t16: &mut u64
+ var $t17: &mut u64
+ var $t18: u64
var $t19: u64
- var $t20: &mut u64
- var $t21: &mut u64
- var $t22: u64
- var $t23: u64
- var $t24: &mut vector
- var $t25: &mut vector
- var $t26: vector
- var $t27: vector
+ var $t20: &mut vector
+ var $t21: &mut vector
+ var $t22: vector
+ var $t23: vector
+ var $t24: bool
+ var $t25: u64
+ var $t26: u64
+ var $t27: u64
var $t28: bool
- var $t29: u64
- var $t30: u64
+ var $t29: vector
+ var $t30: vector
var $t31: u64
var $t32: bool
- var $t33: vector
- var $t34: vector
+ var $t33: u64
+ var $t34: bool
var $t35: u64
- var $t36: bool
- var $t37: u64
- var $t38: u64
- var $t39: u64
- var $t40: bool
- var $t41: vector
- var $t42: vector
- var $t43: u64
- 0: $t1 := 0
- 1: $t2 := 0
- 2: $t0 := ==($t1, $t2)
- 3: if ($t0) goto 4 else goto 6
- 4: label L0
- 5: goto 9
- 6: label L1
- 7: $t3 := 42
- 8: abort($t3)
- 9: label L2
- 10: $t5 := [104, 101, 108, 108, 111]
- 11: $t6 := [104, 101, 108, 108, 111]
- 12: $t4 := ==($t5, $t6)
- 13: if ($t4) goto 14 else goto 16
- 14: label L3
- 15: goto 19
- 16: label L4
- 17: $t7 := 42
- 18: abort($t7)
- 19: label L5
- 20: $t11 := 0
- 21: $t10 := borrow_local($t11)
- 22: $t9 := read_ref($t10)
- 23: $t12 := 0
- 24: $t8 := ==($t9, $t12)
- 25: if ($t8) goto 26 else goto 28
- 26: label L6
- 27: goto 31
- 28: label L7
- 29: $t13 := 42
- 30: abort($t13)
- 31: label L8
- 32: $t17 := [104, 101, 108, 108, 111]
- 33: $t16 := borrow_local($t17)
- 34: $t15 := read_ref($t16)
- 35: $t18 := [104, 101, 108, 108, 111]
- 36: $t14 := ==($t15, $t18)
- 37: if ($t14) goto 38 else goto 40
- 38: label L9
- 39: goto 43
- 40: label L10
- 41: $t19 := 42
- 42: abort($t19)
- 43: label L11
- 44: $t22 := 0
- 45: $t21 := borrow_local($t22)
- 46: $t20 := infer($t21)
- 47: $t23 := 1
- 48: write_ref($t20, $t23)
- 49: $t26 := [104, 101, 108, 108, 111]
- 50: $t25 := borrow_local($t26)
- 51: $t24 := infer($t25)
- 52: $t27 := [98, 121, 101]
- 53: write_ref($t24, $t27)
- 54: $t29 := read_ref($t20)
- 55: $t30 := 1
- 56: $t28 := ==($t29, $t30)
- 57: if ($t28) goto 58 else goto 60
- 58: label L12
- 59: goto 63
- 60: label L13
- 61: $t31 := 42
- 62: abort($t31)
- 63: label L14
- 64: $t33 := read_ref($t24)
- 65: $t34 := [98, 121, 101]
- 66: $t32 := ==($t33, $t34)
- 67: if ($t32) goto 68 else goto 70
- 68: label L15
- 69: goto 73
- 70: label L16
- 71: $t35 := 42
- 72: abort($t35)
- 73: label L17
- 74: $t37 := 0
- 75: $t38 := 0
- 76: $t36 := ==($t37, $t38)
- 77: if ($t36) goto 78 else goto 80
- 78: label L18
- 79: goto 83
- 80: label L19
- 81: $t39 := 42
- 82: abort($t39)
- 83: label L20
- 84: $t41 := [104, 101, 108, 108, 111]
- 85: $t42 := [104, 101, 108, 108, 111]
- 86: $t40 := ==($t41, $t42)
- 87: if ($t40) goto 88 else goto 90
- 88: label L21
- 89: goto 93
- 90: label L22
- 91: $t43 := 42
- 92: abort($t43)
- 93: label L23
- 94: return ()
+ 0: $t0 := true
+ 1: if ($t0) goto 2 else goto 4
+ 2: label L0
+ 3: goto 7
+ 4: label L1
+ 5: $t1 := 42
+ 6: abort($t1)
+ 7: label L2
+ 8: $t2 := true
+ 9: if ($t2) goto 10 else goto 12
+ 10: label L3
+ 11: goto 15
+ 12: label L4
+ 13: $t3 := 42
+ 14: abort($t3)
+ 15: label L5
+ 16: $t7 := 0
+ 17: $t6 := borrow_local($t7)
+ 18: $t5 := read_ref($t6)
+ 19: $t8 := 0
+ 20: $t4 := ==($t5, $t8)
+ 21: if ($t4) goto 22 else goto 24
+ 22: label L6
+ 23: goto 27
+ 24: label L7
+ 25: $t9 := 42
+ 26: abort($t9)
+ 27: label L8
+ 28: $t13 := [104, 101, 108, 108, 111]
+ 29: $t12 := borrow_local($t13)
+ 30: $t11 := read_ref($t12)
+ 31: $t14 := [104, 101, 108, 108, 111]
+ 32: $t10 := ==($t11, $t14)
+ 33: if ($t10) goto 34 else goto 36
+ 34: label L9
+ 35: goto 39
+ 36: label L10
+ 37: $t15 := 42
+ 38: abort($t15)
+ 39: label L11
+ 40: $t18 := 0
+ 41: $t17 := borrow_local($t18)
+ 42: $t16 := infer($t17)
+ 43: $t19 := 1
+ 44: write_ref($t16, $t19)
+ 45: $t22 := [104, 101, 108, 108, 111]
+ 46: $t21 := borrow_local($t22)
+ 47: $t20 := infer($t21)
+ 48: $t23 := [98, 121, 101]
+ 49: write_ref($t20, $t23)
+ 50: $t25 := read_ref($t16)
+ 51: $t26 := 1
+ 52: $t24 := ==($t25, $t26)
+ 53: if ($t24) goto 54 else goto 56
+ 54: label L12
+ 55: goto 59
+ 56: label L13
+ 57: $t27 := 42
+ 58: abort($t27)
+ 59: label L14
+ 60: $t29 := read_ref($t20)
+ 61: $t30 := [98, 121, 101]
+ 62: $t28 := ==($t29, $t30)
+ 63: if ($t28) goto 64 else goto 66
+ 64: label L15
+ 65: goto 69
+ 66: label L16
+ 67: $t31 := 42
+ 68: abort($t31)
+ 69: label L17
+ 70: $t32 := true
+ 71: if ($t32) goto 72 else goto 74
+ 72: label L18
+ 73: goto 77
+ 74: label L19
+ 75: $t33 := 42
+ 76: abort($t33)
+ 77: label L20
+ 78: $t34 := true
+ 79: if ($t34) goto 80 else goto 82
+ 80: label L21
+ 81: goto 85
+ 82: label L22
+ 83: $t35 := 42
+ 84: abort($t35)
+ 85: label L23
+ 86: return ()
}
============ after LiveVarAnalysisProcessor: ================
@@ -149,238 +133,214 @@ fun _0::check() {
fun _0::check() {
var $t0: bool
var $t1: u64
- var $t2: u64
+ var $t2: bool
var $t3: u64
var $t4: bool
- var $t5: vector
- var $t6: vector
+ var $t5: u64
+ var $t6: &u64
var $t7: u64
- var $t8: bool
+ var $t8: u64
var $t9: u64
- var $t10: &u64
- var $t11: u64
- var $t12: u64
- var $t13: u64
- var $t14: bool
- var $t15: vector
- var $t16: &vector
- var $t17: vector
- var $t18: vector
+ var $t10: bool
+ var $t11: vector
+ var $t12: &vector
+ var $t13: vector
+ var $t14: vector
+ var $t15: u64
+ var $t16: &mut u64
+ var $t17: &mut u64
+ var $t18: u64
var $t19: u64
- var $t20: &mut u64
- var $t21: &mut u64
- var $t22: u64
- var $t23: u64
- var $t24: &mut vector
- var $t25: &mut vector
- var $t26: vector
- var $t27: vector
+ var $t20: &mut vector
+ var $t21: &mut vector
+ var $t22: vector
+ var $t23: vector
+ var $t24: bool
+ var $t25: u64
+ var $t26: u64
+ var $t27: u64
var $t28: bool
- var $t29: u64
- var $t30: u64
+ var $t29: vector
+ var $t30: vector
var $t31: u64
var $t32: bool
- var $t33: vector
- var $t34: vector
+ var $t33: u64
+ var $t34: bool
var $t35: u64
- var $t36: bool
- var $t37: u64
- var $t38: u64
- var $t39: u64
- var $t40: bool
- var $t41: vector
- var $t42: vector
- var $t43: u64
- # live vars:
- 0: $t1 := 0
- # live vars: $t1
- 1: $t2 := 0
- # live vars: $t1, $t2
- 2: $t0 := ==($t1, $t2)
+ # live vars:
+ 0: $t0 := true
# live vars: $t0
- 3: if ($t0) goto 4 else goto 6
+ 1: if ($t0) goto 2 else goto 4
+ # live vars:
+ 2: label L0
+ # live vars:
+ 3: goto 7
+ # live vars:
+ 4: label L1
+ # live vars:
+ 5: $t1 := 42
+ # live vars: $t1
+ 6: abort($t1)
+ # live vars:
+ 7: label L2
+ # live vars:
+ 8: $t2 := true
+ # live vars: $t2
+ 9: if ($t2) goto 10 else goto 12
# live vars:
- 4: label L0
+ 10: label L3
# live vars:
- 5: goto 9
+ 11: goto 15
# live vars:
- 6: label L1
+ 12: label L4
# live vars:
- 7: $t3 := 42
+ 13: $t3 := 42
# live vars: $t3
- 8: abort($t3)
+ 14: abort($t3)
# live vars:
- 9: label L2
+ 15: label L5
# live vars:
- 10: $t5 := [104, 101, 108, 108, 111]
+ 16: $t7 := 0
+ # live vars: $t7
+ 17: $t6 := borrow_local($t7)
+ # live vars: $t6
+ 18: $t5 := read_ref($t6)
# live vars: $t5
- 11: $t6 := [104, 101, 108, 108, 111]
- # live vars: $t5, $t6
- 12: $t4 := ==($t5, $t6)
+ 19: $t8 := 0
+ # live vars: $t5, $t8
+ 20: $t4 := ==($t5, $t8)
# live vars: $t4
- 13: if ($t4) goto 14 else goto 16
+ 21: if ($t4) goto 22 else goto 24
# live vars:
- 14: label L3
+ 22: label L6
# live vars:
- 15: goto 19
+ 23: goto 27
# live vars:
- 16: label L4
+ 24: label L7
# live vars:
- 17: $t7 := 42
- # live vars: $t7
- 18: abort($t7)
+ 25: $t9 := 42
+ # live vars: $t9
+ 26: abort($t9)
# live vars:
- 19: label L5
+ 27: label L8
# live vars:
- 20: $t11 := 0
+ 28: $t13 := [104, 101, 108, 108, 111]
+ # live vars: $t13
+ 29: $t12 := borrow_local($t13)
+ # live vars: $t12
+ 30: $t11 := read_ref($t12)
# live vars: $t11
- 21: $t10 := borrow_local($t11)
+ 31: $t14 := [104, 101, 108, 108, 111]
+ # live vars: $t11, $t14
+ 32: $t10 := ==($t11, $t14)
# live vars: $t10
- 22: $t9 := read_ref($t10)
- # live vars: $t9
- 23: $t12 := 0
- # live vars: $t9, $t12
- 24: $t8 := ==($t9, $t12)
- # live vars: $t8
- 25: if ($t8) goto 26 else goto 28
+ 33: if ($t10) goto 34 else goto 36
# live vars:
- 26: label L6
+ 34: label L9
# live vars:
- 27: goto 31
+ 35: goto 39
# live vars:
- 28: label L7
+ 36: label L10
# live vars:
- 29: $t13 := 42
- # live vars: $t13
- 30: abort($t13)
+ 37: $t15 := 42
+ # live vars: $t15
+ 38: abort($t15)
# live vars:
- 31: label L8
+ 39: label L11
# live vars:
- 32: $t17 := [104, 101, 108, 108, 111]
+ 40: $t18 := 0
+ # live vars: $t18
+ 41: $t17 := borrow_local($t18)
# live vars: $t17
- 33: $t16 := borrow_local($t17)
+ 42: $t16 := infer($t17)
# live vars: $t16
- 34: $t15 := read_ref($t16)
- # live vars: $t15
- 35: $t18 := [104, 101, 108, 108, 111]
- # live vars: $t15, $t18
- 36: $t14 := ==($t15, $t18)
- # live vars: $t14
- 37: if ($t14) goto 38 else goto 40
- # live vars:
- 38: label L9
- # live vars:
- 39: goto 43
- # live vars:
- 40: label L10
- # live vars:
- 41: $t19 := 42
- # live vars: $t19
- 42: abort($t19)
- # live vars:
- 43: label L11
+ 43: $t19 := 1
+ # live vars: $t16, $t19
+ 44: write_ref($t16, $t19)
+ # live vars: $t16
+ 45: $t22 := [104, 101, 108, 108, 111]
+ # live vars: $t16, $t22
+ 46: $t21 := borrow_local($t22)
+ # live vars: $t16, $t21
+ 47: $t20 := infer($t21)
+ # live vars: $t16, $t20
+ 48: $t23 := [98, 121, 101]
+ # live vars: $t16, $t20, $t23
+ 49: write_ref($t20, $t23)
+ # live vars: $t16, $t20
+ 50: $t25 := read_ref($t16)
+ # live vars: $t20, $t25
+ 51: $t26 := 1
+ # live vars: $t20, $t25, $t26
+ 52: $t24 := ==($t25, $t26)
+ # live vars: $t20, $t24
+ 53: if ($t24) goto 54 else goto 56
+ # live vars: $t20
+ 54: label L12
+ # live vars: $t20
+ 55: goto 59
+ # live vars: $t20
+ 56: label L13
# live vars:
- 44: $t22 := 0
- # live vars: $t22
- 45: $t21 := borrow_local($t22)
- # live vars: $t21
- 46: $t20 := infer($t21)
+ 57: $t27 := 42
+ # live vars: $t27
+ 58: abort($t27)
# live vars: $t20
- 47: $t23 := 1
- # live vars: $t20, $t23
- 48: write_ref($t20, $t23)
+ 59: label L14
# live vars: $t20
- 49: $t26 := [104, 101, 108, 108, 111]
- # live vars: $t20, $t26
- 50: $t25 := borrow_local($t26)
- # live vars: $t20, $t25
- 51: $t24 := infer($t25)
- # live vars: $t20, $t24
- 52: $t27 := [98, 121, 101]
- # live vars: $t20, $t24, $t27
- 53: write_ref($t24, $t27)
- # live vars: $t20, $t24
- 54: $t29 := read_ref($t20)
- # live vars: $t24, $t29
- 55: $t30 := 1
- # live vars: $t24, $t29, $t30
- 56: $t28 := ==($t29, $t30)
- # live vars: $t24, $t28
- 57: if ($t28) goto 58 else goto 60
- # live vars: $t24
- 58: label L12
- # live vars: $t24
- 59: goto 63
- # live vars: $t24
- 60: label L13
- # live vars:
- 61: $t31 := 42
- # live vars: $t31
- 62: abort($t31)
- # live vars: $t24
- 63: label L14
- # live vars: $t24
- 64: $t33 := read_ref($t24)
- # live vars: $t33
- 65: $t34 := [98, 121, 101]
- # live vars: $t33, $t34
- 66: $t32 := ==($t33, $t34)
- # live vars: $t32
- 67: if ($t32) goto 68 else goto 70
+ 60: $t29 := read_ref($t20)
+ # live vars: $t29
+ 61: $t30 := [98, 121, 101]
+ # live vars: $t29, $t30
+ 62: $t28 := ==($t29, $t30)
+ # live vars: $t28
+ 63: if ($t28) goto 64 else goto 66
# live vars:
- 68: label L15
+ 64: label L15
# live vars:
- 69: goto 73
+ 65: goto 69
# live vars:
- 70: label L16
+ 66: label L16
# live vars:
- 71: $t35 := 42
- # live vars: $t35
- 72: abort($t35)
+ 67: $t31 := 42
+ # live vars: $t31
+ 68: abort($t31)
# live vars:
- 73: label L17
+ 69: label L17
# live vars:
- 74: $t37 := 0
- # live vars: $t37
- 75: $t38 := 0
- # live vars: $t37, $t38
- 76: $t36 := ==($t37, $t38)
- # live vars: $t36
- 77: if ($t36) goto 78 else goto 80
+ 70: $t32 := true
+ # live vars: $t32
+ 71: if ($t32) goto 72 else goto 74
# live vars:
- 78: label L18
+ 72: label L18
# live vars:
- 79: goto 83
+ 73: goto 77
# live vars:
- 80: label L19
+ 74: label L19
# live vars:
- 81: $t39 := 42
- # live vars: $t39
- 82: abort($t39)
+ 75: $t33 := 42
+ # live vars: $t33
+ 76: abort($t33)
# live vars:
- 83: label L20
+ 77: label L20
# live vars:
- 84: $t41 := [104, 101, 108, 108, 111]
- # live vars: $t41
- 85: $t42 := [104, 101, 108, 108, 111]
- # live vars: $t41, $t42
- 86: $t40 := ==($t41, $t42)
- # live vars: $t40
- 87: if ($t40) goto 88 else goto 90
+ 78: $t34 := true
+ # live vars: $t34
+ 79: if ($t34) goto 80 else goto 82
# live vars:
- 88: label L21
+ 80: label L21
# live vars:
- 89: goto 93
+ 81: goto 85
# live vars:
- 90: label L22
+ 82: label L22
# live vars:
- 91: $t43 := 42
- # live vars: $t43
- 92: abort($t43)
+ 83: $t35 := 42
+ # live vars: $t35
+ 84: abort($t35)
# live vars:
- 93: label L23
+ 85: label L23
# live vars:
- 94: return ()
+ 86: return ()
}
============ after ReferenceSafetyProcessor: ================
@@ -389,618 +349,562 @@ fun _0::check() {
fun _0::check() {
var $t0: bool
var $t1: u64
- var $t2: u64
+ var $t2: bool
var $t3: u64
var $t4: bool
- var $t5: vector
- var $t6: vector
+ var $t5: u64
+ var $t6: &u64
var $t7: u64
- var $t8: bool
+ var $t8: u64
var $t9: u64
- var $t10: &u64
- var $t11: u64
- var $t12: u64
- var $t13: u64
- var $t14: bool
- var $t15: vector
- var $t16: &vector
- var $t17: vector
- var $t18: vector
+ var $t10: bool
+ var $t11: vector
+ var $t12: &vector
+ var $t13: vector
+ var $t14: vector
+ var $t15: u64
+ var $t16: &mut u64
+ var $t17: &mut u64
+ var $t18: u64
var $t19: u64
- var $t20: &mut u64
- var $t21: &mut u64
- var $t22: u64
- var $t23: u64
- var $t24: &mut vector
- var $t25: &mut vector
- var $t26: vector
- var $t27: vector
+ var $t20: &mut vector
+ var $t21: &mut vector
+ var $t22: vector
+ var $t23: vector
+ var $t24: bool
+ var $t25: u64
+ var $t26: u64
+ var $t27: u64
var $t28: bool
- var $t29: u64
- var $t30: u64
+ var $t29: vector
+ var $t30: vector
var $t31: u64
var $t32: bool
- var $t33: vector
- var $t34: vector
+ var $t33: u64
+ var $t34: bool
var $t35: u64
- var $t36: bool
- var $t37: u64
- var $t38: u64
- var $t39: u64
- var $t40: bool
- var $t41: vector
- var $t42: vector
- var $t43: u64
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 0: $t1 := 0
- # live vars: $t1
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 1: $t2 := 0
- # live vars: $t1, $t2
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 2: $t0 := ==($t1, $t2)
+ 0: $t0 := true
# live vars: $t0
# graph: {}
# locals: {}
# globals: {}
#
- 3: if ($t0) goto 4 else goto 6
+ 1: if ($t0) goto 2 else goto 4
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 4: label L0
+ 2: label L0
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 5: goto 9
+ 3: goto 7
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 6: label L1
+ 4: label L1
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 7: $t3 := 42
- # live vars: $t3
+ 5: $t1 := 42
+ # live vars: $t1
# graph: {}
# locals: {}
# globals: {}
#
- 8: abort($t3)
+ 6: abort($t1)
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 9: label L2
+ 7: label L2
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 10: $t5 := [104, 101, 108, 108, 111]
- # live vars: $t5
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 11: $t6 := [104, 101, 108, 108, 111]
- # live vars: $t5, $t6
+ 8: $t2 := true
+ # live vars: $t2
# graph: {}
# locals: {}
# globals: {}
#
- 12: $t4 := ==($t5, $t6)
- # live vars: $t4
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 13: if ($t4) goto 14 else goto 16
+ 9: if ($t2) goto 10 else goto 12
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 14: label L3
+ 10: label L3
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 15: goto 19
+ 11: goto 15
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 16: label L4
+ 12: label L4
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 17: $t7 := 42
- # live vars: $t7
+ 13: $t3 := 42
+ # live vars: $t3
# graph: {}
# locals: {}
# globals: {}
#
- 18: abort($t7)
+ 14: abort($t3)
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 19: label L5
+ 15: label L5
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 20: $t11 := 0
- # live vars: $t11
+ 16: $t7 := 0
+ # live vars: $t7
# graph: {}
# locals: {}
# globals: {}
#
- 21: $t10 := borrow_local($t11)
- # live vars: $t10
- # graph: {@1500=local($t11)[borrow(false) -> @1501],@1501=derived[]}
- # locals: {$t10=@1501,$t11=@1500}
+ 17: $t6 := borrow_local($t7)
+ # live vars: $t6
+ # graph: {@1100=local($t7)[borrow(false) -> @1101],@1101=derived[]}
+ # locals: {$t6=@1101,$t7=@1100}
# globals: {}
#
- 22: $t9 := read_ref($t10)
- # live vars: $t9
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ 18: $t5 := read_ref($t6)
+ # live vars: $t5
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 23: $t12 := 0
- # live vars: $t9, $t12
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ 19: $t8 := 0
+ # live vars: $t5, $t8
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 24: $t8 := ==($t9, $t12)
- # live vars: $t8
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ 20: $t4 := ==($t5, $t8)
+ # live vars: $t4
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 25: if ($t8) goto 26 else goto 28
+ 21: if ($t4) goto 22 else goto 24
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 26: label L6
+ 22: label L6
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 27: goto 31
+ 23: goto 27
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 28: label L7
+ 24: label L7
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 29: $t13 := 42
- # live vars: $t13
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ 25: $t9 := 42
+ # live vars: $t9
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 30: abort($t13)
+ 26: abort($t9)
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 31: label L8
+ 27: label L8
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 32: $t17 := [104, 101, 108, 108, 111]
- # live vars: $t17
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ 28: $t13 := [104, 101, 108, 108, 111]
+ # live vars: $t13
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 33: $t16 := borrow_local($t17)
- # live vars: $t16
- # graph: {@1500=local($t11)[],@2100=local($t17)[borrow(false) -> @2101],@2101=derived[]}
- # locals: {$t11=@1500,$t16=@2101,$t17=@2100}
+ 29: $t12 := borrow_local($t13)
+ # live vars: $t12
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[borrow(false) -> @1D01],@1D01=derived[]}
+ # locals: {$t7=@1100,$t12=@1D01,$t13=@1D00}
# globals: {}
#
- 34: $t15 := read_ref($t16)
- # live vars: $t15
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ 30: $t11 := read_ref($t12)
+ # live vars: $t11
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 35: $t18 := [104, 101, 108, 108, 111]
- # live vars: $t15, $t18
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ 31: $t14 := [104, 101, 108, 108, 111]
+ # live vars: $t11, $t14
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 36: $t14 := ==($t15, $t18)
- # live vars: $t14
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ 32: $t10 := ==($t11, $t14)
+ # live vars: $t10
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 37: if ($t14) goto 38 else goto 40
+ 33: if ($t10) goto 34 else goto 36
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 38: label L9
+ 34: label L9
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 39: goto 43
+ 35: goto 39
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 40: label L10
+ 36: label L10
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 41: $t19 := 42
- # live vars: $t19
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ 37: $t15 := 42
+ # live vars: $t15
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 42: abort($t19)
+ 38: abort($t15)
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 43: label L11
+ 39: label L11
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 44: $t22 := 0
- # live vars: $t22
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ 40: $t18 := 0
+ # live vars: $t18
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 45: $t21 := borrow_local($t22)
- # live vars: $t21
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t21=@2D01,$t22=@2D00}
+ 41: $t17 := borrow_local($t18)
+ # live vars: $t17
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t17=@2901,$t18=@2900}
# globals: {}
#
- 46: $t20 := infer($t21)
- # live vars: $t20
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ 42: $t16 := infer($t17)
+ # live vars: $t16
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 47: $t23 := 1
- # live vars: $t20, $t23
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ 43: $t19 := 1
+ # live vars: $t16, $t19
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 48: write_ref($t20, $t23)
- # live vars: $t20
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ 44: write_ref($t16, $t19)
+ # live vars: $t16
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 49: $t26 := [104, 101, 108, 108, 111]
- # live vars: $t20, $t26
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ 45: $t22 := [104, 101, 108, 108, 111]
+ # live vars: $t16, $t22
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 50: $t25 := borrow_local($t26)
- # live vars: $t20, $t25
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t25=@3201,$t26=@3200}
+ 46: $t21 := borrow_local($t22)
+ # live vars: $t16, $t21
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t21=@2E01,$t22=@2E00}
# globals: {}
#
- 51: $t24 := infer($t25)
- # live vars: $t20, $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 47: $t20 := infer($t21)
+ # live vars: $t16, $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 52: $t27 := [98, 121, 101]
- # live vars: $t20, $t24, $t27
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 48: $t23 := [98, 121, 101]
+ # live vars: $t16, $t20, $t23
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 53: write_ref($t24, $t27)
- # live vars: $t20, $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 49: write_ref($t20, $t23)
+ # live vars: $t16, $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 54: $t29 := read_ref($t20)
- # live vars: $t24, $t29
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 50: $t25 := read_ref($t16)
+ # live vars: $t20, $t25
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 55: $t30 := 1
- # live vars: $t24, $t29, $t30
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 51: $t26 := 1
+ # live vars: $t20, $t25, $t26
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 56: $t28 := ==($t29, $t30)
- # live vars: $t24, $t28
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 52: $t24 := ==($t25, $t26)
+ # live vars: $t20, $t24
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 57: if ($t28) goto 58 else goto 60
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 53: if ($t24) goto 54 else goto 56
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 58: label L12
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 54: label L12
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 59: goto 63
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 55: goto 59
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 60: label L13
+ 56: label L13
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 61: $t31 := 42
- # live vars: $t31
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 57: $t27 := 42
+ # live vars: $t27
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 62: abort($t31)
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 58: abort($t27)
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 63: label L14
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ 59: label L14
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 64: $t33 := read_ref($t24)
- # live vars: $t33
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 60: $t29 := read_ref($t20)
+ # live vars: $t29
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 65: $t34 := [98, 121, 101]
- # live vars: $t33, $t34
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 61: $t30 := [98, 121, 101]
+ # live vars: $t29, $t30
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 66: $t32 := ==($t33, $t34)
- # live vars: $t32
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 62: $t28 := ==($t29, $t30)
+ # live vars: $t28
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 67: if ($t32) goto 68 else goto 70
+ 63: if ($t28) goto 64 else goto 66
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 68: label L15
+ 64: label L15
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 69: goto 73
+ 65: goto 69
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 70: label L16
+ 66: label L16
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 71: $t35 := 42
- # live vars: $t35
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 67: $t31 := 42
+ # live vars: $t31
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 72: abort($t35)
+ 68: abort($t31)
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 73: label L17
+ 69: label L17
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 74: $t37 := 0
- # live vars: $t37
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 75: $t38 := 0
- # live vars: $t37, $t38
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 76: $t36 := ==($t37, $t38)
- # live vars: $t36
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 70: $t32 := true
+ # live vars: $t32
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 77: if ($t36) goto 78 else goto 80
+ 71: if ($t32) goto 72 else goto 74
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 78: label L18
+ 72: label L18
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 79: goto 83
+ 73: goto 77
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 80: label L19
+ 74: label L19
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 81: $t39 := 42
- # live vars: $t39
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 75: $t33 := 42
+ # live vars: $t33
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 82: abort($t39)
+ 76: abort($t33)
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 83: label L20
+ 77: label L20
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 84: $t41 := [104, 101, 108, 108, 111]
- # live vars: $t41
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 85: $t42 := [104, 101, 108, 108, 111]
- # live vars: $t41, $t42
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 78: $t34 := true
+ # live vars: $t34
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 86: $t40 := ==($t41, $t42)
- # live vars: $t40
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 87: if ($t40) goto 88 else goto 90
+ 79: if ($t34) goto 80 else goto 82
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 88: label L21
+ 80: label L21
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 89: goto 93
+ 81: goto 85
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 90: label L22
+ 82: label L22
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 91: $t43 := 42
- # live vars: $t43
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ 83: $t35 := 42
+ # live vars: $t35
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 92: abort($t43)
+ 84: abort($t35)
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 93: label L23
+ 85: label L23
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 94: return ()
+ 86: return ()
}
============ after AbortAnalysisProcessor: ================
@@ -1009,713 +913,649 @@ fun _0::check() {
fun _0::check() {
var $t0: bool
var $t1: u64
- var $t2: u64
+ var $t2: bool
var $t3: u64
var $t4: bool
- var $t5: vector
- var $t6: vector
+ var $t5: u64
+ var $t6: &u64
var $t7: u64
- var $t8: bool
+ var $t8: u64
var $t9: u64
- var $t10: &u64
- var $t11: u64
- var $t12: u64
- var $t13: u64
- var $t14: bool
- var $t15: vector
- var $t16: &vector
- var $t17: vector
- var $t18: vector
+ var $t10: bool
+ var $t11: vector
+ var $t12: &vector
+ var $t13: vector
+ var $t14: vector
+ var $t15: u64
+ var $t16: &mut u64
+ var $t17: &mut u64
+ var $t18: u64
var $t19: u64
- var $t20: &mut u64
- var $t21: &mut u64
- var $t22: u64
- var $t23: u64
- var $t24: &mut vector
- var $t25: &mut vector
- var $t26: vector
- var $t27: vector
+ var $t20: &mut vector
+ var $t21: &mut vector
+ var $t22: vector
+ var $t23: vector
+ var $t24: bool
+ var $t25: u64
+ var $t26: u64
+ var $t27: u64
var $t28: bool
- var $t29: u64
- var $t30: u64
+ var $t29: vector
+ var $t30: vector
var $t31: u64
var $t32: bool
- var $t33: vector
- var $t34: vector
+ var $t33: u64
+ var $t34: bool
var $t35: u64
- var $t36: bool
- var $t37: u64
- var $t38: u64
- var $t39: u64
- var $t40: bool
- var $t41: vector
- var $t42: vector
- var $t43: u64
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 0: $t1 := 0
- # abort state: {returns,aborts}
- # live vars: $t1
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 1: $t2 := 0
- # abort state: {returns,aborts}
- # live vars: $t1, $t2
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 2: $t0 := ==($t1, $t2)
+ 0: $t0 := true
# abort state: {returns,aborts}
# live vars: $t0
# graph: {}
# locals: {}
# globals: {}
#
- 3: if ($t0) goto 4 else goto 6
+ 1: if ($t0) goto 2 else goto 4
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 4: label L0
+ 2: label L0
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 5: goto 9
+ 3: goto 7
# abort state: {aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 6: label L1
+ 4: label L1
# abort state: {aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 7: $t3 := 42
+ 5: $t1 := 42
# abort state: {aborts}
- # live vars: $t3
+ # live vars: $t1
# graph: {}
# locals: {}
# globals: {}
#
- 8: abort($t3)
+ 6: abort($t1)
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 9: label L2
+ 7: label L2
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 10: $t5 := [104, 101, 108, 108, 111]
- # abort state: {returns,aborts}
- # live vars: $t5
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 11: $t6 := [104, 101, 108, 108, 111]
+ 8: $t2 := true
# abort state: {returns,aborts}
- # live vars: $t5, $t6
+ # live vars: $t2
# graph: {}
# locals: {}
# globals: {}
#
- 12: $t4 := ==($t5, $t6)
- # abort state: {returns,aborts}
- # live vars: $t4
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 13: if ($t4) goto 14 else goto 16
+ 9: if ($t2) goto 10 else goto 12
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 14: label L3
+ 10: label L3
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 15: goto 19
+ 11: goto 15
# abort state: {aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 16: label L4
+ 12: label L4
# abort state: {aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 17: $t7 := 42
+ 13: $t3 := 42
# abort state: {aborts}
- # live vars: $t7
+ # live vars: $t3
# graph: {}
# locals: {}
# globals: {}
#
- 18: abort($t7)
+ 14: abort($t3)
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 19: label L5
+ 15: label L5
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 20: $t11 := 0
+ 16: $t7 := 0
# abort state: {returns,aborts}
- # live vars: $t11
+ # live vars: $t7
# graph: {}
# locals: {}
# globals: {}
#
- 21: $t10 := borrow_local($t11)
+ 17: $t6 := borrow_local($t7)
# abort state: {returns,aborts}
- # live vars: $t10
- # graph: {@1500=local($t11)[borrow(false) -> @1501],@1501=derived[]}
- # locals: {$t10=@1501,$t11=@1500}
+ # live vars: $t6
+ # graph: {@1100=local($t7)[borrow(false) -> @1101],@1101=derived[]}
+ # locals: {$t6=@1101,$t7=@1100}
# globals: {}
#
- 22: $t9 := read_ref($t10)
+ 18: $t5 := read_ref($t6)
# abort state: {returns,aborts}
- # live vars: $t9
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # live vars: $t5
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 23: $t12 := 0
+ 19: $t8 := 0
# abort state: {returns,aborts}
- # live vars: $t9, $t12
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # live vars: $t5, $t8
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 24: $t8 := ==($t9, $t12)
+ 20: $t4 := ==($t5, $t8)
# abort state: {returns,aborts}
- # live vars: $t8
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # live vars: $t4
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 25: if ($t8) goto 26 else goto 28
+ 21: if ($t4) goto 22 else goto 24
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 26: label L6
+ 22: label L6
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 27: goto 31
+ 23: goto 27
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 28: label L7
+ 24: label L7
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 29: $t13 := 42
+ 25: $t9 := 42
# abort state: {aborts}
- # live vars: $t13
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # live vars: $t9
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 30: abort($t13)
+ 26: abort($t9)
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 31: label L8
+ 27: label L8
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 32: $t17 := [104, 101, 108, 108, 111]
+ 28: $t13 := [104, 101, 108, 108, 111]
# abort state: {returns,aborts}
- # live vars: $t17
- # graph: {@1500=local($t11)[]}
- # locals: {$t11=@1500}
+ # live vars: $t13
+ # graph: {@1100=local($t7)[]}
+ # locals: {$t7=@1100}
# globals: {}
#
- 33: $t16 := borrow_local($t17)
+ 29: $t12 := borrow_local($t13)
# abort state: {returns,aborts}
- # live vars: $t16
- # graph: {@1500=local($t11)[],@2100=local($t17)[borrow(false) -> @2101],@2101=derived[]}
- # locals: {$t11=@1500,$t16=@2101,$t17=@2100}
+ # live vars: $t12
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[borrow(false) -> @1D01],@1D01=derived[]}
+ # locals: {$t7=@1100,$t12=@1D01,$t13=@1D00}
# globals: {}
#
- 34: $t15 := read_ref($t16)
+ 30: $t11 := read_ref($t12)
# abort state: {returns,aborts}
- # live vars: $t15
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # live vars: $t11
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 35: $t18 := [104, 101, 108, 108, 111]
+ 31: $t14 := [104, 101, 108, 108, 111]
# abort state: {returns,aborts}
- # live vars: $t15, $t18
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # live vars: $t11, $t14
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 36: $t14 := ==($t15, $t18)
+ 32: $t10 := ==($t11, $t14)
# abort state: {returns,aborts}
- # live vars: $t14
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # live vars: $t10
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 37: if ($t14) goto 38 else goto 40
+ 33: if ($t10) goto 34 else goto 36
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 38: label L9
+ 34: label L9
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 39: goto 43
+ 35: goto 39
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 40: label L10
+ 36: label L10
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 41: $t19 := 42
+ 37: $t15 := 42
# abort state: {aborts}
- # live vars: $t19
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # live vars: $t15
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 42: abort($t19)
+ 38: abort($t15)
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 43: label L11
+ 39: label L11
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 44: $t22 := 0
+ 40: $t18 := 0
# abort state: {returns,aborts}
- # live vars: $t22
- # graph: {@1500=local($t11)[],@2100=local($t17)[]}
- # locals: {$t11=@1500,$t17=@2100}
+ # live vars: $t18
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[]}
+ # locals: {$t7=@1100,$t13=@1D00}
# globals: {}
#
- 45: $t21 := borrow_local($t22)
+ 41: $t17 := borrow_local($t18)
# abort state: {returns,aborts}
- # live vars: $t21
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t21=@2D01,$t22=@2D00}
+ # live vars: $t17
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t17=@2901,$t18=@2900}
# globals: {}
#
- 46: $t20 := infer($t21)
+ 42: $t16 := infer($t17)
# abort state: {returns,aborts}
- # live vars: $t20
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ # live vars: $t16
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 47: $t23 := 1
+ 43: $t19 := 1
# abort state: {returns,aborts}
- # live vars: $t20, $t23
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ # live vars: $t16, $t19
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 48: write_ref($t20, $t23)
+ 44: write_ref($t16, $t19)
# abort state: {returns,aborts}
- # live vars: $t20
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ # live vars: $t16
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 49: $t26 := [104, 101, 108, 108, 111]
+ 45: $t22 := [104, 101, 108, 108, 111]
# abort state: {returns,aborts}
- # live vars: $t20, $t26
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00}
+ # live vars: $t16, $t22
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900}
# globals: {}
#
- 50: $t25 := borrow_local($t26)
+ 46: $t21 := borrow_local($t22)
# abort state: {returns,aborts}
- # live vars: $t20, $t25
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t25=@3201,$t26=@3200}
+ # live vars: $t16, $t21
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t21=@2E01,$t22=@2E00}
# globals: {}
#
- 51: $t24 := infer($t25)
+ 47: $t20 := infer($t21)
# abort state: {returns,aborts}
- # live vars: $t20, $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t16, $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 52: $t27 := [98, 121, 101]
+ 48: $t23 := [98, 121, 101]
# abort state: {returns,aborts}
- # live vars: $t20, $t24, $t27
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t16, $t20, $t23
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 53: write_ref($t24, $t27)
+ 49: write_ref($t20, $t23)
# abort state: {returns,aborts}
- # live vars: $t20, $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[borrow(true) -> @2D01],@2D01=derived[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t20=@2D01,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t16, $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[borrow(true) -> @2901],@2901=derived[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t16=@2901,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 54: $t29 := read_ref($t20)
+ 50: $t25 := read_ref($t16)
# abort state: {returns,aborts}
- # live vars: $t24, $t29
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20, $t25
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 55: $t30 := 1
+ 51: $t26 := 1
# abort state: {returns,aborts}
- # live vars: $t24, $t29, $t30
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20, $t25, $t26
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 56: $t28 := ==($t29, $t30)
+ 52: $t24 := ==($t25, $t26)
# abort state: {returns,aborts}
- # live vars: $t24, $t28
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20, $t24
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 57: if ($t28) goto 58 else goto 60
+ 53: if ($t24) goto 54 else goto 56
# abort state: {returns,aborts}
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 58: label L12
+ 54: label L12
# abort state: {returns,aborts}
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 59: goto 63
+ 55: goto 59
# abort state: {aborts}
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 60: label L13
+ 56: label L13
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 61: $t31 := 42
+ 57: $t27 := 42
# abort state: {aborts}
- # live vars: $t31
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t27
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 62: abort($t31)
+ 58: abort($t27)
# abort state: {returns,aborts}
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 63: label L14
+ 59: label L14
# abort state: {returns,aborts}
- # live vars: $t24
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[borrow(true) -> @3201],@3201=derived[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t24=@3201,$t26=@3200}
+ # live vars: $t20
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[borrow(true) -> @2E01],@2E01=derived[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t20=@2E01,$t22=@2E00}
# globals: {}
#
- 64: $t33 := read_ref($t24)
+ 60: $t29 := read_ref($t20)
# abort state: {returns,aborts}
- # live vars: $t33
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t29
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 65: $t34 := [98, 121, 101]
+ 61: $t30 := [98, 121, 101]
# abort state: {returns,aborts}
- # live vars: $t33, $t34
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t29, $t30
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 66: $t32 := ==($t33, $t34)
+ 62: $t28 := ==($t29, $t30)
# abort state: {returns,aborts}
- # live vars: $t32
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t28
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 67: if ($t32) goto 68 else goto 70
+ 63: if ($t28) goto 64 else goto 66
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 68: label L15
+ 64: label L15
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 69: goto 73
+ 65: goto 69
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 70: label L16
+ 66: label L16
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 71: $t35 := 42
+ 67: $t31 := 42
# abort state: {aborts}
- # live vars: $t35
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t31
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 72: abort($t35)
+ 68: abort($t31)
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 73: label L17
+ 69: label L17
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 74: $t37 := 0
- # abort state: {returns,aborts}
- # live vars: $t37
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 75: $t38 := 0
+ 70: $t32 := true
# abort state: {returns,aborts}
- # live vars: $t37, $t38
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 76: $t36 := ==($t37, $t38)
- # abort state: {returns,aborts}
- # live vars: $t36
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t32
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 77: if ($t36) goto 78 else goto 80
+ 71: if ($t32) goto 72 else goto 74
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 78: label L18
+ 72: label L18
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 79: goto 83
+ 73: goto 77
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 80: label L19
+ 74: label L19
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 81: $t39 := 42
+ 75: $t33 := 42
# abort state: {aborts}
- # live vars: $t39
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t33
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 82: abort($t39)
+ 76: abort($t33)
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 83: label L20
+ 77: label L20
# abort state: {returns,aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 84: $t41 := [104, 101, 108, 108, 111]
+ 78: $t34 := true
# abort state: {returns,aborts}
- # live vars: $t41
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t34
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 85: $t42 := [104, 101, 108, 108, 111]
- # abort state: {returns,aborts}
- # live vars: $t41, $t42
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 86: $t40 := ==($t41, $t42)
- # abort state: {returns,aborts}
- # live vars: $t40
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
- # globals: {}
- #
- 87: if ($t40) goto 88 else goto 90
+ 79: if ($t34) goto 80 else goto 82
# abort state: {returns}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 88: label L21
+ 80: label L21
# abort state: {returns}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 89: goto 93
+ 81: goto 85
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 90: label L22
+ 82: label L22
# abort state: {aborts}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 91: $t43 := 42
+ 83: $t35 := 42
# abort state: {aborts}
- # live vars: $t43
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # live vars: $t35
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 92: abort($t43)
+ 84: abort($t35)
# abort state: {returns}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 93: label L23
+ 85: label L23
# abort state: {returns}
# live vars:
- # graph: {@1500=local($t11)[],@2100=local($t17)[],@2D00=local($t22)[],@3200=local($t26)[]}
- # locals: {$t11=@1500,$t17=@2100,$t22=@2D00,$t26=@3200}
+ # graph: {@1100=local($t7)[],@1D00=local($t13)[],@2900=local($t18)[],@2E00=local($t22)[]}
+ # locals: {$t7=@1100,$t13=@1D00,$t18=@2900,$t22=@2E00}
# globals: {}
#
- 94: return ()
+ 86: return ()
}
============ after AbilityProcessor: ================
@@ -1724,142 +1564,126 @@ fun _0::check() {
fun _0::check() {
var $t0: bool
var $t1: u64
- var $t2: u64
+ var $t2: bool
var $t3: u64
var $t4: bool
- var $t5: vector
- var $t6: vector
+ var $t5: u64
+ var $t6: &u64
var $t7: u64
- var $t8: bool
+ var $t8: u64
var $t9: u64
- var $t10: &u64
- var $t11: u64
- var $t12: u64
- var $t13: u64
- var $t14: bool
- var $t15: vector
- var $t16: &vector
- var $t17: vector
- var $t18: vector
+ var $t10: bool
+ var $t11: vector
+ var $t12: &vector
+ var $t13: vector
+ var $t14: vector
+ var $t15: u64
+ var $t16: &mut u64
+ var $t17: &mut u64
+ var $t18: u64
var $t19: u64
- var $t20: &mut u64
- var $t21: &mut u64
- var $t22: u64
- var $t23: u64
- var $t24: &mut vector
- var $t25: &mut vector
- var $t26: vector
- var $t27: vector
+ var $t20: &mut vector
+ var $t21: &mut vector
+ var $t22: vector
+ var $t23: vector
+ var $t24: bool
+ var $t25: u64
+ var $t26: u64
+ var $t27: u64
var $t28: bool
- var $t29: u64
- var $t30: u64
+ var $t29: vector
+ var $t30: vector
var $t31: u64
var $t32: bool
- var $t33: vector
- var $t34: vector
+ var $t33: u64
+ var $t34: bool
var $t35: u64
- var $t36: bool
- var $t37: u64
- var $t38: u64
- var $t39: u64
- var $t40: bool
- var $t41: vector
- var $t42: vector
- var $t43: u64
- 0: $t1 := 0
- 1: $t2 := 0
- 2: $t0 := ==($t1, $t2)
- 3: if ($t0) goto 4 else goto 6
- 4: label L0
- 5: goto 9
- 6: label L1
- 7: $t3 := 42
- 8: abort($t3)
- 9: label L2
- 10: $t5 := [104, 101, 108, 108, 111]
- 11: $t6 := [104, 101, 108, 108, 111]
- 12: $t4 := ==($t5, $t6)
- 13: if ($t4) goto 14 else goto 16
- 14: label L3
- 15: goto 19
- 16: label L4
- 17: $t7 := 42
- 18: abort($t7)
- 19: label L5
- 20: $t11 := 0
- 21: $t10 := borrow_local($t11)
- 22: $t9 := read_ref($t10)
- 23: $t12 := 0
- 24: $t8 := ==($t9, $t12)
- 25: if ($t8) goto 26 else goto 28
- 26: label L6
- 27: goto 31
- 28: label L7
- 29: $t13 := 42
- 30: abort($t13)
- 31: label L8
- 32: $t17 := [104, 101, 108, 108, 111]
- 33: $t16 := borrow_local($t17)
- 34: $t15 := read_ref($t16)
- 35: $t18 := [104, 101, 108, 108, 111]
- 36: $t14 := ==($t15, $t18)
- 37: if ($t14) goto 38 else goto 40
- 38: label L9
- 39: goto 43
- 40: label L10
- 41: $t19 := 42
- 42: abort($t19)
- 43: label L11
- 44: $t22 := 0
- 45: $t21 := borrow_local($t22)
- 46: $t20 := move($t21)
- 47: $t23 := 1
- 48: write_ref($t20, $t23)
- 49: $t26 := [104, 101, 108, 108, 111]
- 50: $t25 := borrow_local($t26)
- 51: $t24 := move($t25)
- 52: $t27 := [98, 121, 101]
- 53: write_ref($t24, $t27)
- 54: $t29 := read_ref($t20)
- 55: $t30 := 1
- 56: $t28 := ==($t29, $t30)
- 57: if ($t28) goto 58 else goto 60
- 58: label L12
- 59: goto 64
- 60: label L13
- 61: drop($t24)
- 62: $t31 := 42
- 63: abort($t31)
- 64: label L14
- 65: $t33 := read_ref($t24)
- 66: $t34 := [98, 121, 101]
- 67: $t32 := ==($t33, $t34)
- 68: if ($t32) goto 69 else goto 71
- 69: label L15
- 70: goto 74
- 71: label L16
- 72: $t35 := 42
- 73: abort($t35)
- 74: label L17
- 75: $t37 := 0
- 76: $t38 := 0
- 77: $t36 := ==($t37, $t38)
- 78: if ($t36) goto 79 else goto 81
- 79: label L18
- 80: goto 84
- 81: label L19
- 82: $t39 := 42
- 83: abort($t39)
- 84: label L20
- 85: $t41 := [104, 101, 108, 108, 111]
- 86: $t42 := [104, 101, 108, 108, 111]
- 87: $t40 := ==($t41, $t42)
- 88: if ($t40) goto 89 else goto 91
- 89: label L21
- 90: goto 94
- 91: label L22
- 92: $t43 := 42
- 93: abort($t43)
- 94: label L23
- 95: return ()
+ 0: $t0 := true
+ 1: if ($t0) goto 2 else goto 4
+ 2: label L0
+ 3: goto 7
+ 4: label L1
+ 5: $t1 := 42
+ 6: abort($t1)
+ 7: label L2
+ 8: $t2 := true
+ 9: if ($t2) goto 10 else goto 12
+ 10: label L3
+ 11: goto 15
+ 12: label L4
+ 13: $t3 := 42
+ 14: abort($t3)
+ 15: label L5
+ 16: $t7 := 0
+ 17: $t6 := borrow_local($t7)
+ 18: $t5 := read_ref($t6)
+ 19: $t8 := 0
+ 20: $t4 := ==($t5, $t8)
+ 21: if ($t4) goto 22 else goto 24
+ 22: label L6
+ 23: goto 27
+ 24: label L7
+ 25: $t9 := 42
+ 26: abort($t9)
+ 27: label L8
+ 28: $t13 := [104, 101, 108, 108, 111]
+ 29: $t12 := borrow_local($t13)
+ 30: $t11 := read_ref($t12)
+ 31: $t14 := [104, 101, 108, 108, 111]
+ 32: $t10 := ==($t11, $t14)
+ 33: if ($t10) goto 34 else goto 36
+ 34: label L9
+ 35: goto 39
+ 36: label L10
+ 37: $t15 := 42
+ 38: abort($t15)
+ 39: label L11
+ 40: $t18 := 0
+ 41: $t17 := borrow_local($t18)
+ 42: $t16 := move($t17)
+ 43: $t19 := 1
+ 44: write_ref($t16, $t19)
+ 45: $t22 := [104, 101, 108, 108, 111]
+ 46: $t21 := borrow_local($t22)
+ 47: $t20 := move($t21)
+ 48: $t23 := [98, 121, 101]
+ 49: write_ref($t20, $t23)
+ 50: $t25 := read_ref($t16)
+ 51: $t26 := 1
+ 52: $t24 := ==($t25, $t26)
+ 53: if ($t24) goto 54 else goto 56
+ 54: label L12
+ 55: goto 60
+ 56: label L13
+ 57: drop($t20)
+ 58: $t27 := 42
+ 59: abort($t27)
+ 60: label L14
+ 61: $t29 := read_ref($t20)
+ 62: $t30 := [98, 121, 101]
+ 63: $t28 := ==($t29, $t30)
+ 64: if ($t28) goto 65 else goto 67
+ 65: label L15
+ 66: goto 70
+ 67: label L16
+ 68: $t31 := 42
+ 69: abort($t31)
+ 70: label L17
+ 71: $t32 := true
+ 72: if ($t32) goto 73 else goto 75
+ 73: label L18
+ 74: goto 78
+ 75: label L19
+ 76: $t33 := 42
+ 77: abort($t33)
+ 78: label L20
+ 79: $t34 := true
+ 80: if ($t34) goto 81 else goto 83
+ 81: label L21
+ 82: goto 86
+ 83: label L22
+ 84: $t35 := 42
+ 85: abort($t35)
+ 86: label L23
+ 87: return ()
}
diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp b/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp
index ab7df85d03331..63bbcb2991125 100644
--- a/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp
+++ b/third_party/move/move-compiler-v2/tests/ability-transform/dead_but_borrowed.exp
@@ -3,16 +3,14 @@
[variant baseline]
fun explicate_drop::test0(): u8 {
var $t0: u8
- var $t1: u8
- var $t2: u8
- var $t3: &u8
- var $t4: &u8
- 0: $t2 := 42
- 1: $t1 := infer($t2)
- 2: $t4 := borrow_local($t1)
- 3: $t3 := infer($t4)
- 4: $t0 := read_ref($t3)
- 5: return $t0
+ var $t1: &u8
+ var $t2: &u8
+ var $t3: u8
+ 0: $t3 := 42
+ 1: $t2 := borrow_local($t3)
+ 2: $t1 := infer($t2)
+ 3: $t0 := read_ref($t1)
+ 4: return $t0
}
============ after LiveVarAnalysisProcessor: ================
@@ -20,22 +18,19 @@ fun explicate_drop::test0(): u8 {
[variant baseline]
fun explicate_drop::test0(): u8 {
var $t0: u8
- var $t1: u8
- var $t2: u8
- var $t3: &u8
- var $t4: &u8
+ var $t1: &u8
+ var $t2: &u8
+ var $t3: u8
# live vars:
- 0: $t2 := 42
+ 0: $t3 := 42
+ # live vars: $t3
+ 1: $t2 := borrow_local($t3)
# live vars: $t2
- 1: $t1 := infer($t2)
+ 2: $t1 := infer($t2)
# live vars: $t1
- 2: $t4 := borrow_local($t1)
- # live vars: $t4
- 3: $t3 := infer($t4)
- # live vars: $t3
- 4: $t0 := read_ref($t3)
+ 3: $t0 := read_ref($t1)
# live vars: $t0
- 5: return $t0
+ 4: return $t0
}
============ after ReferenceSafetyProcessor: ================
@@ -43,46 +38,39 @@ fun explicate_drop::test0(): u8 {
[variant baseline]
fun explicate_drop::test0(): u8 {
var $t0: u8
- var $t1: u8
- var $t2: u8
- var $t3: &u8
- var $t4: &u8
+ var $t1: &u8
+ var $t2: &u8
+ var $t3: u8
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 0: $t2 := 42
- # live vars: $t2
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 1: $t1 := infer($t2)
- # live vars: $t1
+ 0: $t3 := 42
+ # live vars: $t3
# graph: {}
# locals: {}
# globals: {}
#
- 2: $t4 := borrow_local($t1)
- # live vars: $t4
- # graph: {@200=local($t1)[borrow(false) -> @201],@201=derived[]}
- # locals: {$t1=@200,$t4=@201}
+ 1: $t2 := borrow_local($t3)
+ # live vars: $t2
+ # graph: {@100=local($t3)[borrow(false) -> @101],@101=derived[]}
+ # locals: {$t2=@101,$t3=@100}
# globals: {}
#
- 3: $t3 := infer($t4)
- # live vars: $t3
- # graph: {@200=local($t1)[borrow(false) -> @201],@201=derived[]}
- # locals: {$t1=@200,$t3=@201}
+ 2: $t1 := infer($t2)
+ # live vars: $t1
+ # graph: {@100=local($t3)[borrow(false) -> @101],@101=derived[]}
+ # locals: {$t1=@101,$t3=@100}
# globals: {}
#
- 4: $t0 := read_ref($t3)
+ 3: $t0 := read_ref($t1)
# live vars: $t0
- # graph: {@200=local($t1)[]}
- # locals: {$t1=@200}
+ # graph: {@100=local($t3)[]}
+ # locals: {$t3=@100}
# globals: {}
#
- 5: return $t0
+ 4: return $t0
}
============ after AbortAnalysisProcessor: ================
@@ -90,52 +78,44 @@ fun explicate_drop::test0(): u8 {
[variant baseline]
fun explicate_drop::test0(): u8 {
var $t0: u8
- var $t1: u8
- var $t2: u8
- var $t3: &u8
- var $t4: &u8
+ var $t1: &u8
+ var $t2: &u8
+ var $t3: u8
# abort state: {returns}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 0: $t2 := 42
+ 0: $t3 := 42
# abort state: {returns}
- # live vars: $t2
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 1: $t1 := infer($t2)
- # abort state: {returns}
- # live vars: $t1
+ # live vars: $t3
# graph: {}
# locals: {}
# globals: {}
#
- 2: $t4 := borrow_local($t1)
+ 1: $t2 := borrow_local($t3)
# abort state: {returns}
- # live vars: $t4
- # graph: {@200=local($t1)[borrow(false) -> @201],@201=derived[]}
- # locals: {$t1=@200,$t4=@201}
+ # live vars: $t2
+ # graph: {@100=local($t3)[borrow(false) -> @101],@101=derived[]}
+ # locals: {$t2=@101,$t3=@100}
# globals: {}
#
- 3: $t3 := infer($t4)
+ 2: $t1 := infer($t2)
# abort state: {returns}
- # live vars: $t3
- # graph: {@200=local($t1)[borrow(false) -> @201],@201=derived[]}
- # locals: {$t1=@200,$t3=@201}
+ # live vars: $t1
+ # graph: {@100=local($t3)[borrow(false) -> @101],@101=derived[]}
+ # locals: {$t1=@101,$t3=@100}
# globals: {}
#
- 4: $t0 := read_ref($t3)
+ 3: $t0 := read_ref($t1)
# abort state: {returns}
# live vars: $t0
- # graph: {@200=local($t1)[]}
- # locals: {$t1=@200}
+ # graph: {@100=local($t3)[]}
+ # locals: {$t3=@100}
# globals: {}
#
- 5: return $t0
+ 4: return $t0
}
============ after AbilityProcessor: ================
@@ -143,14 +123,12 @@ fun explicate_drop::test0(): u8 {
[variant baseline]
fun explicate_drop::test0(): u8 {
var $t0: u8
- var $t1: u8
- var $t2: u8
- var $t3: &u8
- var $t4: &u8
- 0: $t2 := 42
- 1: $t1 := move($t2)
- 2: $t4 := borrow_local($t1)
- 3: $t3 := move($t4)
- 4: $t0 := read_ref($t3)
- 5: return $t0
+ var $t1: &u8
+ var $t2: &u8
+ var $t3: u8
+ 0: $t3 := 42
+ 1: $t2 := borrow_local($t3)
+ 2: $t1 := move($t2)
+ 3: $t0 := read_ref($t1)
+ 4: return $t0
}
diff --git a/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp b/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp
index cfd0818c613f5..14f50f0dde338 100644
--- a/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp
+++ b/third_party/move/move-compiler-v2/tests/ability-transform/foreach_mut_expanded.exp
@@ -8,66 +8,54 @@ fun m::test_for_each_mut() {
var $t3: u64
var $t4: u64
var $t5: u64
- var $t6: u64
- var $t7: u64
- var $t8: u64
- var $t9: &vector
- var $t10: &mut vector
- var $t11: &mut vector
- var $t12: bool
- var $t13: &mut u64
- var $t14: &mut u64
- var $t15: u64
- var $t16: u64
+ var $t6: &vector
+ var $t7: &mut vector
+ var $t8: &mut vector
+ var $t9: bool
+ var $t10: &mut u64
+ var $t11: &mut u64
+ var $t12: u64
+ var $t13: u64
+ var $t14: u64
+ var $t15: bool
+ var $t16: vector
var $t17: u64
- var $t18: bool
- var $t19: vector
- var $t20: u64
- var $t21: u64
- var $t22: u64
- var $t23: u64
- 0: $t2 := 1
- 1: $t3 := 2
- 2: $t4 := 3
- 3: $t1 := vector($t2, $t3, $t4)
- 4: $t0 := infer($t1)
- 5: $t6 := 0
- 6: $t5 := infer($t6)
- 7: $t9 := borrow_local($t0)
- 8: $t8 := vector::length($t9)
- 9: $t7 := infer($t8)
- 10: $t11 := borrow_local($t0)
- 11: $t10 := infer($t11)
- 12: label L0
- 13: $t12 := <($t5, $t7)
- 14: if ($t12) goto 15 else goto 24
- 15: label L2
- 16: $t14 := vector::borrow_mut($t10, $t5)
- 17: $t13 := infer($t14)
- 18: $t15 := 2
- 19: write_ref($t13, $t15)
- 20: $t17 := 1
- 21: $t16 := +($t5, $t17)
- 22: $t5 := infer($t16)
- 23: goto 26
- 24: label L3
- 25: goto 28
- 26: label L4
- 27: goto 12
- 28: label L1
- 29: $t20 := 2
- 30: $t21 := 3
- 31: $t22 := 4
- 32: $t19 := vector($t20, $t21, $t22)
- 33: $t18 := ==($t0, $t19)
- 34: if ($t18) goto 35 else goto 37
- 35: label L5
- 36: goto 40
- 37: label L6
- 38: $t23 := 0
- 39: abort($t23)
- 40: label L7
- 41: return ()
+ 0: $t1 := ["1", "2", "3"]
+ 1: $t0 := infer($t1)
+ 2: $t3 := 0
+ 3: $t2 := infer($t3)
+ 4: $t6 := borrow_local($t0)
+ 5: $t5 := vector::length($t6)
+ 6: $t4 := infer($t5)
+ 7: $t8 := borrow_local($t0)
+ 8: $t7 := infer($t8)
+ 9: label L0
+ 10: $t9 := <($t2, $t4)
+ 11: if ($t9) goto 12 else goto 21
+ 12: label L2
+ 13: $t11 := vector::borrow_mut($t7, $t2)
+ 14: $t10 := infer($t11)
+ 15: $t12 := 2
+ 16: write_ref($t10, $t12)
+ 17: $t14 := 1
+ 18: $t13 := +($t2, $t14)
+ 19: $t2 := infer($t13)
+ 20: goto 23
+ 21: label L3
+ 22: goto 25
+ 23: label L4
+ 24: goto 9
+ 25: label L1
+ 26: $t16 := ["2", "3", "4"]
+ 27: $t15 := ==($t0, $t16)
+ 28: if ($t15) goto 29 else goto 31
+ 29: label L5
+ 30: goto 34
+ 31: label L6
+ 32: $t17 := 0
+ 33: abort($t17)
+ 34: label L7
+ 35: return ()
}
============ after LiveVarAnalysisProcessor: ================
@@ -80,108 +68,90 @@ fun m::test_for_each_mut() {
var $t3: u64
var $t4: u64
var $t5: u64
- var $t6: u64
- var $t7: u64
- var $t8: u64
- var $t9: &vector
- var $t10: &mut vector
- var $t11: &mut vector
- var $t12: bool
- var $t13: &mut u64
- var $t14: &mut u64
- var $t15: u64
- var $t16: u64
+ var $t6: &vector
+ var $t7: &mut vector
+ var $t8: &mut vector
+ var $t9: bool
+ var $t10: &mut u64
+ var $t11: &mut u64
+ var $t12: u64
+ var $t13: u64
+ var $t14: u64
+ var $t15: bool
+ var $t16: vector
var $t17: u64
- var $t18: bool
- var $t19: vector
- var $t20: u64
- var $t21: u64
- var $t22: u64
- var $t23: u64
# live vars:
- 0: $t2 := 1
- # live vars: $t2
- 1: $t3 := 2
- # live vars: $t2, $t3
- 2: $t4 := 3
- # live vars: $t2, $t3, $t4
- 3: $t1 := vector($t2, $t3, $t4)
+ 0: $t1 := ["1", "2", "3"]
# live vars: $t1
- 4: $t0 := infer($t1)
+ 1: $t0 := infer($t1)
# live vars: $t0
- 5: $t6 := 0
- # live vars: $t0, $t6
- 6: $t5 := infer($t6)
- # live vars: $t0, $t5
- 7: $t9 := borrow_local($t0)
- # live vars: $t0, $t5, $t9
- 8: $t8 := vector::length($t9)
- # live vars: $t0, $t5, $t8
- 9: $t7 := infer($t8)
- # live vars: $t0, $t5, $t7
- 10: $t11 := borrow_local($t0)
- # live vars: $t0, $t5, $t7, $t11
- 11: $t10 := infer($t11)
- # live vars: $t0, $t5, $t7, $t10
- 12: label L0
- # live vars: $t0, $t5, $t7, $t10
- 13: $t12 := <($t5, $t7)
- # live vars: $t0, $t5, $t7, $t10, $t12
- 14: if ($t12) goto 15 else goto 24
- # live vars: $t0, $t5, $t7, $t10
- 15: label L2
- # live vars: $t0, $t5, $t7, $t10
- 16: $t14 := vector::borrow_mut($t10, $t5)
- # live vars: $t0, $t5, $t7, $t10, $t14
- 17: $t13 := infer($t14)
- # live vars: $t0, $t5, $t7, $t10, $t13
- 18: $t15 := 2
- # live vars: $t0, $t5, $t7, $t10, $t13, $t15
- 19: write_ref($t13, $t15)
- # live vars: $t0, $t5, $t7, $t10
- 20: $t17 := 1
- # live vars: $t0, $t5, $t7, $t10, $t17
- 21: $t16 := +($t5, $t17)
- # live vars: $t0, $t7, $t10, $t16
- 22: $t5 := infer($t16)
- # live vars: $t0, $t5, $t7, $t10
- 23: goto 26
- # live vars: $t0, $t5, $t7, $t10
- 24: label L3
+ 2: $t3 := 0
+ # live vars: $t0, $t3
+ 3: $t2 := infer($t3)
+ # live vars: $t0, $t2
+ 4: $t6 := borrow_local($t0)
+ # live vars: $t0, $t2, $t6
+ 5: $t5 := vector::length($t6)
+ # live vars: $t0, $t2, $t5
+ 6: $t4 := infer($t5)
+ # live vars: $t0, $t2, $t4
+ 7: $t8 := borrow_local($t0)
+ # live vars: $t0, $t2, $t4, $t8
+ 8: $t7 := infer($t8)
+ # live vars: $t0, $t2, $t4, $t7
+ 9: label L0
+ # live vars: $t0, $t2, $t4, $t7
+ 10: $t9 := <($t2, $t4)
+ # live vars: $t0, $t2, $t4, $t7, $t9
+ 11: if ($t9) goto 12 else goto 21
+ # live vars: $t0, $t2, $t4, $t7
+ 12: label L2
+ # live vars: $t0, $t2, $t4, $t7
+ 13: $t11 := vector::borrow_mut($t7, $t2)
+ # live vars: $t0, $t2, $t4, $t7, $t11
+ 14: $t10 := infer($t11)
+ # live vars: $t0, $t2, $t4, $t7, $t10
+ 15: $t12 := 2
+ # live vars: $t0, $t2, $t4, $t7, $t10, $t12
+ 16: write_ref($t10, $t12)
+ # live vars: $t0, $t2, $t4, $t7
+ 17: $t14 := 1
+ # live vars: $t0, $t2, $t4, $t7, $t14
+ 18: $t13 := +($t2, $t14)
+ # live vars: $t0, $t4, $t7, $t13
+ 19: $t2 := infer($t13)
+ # live vars: $t0, $t2, $t4, $t7
+ 20: goto 23
+ # live vars: $t0, $t2, $t4, $t7
+ 21: label L3
# live vars: $t0
- 25: goto 28
- # live vars: $t0, $t5, $t7, $t10
- 26: label L4
- # live vars: $t0, $t5, $t7, $t10
- 27: goto 12
+ 22: goto 25
+ # live vars: $t0, $t2, $t4, $t7
+ 23: label L4
+ # live vars: $t0, $t2, $t4, $t7
+ 24: goto 9
# live vars: $t0
- 28: label L1
+ 25: label L1
# live vars: $t0
- 29: $t20 := 2
- # live vars: $t0, $t20
- 30: $t21 := 3
- # live vars: $t0, $t20, $t21
- 31: $t22 := 4
- # live vars: $t0, $t20, $t21, $t22
- 32: $t19 := vector($t20, $t21, $t22)
- # live vars: $t0, $t19
- 33: $t18 := ==($t0, $t19)
- # live vars: $t18
- 34: if ($t18) goto 35 else goto 37
+ 26: $t16 := ["2", "3", "4"]
+ # live vars: $t0, $t16
+ 27: $t15 := ==($t0, $t16)
+ # live vars: $t15
+ 28: if ($t15) goto 29 else goto 31
# live vars:
- 35: label L5
+ 29: label L5
# live vars:
- 36: goto 40
+ 30: goto 34
# live vars:
- 37: label L6
+ 31: label L6
# live vars:
- 38: $t23 := 0
- # live vars: $t23
- 39: abort($t23)
+ 32: $t17 := 0
+ # live vars: $t17
+ 33: abort($t17)
# live vars:
- 40: label L7
+ 34: label L7
# live vars:
- 41: return ()
+ 35: return ()
}
============ after ReferenceSafetyProcessor: ================
@@ -194,276 +164,234 @@ fun m::test_for_each_mut() {
var $t3: u64
var $t4: u64
var $t5: u64
- var $t6: u64
- var $t7: u64
- var $t8: u64
- var $t9: &vector
- var $t10: &mut vector
- var $t11: &mut vector
- var $t12: bool
- var $t13: &mut u64
- var $t14: &mut u64
- var $t15: u64
- var $t16: u64
+ var $t6: &vector
+ var $t7: &mut vector
+ var $t8: &mut vector
+ var $t9: bool
+ var $t10: &mut u64
+ var $t11: &mut u64
+ var $t12: u64
+ var $t13: u64
+ var $t14: u64
+ var $t15: bool
+ var $t16: vector
var $t17: u64
- var $t18: bool
- var $t19: vector
- var $t20: u64
- var $t21: u64
- var $t22: u64
- var $t23: u64
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 0: $t2 := 1
- # live vars: $t2
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 1: $t3 := 2
- # live vars: $t2, $t3
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 2: $t4 := 3
- # live vars: $t2, $t3, $t4
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 3: $t1 := vector($t2, $t3, $t4)
+ 0: $t1 := ["1", "2", "3"]
# live vars: $t1
# graph: {}
# locals: {}
# globals: {}
#
- 4: $t0 := infer($t1)
+ 1: $t0 := infer($t1)
# live vars: $t0
# graph: {}
# locals: {}
# globals: {}
#
- 5: $t6 := 0
- # live vars: $t0, $t6
+ 2: $t3 := 0
+ # live vars: $t0, $t3
# graph: {}
# locals: {}
# globals: {}
#
- 6: $t5 := infer($t6)
- # live vars: $t0, $t5
+ 3: $t2 := infer($t3)
+ # live vars: $t0, $t2
# graph: {}
# locals: {}
# globals: {}
#
- 7: $t9 := borrow_local($t0)
- # live vars: $t0, $t5, $t9
- # graph: {@700=local($t0)[borrow(false) -> @701],@701=derived[]}
- # locals: {$t0=@700,$t9=@701}
+ 4: $t6 := borrow_local($t0)
+ # live vars: $t0, $t2, $t6
+ # graph: {@400=local($t0)[borrow(false) -> @401],@401=derived[]}
+ # locals: {$t0=@400,$t6=@401}
# globals: {}
#
- 8: $t8 := vector::length($t9)
- # live vars: $t0, $t5, $t8
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ 5: $t5 := vector::length($t6)
+ # live vars: $t0, $t2, $t5
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 9: $t7 := infer($t8)
- # live vars: $t0, $t5, $t7
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ 6: $t4 := infer($t5)
+ # live vars: $t0, $t2, $t4
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 10: $t11 := borrow_local($t0)
- # live vars: $t0, $t5, $t7, $t11
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t11=@A01}
+ 7: $t8 := borrow_local($t0)
+ # live vars: $t0, $t2, $t4, $t8
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t8=@701}
# globals: {}
#
- 11: $t10 := infer($t11)
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 8: $t7 := infer($t8)
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 12: label L0
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 9: label L0
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 13: $t12 := <($t5, $t7)
- # live vars: $t0, $t5, $t7, $t10, $t12
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 10: $t9 := <($t2, $t4)
+ # live vars: $t0, $t2, $t4, $t7, $t9
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 14: if ($t12) goto 15 else goto 24
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 11: if ($t9) goto 12 else goto 21
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 15: label L2
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 12: label L2
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 16: $t14 := vector::borrow_mut($t10, $t5)
- # live vars: $t0, $t5, $t7, $t10, $t14
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[call(true) -> @1000],@1000=derived[]}
- # locals: {$t0=@700,$t10=@A01,$t14=@1000}
+ 13: $t11 := vector::borrow_mut($t7, $t2)
+ # live vars: $t0, $t2, $t4, $t7, $t11
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[call(true) -> @D00],@D00=derived[]}
+ # locals: {$t0=@400,$t7=@701,$t11=@D00}
# globals: {}
#
- 17: $t13 := infer($t14)
- # live vars: $t0, $t5, $t7, $t10, $t13
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[call(true) -> @1000],@1000=derived[]}
- # locals: {$t0=@700,$t10=@A01,$t13=@1000}
+ 14: $t10 := infer($t11)
+ # live vars: $t0, $t2, $t4, $t7, $t10
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[call(true) -> @D00],@D00=derived[]}
+ # locals: {$t0=@400,$t7=@701,$t10=@D00}
# globals: {}
#
- 18: $t15 := 2
- # live vars: $t0, $t5, $t7, $t10, $t13, $t15
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[call(true) -> @1000],@1000=derived[]}
- # locals: {$t0=@700,$t10=@A01,$t13=@1000}
+ 15: $t12 := 2
+ # live vars: $t0, $t2, $t4, $t7, $t10, $t12
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[call(true) -> @D00],@D00=derived[]}
+ # locals: {$t0=@400,$t7=@701,$t10=@D00}
# globals: {}
#
- 19: write_ref($t13, $t15)
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 16: write_ref($t10, $t12)
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 20: $t17 := 1
- # live vars: $t0, $t5, $t7, $t10, $t17
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 17: $t14 := 1
+ # live vars: $t0, $t2, $t4, $t7, $t14
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 21: $t16 := +($t5, $t17)
- # live vars: $t0, $t7, $t10, $t16
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 18: $t13 := +($t2, $t14)
+ # live vars: $t0, $t4, $t7, $t13
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 22: $t5 := infer($t16)
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 19: $t2 := infer($t13)
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 23: goto 26
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 20: goto 23
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 24: label L3
+ 21: label L3
# live vars: $t0
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 25: goto 28
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 22: goto 25
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 26: label L4
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ 23: label L4
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 27: goto 12
+ 24: goto 9
# live vars: $t0
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 28: label L1
+ 25: label L1
# live vars: $t0
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
- # globals: {}
- #
- 29: $t20 := 2
- # live vars: $t0, $t20
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
- # globals: {}
- #
- 30: $t21 := 3
- # live vars: $t0, $t20, $t21
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 31: $t22 := 4
- # live vars: $t0, $t20, $t21, $t22
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ 26: $t16 := ["2", "3", "4"]
+ # live vars: $t0, $t16
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 32: $t19 := vector($t20, $t21, $t22)
- # live vars: $t0, $t19
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ 27: $t15 := ==($t0, $t16)
+ # live vars: $t15
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 33: $t18 := ==($t0, $t19)
- # live vars: $t18
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
- # globals: {}
- #
- 34: if ($t18) goto 35 else goto 37
+ 28: if ($t15) goto 29 else goto 31
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 35: label L5
+ 29: label L5
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 36: goto 40
+ 30: goto 34
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 37: label L6
+ 31: label L6
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 38: $t23 := 0
- # live vars: $t23
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ 32: $t17 := 0
+ # live vars: $t17
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 39: abort($t23)
+ 33: abort($t17)
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 40: label L7
+ 34: label L7
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 41: return ()
+ 35: return ()
}
============ after AbortAnalysisProcessor: ================
@@ -476,318 +404,270 @@ fun m::test_for_each_mut() {
var $t3: u64
var $t4: u64
var $t5: u64
- var $t6: u64
- var $t7: u64
- var $t8: u64
- var $t9: &vector
- var $t10: &mut vector
- var $t11: &mut vector
- var $t12: bool
- var $t13: &mut u64
- var $t14: &mut u64
- var $t15: u64
- var $t16: u64
+ var $t6: &vector
+ var $t7: &mut vector
+ var $t8: &mut vector
+ var $t9: bool
+ var $t10: &mut u64
+ var $t11: &mut u64
+ var $t12: u64
+ var $t13: u64
+ var $t14: u64
+ var $t15: bool
+ var $t16: vector
var $t17: u64
- var $t18: bool
- var $t19: vector
- var $t20: u64
- var $t21: u64
- var $t22: u64
- var $t23: u64
# abort state: {returns,aborts}
# live vars:
# graph: {}
# locals: {}
# globals: {}
#
- 0: $t2 := 1
- # abort state: {returns,aborts}
- # live vars: $t2
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 1: $t3 := 2
- # abort state: {returns,aborts}
- # live vars: $t2, $t3
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 2: $t4 := 3
- # abort state: {returns,aborts}
- # live vars: $t2, $t3, $t4
- # graph: {}
- # locals: {}
- # globals: {}
- #
- 3: $t1 := vector($t2, $t3, $t4)
+ 0: $t1 := ["1", "2", "3"]
# abort state: {returns,aborts}
# live vars: $t1
# graph: {}
# locals: {}
# globals: {}
#
- 4: $t0 := infer($t1)
+ 1: $t0 := infer($t1)
# abort state: {returns,aborts}
# live vars: $t0
# graph: {}
# locals: {}
# globals: {}
#
- 5: $t6 := 0
+ 2: $t3 := 0
# abort state: {returns,aborts}
- # live vars: $t0, $t6
+ # live vars: $t0, $t3
# graph: {}
# locals: {}
# globals: {}
#
- 6: $t5 := infer($t6)
+ 3: $t2 := infer($t3)
# abort state: {returns,aborts}
- # live vars: $t0, $t5
+ # live vars: $t0, $t2
# graph: {}
# locals: {}
# globals: {}
#
- 7: $t9 := borrow_local($t0)
+ 4: $t6 := borrow_local($t0)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t9
- # graph: {@700=local($t0)[borrow(false) -> @701],@701=derived[]}
- # locals: {$t0=@700,$t9=@701}
+ # live vars: $t0, $t2, $t6
+ # graph: {@400=local($t0)[borrow(false) -> @401],@401=derived[]}
+ # locals: {$t0=@400,$t6=@401}
# globals: {}
#
- 8: $t8 := vector::length($t9)
+ 5: $t5 := vector::length($t6)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t8
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # live vars: $t0, $t2, $t5
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 9: $t7 := infer($t8)
+ 6: $t4 := infer($t5)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # live vars: $t0, $t2, $t4
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 10: $t11 := borrow_local($t0)
+ 7: $t8 := borrow_local($t0)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t11
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t11=@A01}
+ # live vars: $t0, $t2, $t4, $t8
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t8=@701}
# globals: {}
#
- 11: $t10 := infer($t11)
+ 8: $t7 := infer($t8)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 12: label L0
+ 9: label L0
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 13: $t12 := <($t5, $t7)
+ 10: $t9 := <($t2, $t4)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10, $t12
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7, $t9
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 14: if ($t12) goto 15 else goto 24
+ 11: if ($t9) goto 12 else goto 21
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 15: label L2
+ 12: label L2
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 16: $t14 := vector::borrow_mut($t10, $t5)
+ 13: $t11 := vector::borrow_mut($t7, $t2)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10, $t14
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[call(true) -> @1000],@1000=derived[]}
- # locals: {$t0=@700,$t10=@A01,$t14=@1000}
+ # live vars: $t0, $t2, $t4, $t7, $t11
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[call(true) -> @D00],@D00=derived[]}
+ # locals: {$t0=@400,$t7=@701,$t11=@D00}
# globals: {}
#
- 17: $t13 := infer($t14)
+ 14: $t10 := infer($t11)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10, $t13
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[call(true) -> @1000],@1000=derived[]}
- # locals: {$t0=@700,$t10=@A01,$t13=@1000}
+ # live vars: $t0, $t2, $t4, $t7, $t10
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[call(true) -> @D00],@D00=derived[]}
+ # locals: {$t0=@400,$t7=@701,$t10=@D00}
# globals: {}
#
- 18: $t15 := 2
+ 15: $t12 := 2
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10, $t13, $t15
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[call(true) -> @1000],@1000=derived[]}
- # locals: {$t0=@700,$t10=@A01,$t13=@1000}
+ # live vars: $t0, $t2, $t4, $t7, $t10, $t12
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[call(true) -> @D00],@D00=derived[]}
+ # locals: {$t0=@400,$t7=@701,$t10=@D00}
# globals: {}
#
- 19: write_ref($t13, $t15)
+ 16: write_ref($t10, $t12)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 20: $t17 := 1
+ 17: $t14 := 1
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10, $t17
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7, $t14
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 21: $t16 := +($t5, $t17)
+ 18: $t13 := +($t2, $t14)
# abort state: {returns,aborts}
- # live vars: $t0, $t7, $t10, $t16
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t4, $t7, $t13
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 22: $t5 := infer($t16)
+ 19: $t2 := infer($t13)
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 23: goto 26
+ 20: goto 23
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 24: label L3
+ 21: label L3
# abort state: {returns,aborts}
# live vars: $t0
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 25: goto 28
+ 22: goto 25
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 26: label L4
+ 23: label L4
# abort state: {returns,aborts}
- # live vars: $t0, $t5, $t7, $t10
- # graph: {@700=local($t0)[borrow(true) -> @A01],@A01=derived[]}
- # locals: {$t0=@700,$t10=@A01}
+ # live vars: $t0, $t2, $t4, $t7
+ # graph: {@400=local($t0)[borrow(true) -> @701],@701=derived[]}
+ # locals: {$t0=@400,$t7=@701}
# globals: {}
#
- 27: goto 12
+ 24: goto 9
# abort state: {returns,aborts}
# live vars: $t0
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 28: label L1
+ 25: label L1
# abort state: {returns,aborts}
# live vars: $t0
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
- # globals: {}
- #
- 29: $t20 := 2
- # abort state: {returns,aborts}
- # live vars: $t0, $t20
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
- # globals: {}
- #
- 30: $t21 := 3
- # abort state: {returns,aborts}
- # live vars: $t0, $t20, $t21
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
- # globals: {}
- #
- 31: $t22 := 4
- # abort state: {returns,aborts}
- # live vars: $t0, $t20, $t21, $t22
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 32: $t19 := vector($t20, $t21, $t22)
+ 26: $t16 := ["2", "3", "4"]
# abort state: {returns,aborts}
- # live vars: $t0, $t19
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # live vars: $t0, $t16
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 33: $t18 := ==($t0, $t19)
+ 27: $t15 := ==($t0, $t16)
# abort state: {returns,aborts}
- # live vars: $t18
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # live vars: $t15
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 34: if ($t18) goto 35 else goto 37
+ 28: if ($t15) goto 29 else goto 31
# abort state: {returns}
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 35: label L5
+ 29: label L5
# abort state: {returns}
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 36: goto 40
+ 30: goto 34
# abort state: {aborts}
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 37: label L6
+ 31: label L6
# abort state: {aborts}
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 38: $t23 := 0
+ 32: $t17 := 0
# abort state: {aborts}
- # live vars: $t23
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # live vars: $t17
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 39: abort($t23)
+ 33: abort($t17)
# abort state: {returns}
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 40: label L7
+ 34: label L7
# abort state: {returns}
# live vars:
- # graph: {@700=local($t0)[]}
- # locals: {$t0=@700}
+ # graph: {@400=local($t0)[]}
+ # locals: {$t0=@400}
# globals: {}
#
- 41: return ()
+ 35: return ()
}
============ after AbilityProcessor: ================
@@ -800,67 +680,55 @@ fun m::test_for_each_mut() {
var $t3: u64
var $t4: u64
var $t5: u64
- var $t6: u64
- var $t7: u64
- var $t8: u64
- var $t9: &vector
- var $t10: &mut vector
- var $t11: &mut vector
- var $t12: bool
- var $t13: &mut u64
- var $t14: &mut u64
- var $t15: u64
- var $t16: u64
+ var $t6: &vector
+ var $t7: &mut vector
+ var $t8: &mut vector
+ var $t9: bool
+ var $t10: &mut u64
+ var $t11: &mut u64
+ var $t12: u64
+ var $t13: u64
+ var $t14: u64
+ var $t15: bool
+ var $t16: vector
var $t17: u64
- var $t18: bool
- var $t19: vector
- var $t20: u64
- var $t21: u64
- var $t22: u64
- var $t23: u64
- var $t24: &mut vector
- 0: $t2 := 1
- 1: $t3 := 2
- 2: $t4 := 3
- 3: $t1 := vector($t2, $t3, $t4)
- 4: $t0 := move($t1)
- 5: $t6 := 0
- 6: $t5 := move($t6)
- 7: $t9 := borrow_local($t0)
- 8: $t8 := vector::length($t9)
- 9: $t7 := move($t8)
- 10: $t11 := borrow_local($t0)
- 11: $t10 := move($t11)
- 12: label L0
- 13: $t12 := <($t5, $t7)
- 14: if ($t12) goto 15 else goto 25
- 15: label L2
- 16: $t24 := copy($t10)
- 17: $t14 := vector::borrow_mut($t24, $t5)
- 18: $t13 := move($t14)
- 19: $t15 := 2
- 20: write_ref($t13, $t15)
- 21: $t17 := 1
- 22: $t16 := +($t5, $t17)
- 23: $t5 := move($t16)
- 24: goto 28
- 25: label L3
- 26: drop($t10)
- 27: goto 30
- 28: label L4
- 29: goto 12
- 30: label L1
- 31: $t20 := 2
- 32: $t21 := 3
- 33: $t22 := 4
- 34: $t19 := vector($t20, $t21, $t22)
- 35: $t18 := ==($t0, $t19)
- 36: if ($t18) goto 37 else goto 39
- 37: label L5
- 38: goto 42
- 39: label L6
- 40: $t23 := 0
- 41: abort($t23)
- 42: label L7
- 43: return ()
+ var $t18: &mut vector