11use super :: CombDataflow ;
22use crate :: ir_visitor:: { Action , Construct , Visitor , VisitorData } ;
3+ use core:: time;
34use easy_smt:: { self as smt, SExpr , SExprData } ;
45use fil_ir:: { self as ir, AddCtx , Ctx , DisplayCtx , MutCtx , PortOwner } ;
56use fil_utils:: { AttrCtx , CompNum } ;
@@ -30,6 +31,12 @@ pub struct Solve {
3031 goal : SchedulingGoal ,
3132 /// The expression to minimize
3233 minimize_expr : smt:: SExpr ,
34+ // /// Map from ir elements to SExprs
35+ // expr_map: ir::SparseInfoMap<ir::Expr, SExpr>,
36+ // port_map: ir::SparseInfoMap<ir::PortIdx, SExpr>,
37+ // event_map: ir::SparseInfoMap<ir::EventIdx, SExpr>,
38+ // time_map: ir::SparseInfoMap<ir::TimeIdx, SExpr>,
39+ // prop_map: ir::SparseInfoMap<ir::PropIdx, SExpr>,
3340}
3441
3542impl Solve {
@@ -42,8 +49,12 @@ impl Solve {
4249 }
4350
4451 /// Get the constant name for the time of an event
45- pub fn get_evt_name ( & self , inv : ir:: InvIdx , evt : ir:: EventIdx ) -> String {
46- format ! ( "inv{}ev{}" , inv. get( ) , evt. get( ) )
52+ pub fn get_evt_name (
53+ & self ,
54+ inv : ir:: InvIdx ,
55+ evt : ir:: Foreign < ir:: Event , ir:: Component > ,
56+ ) -> String {
57+ format ! ( "inv{}ev{}" , inv. get( ) , evt. key( ) . get( ) )
4758 }
4859
4960 /// Get the SExprs for the start and end of a port
@@ -56,7 +67,7 @@ impl Solve {
5667 pub fn get_inv_evt (
5768 & self ,
5869 inv : ir:: InvIdx ,
59- evt : ir:: EventIdx ,
70+ evt : ir:: Foreign < ir :: Event , ir :: Component > ,
6071 ) -> smt:: SExpr {
6172 self . sol . atom ( self . get_evt_name ( inv, evt) )
6273 }
@@ -232,28 +243,27 @@ impl Visitor for Solve {
232243
233244 log:: trace!( "Scheduling invocation {}" , comp. display( inv_idx) ) ;
234245
235- // Make sure that the invocation is scheduled at a positive time
236- self . sol
237- . assert ( self . sol . gte ( sexpr, self . sol . numeral ( 0 ) ) )
238- . unwrap ( ) ;
239-
240246 let inv = comp. get ( inv_idx) ;
241247
242248 // Get the events of the invocation as variables
243249 let events: ir:: SparseInfoMap < ir:: Event , SExpr > = inv
244250 . events
245251 . iter ( )
246- . map ( |ir:: EventBind { arg, .. } | {
247- let event = comp. get ( * arg) . event ;
248- (
249- event,
250- self . sol
251- . declare_const (
252- self . get_evt_name ( inv_idx, event) ,
253- self . sol . int_sort ( ) ,
254- )
255- . unwrap ( ) ,
256- )
252+ . map ( |ir:: EventBind { base, .. } | {
253+ let sexpr = self
254+ . sol
255+ . declare_const (
256+ self . get_evt_name ( inv_idx, * base) ,
257+ self . sol . int_sort ( ) ,
258+ )
259+ . unwrap ( ) ;
260+
261+ // Make sure that the event is scheduled at a positive time
262+ self . sol
263+ . assert ( self . sol . gte ( sexpr, self . sol . numeral ( 0 ) ) )
264+ . unwrap ( ) ;
265+
266+ ( base. key ( ) , sexpr)
257267 } )
258268 . collect ( ) ;
259269
@@ -265,13 +275,26 @@ impl Visitor for Solve {
265275
266276 for pidx in inv. ports . iter ( ) {
267277 let port = comp. get ( * pidx) ;
268- let PortOwner :: Inv {
269- base : foreign_pidx, ..
270- } = port. owner
278+ let ir:: Port {
279+ owner :
280+ ir:: PortOwner :: Inv {
281+ base : foreign_pidx, ..
282+ } ,
283+ live :
284+ ir:: Liveness {
285+ range : ir:: Range { start, end } ,
286+ ..
287+ } ,
288+ ..
289+ } = port
271290 else {
272291 unreachable ! ( "Port {} is not owned by an invocation" , pidx)
273292 } ;
274293
294+ // Find the events associated with the start and end of the port
295+ let start_expr = * events. get ( comp. get ( * start) . event ) ;
296+ let end_expr = * events. get ( comp. get ( * end) . event ) ;
297+
275298 let ( start, end) = foreign_pidx. apply (
276299 |p, foreign_comp| {
277300 let ir:: Range { start, end } =
@@ -288,9 +311,9 @@ impl Visitor for Solve {
288311 ) ;
289312
290313 // Create expressions for the ports relative to the invocation
291- let start_expr = self . sol . plus ( sexpr , self . sol . numeral ( start) ) ;
314+ let start_expr = self . sol . plus ( start_expr , self . sol . numeral ( start) ) ;
292315
293- let end_expr = self . sol . plus ( sexpr , self . sol . numeral ( end) ) ;
316+ let end_expr = self . sol . plus ( end_expr , self . sol . numeral ( end) ) ;
294317
295318 log:: trace!(
296319 "Port {} is live from {} to {}" ,
@@ -397,41 +420,47 @@ impl Visitor for Solve {
397420 // Loop through invocations and find what they're bound to
398421 // collect here to let us mutate [data.comp] inside the loop
399422 for inv_idx in data. comp . invocations ( ) . idx_iter ( ) {
400- let name = self . get_inv ( inv_idx) ;
401- let SExprData :: Atom ( s) = self . sol . get ( name) else {
402- unreachable ! (
403- "Expected invocation {} to be an atom, got {}" ,
404- inv_idx,
405- self . sol. display( name)
406- )
407- } ;
408-
409- let time = * bindings. get ( s) . unwrap ( ) ;
410-
411- let time = data. comp . add ( ir:: Expr :: Concrete ( time) ) ;
412-
413- let time = data. comp . add ( ir:: Time {
414- event,
415- offset : time,
416- } ) ;
417-
418- log:: debug!(
419- "Invocation {} scheduled at cycle {}" ,
420- data. comp. display( inv_idx) ,
421- data. comp. display( time)
422- ) ;
423-
424- // Set the time of the invocation
425- let inv = data. comp . get_mut ( inv_idx) ;
426-
427- // make sure this invoke only has one event
428- // assert_eq!(
429- // inv.events.len(),
430- // 1,
431- // "Attempting to schedule an invocation with multiple events"
432- // );
433-
434- inv. events [ 0 ] . arg = time;
423+ let new_times = data
424+ . comp
425+ . get ( inv_idx)
426+ . events
427+ . iter ( )
428+ . map ( |ir:: EventBind { base, arg, .. } | {
429+ let SExprData :: Atom ( s) =
430+ self . sol . get ( self . get_inv_evt ( inv_idx, * base) )
431+ else {
432+ unreachable ! ( )
433+ } ;
434+
435+ ( arg. event ( & data. comp ) , * bindings. get ( s) . unwrap ( ) )
436+ } )
437+ . collect_vec ( ) ;
438+
439+ // Needds to be broken up because we need mutable access to data.comp
440+ let new_times = new_times
441+ . into_iter ( )
442+ . map ( |( event, time) | {
443+ let time = data. comp . add ( ir:: Expr :: Concrete ( time) ) ;
444+
445+ let time = data. comp . add ( ir:: Time {
446+ event,
447+ offset : time,
448+ } ) ;
449+
450+ log:: debug!(
451+ "Invocation {} scheduled at cycle {}" ,
452+ data. comp. display( inv_idx) ,
453+ data. comp. display( time)
454+ ) ;
455+ time
456+ } )
457+ . collect_vec ( ) ;
458+
459+ for ( ir:: EventBind { arg, .. } , time) in
460+ data. comp . get_mut ( inv_idx) . events . iter_mut ( ) . zip ( new_times)
461+ {
462+ * arg = time
463+ }
435464 }
436465
437466 // Loop through ports and set their live ranges
0 commit comments