aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-03-20 06:03:40 +0100
committerBjörn Gustavsson <[email protected]>2019-03-20 15:06:08 +0100
commitdb5e8bda8cad4f16e0573d23a3ab1e37cadf78c4 (patch)
tree53984ec1a13c233a4b772d4fe560aedc486b2af2
parent6e87e37bdd01401aa340a0f47e2d10fd8fe472ee (diff)
downloadotp-db5e8bda8cad4f16e0573d23a3ab1e37cadf78c4.tar.gz
otp-db5e8bda8cad4f16e0573d23a3ab1e37cadf78c4.tar.bz2
otp-db5e8bda8cad4f16e0573d23a3ab1e37cadf78c4.zip
Optimize moving of several Y registers to X registers
Introduce move_src_window[234] instructions for moving several consecutively numbered Y registers to discontiguously numbered X registers. This optimization is effective because the compiler has sorted the `move` instructions in Y register order.
-rw-r--r--erts/emulator/beam/instrs.tab33
-rw-r--r--erts/emulator/beam/ops.tab29
2 files changed, 60 insertions, 2 deletions
diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab
index 3cb12dba4a..692408e212 100644
--- a/erts/emulator/beam/instrs.tab
+++ b/erts/emulator/beam/instrs.tab
@@ -515,6 +515,39 @@ move_shift(Src, SD, D) {
$SD = V;
}
+move_src_window2(Src, D1, D2) {
+ Eterm* src = &$Src;
+ Eterm s1, s2;
+ s1 = src[0];
+ s2 = src[1];
+ $D1 = s1;
+ $D2 = s2;
+}
+
+move_src_window3(Src, D1, D2, D3) {
+ Eterm* src = &$Src;
+ Eterm s1, s2, s3;
+ s1 = src[0];
+ s2 = src[1];
+ s3 = src[2];
+ $D1 = s1;
+ $D2 = s2;
+ $D3 = s3;
+}
+
+move_src_window4(Src, D1, D2, D3, D4) {
+ Eterm* src = &$Src;
+ Eterm s1, s2, s3, s4;
+ s1 = src[0];
+ s2 = src[1];
+ s3 = src[2];
+ s4 = src[3];
+ $D1 = s1;
+ $D2 = s2;
+ $D3 = s3;
+ $D4 = s4;
+}
+
move_window2(S1, S2, D) {
Eterm xt0, xt1;
Eterm* y = &$D;
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 067f81930d..6832e65b1b 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -270,8 +270,8 @@ move_jump f cxy xy
move_jump f c r
-# Movement to and from the stack is common
-# Try to pack as much as we can into one instruction
+# Movement to and from the stack is common.
+# Try to pack as much as we can into one instruction.
# Window move
move_window/5
@@ -299,6 +299,31 @@ move_window3 x x x y
move_window4 x x x x y
move_window5 x x x x x y
+# y -> x
+
+move_src_window/4
+move_src_window/5
+
+move Y1=y X1=x | move Y2=y X2=x | succ(Y1, Y2) => \
+ move_src_window Y1 Y2 X1 X2
+
+move_src_window Y1 Y2 X1 X2 | move Y3=y X3=x | succ(Y2, Y3) => \
+ move_src_window Y1 Y3 X1 X2 X3
+move_src_window Y1 Y2 X1 X2 | move Y3=y X3=x | move Y4=y X4=x | succ(Y3, Y4) => \
+ move_src_window2 Y1 X1 X2 | move_src_window Y3 Y4 X3 X4
+move_src_window Y1 Y2 X1 X2 | move Y3=y X3=x => \
+ move3 Y1 X1 Y2 X2 Y3 X3
+
+move_src_window Y1 Y3 X1 X2 X3 | move Y4=y X4=x | succ(Y3, Y4) => \
+ move_src_window4 Y1 X1 X2 X3 X4
+
+move_src_window Y1 y X1 X2 => move_src_window2 Y1 X1 X2
+move_src_window Y1 y X1 X2 X3 => move_src_window3 Y1 X1 X2 X3
+
+move_src_window2 y x x
+move_src_window3 y x x x
+move_src_window4 y x x x x
+
# Swap registers.
move R1=xy Tmp=x | move R2=xy R1 | move Tmp R2 => swap_temp R1 R2 Tmp