Skip to content

Commit 0d19eb1

Browse files
[EVM] Enable Tail Duplication after stackification
In order to do this, the following is done: 1. Remove the call to disablePass(&TailDuplicateID), as we want to enable it after stackification. 2. Implement addMachineLateOptimization, to explicitly disable TailDuplicate before stackification. 3. Add isNotDuplicable to some stackify instructions. Some of them can cause functional issues if duplicated (e.g. PUSH_LABEL) and some of them can increase code size (e.g. PUSH instructions). Signed-off-by: Vladimir Radosavljevic <[email protected]>
1 parent 9561c2a commit 0d19eb1

File tree

7 files changed

+50
-27
lines changed

7 files changed

+50
-27
lines changed

llvm/lib/Target/EVM/EVMInstrInfo.td

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ def FCALL
243243
"FCALL\t$callee">;
244244
} // Uses = [SP], isCall = 1
245245

246-
let isCall = 1 in def PseudoCALL
246+
let isCall = 1, isNotDuplicable = 1 in
247+
def PseudoCALL
247248
: EVMPseudo<(outs), (ins jmptarget:$callee, variable_ops), [], true> {
248249
// PUSH4_S + JUMP_S.
249250
let Size = 6;
@@ -836,12 +837,14 @@ foreach I = {1-16} in {
836837

837838
def PUSH_LABEL : NI<(outs), (ins jmptarget:$dst), [], true, "", 0, 0> {
838839
let isCodeGenOnly = 1;
840+
let isNotDuplicable = 1;
839841
// PUSH4_S.
840842
let Size = 5;
841843
}
842844

843845
def PUSH_FRAME : NI<(outs), (ins i256imm:$imm), [], true, "", 0, 0> {
844846
let isCodeGenOnly = 1;
847+
let isNotDuplicable = 1;
845848
}
846849

847850
// Define register PUSH* instructions
@@ -877,6 +880,7 @@ def PUSH2_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH2$imm",
877880
let BaseName = "PUSH2";
878881
}
879882

883+
let isNotDuplicable = 1 in
880884
def PUSH3_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH3$imm",
881885
0x62, 3> {
882886
bits<24> imm;
@@ -886,6 +890,7 @@ def PUSH3_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH3$imm",
886890
let BaseName = "PUSH3";
887891
}
888892

893+
let isNotDuplicable = 1 in
889894
def PUSH4_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH4$imm",
890895
0x63, 3> {
891896
bits<32> imm;
@@ -895,6 +900,7 @@ def PUSH4_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH4$imm",
895900
let BaseName = "PUSH4";
896901
}
897902

903+
let isNotDuplicable = 1 in
898904
def PUSH5_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH5$imm",
899905
0x64, 3> {
900906
bits<40> imm;
@@ -904,6 +910,7 @@ def PUSH5_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH5$imm",
904910
let BaseName = "PUSH5";
905911
}
906912

913+
let isNotDuplicable = 1 in
907914
def PUSH6_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH6$imm",
908915
0x65, 3> {
909916
bits<48> imm;
@@ -913,6 +920,7 @@ def PUSH6_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH6$imm",
913920
let BaseName = "PUSH6";
914921
}
915922

923+
let isNotDuplicable = 1 in
916924
def PUSH7_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH7$imm",
917925
0x66, 3> {
918926
bits<56> imm;
@@ -922,6 +930,7 @@ def PUSH7_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH7$imm",
922930
let BaseName = "PUSH7";
923931
}
924932

933+
let isNotDuplicable = 1 in
925934
def PUSH8_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH8$imm",
926935
0x67, 3> {
927936
bits<64> imm;
@@ -931,6 +940,7 @@ def PUSH8_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH8$imm",
931940
let BaseName = "PUSH8";
932941
}
933942

943+
let isNotDuplicable = 1 in
934944
def PUSH9_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH9$imm",
935945
0x68, 3> {
936946
bits<72> imm;
@@ -941,6 +951,7 @@ def PUSH9_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH9$imm",
941951
let DecoderMethod = "decodePUSH<9>";
942952
}
943953

954+
let isNotDuplicable = 1 in
944955
def PUSH10_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH10$imm",
945956
0x69, 3> {
946957
bits<80> imm;
@@ -951,6 +962,7 @@ def PUSH10_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH10$imm",
951962
let DecoderMethod = "decodePUSH<10>";
952963
}
953964

965+
let isNotDuplicable = 1 in
954966
def PUSH11_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH11$imm",
955967
0x6a, 3> {
956968
bits<88> imm;
@@ -961,6 +973,7 @@ def PUSH11_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH11$imm",
961973
let DecoderMethod = "decodePUSH<11>";
962974
}
963975

976+
let isNotDuplicable = 1 in
964977
def PUSH12_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH12$imm",
965978
0x6b, 3> {
966979
bits<96> imm;
@@ -971,6 +984,7 @@ def PUSH12_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH12$imm",
971984
let DecoderMethod = "decodePUSH<12>";
972985
}
973986

987+
let isNotDuplicable = 1 in
974988
def PUSH13_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH13$imm",
975989
0x6c, 3> {
976990
bits<104> imm;
@@ -981,6 +995,7 @@ def PUSH13_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH13$imm",
981995
let DecoderMethod = "decodePUSH<13>";
982996
}
983997

998+
let isNotDuplicable = 1 in
984999
def PUSH14_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH14$imm",
9851000
0x6d, 3> {
9861001
bits<112> imm;
@@ -991,6 +1006,7 @@ def PUSH14_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH14$imm",
9911006
let DecoderMethod = "decodePUSH<14>";
9921007
}
9931008

1009+
let isNotDuplicable = 1 in
9941010
def PUSH15_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH15$imm",
9951011
0x6e, 3> {
9961012
bits<120> imm;
@@ -1001,6 +1017,7 @@ def PUSH15_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH15$imm",
10011017
let DecoderMethod = "decodePUSH<15>";
10021018
}
10031019

1020+
let isNotDuplicable = 1 in
10041021
def PUSH16_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH16$imm",
10051022
0x6f, 3> {
10061023
bits<128> imm;
@@ -1011,6 +1028,7 @@ def PUSH16_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH16$imm",
10111028
let DecoderMethod = "decodePUSH<16>";
10121029
}
10131030

1031+
let isNotDuplicable = 1 in
10141032
def PUSH17_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH17$imm",
10151033
0x70, 3> {
10161034
bits<136> imm;
@@ -1031,6 +1049,7 @@ def PUSH18_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH18$imm",
10311049
let DecoderMethod = "decodePUSH<18>";
10321050
}
10331051

1052+
let isNotDuplicable = 1 in
10341053
def PUSH19_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH19$imm",
10351054
0x72, 3> {
10361055
bits<152> imm;
@@ -1041,6 +1060,7 @@ def PUSH19_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH19$imm",
10411060
let DecoderMethod = "decodePUSH<19>";
10421061
}
10431062

1063+
let isNotDuplicable = 1 in
10441064
def PUSH20_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH20$imm",
10451065
0x73, 3> {
10461066
bits<160> imm;
@@ -1051,6 +1071,7 @@ def PUSH20_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH20$imm",
10511071
let DecoderMethod = "decodePUSH<20>";
10521072
}
10531073

1074+
let isNotDuplicable = 1 in
10541075
def PUSH21_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH21$imm",
10551076
0x74, 3> {
10561077
bits<168> imm;
@@ -1061,6 +1082,7 @@ def PUSH21_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH21$imm",
10611082
let DecoderMethod = "decodePUSH<21>";
10621083
}
10631084

1085+
let isNotDuplicable = 1 in
10641086
def PUSH22_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH22$imm",
10651087
0x75, 3> {
10661088
bits<176> imm;
@@ -1071,6 +1093,7 @@ def PUSH22_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH22$imm",
10711093
let DecoderMethod = "decodePUSH<22>";
10721094
}
10731095

1096+
let isNotDuplicable = 1 in
10741097
def PUSH23_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH23$imm",
10751098
0x76, 3> {
10761099
bits<184> imm;
@@ -1081,6 +1104,7 @@ def PUSH23_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH23$imm",
10811104
let DecoderMethod = "decodePUSH<23>";
10821105
}
10831106

1107+
let isNotDuplicable = 1 in
10841108
def PUSH24_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH24$imm",
10851109
0x77, 3> {
10861110
bits<192> imm;
@@ -1091,6 +1115,7 @@ def PUSH24_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH24$imm",
10911115
let DecoderMethod = "decodePUSH<24>";
10921116
}
10931117

1118+
let isNotDuplicable = 1 in
10941119
def PUSH25_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH25$imm",
10951120
0x78, 3> {
10961121
bits<200> imm;
@@ -1101,6 +1126,7 @@ def PUSH25_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH25$imm",
11011126
let DecoderMethod = "decodePUSH<25>";
11021127
}
11031128

1129+
let isNotDuplicable = 1 in
11041130
def PUSH26_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH26$imm",
11051131
0x79, 3> {
11061132
bits<208> imm;
@@ -1111,6 +1137,7 @@ def PUSH26_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH26$imm",
11111137
let DecoderMethod = "decodePUSH<26>";
11121138
}
11131139

1140+
let isNotDuplicable = 1 in
11141141
def PUSH27_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH27$imm",
11151142
0x7a, 3> {
11161143
bits<216> imm;
@@ -1121,6 +1148,7 @@ def PUSH27_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH27$imm",
11211148
let DecoderMethod = "decodePUSH<27>";
11221149
}
11231150

1151+
let isNotDuplicable = 1 in
11241152
def PUSH28_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH28$imm",
11251153
0x7b, 3> {
11261154
bits<224> imm;
@@ -1131,6 +1159,7 @@ def PUSH28_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH28$imm",
11311159
let DecoderMethod = "decodePUSH<28>";
11321160
}
11331161

1162+
let isNotDuplicable = 1 in
11341163
def PUSH29_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH29$imm",
11351164
0x7c, 3> {
11361165
bits<232> imm;
@@ -1141,6 +1170,7 @@ def PUSH29_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH29$imm",
11411170
let DecoderMethod = "decodePUSH<29>";
11421171
}
11431172

1173+
let isNotDuplicable = 1 in
11441174
def PUSH30_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH30$imm",
11451175
0x7d, 3> {
11461176
bits<240> imm;
@@ -1151,6 +1181,7 @@ def PUSH30_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH30$imm",
11511181
let DecoderMethod = "decodePUSH<30>";
11521182
}
11531183

1184+
let isNotDuplicable = 1 in
11541185
def PUSH31_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH31$imm",
11551186
0x7e, 3> {
11561187
bits<248> imm;
@@ -1161,6 +1192,7 @@ def PUSH31_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH31$imm",
11611192
let DecoderMethod = "decodePUSH<31>";
11621193
}
11631194

1195+
let isNotDuplicable = 1 in
11641196
def PUSH32_S : PushBase<(outs), (ins i256imm:$imm), [], true, "PUSH32$imm",
11651197
0x7f, 3> {
11661198
bits<256> imm;
@@ -1176,6 +1208,7 @@ let isAsCheapAsAMove = 1, isReMaterializable = 1, isCodeGenOnly = 1, hasSideEffe
11761208
let BaseName = "DATASIZE" in {
11771209
def DATASIZE : NI<(outs GPR:$dst), (ins jmptarget:$reloc), [], false, "", 0, 0>;
11781210
def DATASIZE_S : NI<(outs), (ins jmptarget:$reloc), [], true, "", 0, 0> {
1211+
let isNotDuplicable = 1;
11791212
// PUSH4_S
11801213
let Size = 5;
11811214
}
@@ -1184,6 +1217,7 @@ let isAsCheapAsAMove = 1, isReMaterializable = 1, isCodeGenOnly = 1, hasSideEffe
11841217
let BaseName = "DATAOFFSET" in {
11851218
def DATAOFFSET : NI<(outs GPR:$dst), (ins jmptarget:$reloc), [], false, "", 0, 0>;
11861219
def DATAOFFSET_S : NI<(outs), (ins jmptarget:$reloc), [], true, "", 0, 0> {
1220+
let isNotDuplicable = 1;
11871221
// PUSH4_S
11881222
let Size = 5;
11891223
}
@@ -1192,6 +1226,7 @@ let isAsCheapAsAMove = 1, isReMaterializable = 1, isCodeGenOnly = 1, hasSideEffe
11921226
let BaseName = "LINKERSYMBOL" in {
11931227
def LINKERSYMBOL : NI<(outs GPR:$dst), (ins jmptarget:$sym), [], false, "", 0, 0>;
11941228
def LINKERSYMBOL_S : NI<(outs), (ins jmptarget:$sym), [], true, "", 0, 0> {
1229+
let isNotDuplicable = 1;
11951230
// PUSH20_S
11961231
let Size = 21;
11971232
}
@@ -1200,6 +1235,7 @@ let isAsCheapAsAMove = 1, isReMaterializable = 1, isCodeGenOnly = 1, hasSideEffe
12001235
let BaseName = "LOADIMMUTABLE" in {
12011236
def LOADIMMUTABLE : NI<(outs GPR:$dst), (ins jmptarget:$sym), [], false, "", 0, 0>;
12021237
def LOADIMMUTABLE_S : NI<(outs), (ins jmptarget:$sym), [], true, "", 0, 0> {
1238+
let isNotDuplicable = 1;
12031239
// PUSH32_S
12041240
let Size = 33;
12051241
}

llvm/lib/Target/EVM/EVMTargetMachine.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ class EVMPassConfig final : public TargetPassConfig {
203203
bool addGCPasses() override { return false; }
204204
bool addInstSelector() override;
205205
void addPostRegAlloc() override;
206+
void addMachineLateOptimization() override;
206207
void addPreEmitPass() override;
207208
void addPreEmitPass2() override;
208209
};
@@ -252,7 +253,6 @@ void EVMPassConfig::addPostRegAlloc() {
252253
disablePass(&LiveDebugValuesID);
253254
disablePass(&PatchableFunctionID);
254255
disablePass(&ShrinkWrapID);
255-
disablePass(&TailDuplicateID);
256256

257257
// TODO: This pass is disabled in WebAssembly, as it hurts code size because
258258
// it can generate irreducible control flow. Check if this also true for EVM?
@@ -261,6 +261,10 @@ void EVMPassConfig::addPostRegAlloc() {
261261
TargetPassConfig::addPostRegAlloc();
262262
}
263263

264+
void EVMPassConfig::addMachineLateOptimization() {
265+
addPass(&BranchFolderPassID);
266+
}
267+
264268
void EVMPassConfig::addPreEmitPass() {
265269
TargetPassConfig::addPreEmitPass();
266270

@@ -276,8 +280,10 @@ void EVMPassConfig::addPreEmitPass() {
276280
// Optimize branch instructions after stackification. This is done again
277281
// here, since EVMSplitCriticalEdges may introduce new BBs that could
278282
// contain only branches after stackification.
279-
if (getOptLevel() != CodeGenOptLevel::None)
283+
if (getOptLevel() != CodeGenOptLevel::None) {
280284
addPass(&BranchFolderPassID);
285+
addPass(&TailDuplicateID);
286+
}
281287
}
282288
}
283289

llvm/test/CodeGen/EVM/O3-pipeline.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ target triple = "evm"
140140
; CHECK-NEXT: Machine Natural Loop Construction
141141
; CHECK-NEXT: Machine Block Frequency Analysis
142142
; CHECK-NEXT: Control Flow Optimizer
143+
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
144+
; CHECK-NEXT: Tail Duplication
143145
; CHECK-NEXT: Machine Sanitizer Binary Metadata
144146
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
145147
; CHECK-NEXT: Machine Optimization Remark Emitter

llvm/test/CodeGen/EVM/br.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ define i256 @diamond(i256 %rs1, i256 %rs2) nounwind {
1818
; CHECK-NEXT: SWAP2
1919
; CHECK-NEXT: POP
2020
; CHECK-NEXT: MUL
21-
; CHECK-NEXT: PUSH4 @.BB0_3
21+
; CHECK-NEXT: SWAP1
2222
; CHECK-NEXT: JUMP
2323
; CHECK-NEXT: .BB0_2: ; %false_bb
2424
; CHECK-NEXT: JUMPDEST
2525
; CHECK-NEXT: ADD
26-
; CHECK-NEXT: .BB0_3: ; %end_bb
27-
; CHECK-NEXT: JUMPDEST
2826
; CHECK-NEXT: SWAP1
2927
; CHECK-NEXT: JUMP
3028

llvm/test/CodeGen/EVM/machine-sink-cheap-instructions.ll

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ define i256 @test1(i256 %arg) {
1616
; CHECK-NEXT: JUMPI
1717
; CHECK-NEXT: ; %bb.1:
1818
; CHECK-NEXT: PUSH0
19-
; CHECK-NEXT: PUSH4 @.BB0_3
19+
; CHECK-NEXT: SWAP1
2020
; CHECK-NEXT: JUMP
2121
; CHECK-NEXT: .BB0_2: ; %bb1
2222
; CHECK-NEXT: JUMPDEST
@@ -25,8 +25,6 @@ define i256 @test1(i256 %arg) {
2525
; CHECK-NEXT: JUMP
2626
; CHECK-NEXT: .FUNC_RET0:
2727
; CHECK-NEXT: JUMPDEST
28-
; CHECK-NEXT: .BB0_3: ; %bb2
29-
; CHECK-NEXT: JUMPDEST
3028
; CHECK-NEXT: SWAP1
3129
; CHECK-NEXT: JUMP
3230
entry:
@@ -52,7 +50,7 @@ define i256 @test2(i256 %arg) {
5250
; CHECK-NEXT: JUMPI
5351
; CHECK-NEXT: ; %bb.1:
5452
; CHECK-NEXT: ADDRESS
55-
; CHECK-NEXT: PUSH4 @.BB1_3
53+
; CHECK-NEXT: SWAP1
5654
; CHECK-NEXT: JUMP
5755
; CHECK-NEXT: .BB1_2: ; %bb1
5856
; CHECK-NEXT: JUMPDEST
@@ -61,8 +59,6 @@ define i256 @test2(i256 %arg) {
6159
; CHECK-NEXT: JUMP
6260
; CHECK-NEXT: .FUNC_RET1:
6361
; CHECK-NEXT: JUMPDEST
64-
; CHECK-NEXT: .BB1_3: ; %bb2
65-
; CHECK-NEXT: JUMPDEST
6662
; CHECK-NEXT: SWAP1
6763
; CHECK-NEXT: JUMP
6864
entry:

0 commit comments

Comments
 (0)