@@ -82,10 +82,16 @@ static void lowerJumpUnless(MachineInstr &MI, const EVMInstrInfo *TII,
82
82
// / Returns `true` if any fold was performed.
83
83
static bool tryFoldJumpUnless (MachineInstr &MI, const EVMInstrInfo *TII) {
84
84
auto I = MachineBasicBlock::iterator (&MI);
85
- auto *PrevMI = I == MI.getParent ()->begin () ? nullptr : &*std::prev (I);
86
- bool CanFold = PrevMI && (PrevMI->getOpcode () == EVM::ISZERO_S ||
87
- PrevMI->getOpcode () == EVM::EQ_S ||
88
- PrevMI->getOpcode () == EVM::SUB_S);
85
+ if (I == MI.getParent ()->begin ())
86
+ return false ;
87
+ auto PrevMI = std::prev (I);
88
+ while (PrevMI != MI.getParent ()->begin () && PrevMI->getOpcode () == EVM::OR_S)
89
+ PrevMI = std::prev (PrevMI);
90
+ if (PrevMI == MI.getParent ()->begin ())
91
+ return false ;
92
+ bool CanFold = PrevMI->getOpcode () == EVM::ISZERO_S ||
93
+ PrevMI->getOpcode () == EVM::EQ_S ||
94
+ PrevMI->getOpcode () == EVM::SUB_S;
89
95
90
96
if (!CanFold)
91
97
return false ;
@@ -121,6 +127,48 @@ static void lowerPseudoJumpUnless(MachineInstr &MI, const EVMInstrInfo *TII,
121
127
.add (MI.getOperand (0 ));
122
128
}
123
129
130
+ static void optimizePseudoJumpI (MachineInstr &MI, const EVMInstrInfo *TII,
131
+ const bool IsStackified,
132
+ const bool FoldJumps) {
133
+ assert (IsStackified && " Found pseudo jump_unless in non-stackified function" );
134
+ assert (MI.getNumExplicitOperands () == 1 &&
135
+ " Unexpected number of operands in pseudo jump_unless" );
136
+
137
+ if (!FoldJumps)
138
+ return ;
139
+ auto I = MachineBasicBlock::iterator (&MI);
140
+ if (I == MI.getParent ()->begin ())
141
+ return ;
142
+ auto PrevMI = std::prev (I);
143
+ while (PrevMI != MI.getParent ()->begin () && PrevMI->getOpcode () == EVM::OR_S)
144
+ PrevMI = std::prev (PrevMI);
145
+ if (PrevMI == MI.getParent ()->begin () || PrevMI->getOpcode () != EVM::ISZERO_S)
146
+ return ;
147
+ PrevMI = std::prev (PrevMI);
148
+ if (PrevMI == MI.getParent ()->begin ())
149
+ return ;
150
+ bool CanFold = PrevMI->getOpcode () == EVM::ISZERO_S ||
151
+ PrevMI->getOpcode () == EVM::EQ_S ||
152
+ PrevMI->getOpcode () == EVM::SUB_S;
153
+
154
+ if (!CanFold)
155
+ return ;
156
+
157
+ ++NumPseudoJumpUnlessFolded;
158
+
159
+ if (PrevMI->getOpcode () == EVM::ISZERO_S)
160
+ PrevMI->eraseFromParent ();
161
+ else if (PrevMI->getOpcode () == EVM::EQ_S) {
162
+ if (auto PrevPrevMI = std::prev (PrevMI); PrevPrevMI != MI.getParent ()->begin () && PrevPrevMI->getOpcode () == EVM::PUSH0_S) {
163
+ PrevPrevMI->eraseFromParent ();
164
+ PrevMI->eraseFromParent ();
165
+ } else
166
+ PrevMI->setDesc (TII->get (EVM::SUB_S));
167
+ }
168
+ else if (PrevMI->getOpcode () == EVM::SUB_S)
169
+ PrevMI->setDesc (TII->get (EVM::EQ_S));
170
+ }
171
+
124
172
bool EVMLowerJumpUnless::runOnMachineFunction (MachineFunction &MF) {
125
173
LLVM_DEBUG ({
126
174
dbgs () << " ********** Lower jump_unless instructions **********\n "
@@ -147,6 +195,9 @@ bool EVMLowerJumpUnless::runOnMachineFunction(MachineFunction &MF) {
147
195
case EVM::JUMP_UNLESS:
148
196
lowerJumpUnless (*TermIt, TII, IsStackified, MRI);
149
197
break ;
198
+ case EVM::PseudoJUMPI:
199
+ optimizePseudoJumpI (*TermIt, TII, IsStackified, OptLevel != CodeGenOptLevel::None);
200
+ break ;
150
201
default :
151
202
continue ;
152
203
}
0 commit comments