Skip to content
Snippets Groups Projects

Optimize edge detection

Merged rarbore2 requested to merge edge_opt into main
7 files
+ 141
41
Compare changes
  • Side-by-side
  • Inline
Files
7
+ 43
15
@@ -560,23 +560,33 @@ impl<'a> RTContext<'a> {
@@ -560,23 +560,33 @@ impl<'a> RTContext<'a> {
// same interface as AsyncRust functions.
// same interface as AsyncRust functions.
let block = &mut blocks.get_mut(&bb).unwrap().data;
let block = &mut blocks.get_mut(&bb).unwrap().data;
let is_async = func.schedules[id.idx()].contains(&Schedule::AsyncCall);
let is_async = func.schedules[id.idx()].contains(&Schedule::AsyncCall);
 
if is_async {
 
for arg in args {
 
if let Some(arc) = self.clone_arc(*arg, false) {
 
write!(block, "{}", arc)?;
 
}
 
}
 
}
let device = self.devices[callee_id.idx()];
let device = self.devices[callee_id.idx()];
let prefix = match (device, is_async) {
let prefix = match (device, is_async) {
(Device::AsyncRust, false) => "",
(Device::AsyncRust, false) | (_, false) => {
(_, false) => "",
format!("{} = ", self.get_value(id, bb, true))
(Device::AsyncRust, true) => "Some(::async_std::task::spawn(",
}
(_, true) => "Some(::async_std::task::spawn(async move {",
(_, true) => format!(
 
"{}::async_std::task::spawn(async move {{ async_call_sender_{}.send(",
 
self.clone_arc(id, true).unwrap(),
 
id.idx()
 
),
};
};
let postfix = match (device, is_async) {
let postfix = match (device, is_async) {
(Device::AsyncRust, false) => ".await",
(Device::AsyncRust, false) => ".await",
(_, false) => "",
(_, false) => "",
(Device::AsyncRust, true) => "))",
(Device::AsyncRust, true) => ".await).await})",
(_, true) => "}))",
(_, true) => ").await})",
};
};
write!(
write!(
block,
block,
"{} = {}{}(",
"{}{}(",
self.get_value(id, bb, true),
prefix,
prefix,
self.module.functions[callee_id.idx()].name
self.module.functions[callee_id.idx()].name
)?;
)?;
@@ -1069,11 +1079,15 @@ impl<'a> RTContext<'a> {
@@ -1069,11 +1079,15 @@ impl<'a> RTContext<'a> {
}
}
// If the node is a call with an AsyncCall schedule, it should be
// If the node is a call with an AsyncCall schedule, it should be
// spawned as a task and awaited later.
// lowered to a channel.
let is_async_call =
let is_async_call =
func.nodes[idx].is_call() && func.schedules[idx].contains(&Schedule::AsyncCall);
func.nodes[idx].is_call() && func.schedules[idx].contains(&Schedule::AsyncCall);
if is_async_call {
if is_async_call {
write!(w, "let mut async_call_{} = None;", idx)?;
write!(
 
w,
 
"let mut async_call_channel_{} = ::async_std::channel::bounded(1);let async_call_sender_{} = ::std::sync::Arc::new(async_call_channel_{}.0);let async_call_receiver_{} = ::std::sync::Arc::new(async_call_channel_{}.1);",
 
idx, idx, idx, idx, idx
 
)?;
} else {
} else {
write!(
write!(
w,
w,
@@ -1356,16 +1370,30 @@ impl<'a> RTContext<'a> {
@@ -1356,16 +1370,30 @@ impl<'a> RTContext<'a> {
} else if func.nodes[id.idx()].is_call()
} else if func.nodes[id.idx()].is_call()
&& func.schedules[id.idx()].contains(&Schedule::AsyncCall)
&& func.schedules[id.idx()].contains(&Schedule::AsyncCall)
{
{
format!(
assert!(!lhs);
"async_call_{}{}",
format!("async_call_receiver_{}.recv().await.unwrap()", id.idx(),)
id.idx(),
if lhs { "" } else { ".unwrap().await" }
)
} else {
} else {
format!("node_{}", id.idx())
format!("node_{}", id.idx())
}
}
}
}
 
fn clone_arc(&self, id: NodeID, lhs: bool) -> Option<String> {
 
let func = self.get_func();
 
if func.nodes[id.idx()].is_call() && func.schedules[id.idx()].contains(&Schedule::AsyncCall)
 
{
 
let kind = if lhs { "sender" } else { "receiver" };
 
Some(format!(
 
"let async_call_{}_{} = async_call_{}_{}.clone();",
 
kind,
 
id.idx(),
 
kind,
 
id.idx()
 
))
 
} else {
 
None
 
}
 
}
 
fn get_type(&self, id: TypeID) -> &'static str {
fn get_type(&self, id: TypeID) -> &'static str {
convert_type(&self.module.types[id.idx()])
convert_type(&self.module.types[id.idx()])
}
}
Loading