14
14
#include " EVMMachineFunctionInfo.h"
15
15
#include " EVMSubtarget.h"
16
16
#include " MCTargetDesc/EVMMCTargetDesc.h"
17
- #include " llvm/ADT/Statistic.h"
18
17
#include " llvm/CodeGen/MachineFunctionPass.h"
19
18
#include " llvm/CodeGen/MachineInstrBuilder.h"
20
- #include " llvm/Support/CodeGen.h"
21
- #include " llvm/Target/TargetMachine.h"
22
- #include " llvm/Target/TargetOptions.h"
23
19
24
20
using namespace llvm ;
25
21
26
22
#define DEBUG_TYPE " evm-lower-jump-unless"
27
23
#define EVM_LOWER_JUMP_UNLESS_NAME " EVM Lower jump_unless"
28
24
29
- STATISTIC (NumPseudoJumpUnlessFolded, " Number of PseudoJUMP_UNLESS folded" );
30
-
31
25
namespace {
32
26
class EVMLowerJumpUnless final : public MachineFunctionPass {
33
27
public:
@@ -72,51 +66,14 @@ static void lowerJumpUnless(MachineInstr &MI, const EVMInstrInfo *TII,
72
66
.addReg (NewReg);
73
67
}
74
68
75
- // / Fold `<PrevMI> ; PseudoJUMP_UNLESS` into `PseudoJUMPI`.
76
- // /
77
- // / Supported `PrevMI` patterns and changes:
78
- // / • `ISZERO_S` -> delete `ISZERO_S`
79
- // / • `EQ_S` -> change to `SUB_S`
80
- // / • `SUB_S` -> change to `EQ_S`
81
- // /
82
- // / Returns `true` if any fold was performed.
83
- static bool tryFoldJumpUnless (MachineInstr &MI, const EVMInstrInfo *TII) {
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);
89
-
90
- if (!CanFold)
91
- return false ;
92
-
93
- ++NumPseudoJumpUnlessFolded;
94
-
95
- if (PrevMI->getOpcode () == EVM::ISZERO_S)
96
- PrevMI->eraseFromParent ();
97
- else if (PrevMI->getOpcode () == EVM::EQ_S)
98
- PrevMI->setDesc (TII->get (EVM::SUB_S));
99
- else if (PrevMI->getOpcode () == EVM::SUB_S)
100
- PrevMI->setDesc (TII->get (EVM::EQ_S));
101
- return true ;
102
- }
103
-
104
- // / Lower a `PseudoJUMP_UNLESS` to condition-setting + `PseudoJUMPI`.
105
- // /
106
- // / If `FoldJumps` is enabled and the local pattern allows it, an
107
- // / optimisation in `tryFoldJumpUnless` removes the explicit `ISZERO_S`.
108
- // / Otherwise the pseudo-op expands to:
109
- // / ISZERO_S
110
- // / PseudoJUMPI
69
+ // Lower pseudo jump_unless into iszero and jumpi instructions. This pseudo
70
+ // instruction can only be present in stackified functions.
111
71
static void lowerPseudoJumpUnless (MachineInstr &MI, const EVMInstrInfo *TII,
112
- const bool IsStackified,
113
- const bool FoldJumps) {
72
+ const bool IsStackified) {
114
73
assert (IsStackified && " Found pseudo jump_unless in non-stackified function" );
115
74
assert (MI.getNumExplicitOperands () == 1 &&
116
75
" Unexpected number of operands in pseudo jump_unless" );
117
-
118
- if (!FoldJumps || !tryFoldJumpUnless (MI, TII))
119
- BuildMI (*MI.getParent (), MI, MI.getDebugLoc (), TII->get (EVM::ISZERO_S));
76
+ BuildMI (*MI.getParent (), MI, MI.getDebugLoc (), TII->get (EVM::ISZERO_S));
120
77
BuildMI (*MI.getParent (), MI, MI.getDebugLoc (), TII->get (EVM::PseudoJUMPI))
121
78
.add (MI.getOperand (0 ));
122
79
}
@@ -127,32 +84,24 @@ bool EVMLowerJumpUnless::runOnMachineFunction(MachineFunction &MF) {
127
84
<< " ********** Function: " << MF.getName () << ' \n ' ;
128
85
});
129
86
130
- CodeGenOptLevel OptLevel = MF.getTarget ().getOptLevel ();
131
87
MachineRegisterInfo &MRI = MF.getRegInfo ();
132
88
const auto *TII = MF.getSubtarget <EVMSubtarget>().getInstrInfo ();
133
89
const bool IsStackified =
134
90
MF.getInfo <EVMMachineFunctionInfo>()->getIsStackified ();
135
91
136
92
bool Changed = false ;
137
93
for (MachineBasicBlock &MBB : MF) {
138
- auto TermIt = MBB.getFirstInstrTerminator ();
139
- if (TermIt == MBB.end ())
140
- continue ;
141
-
142
- switch (TermIt->getOpcode ()) {
143
- case EVM::PseudoJUMP_UNLESS:
144
- lowerPseudoJumpUnless (*TermIt, TII, IsStackified,
145
- OptLevel != CodeGenOptLevel::None);
146
- break ;
147
- case EVM::JUMP_UNLESS:
148
- lowerJumpUnless (*TermIt, TII, IsStackified, MRI);
149
- break ;
150
- default :
151
- continue ;
94
+ for (auto &MI : make_early_inc_range (MBB)) {
95
+ if (MI.getOpcode () == EVM::PseudoJUMP_UNLESS)
96
+ lowerPseudoJumpUnless (MI, TII, IsStackified);
97
+ else if (MI.getOpcode () == EVM::JUMP_UNLESS)
98
+ lowerJumpUnless (MI, TII, IsStackified, MRI);
99
+ else
100
+ continue ;
101
+
102
+ MI.eraseFromParent ();
103
+ Changed = true ;
152
104
}
153
-
154
- TermIt->eraseFromParent ();
155
- Changed = true ;
156
105
}
157
106
return Changed;
158
107
}
0 commit comments