Skip to content

Commit c9e3b71

Browse files
authored
Merge pull request bytecodealliance#1729 from cfallin/machinst-branch-opt
Fix MachBuffer branch optimization.
2 parents e229fbc + 13e1290 commit c9e3b71

File tree

3 files changed

+447
-81
lines changed

3 files changed

+447
-81
lines changed

cranelift/codegen/src/isa/aarch64/inst/emit.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,17 +1163,13 @@ impl MachInstEmit for Inst {
11631163
}
11641164
&Inst::Jump { ref dest } => {
11651165
let off = sink.cur_offset();
1166-
// Emit the jump itself.
1167-
sink.put4(enc_jump26(0b000101, dest.as_offset26_or_zero()));
1168-
// After the jump has been emitted, indicate that it uses a
1169-
// label, if so, so that a fixup can occur later. This happens
1170-
// after we emit the bytes because the fixup might occur right
1171-
// away (so the bytes must actually exist now).
1166+
// Indicate that the jump uses a label, if so, so that a fixup can occur later.
11721167
if let Some(l) = dest.as_label() {
11731168
sink.use_label_at_offset(off, l, LabelUse::Branch26);
1174-
let cur_off = sink.cur_offset();
1175-
sink.add_uncond_branch(off, cur_off, l);
1169+
sink.add_uncond_branch(off, off + 4, l);
11761170
}
1171+
// Emit the jump itself.
1172+
sink.put4(enc_jump26(0b000101, dest.as_offset26_or_zero()));
11771173
}
11781174
&Inst::Ret => {
11791175
sink.put4(0xd65f03c0);
@@ -1208,28 +1204,27 @@ impl MachInstEmit for Inst {
12081204
} => {
12091205
// Conditional part first.
12101206
let cond_off = sink.cur_offset();
1211-
sink.put4(enc_conditional_br(taken, kind));
12121207
if let Some(l) = taken.as_label() {
12131208
sink.use_label_at_offset(cond_off, l, LabelUse::Branch19);
1214-
let cur_off = sink.cur_offset();
12151209
let inverted = enc_conditional_br(taken, kind.invert()).to_le_bytes();
1216-
sink.add_cond_branch(cond_off, cur_off, l, &inverted[..]);
1210+
sink.add_cond_branch(cond_off, cond_off + 4, l, &inverted[..]);
12171211
}
1218-
// Unconditional part.
1212+
sink.put4(enc_conditional_br(taken, kind));
1213+
1214+
// Unconditional part next.
12191215
let uncond_off = sink.cur_offset();
1220-
sink.put4(enc_jump26(0b000101, not_taken.as_offset26_or_zero()));
12211216
if let Some(l) = not_taken.as_label() {
12221217
sink.use_label_at_offset(uncond_off, l, LabelUse::Branch26);
1223-
let cur_off = sink.cur_offset();
1224-
sink.add_uncond_branch(uncond_off, cur_off, l);
1218+
sink.add_uncond_branch(uncond_off, uncond_off + 4, l);
12251219
}
1220+
sink.put4(enc_jump26(0b000101, not_taken.as_offset26_or_zero()));
12261221
}
12271222
&Inst::OneWayCondBr { target, kind } => {
12281223
let off = sink.cur_offset();
1229-
sink.put4(enc_conditional_br(target, kind));
12301224
if let Some(l) = target.as_label() {
12311225
sink.use_label_at_offset(off, l, LabelUse::Branch19);
12321226
}
1227+
sink.put4(enc_conditional_br(target, kind));
12331228
}
12341229
&Inst::IndirectBr { rn, .. } => {
12351230
sink.put4(enc_br(rn));
@@ -1307,12 +1302,12 @@ impl MachInstEmit for Inst {
13071302
for &target in targets.iter() {
13081303
let word_off = sink.cur_offset();
13091304
let off_into_table = word_off - jt_off;
1310-
sink.put4(off_into_table);
13111305
sink.use_label_at_offset(
13121306
word_off,
13131307
target.as_label().unwrap(),
13141308
LabelUse::PCRel32,
13151309
);
1310+
sink.put4(off_into_table);
13161311
}
13171312

13181313
// Lowering produces an EmitIsland before using a JTSequence, so we can safely

cranelift/codegen/src/isa/x64/inst/emit.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -812,14 +812,14 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer<Inst>) {
812812
let disp = dest.as_offset32_or_zero() - 5;
813813
let disp = disp as u32;
814814
let br_start = sink.cur_offset();
815-
sink.put1(0xE9);
816-
let br_disp_off = sink.cur_offset();
817-
sink.put4(disp);
818-
let br_end = sink.cur_offset();
815+
let br_disp_off = br_start + 1;
816+
let br_end = br_start + 5;
819817
if let Some(l) = dest.as_label() {
820818
sink.use_label_at_offset(br_disp_off, l, LabelUse::Rel32);
821819
sink.add_uncond_branch(br_start, br_end, l);
822820
}
821+
sink.put1(0xE9);
822+
sink.put4(disp);
823823
}
824824
Inst::JmpCondSymm {
825825
cc,
@@ -835,31 +835,31 @@ pub(crate) fn emit(inst: &Inst, sink: &mut MachBuffer<Inst>) {
835835
let taken_disp = taken.as_offset32_or_zero() - 6;
836836
let taken_disp = taken_disp as u32;
837837
let cond_start = sink.cur_offset();
838-
sink.put1(0x0F);
839-
sink.put1(0x80 + cc.get_enc());
840-
let cond_disp_off = sink.cur_offset();
841-
sink.put4(taken_disp);
842-
let cond_end = sink.cur_offset();
838+
let cond_disp_off = cond_start + 2;
839+
let cond_end = cond_start + 6;
843840
if let Some(l) = taken.as_label() {
844841
sink.use_label_at_offset(cond_disp_off, l, LabelUse::Rel32);
845842
let inverted: [u8; 6] =
846843
[0x0F, 0x80 + (cc.invert().get_enc()), 0xFA, 0xFF, 0xFF, 0xFF];
847844
sink.add_cond_branch(cond_start, cond_end, l, &inverted[..]);
848845
}
846+
sink.put1(0x0F);
847+
sink.put1(0x80 + cc.get_enc());
848+
sink.put4(taken_disp);
849849

850850
// Unconditional part.
851851

852852
let nt_disp = not_taken.as_offset32_or_zero() - 5;
853853
let nt_disp = nt_disp as u32;
854854
let uncond_start = sink.cur_offset();
855-
sink.put1(0xE9);
856-
let uncond_disp_off = sink.cur_offset();
857-
sink.put4(nt_disp);
858-
let uncond_end = sink.cur_offset();
855+
let uncond_disp_off = uncond_start + 1;
856+
let uncond_end = uncond_start + 5;
859857
if let Some(l) = not_taken.as_label() {
860858
sink.use_label_at_offset(uncond_disp_off, l, LabelUse::Rel32);
861859
sink.add_uncond_branch(uncond_start, uncond_end, l);
862860
}
861+
sink.put1(0xE9);
862+
sink.put4(nt_disp);
863863
}
864864
Inst::JmpUnknown { target } => {
865865
match target {

0 commit comments

Comments
 (0)