Fix #686: Allow code shrink in relaxation if the shrinking pass hasn't been run;
Also: - make sure to apply diversions when determining offsets for code relaxation. - select the smallest encoding when selecting a relaxed branch instruction.
This commit is contained in:
@@ -62,6 +62,7 @@ pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> CodegenResult<Cod
|
|||||||
divert.clear();
|
divert.clear();
|
||||||
cur.func.offsets[ebb] = offset;
|
cur.func.offsets[ebb] = offset;
|
||||||
while let Some(inst) = cur.next_inst() {
|
while let Some(inst) = cur.next_inst() {
|
||||||
|
divert.apply(&cur.func.dfg[inst]);
|
||||||
let enc = cur.func.encodings[inst];
|
let enc = cur.func.encodings[inst];
|
||||||
offset += encinfo.byte_size(enc, inst, &divert, &cur.func);
|
offset += encinfo.byte_size(enc, inst, &divert, &cur.func);
|
||||||
}
|
}
|
||||||
@@ -81,10 +82,6 @@ pub fn relax_branches(func: &mut Function, isa: &TargetIsa) -> CodegenResult<Cod
|
|||||||
|
|
||||||
// Record the offset for `ebb` and make sure we iterate until offsets are stable.
|
// Record the offset for `ebb` and make sure we iterate until offsets are stable.
|
||||||
if cur.func.offsets[ebb] != offset {
|
if cur.func.offsets[ebb] != offset {
|
||||||
debug_assert!(
|
|
||||||
cur.func.offsets[ebb] < offset,
|
|
||||||
"Code shrinking during relaxation"
|
|
||||||
);
|
|
||||||
cur.func.offsets[ebb] = offset;
|
cur.func.offsets[ebb] = offset;
|
||||||
go_again = true;
|
go_again = true;
|
||||||
}
|
}
|
||||||
@@ -173,12 +170,12 @@ fn relax_branch(
|
|||||||
dest_offset
|
dest_offset
|
||||||
);
|
);
|
||||||
|
|
||||||
// Pick the first encoding that can handle the branch range.
|
// Pick the smallest encoding that can handle the branch range.
|
||||||
let dfg = &cur.func.dfg;
|
let dfg = &cur.func.dfg;
|
||||||
let ctrl_type = dfg.ctrl_typevar(inst);
|
let ctrl_type = dfg.ctrl_typevar(inst);
|
||||||
if let Some(enc) = isa
|
if let Some(enc) = isa
|
||||||
.legal_encodings(cur.func, &dfg[inst], ctrl_type)
|
.legal_encodings(cur.func, &dfg[inst], ctrl_type)
|
||||||
.find(|&enc| {
|
.filter(|&enc| {
|
||||||
let range = encinfo.branch_range(enc).expect("Branch with no range");
|
let range = encinfo.branch_range(enc).expect("Branch with no range");
|
||||||
if !range.contains(offset, dest_offset) {
|
if !range.contains(offset, dest_offset) {
|
||||||
debug!(" trying [{}]: out of range", encinfo.display(enc));
|
debug!(" trying [{}]: out of range", encinfo.display(enc));
|
||||||
@@ -198,7 +195,9 @@ fn relax_branch(
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.min_by_key(|&enc| encinfo.byte_size(enc, inst, &divert, &cur.func))
|
||||||
{
|
{
|
||||||
|
debug_assert!(enc != cur.func.encodings[inst]);
|
||||||
cur.func.encodings[inst] = enc;
|
cur.func.encodings[inst] = enc;
|
||||||
return encinfo.byte_size(enc, inst, &divert, &cur.func);
|
return encinfo.byte_size(enc, inst, &divert, &cur.func);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
test compile
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
; This checks that code shrink is allowed while relaxing code, when code shrink
|
||||||
|
; has not run.
|
||||||
|
|
||||||
|
function u0:0(i64, i64) -> i64 system_v {
|
||||||
|
ss1 = explicit_slot 8
|
||||||
|
sig0 = (i64) -> i64 system_v
|
||||||
|
fn0 = u0:8 sig0
|
||||||
|
|
||||||
|
ebb0(v0: i64, v1: i64):
|
||||||
|
v3 = stack_addr.i64 ss1
|
||||||
|
v5 = call fn0(v1)
|
||||||
|
v6 = iconst.i64 0
|
||||||
|
v8 = iconst.i64 0
|
||||||
|
jump ebb3(v6, v1, v8)
|
||||||
|
|
||||||
|
ebb3(v39: i64, v40: i64, v42: i64):
|
||||||
|
v9 = load.i64 v3
|
||||||
|
v11 = icmp_imm ugt v9, 1
|
||||||
|
v12 = bint.i8 v11
|
||||||
|
v13 = uextend.i32 v12
|
||||||
|
v14 = icmp_imm eq v13, 0
|
||||||
|
brnz v14, ebb4
|
||||||
|
jump ebb5
|
||||||
|
|
||||||
|
ebb4:
|
||||||
|
v18 = icmp_imm.i64 eq v40, 0
|
||||||
|
v19 = bint.i8 v18
|
||||||
|
v20 = uextend.i32 v19
|
||||||
|
brz v20, ebb6
|
||||||
|
trap user0
|
||||||
|
|
||||||
|
ebb5:
|
||||||
|
v22 = iconst.i32 1
|
||||||
|
v23 = ishl.i64 v39, v22
|
||||||
|
v25 = iconst.i64 1
|
||||||
|
v26 = band.i64 v42, v25
|
||||||
|
v27 = bor v23, v26
|
||||||
|
v28 = iconst.i32 1
|
||||||
|
v29 = ushr.i64 v42, v28
|
||||||
|
v30 = load.i64 v3
|
||||||
|
v31 = iconst.i32 1
|
||||||
|
v32 = ushr v30, v31
|
||||||
|
store v32, v3
|
||||||
|
jump ebb3(v27, v40, v29)
|
||||||
|
|
||||||
|
ebb6:
|
||||||
|
v38 = iconst.i64 0
|
||||||
|
return v38
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user