B-Lang-org / bsc

Bluespec Compiler (BSC)
Other
955 stars 146 forks source link

Fix scheduling annotations for methods with actions conditional on the arguments #656

Closed quark17 closed 11 months ago

quark17 commented 11 months ago

Fixes #641.

There is some reorganization of the code in ASchedule that constructs the three conflict graphs (CF, SC, and PC, indicating the scheduling limitations between rules/methods). This code contained forced evaluations of the graphs, to prevent memory usage from growing too much (due to the graphs being contructed lazily), and the location of that forcing has moved -- the graphs are constructed in steps (first the initial graph based on pairwise method calls then user pragmas then methods with arguments), and the forcing is now after the first step, not the third, but the first step is the most significant, so experiments suggest that forcing there has the same memory footprint. (It's also probably important to force each graph before starting the next, so all three aren't in memory at once.) If any issues are detected, we can profile the example and revisit this choice.

There was already a step that was adding conflict edges for ActionValue methods where arguments are used in the return value. That just needed to be extended to also check for Action/ActionValue methods where arguments are used in the condition of an action. The effort of both checks is now avoided by first looking for whether a conflict edge already exists for the method relative to itself, and skipping the checks if so. (This was the motivation for the reorganization: so that an initial SC graph was available for lookup when computing the edges to add.)

Test case added.

There was only one group of existing tests affected by the change. It was an example where a method was writing into a vector of registers and the specific register index was coming from an argument:

Vector#(Size, Reg#(Bool))  rgs <- replicateM( mkReg(False) ) ;

method Action set (Index idx);
  rgs[idx] <= True;
endmethod

BSC was inferring SBR for this method, but that would result in incorrect code-generation for a parent module that called the method twice with different argument values: the first call would be ignored and only the register at the second index would be updated. With this PR, BSC infers C by inserting a conflict edge (for the method with itself) in the SC conflict graph.

quark17 commented 11 months ago

I realized that the new code (for computing the method-arg conflict edges) should go in a separate function, to abstract it away and reduce clutter. So I pushed a new commit that does that.