Skip to content

Commit 6a3a615

Browse files
committed
Revert "Remove the OperandConstraint::Stack variant (#185)"
This reverts commit abdc3d6.
1 parent 8619ae7 commit 6a3a615

File tree

8 files changed

+63
-11
lines changed

8 files changed

+63
-11
lines changed

doc/ION.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,14 @@ other):
442442

443443
```plain
444444
445-
Any(rc)
446-
/ \
447-
FixedReg(reg) FixedStack(reg)
448-
\ /
449-
Conflict
445+
___Unknown_____
446+
| | |
447+
| | |
448+
| ____Any(rc) |
449+
|/ | |
450+
Stack(rc) FixedReg(reg)
451+
\ /
452+
Conflict
450453
```
451454

452455
Once we have the Requirement for a bundle, we can decide what to do.

src/checker.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,17 @@ impl CheckerState {
640640
}
641641
return Err(CheckerError::AllocationIsNotReg { inst, op, alloc });
642642
}
643+
OperandConstraint::Stack => {
644+
if alloc.kind() != AllocationKind::Stack {
645+
// Accept pregs that represent a fixed stack slot.
646+
if let Some(preg) = alloc.as_reg() {
647+
if checker.machine_env.fixed_stack_slots.contains(&preg) {
648+
return Ok(());
649+
}
650+
}
651+
return Err(CheckerError::AllocationIsNotStack { inst, op, alloc });
652+
}
653+
}
643654
OperandConstraint::FixedReg(preg) => {
644655
if alloc != Allocation::reg(preg) {
645656
return Err(CheckerError::AllocationIsNotFixedReg { inst, op, alloc });

src/ion/data_structures.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub struct LiveBundle {
205205
pub spill_weight_and_props: u32,
206206
}
207207

208-
pub const BUNDLE_MAX_SPILL_WEIGHT: u32 = (1 << 29) - 1;
208+
pub const BUNDLE_MAX_SPILL_WEIGHT: u32 = (1 << 28) - 1;
209209
pub const MINIMAL_FIXED_BUNDLE_SPILL_WEIGHT: u32 = BUNDLE_MAX_SPILL_WEIGHT;
210210
pub const MINIMAL_BUNDLE_SPILL_WEIGHT: u32 = BUNDLE_MAX_SPILL_WEIGHT - 1;
211211
pub const BUNDLE_MAX_NORMAL_SPILL_WEIGHT: u32 = BUNDLE_MAX_SPILL_WEIGHT - 2;
@@ -218,12 +218,14 @@ impl LiveBundle {
218218
minimal: bool,
219219
fixed: bool,
220220
fixed_def: bool,
221+
stack: bool,
221222
) {
222223
debug_assert!(spill_weight <= BUNDLE_MAX_SPILL_WEIGHT);
223224
self.spill_weight_and_props = spill_weight
224225
| (if minimal { 1 << 31 } else { 0 })
225226
| (if fixed { 1 << 30 } else { 0 })
226-
| (if fixed_def { 1 << 29 } else { 0 });
227+
| (if fixed_def { 1 << 29 } else { 0 })
228+
| (if stack { 1 << 28 } else { 0 });
227229
}
228230

229231
#[inline(always)]

src/ion/liveranges.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,10 @@ impl<'a, F: Function> Env<'a, F> {
824824
first_reg_slot.get_or_insert(u.slot);
825825
}
826826
}
827+
// Maybe this could be supported in this future...
828+
OperandConstraint::Stack => panic!(
829+
"multiple uses of vreg with a Stack constraint are not supported"
830+
),
827831
}
828832
}
829833

