Skip to content

Commit

Permalink
Enhance optimization of consecutive move instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorng committed Jan 5, 2024
1 parent 9c2c0f7 commit c861a5b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
14 changes: 10 additions & 4 deletions erts/emulator/beam/jit/arm/instr_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,25 +603,31 @@ void BeamModuleAssembler::emit_move_trim(const ArgSource &Src,
}

void BeamModuleAssembler::emit_store_two_values(const ArgSource &Src1,
const ArgYRegister &Dst1,
const ArgRegister &Dst1,
const ArgSource &Src2,
const ArgYRegister &Dst2) {
const ArgRegister &Dst2) {
auto [src1, src2] = load_sources(Src1, TMP1, Src2, TMP2);
auto dst1 = init_destination(Dst1, src1.reg);
auto dst2 = init_destination(Dst2, src2.reg);

ASSERT(!isRegisterBacked(Dst1));
ASSERT(!isRegisterBacked(Dst2));

flush_vars(dst1, dst2);
}

void BeamModuleAssembler::emit_load_two_xregs(const ArgYRegister &Src1,
void BeamModuleAssembler::emit_load_two_xregs(const ArgRegister &Src1,
const ArgXRegister &Dst1,
const ArgYRegister &Src2,
const ArgRegister &Src2,
const ArgXRegister &Dst2) {
ASSERT(ArgVal::memory_relation(Src1, Src2) ==
ArgVal::Relation::consecutive);
auto dst1 = init_destination(Dst1, TMP1);
auto dst2 = init_destination(Dst2, TMP2);

ASSERT(!isRegisterBacked(Src1));
ASSERT(!isRegisterBacked(Src2));

safe_ldp(dst1.reg, dst2.reg, Src1, Src2);
flush_vars(dst1, dst2);
}
Expand Down
26 changes: 22 additions & 4 deletions erts/emulator/beam/jit/arm/ops.tab
Original file line number Diff line number Diff line change
Expand Up @@ -340,17 +340,29 @@ move S1=y D1=x | move S2=y D2=x |
distinct(D1, D2) =>
load_two_xregs S1 D1 S2 D2

move S1=x D1=x | move S2=x D2=x |
consecutive_xregs(S1, S2) |
distinct(D1, D2) =>
load_two_xregs S1 D1 S2 D2

move S1=y D1=x | move S2=y D2=x |
consecutive_words(S2, S1) |
distinct(D1, S2) |
distinct(D1, D2) =>
load_two_xregs S2 D2 S1 D1

move S1=x D1=x | move S2=x D2=x |
consecutive_xregs(S2, S1) |
distinct(D1, S2) |
distinct(D1, D2) =>
load_two_xregs S2 D2 S1 D1

# Optimize storing two values in Y registers when destination Y
# registers are consecutive.

move S1 D1=y | move S2 D2=y | consecutive_words(D1, D2) =>
move S1 D1=y | move S2 D2=y | consecutive_words(D1, D2) | distinct(D1, S2) =>
store_two_values S1 D1 S2 D2
move S1 D1=y | move S2 D2=y | consecutive_words(D2, D1) =>
move S1 D1=y | move S2 D2=y | consecutive_words(D2, D1) | distinct(D1, S2) =>
store_two_values S2 D2 S1 D1

move S1=y D1 | move S2=y D2 | consecutive_words(S1, S2) | trim N u =>
Expand All @@ -359,6 +371,12 @@ move S1=y D1 | move S2=y D2 | consecutive_words(S1, S2) | trim N u =>
move S2=y D2 | move S1=y D1 | consecutive_words(S1, S2) | trim N u =>
move_two_trim S1 D1 S2 D2 N

move S1 D1=x | move S2 D2=x | consecutive_xregs(D1, D2) | distinct(D1, S2) =>
store_two_values S1 D1 S2 D2

move S1 D1=x | move S2 D2=x | consecutive_xregs(D2, D1) | distinct(D1, S2) =>
store_two_values S2 D2 S1 D1

move Src Dst | trim N u => move_trim Src Dst N

move_two_trim y d y d t
Expand All @@ -368,8 +386,8 @@ move_trim s d t
move Src Dst => i_move Src Dst

i_move s d
store_two_values s y s y
load_two_xregs y x y x
store_two_values s d s d
load_two_xregs d x d x

#
# Swap instructions.
Expand Down
4 changes: 4 additions & 0 deletions erts/emulator/beam/jit/arm/predicates.tab
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ pred.never_fails(Bif) {
return 0;
}

pred.consecutive_xregs(A1, A2) {
return A1.type == TAG_x && A2.type == TAG_x && A1.val + 1 == A2.val && A1.val >= 6;
}

pred.consecutive_words(A1, A2) {
return A1.type == A2.type && A1.val + 1 == A2.val;
}
Expand Down

0 comments on commit c861a5b

Please sign in to comment.