@@ -17,6 +17,7 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
17
17
let block = Block :: new ( block) ;
18
18
let mut def = |vreg : VReg , inst| {
19
19
if defined_in[ vreg. vreg ( ) ] . is_valid ( ) {
20
+ trace ! ( "Multiple def constraints for {:?}" , vreg) ;
20
21
Err ( RegAllocError :: SSA ( vreg, inst) )
21
22
} else {
22
23
defined_in[ vreg. vreg ( ) ] = block;
@@ -48,6 +49,12 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
48
49
for iix in f. block_insns ( block) . iter ( ) {
49
50
let operands = f. inst_operands ( iix) ;
50
51
for operand in operands {
52
+ // Fixed registers uses will likely not be SSA, but they also
53
+ // won't receive assignments.
54
+ if operand. as_fixed_nonallocatable ( ) . is_some ( ) {
55
+ continue ;
56
+ }
57
+
51
58
match operand. kind ( ) {
52
59
OperandKind :: Use => {
53
60
let def_block = defined_in[ operand. vreg ( ) . vreg ( ) ] ;
@@ -58,6 +65,7 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
58
65
cfginfo. dominates ( def_block, block)
59
66
} ;
60
67
if !okay {
68
+ trace ! ( "Invalid use {:?}" , operand. vreg( ) ) ;
61
69
return Err ( RegAllocError :: SSA ( operand. vreg ( ) , iix) ) ;
62
70
}
63
71
}
@@ -69,10 +77,12 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
69
77
// Mod (modify) operands are not used in SSA,
70
78
// but can be used by non-SSA code (e.g. with
71
79
// the regalloc.rs compatibility shim).
80
+ trace ! ( "Unexpected mod {:?}" , operand. vreg( ) ) ;
72
81
return Err ( RegAllocError :: SSA ( operand. vreg ( ) , iix) ) ;
73
82
}
74
83
}
75
84
}
85
+
76
86
// In SSA form, an instruction can't use a VReg that it
77
87
// also defines. So only record this instruction's defs
78
88
// after its uses have been checked.
@@ -94,19 +104,26 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
94
104
for insn in insns. iter ( ) {
95
105
if insn == insns. last ( ) {
96
106
if !( f. is_branch ( insn) || f. is_ret ( insn) ) {
107
+ trace ! ( "block {:?} is not terminated by a branch or ret!" , block) ;
97
108
return Err ( RegAllocError :: BB ( block) ) ;
98
109
}
99
110
if f. is_branch ( insn) {
100
111
for ( i, & succ) in f. block_succs ( block) . iter ( ) . enumerate ( ) {
101
112
let blockparams_in = f. block_params ( succ) ;
102
113
let blockparams_out = f. branch_blockparams ( block, insn, i) ;
103
114
if blockparams_in. len ( ) != blockparams_out. len ( ) {
115
+ trace ! (
116
+ "Mismatch on block params, found {} expected {}" ,
117
+ blockparams_out. len( ) ,
118
+ blockparams_in. len( )
119
+ ) ;
104
120
return Err ( RegAllocError :: Branch ( insn) ) ;
105
121
}
106
122
}
107
123
}
108
124
} else {
109
125
if f. is_branch ( insn) || f. is_ret ( insn) {
126
+ trace ! ( "Block terminator found in the middle of a block" ) ;
110
127
return Err ( RegAllocError :: BB ( block) ) ;
111
128
}
112
129
}
@@ -116,6 +133,7 @@ pub fn validate_ssa<F: Function>(f: &F, cfginfo: &CFGInfo) -> Result<(), RegAllo
116
133
// Check that the entry block has no block args: otherwise it is
117
134
// undefined what their value would be.
118
135
if f. block_params ( f. entry_block ( ) ) . len ( ) > 0 {
136
+ trace ! ( "Entry block contains block args" ) ;
119
137
return Err ( RegAllocError :: BB ( f. entry_block ( ) ) ) ;
120
138
}
121
139
0 commit comments