src/ion/merge.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ impl<'a, F: Function> Env<'a, F> {
282282

283283
let mut fixed = false;
284284
let mut fixed_def = false;
285+
let mut stack = false;
285286
for entry in &self.bundles[bundle].ranges {
286287
for u in &self.ranges[entry.index].uses {
287288
if let OperandConstraint::FixedReg(_) = u.operand.constraint() {
@@ -290,7 +291,10 @@ impl<'a, F: Function> Env<'a, F> {
290291
fixed_def = true;
291292
}
292293
}
293-
if fixed && fixed_def {
294+
if let OperandConstraint::Stack = u.operand.constraint() {
295+
stack = true;
296+
}
297+
if fixed && stack && fixed_def {
294298
break;
295299
}
296300
}
@@ -301,6 +305,9 @@ impl<'a, F: Function> Env<'a, F> {
301305
if fixed_def {
302306
self.bundles[bundle].set_cached_fixed_def();
303307
}
308+
if stack {
309+
self.bundles[bundle].set_cached_stack();
310+
}
304311

305312
// Create a spillslot for this bundle.
306313
let reg = self.vreg(vreg);

src/ion/process.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ impl<'a, F: Function> Env<'a, F> {
267267
let minimal;
268268
let mut fixed = false;
269269
let mut fixed_def = false;
270+
let mut stack = false;
270271
let bundledata = &self.ctx.bundles[bundle];
271272
let num_ranges = bundledata.ranges.len();
272273
let first_range = bundledata.ranges[0].index;
@@ -288,7 +289,12 @@ impl<'a, F: Function> Env<'a, F> {
288289
trace!(" -> is fixed def");
289290
fixed_def = true;
290291
}
291-
292+
}
293+
if let OperandConstraint::Stack = u.operand.constraint() {
294+
trace!(" -> stack operand at {:?}: {:?}", u.pos, u.operand);
295+
stack = true;
296+
}
297+
if stack && fixed {
292298
break;
293299
}
294300
}
@@ -351,6 +357,7 @@ impl<'a, F: Function> Env<'a, F> {
351357
minimal,
352358
fixed,
353359
fixed_def,
360+
stack,
354361
);
355362
}
356363

@@ -1036,6 +1043,12 @@ impl<'a, F: Function> Env<'a, F> {
10361043
let fixed_preg = match req {
10371044
Requirement::FixedReg(preg) | Requirement::FixedStack(preg) => Some(preg),
10381045
Requirement::Register => None,
1046+
Requirement::Stack => {
1047+
// If we must be on the stack, mark our spillset
1048+
// as required immediately.
1049+
self.spillsets[self.bundles[bundle].spillset].required = true;
1050+
return Ok(());
1051+
}
10391052

10401053
Requirement::Any => {
10411054
self.ctx.spilled_bundles.push(bundle);

src/ion/requirement.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub enum Requirement {
6161
FixedReg(PReg),
6262
FixedStack(PReg),
6363
Register,
64+
Stack,
6465
Any,
6566
}
6667
impl Requirement {
@@ -69,10 +70,15 @@ impl Requirement {
6970
match (self, other) {
7071
(other, Requirement::Any) | (Requirement::Any, other) => Ok(other),
7172
(Requirement::Register, Requirement::Register) => Ok(self),
73+
(Requirement::Stack, Requirement::Stack) => Ok(self),
7274
(Requirement::Register, Requirement::FixedReg(preg))
7375
| (Requirement::FixedReg(preg), Requirement::Register) => {
7476
Ok(Requirement::FixedReg(preg))
7577
}
78+
(Requirement::Stack, Requirement::FixedStack(preg))
79+
| (Requirement::FixedStack(preg), Requirement::Stack) => {
80+
Ok(Requirement::FixedStack(preg))
81+
}
7682
(Requirement::FixedReg(a), Requirement::FixedReg(b)) if a == b => Ok(self),
7783
(Requirement::FixedStack(a), Requirement::FixedStack(b)) if a == b => Ok(self),
7884
_ => Err(RequirementConflict),
@@ -82,7 +88,7 @@ impl Requirement {
8288
#[inline(always)]
8389
pub fn is_stack(self) -> bool {
8490
match self {
85-
Requirement::FixedStack(..) => true,
91+
Requirement::Stack | Requirement::FixedStack(..) => true,
8692
Requirement::Register | Requirement::FixedReg(..) => false,
8793
Requirement::Any => false,
8894
}
@@ -92,7 +98,7 @@ impl Requirement {
9298
pub fn is_reg(self) -> bool {
9399
match self {
94100
Requirement::Register | Requirement::FixedReg(..) => true,
95-
Requirement::FixedStack(..) => false,
101+
Requirement::Stack | Requirement::FixedStack(..) => false,
96102
Requirement::Any => false,
97103
}
98104
}
@@ -110,6 +116,7 @@ impl<'a, F: Function> Env<'a, F> {
110116
}
111117
}
112118
OperandConstraint::Reg | OperandConstraint::Reuse(_) => Requirement::Register,
119+
OperandConstraint::Stack => Requirement::Stack,
113120
OperandConstraint::Any => Requirement::Any,
114121
}
115122
}

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,8 @@ pub enum OperandConstraint {
528528
Any,
529529
/// Operand must be in a register. Register is read-only for Uses.
530530
Reg,
531+
/// Operand must be on the stack.
532+
Stack,
531533
/// Operand must be in a fixed register.
532534
FixedReg(PReg),
533535
/// On defs only: reuse a use's register.
@@ -539,6 +541,7 @@ impl core::fmt::Display for OperandConstraint {
539541
match self {
540542
Self::Any => write!(f, "any"),
541543
Self::Reg => write!(f, "reg"),
544+
Self::Stack => write!(f, "stack"),
542545
Self::FixedReg(preg) => write!(f, "fixed({})", preg),
543546
Self::Reuse(idx) => write!(f, "reuse({})", idx),
544547
}
@@ -634,6 +637,7 @@ impl Operand {
634637
let constraint_field = match constraint {
635638
OperandConstraint::Any => 0,
636639
OperandConstraint::Reg => 1,
640+
OperandConstraint::Stack => 2,
637641
OperandConstraint::FixedReg(preg) => {
638642
debug_assert_eq!(preg.class(), vreg.class());
639643
0b1000000 | preg.hw_enc() as u32
@@ -906,6 +910,7 @@ impl Operand {
906910
match constraint_field {
907911
0 => OperandConstraint::Any,
908912
1 => OperandConstraint::Reg,
913+
2 => OperandConstraint::Stack,
909914
_ => unreachable!(),
910915
}
911916
}

0 commit comments

Comments
 (0)