32#define DEBUG_TYPE "M68k-collapse-movem"
36enum UpdateType { Ascending, Descending, Intermixed };
50 enum class AccessTy {
None, Load, Store };
55 : Begin(
nullptr), End(
nullptr),
Base(0), Start(INT_MIN), Stop(INT_MAX),
56 Mask(0), Access(AccessTy::None) {}
68 bool hasBase()
const {
return Base != 0; }
70 unsigned getBase()
const {
85 unsigned getMask()
const {
return Mask; }
87 void setBase(
int Value) {
93 UpdateType classifyUpdateByMask(
unsigned NewMask)
const {
94 assert(NewMask &&
"Mask needs to select at least one register");
98 }
else if (NewMask < Mask) {
105 bool update(
int O,
int M) {
106 UpdateType
Type = classifyUpdateByMask(M);
107 if (
Type == Intermixed)
109 if (Start == INT_MIN) {
113 }
else if (
Type == Descending && O == Start - 4) {
117 }
else if (
Type == Ascending && O == Stop + 4) {
126 int getFinalOffset()
const {
129 "MOVEM in control mode should increment the address in each iteration");
133 bool updateMask(
unsigned Value) {
134 assert(isUInt<16>(
Value) &&
"Mask must fit 16 bit");
136 "This is weird, there should be no intersections");
141 void setLoad() { Access = AccessTy::Load; }
142 void setStore() { Access = AccessTy::Store; }
144 bool isLoad()
const {
return Access == AccessTy::Load; }
145 bool isStore()
const {
return Access == AccessTy::Store; }
169 auto MI = State.begin();
170 auto End = State.end();
174 if (std::next(
MI) == End) {
175 State = MOVEMState();
181 auto Next = std::next(
MI);
187 if (State.isLoad()) {
190 .
addImm(State.getFinalOffset())
194 .
addImm(State.getFinalOffset())
199 State = MOVEMState();
203 MOVEMState &State,
unsigned Mask,
int Offset,
unsigned Reg,
204 bool IsStore =
false) {
205 if (State.hasBase()) {
208 MOVEMState Temp = State;
209 if (State.isStore() == IsStore && State.getBase() == Reg &&
210 State.update(
Offset, Mask)) {
218 return ProcessMI(
MBB,
MI, State, Mask,
Offset, Reg, IsStore);
221 }
else if (Reg ==
TRI->getStackRegister() ||
222 Reg ==
TRI->getBaseRegister() ||
226 State.update(
Offset, Mask);
227 IsStore ? State.setStore() : State.setLoad();
248 for (
auto &
MBB : MF) {
252 auto NMI = std::next(
MI);
253 switch (
MI->getOpcode()) {
255 if (State.hasBase()) {
262 Mask =
MI->getOperand(1).getImm();
263 Reg =
MI->getOperand(0).getReg();
268 Mask =
MI->getOperand(2).getImm();
269 Reg =
MI->getOperand(1).getReg();
270 Offset =
MI->getOperand(0).getImm();
274 Mask =
MI->getOperand(0).getImm();
275 Reg =
MI->getOperand(1).getReg();
280 Mask =
MI->getOperand(0).getImm();
281 Reg =
MI->getOperand(2).getReg();
282 Offset =
MI->getOperand(1).getImm();
289 if (State.hasBase()) {
301char M68kCollapseMOVEM::ID = 0;
306 return new M68kCollapseMOVEM();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool isLoad(int Opcode)
static bool isStore(int Opcode)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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
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.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringRef - Represent a constant reference to a string, i.e.
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.
constexpr std::nullopt_t None