14
14
15
15
use super :: { Env , LiveBundleIndex , SpillSet , SpillSlotIndex , VRegIndex } ;
16
16
use crate :: {
17
- ion:: data_structures:: { BlockparamOut , CodeRange } ,
18
- Function , Inst , OperandConstraint , OperandKind , PReg , ProgPoint ,
17
+ ion:: data_structures:: BlockparamOut , Function , Inst , OperandConstraint , OperandKind , PReg ,
19
18
} ;
20
19
use alloc:: format;
21
20
use smallvec:: smallvec;
@@ -59,21 +58,6 @@ impl<'a, F: Function> Env<'a, F> {
59
58
}
60
59
}
61
60
62
- // If a bundle has a fixed-reg def then we need to be careful to not
63
- // extend the bundle to include another use in the same instruction.
64
- // This could result in a minimal bundle that is impossible to split.
65
- //
66
- // This can only happen with an early use and a late def, so we round
67
- // the start of each range containing a fixed def up to the start of
68
- // its instruction to detect overlaps.
69
- let adjust_range_start = |bundle_idx, range : CodeRange | {
70
- if self . bundles [ bundle_idx] . cached_fixed_def ( ) {
71
- ProgPoint :: before ( range. from . inst ( ) )
72
- } else {
73
- range. from
74
- }
75
- } ;
76
-
77
61
// Check for overlap in LiveRanges and for conflicting
78
62
// requirements.
79
63
let ranges_from = & self . bundles [ from] . ranges [ ..] ;
@@ -92,11 +76,9 @@ impl<'a, F: Function> Env<'a, F> {
92
76
return false ;
93
77
}
94
78
95
- if adjust_range_start ( from , ranges_from[ idx_from] . range ) >= ranges_to[ idx_to] . range . to {
79
+ if ranges_from[ idx_from] . range . from >= ranges_to[ idx_to] . range . to {
96
80
idx_to += 1 ;
97
- } else if adjust_range_start ( to, ranges_to[ idx_to] . range )
98
- >= ranges_from[ idx_from] . range . to
99
- {
81
+ } else if ranges_to[ idx_to] . range . from >= ranges_from[ idx_from] . range . to {
100
82
idx_from += 1 ;
101
83
} else {
102
84
// Overlap -- cannot merge.
@@ -109,6 +91,15 @@ impl<'a, F: Function> Env<'a, F> {
109
91
}
110
92
}
111
93
94
+ // Avoid merging if either side has a fixed-reg def: this can
95
+ // result in an impossible-to-solve allocation problem if
96
+ // there is a fixed-reg use in the same reg on the same
97
+ // instruction.
98
+ if self . bundles [ from] . cached_fixed_def ( ) || self . bundles [ to] . cached_fixed_def ( ) {
99
+ trace ! ( " -> one bundle has a fixed def; aborting merge" ) ;
100
+ return false ;
101
+ }
102
+
112
103
// Check for a requirements conflict.
113
104
if self . bundles [ from] . cached_stack ( )
114
105
|| self . bundles [ from] . cached_fixed ( )
0 commit comments