32#define DEBUG_TYPE "m68k-collapse-movem"
33#define PASS_NAME "M68k MOVEM collapser pass"
37enum UpdateType { Ascending, Descending, Intermixed };
51 enum class AccessTy {
None, Load, Store };
56 : Begin(
nullptr),
End(
nullptr),
Base(0), Start(INT_MIN), Stop(INT_MAX),
57 Mask(0), Access(AccessTy::None) {}
69 bool hasBase()
const {
return Base != 0; }
71 unsigned getBase()
const {
86 unsigned getMask()
const {
return Mask; }
88 void setBase(
int Value) {
94 UpdateType classifyUpdateByMask(
unsigned NewMask)
const {
95 assert(NewMask &&
"Mask needs to select at least one register");
99 }
else if (NewMask < Mask) {
106 bool update(
int O,
int M) {
107 UpdateType
Type = classifyUpdateByMask(M);
108 if (
Type == Intermixed)
110 if (Start == INT_MIN) {
114 }
else if (
Type == Descending && O == Start - 4) {
118 }
else if (
Type == Ascending && O == Stop + 4) {
127 int getFinalOffset()
const {
130 "MOVEM in control mode should increment the address in each iteration");
134 bool updateMask(
unsigned Value) {
135 assert(isUInt<16>(
Value) &&
"Mask must fit 16 bit");
137 "This is weird, there should be no intersections");
142 void setLoad() { Access = AccessTy::Load; }
143 void setStore() { Access = AccessTy::Store; }
145 bool isLoad()
const {
return Access == AccessTy::Load; }
146 bool isStore()
const {
return Access == AccessTy::Store; }
170 auto MI = State.begin();
171 auto End = State.end();
175 if (std::next(
MI) ==
End) {
176 State = MOVEMState();
182 auto Next = std::next(
MI);
188 if (State.isLoad()) {
191 .
addImm(State.getFinalOffset())
195 .
addImm(State.getFinalOffset())
200 State = MOVEMState();
204 MOVEMState &State,
unsigned Mask,
int Offset,
unsigned Reg,
205 bool IsStore =
false) {
206 if (State.hasBase()) {
209 MOVEMState Temp = State;
210 if (State.isStore() == IsStore && State.getBase() == Reg &&
211 State.update(
Offset, Mask)) {
219 return ProcessMI(
MBB,
MI, State, Mask,
Offset, Reg, IsStore);
222 }
else if (Reg ==
TRI->getStackRegister() ||
223 Reg ==
TRI->getBaseRegister() ||
227 State.update(
Offset, Mask);
228 IsStore ? State.setStore() : State.setLoad();
249 for (
auto &
MBB : MF) {
253 auto NMI = std::next(
MI);
254 switch (
MI->getOpcode()) {
256 if (State.hasBase()) {
263 Mask =
MI->getOperand(1).getImm();
264 Reg =
MI->getOperand(0).getReg();
269 Mask =
MI->getOperand(2).getImm();
270 Reg =
MI->getOperand(1).getReg();
271 Offset =
MI->getOperand(0).getImm();
275 Mask =
MI->getOperand(0).getImm();
276 Reg =
MI->getOperand(1).getReg();
281 Mask =
MI->getOperand(0).getImm();
282 Reg =
MI->getOperand(2).getReg();
283 Offset =
MI->getOperand(1).getImm();
290 if (State.hasBase()) {
300char M68kCollapseMOVEM::ID = 0;
307 return new M68kCollapseMOVEM();
static bool isLoad(int Opcode)
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
const HexagonInstrInfo * TII
This file contains the M68k declaration of TargetFrameLowering class.
This file contains the M68k implementation of the TargetInstrInfo class.
This file declares the M68k specific subclass of MachineFunctionInfo.
This file declares the M68k specific subclass of TargetSubtargetInfo.
This file contains the entry points for global functions defined in the M68k target library,...
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass class - This class is used to implement most global optimizations.
const M68kInstrInfo * getInstrInfo() const override
const M68kRegisterInfo * getRegisterInfo() const override
const M68kFrameLowering * getFrameLowering() const override
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createM68kCollapseMOVEMPass()
Finds sequential MOVEM instruction and collapse them into a single one.