Use bforest::Map for representing live ranges.

Get rid of the per-value Vec in the LiveRange data type and use a
bforest::Map instead to represent the live-in intervals for non-local
live ranges.

This has some advantages:

- The memory footprint of a local live range is reduced from 40 to 20
  bytes, and
- Clearing the Liveness data structure is now a constant time operation
  which doesn't call free().
- The potentially quadratic behavior when computing large live ranges is
  controlled by the logarithmic B-tree operations.
This commit is contained in:
Jakob Stoklund Olesen
2017-12-04 13:43:10 -08:00
parent 27d5543adc
commit feaea238bc
9 changed files with 279 additions and 215 deletions

View File

@@ -157,13 +157,11 @@ impl DomForest {
layout,
domtree,
};
let ctx = liveness.context(layout);
for node in merged {
if let Some(parent) = self.push_node(node, layout, domtree) {
// Check if `parent` live range contains `node.def`.
let lr = liveness.get(parent).expect(
"No live range for parent value",
);
if lr.overlaps_def(node.def, layout.pp_ebb(node.def), layout) {
if liveness[parent].overlaps_def(node.def, layout.pp_ebb(node.def), ctx) {
// Interference detected. Get the `(a, b)` order right in the error.
return Err(if node.set == 0 {
(node.value, parent)
@@ -447,7 +445,11 @@ impl<'a> Context<'a> {
if self.liveness
.get(a)
.expect("No live range for interfering value")
.reaches_use(pred_inst, pred_ebb, &self.func.layout)
.reaches_use(
pred_inst,
pred_ebb,
self.liveness.context(&self.func.layout),
)
{
// Splitting at `pred_inst` wouldn't resolve the interference, so we need to
// start over.