Rename OperandPolicy to OperandConstraint as per feedback from @julian-seward1.
This commit is contained in:
@@ -20,7 +20,7 @@ use super::{
|
||||
};
|
||||
use crate::bitvec::BitVec;
|
||||
use crate::{
|
||||
Allocation, Block, Function, Inst, InstPosition, Operand, OperandKind, OperandPolicy,
|
||||
Allocation, Block, Function, Inst, InstPosition, Operand, OperandKind, OperandConstraint,
|
||||
OperandPos, PReg, ProgPoint, RegAllocError, VReg,
|
||||
};
|
||||
use fxhash::FxHashSet;
|
||||
@@ -29,19 +29,19 @@ use std::collections::{HashSet, VecDeque};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[inline(always)]
|
||||
pub fn spill_weight_from_policy(policy: OperandPolicy, loop_depth: usize, is_def: bool) -> u32 {
|
||||
pub fn spill_weight_from_constraint(constraint: OperandConstraint, loop_depth: usize, is_def: bool) -> u32 {
|
||||
// A bonus of 1000 for one loop level, 4000 for two loop levels,
|
||||
// 16000 for three loop levels, etc. Avoids exponentiation.
|
||||
// Bound `loop_depth` at 2 so that `hot_bonus` is at most 16000.
|
||||
let loop_depth = std::cmp::min(2, loop_depth);
|
||||
let hot_bonus = 1000 * (1 << (2 * loop_depth));
|
||||
let def_bonus = if is_def { 2000 } else { 0 };
|
||||
let policy_bonus = match policy {
|
||||
OperandPolicy::Any => 1000,
|
||||
OperandPolicy::Reg | OperandPolicy::FixedReg(_) => 2000,
|
||||
let constraint_bonus = match constraint {
|
||||
OperandConstraint::Any => 1000,
|
||||
OperandConstraint::Reg | OperandConstraint::FixedReg(_) => 2000,
|
||||
_ => 0,
|
||||
};
|
||||
hot_bonus + def_bonus + policy_bonus
|
||||
hot_bonus + def_bonus + constraint_bonus
|
||||
}
|
||||
|
||||
impl<'a, F: Function> Env<'a, F> {
|
||||
@@ -184,11 +184,11 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
|
||||
pub fn insert_use_into_liverange(&mut self, into: LiveRangeIndex, mut u: Use) {
|
||||
let operand = u.operand;
|
||||
let policy = operand.policy();
|
||||
let constraint = operand.constraint();
|
||||
let block = self.cfginfo.insn_block[u.pos.inst().index()];
|
||||
let loop_depth = self.cfginfo.approx_loop_depth[block.index()] as usize;
|
||||
let weight =
|
||||
spill_weight_from_policy(policy, loop_depth, operand.kind() != OperandKind::Use);
|
||||
spill_weight_from_constraint(constraint, loop_depth, operand.kind() != OperandKind::Use);
|
||||
u.weight = u16::try_from(weight).expect("weight too large for u16 field");
|
||||
|
||||
log::debug!(
|
||||
@@ -415,7 +415,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
// proper interference wrt other inputs.
|
||||
let mut reused_input = None;
|
||||
for op in self.func.inst_operands(inst) {
|
||||
if let OperandPolicy::Reuse(i) = op.policy() {
|
||||
if let OperandConstraint::Reuse(i) = op.constraint() {
|
||||
reused_input = Some(i);
|
||||
break;
|
||||
}
|
||||
@@ -465,12 +465,12 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
);
|
||||
}
|
||||
|
||||
let src_preg = match src.policy() {
|
||||
OperandPolicy::FixedReg(r) => r,
|
||||
let src_preg = match src.constraint() {
|
||||
OperandConstraint::FixedReg(r) => r,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let dst_preg = match dst.policy() {
|
||||
OperandPolicy::FixedReg(r) => r,
|
||||
let dst_preg = match dst.constraint() {
|
||||
OperandConstraint::FixedReg(r) => r,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.insert_move(
|
||||
@@ -484,7 +484,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
// If exactly one of source and dest (but not
|
||||
// both) is a pinned-vreg, convert this into a
|
||||
// ghost use on the other vreg with a FixedReg
|
||||
// policy.
|
||||
// constraint.
|
||||
else if self.vregs[src.vreg().vreg()].is_pinned
|
||||
|| self.vregs[dst.vreg().vreg()].is_pinned
|
||||
{
|
||||
@@ -513,20 +513,20 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
ProgPoint::after(inst),
|
||||
)
|
||||
};
|
||||
let policy = OperandPolicy::FixedReg(preg);
|
||||
let operand = Operand::new(vreg, policy, kind, pos);
|
||||
let constraint = OperandConstraint::FixedReg(preg);
|
||||
let operand = Operand::new(vreg, constraint, kind, pos);
|
||||
|
||||
log::debug!(
|
||||
concat!(
|
||||
" -> preg {:?} vreg {:?} kind {:?} ",
|
||||
"pos {:?} progpoint {:?} policy {:?} operand {:?}"
|
||||
"pos {:?} progpoint {:?} constraint {:?} operand {:?}"
|
||||
),
|
||||
preg,
|
||||
vreg,
|
||||
kind,
|
||||
pos,
|
||||
progpoint,
|
||||
policy,
|
||||
constraint,
|
||||
operand
|
||||
);
|
||||
|
||||
@@ -701,23 +701,23 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
// positions of After and Before respectively
|
||||
// (see note below), and to have Any
|
||||
// constraints if they were originally Reg.
|
||||
let src_policy = match src.policy() {
|
||||
OperandPolicy::Reg => OperandPolicy::Any,
|
||||
let src_constraint = match src.constraint() {
|
||||
OperandConstraint::Reg => OperandConstraint::Any,
|
||||
x => x,
|
||||
};
|
||||
let dst_policy = match dst.policy() {
|
||||
OperandPolicy::Reg => OperandPolicy::Any,
|
||||
let dst_constraint = match dst.constraint() {
|
||||
OperandConstraint::Reg => OperandConstraint::Any,
|
||||
x => x,
|
||||
};
|
||||
let src = Operand::new(
|
||||
src.vreg(),
|
||||
src_policy,
|
||||
src_constraint,
|
||||
OperandKind::Use,
|
||||
OperandPos::After,
|
||||
);
|
||||
let dst = Operand::new(
|
||||
dst.vreg(),
|
||||
dst_policy,
|
||||
dst_constraint,
|
||||
OperandKind::Def,
|
||||
OperandPos::Before,
|
||||
);
|
||||
@@ -728,9 +728,9 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
format!(
|
||||
" prog-move v{} ({:?}) -> v{} ({:?})",
|
||||
src.vreg().vreg(),
|
||||
src_policy,
|
||||
src_constraint,
|
||||
dst.vreg().vreg(),
|
||||
dst_policy,
|
||||
dst_constraint,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1049,7 +1049,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
let pos = ProgPoint::before(self.safepoints[safepoint_idx]);
|
||||
let operand = Operand::new(
|
||||
self.vreg_regs[vreg.index()],
|
||||
OperandPolicy::Stack,
|
||||
OperandConstraint::Stack,
|
||||
OperandKind::Use,
|
||||
OperandPos::Before,
|
||||
);
|
||||
@@ -1116,7 +1116,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
}
|
||||
last_point = Some(pos);
|
||||
|
||||
if let OperandPolicy::FixedReg(preg) = op.policy() {
|
||||
if let OperandConstraint::FixedReg(preg) = op.constraint() {
|
||||
let vreg_idx = VRegIndex::new(op.vreg().vreg());
|
||||
let preg_idx = PRegIndex::new(preg.index());
|
||||
log::debug!(
|
||||
@@ -1129,11 +1129,11 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
{
|
||||
let orig_preg = first_preg[idx];
|
||||
if orig_preg != preg_idx {
|
||||
log::debug!(" -> duplicate; switching to policy Reg");
|
||||
log::debug!(" -> duplicate; switching to constraint Reg");
|
||||
fixups.push((pos, orig_preg, preg_idx, slot));
|
||||
*op = Operand::new(
|
||||
op.vreg(),
|
||||
OperandPolicy::Reg,
|
||||
OperandConstraint::Reg,
|
||||
op.kind(),
|
||||
op.pos(),
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@ use super::{
|
||||
Env, LiveBundleIndex, LiveRangeIndex, LiveRangeKey, Requirement, SpillSet, SpillSetIndex,
|
||||
SpillSlotIndex, VRegIndex,
|
||||
};
|
||||
use crate::{Function, Inst, OperandPolicy, PReg};
|
||||
use crate::{Function, Inst, OperandConstraint, PReg};
|
||||
use smallvec::smallvec;
|
||||
|
||||
impl<'a, F: Function> Env<'a, F> {
|
||||
@@ -269,10 +269,10 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
let mut stack = false;
|
||||
for entry in &self.bundles[bundle.index()].ranges {
|
||||
for u in &self.ranges[entry.index.index()].uses {
|
||||
if let OperandPolicy::FixedReg(_) = u.operand.policy() {
|
||||
if let OperandConstraint::FixedReg(_) = u.operand.constraint() {
|
||||
fixed = true;
|
||||
}
|
||||
if let OperandPolicy::Stack = u.operand.policy() {
|
||||
if let OperandConstraint::Stack = u.operand.constraint() {
|
||||
stack = true;
|
||||
}
|
||||
if fixed && stack {
|
||||
@@ -306,10 +306,10 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
for inst in 0..self.func.insts() {
|
||||
let inst = Inst::new(inst);
|
||||
|
||||
// Attempt to merge Reuse-policy operand outputs with the
|
||||
// Attempt to merge Reuse-constraint operand outputs with the
|
||||
// corresponding inputs.
|
||||
for op in self.func.inst_operands(inst) {
|
||||
if let OperandPolicy::Reuse(reuse_idx) = op.policy() {
|
||||
if let OperandConstraint::Reuse(reuse_idx) = op.constraint() {
|
||||
let src_vreg = op.vreg();
|
||||
let dst_vreg = self.func.inst_operands(inst)[reuse_idx].vreg();
|
||||
if self.vregs[src_vreg.vreg()].is_pinned
|
||||
|
||||
@@ -20,7 +20,7 @@ use super::{
|
||||
|
||||
use crate::moves::ParallelMoves;
|
||||
use crate::{
|
||||
Allocation, Block, Edit, Function, Inst, InstPosition, OperandKind, OperandPolicy, OperandPos,
|
||||
Allocation, Block, Edit, Function, Inst, InstPosition, OperandKind, OperandConstraint, OperandPos,
|
||||
ProgPoint, RegClass, VReg,
|
||||
};
|
||||
use log::debug;
|
||||
@@ -489,7 +489,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
if slot != SLOT_NONE {
|
||||
self.set_alloc(inst, slot as usize, alloc);
|
||||
}
|
||||
if let OperandPolicy::Reuse(_) = operand.policy() {
|
||||
if let OperandConstraint::Reuse(_) = operand.constraint() {
|
||||
reuse_input_insts.push(inst);
|
||||
}
|
||||
}
|
||||
@@ -755,7 +755,7 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
let mut input_reused: SmallVec<[usize; 4]> = smallvec![];
|
||||
for output_idx in 0..self.func.inst_operands(inst).len() {
|
||||
let operand = self.func.inst_operands(inst)[output_idx];
|
||||
if let OperandPolicy::Reuse(input_idx) = operand.policy() {
|
||||
if let OperandConstraint::Reuse(input_idx) = operand.constraint() {
|
||||
debug_assert!(!input_reused.contains(&input_idx));
|
||||
debug_assert_eq!(operand.pos(), OperandPos::After);
|
||||
input_reused.push(input_idx);
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
//! Main allocation loop that processes bundles.
|
||||
|
||||
use super::{
|
||||
spill_weight_from_policy, CodeRange, Env, LiveBundleIndex, LiveBundleVec, LiveRangeFlag,
|
||||
spill_weight_from_constraint, CodeRange, Env, LiveBundleIndex, LiveBundleVec, LiveRangeFlag,
|
||||
LiveRangeIndex, LiveRangeKey, LiveRangeList, LiveRangeListEntry, PRegIndex, RegTraversalIter,
|
||||
Requirement, UseList,
|
||||
};
|
||||
use crate::{
|
||||
Allocation, Function, Inst, InstPosition, OperandKind, OperandPolicy, PReg, ProgPoint,
|
||||
Allocation, Function, Inst, InstPosition, OperandKind, OperandConstraint, PReg, ProgPoint,
|
||||
RegAllocError,
|
||||
};
|
||||
use fxhash::FxHashSet;
|
||||
@@ -273,11 +273,11 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
} else {
|
||||
for u in &first_range_data.uses {
|
||||
log::debug!(" -> use: {:?}", u);
|
||||
if let OperandPolicy::FixedReg(_) = u.operand.policy() {
|
||||
if let OperandConstraint::FixedReg(_) = u.operand.constraint() {
|
||||
log::debug!(" -> fixed use at {:?}: {:?}", u.pos, u.operand);
|
||||
fixed = true;
|
||||
}
|
||||
if let OperandPolicy::Stack = u.operand.policy() {
|
||||
if let OperandConstraint::Stack = u.operand.constraint() {
|
||||
log::debug!(" -> stack use at {:?}: {:?}", u.pos, u.operand);
|
||||
stack = true;
|
||||
}
|
||||
@@ -886,8 +886,8 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
|
||||
let loop_depth = self.cfginfo.approx_loop_depth
|
||||
[self.cfginfo.insn_block[first_conflict_point.inst().index()].index()];
|
||||
let move_cost = spill_weight_from_policy(
|
||||
OperandPolicy::Reg,
|
||||
let move_cost = spill_weight_from_constraint(
|
||||
OperandConstraint::Reg,
|
||||
loop_depth as usize,
|
||||
/* is_def = */ true,
|
||||
);
|
||||
@@ -905,8 +905,8 @@ impl<'a, F: Function> Env<'a, F> {
|
||||
|
||||
let loop_depth = self.cfginfo.approx_loop_depth
|
||||
[self.cfginfo.insn_block[point.inst().index()].index()];
|
||||
let move_cost = spill_weight_from_policy(
|
||||
OperandPolicy::Reg,
|
||||
let move_cost = spill_weight_from_constraint(
|
||||
OperandConstraint::Reg,
|
||||
loop_depth as usize,
|
||||
/* is_def = */ true,
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Requirements computation.
|
||||
|
||||
use super::{Env, LiveBundleIndex};
|
||||
use crate::{Function, Operand, OperandPolicy, PReg, RegClass};
|
||||
use crate::{Function, Operand, OperandConstraint, PReg, RegClass};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Requirement {
|
||||
@@ -64,10 +64,10 @@ impl Requirement {
|
||||
}
|
||||
#[inline(always)]
|
||||
pub fn from_operand(op: Operand) -> Requirement {
|
||||
match op.policy() {
|
||||
OperandPolicy::FixedReg(preg) => Requirement::Fixed(preg),
|
||||
OperandPolicy::Reg | OperandPolicy::Reuse(_) => Requirement::Register(op.class()),
|
||||
OperandPolicy::Stack => Requirement::Stack(op.class()),
|
||||
match op.constraint() {
|
||||
OperandConstraint::FixedReg(preg) => Requirement::Fixed(preg),
|
||||
OperandConstraint::Reg | OperandConstraint::Reuse(_) => Requirement::Register(op.class()),
|
||||
OperandConstraint::Stack => Requirement::Stack(op.class()),
|
||||
_ => Requirement::Any(op.class()),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user