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) {
112 UpdateType
Type = classifyUpdateByMask(M);
113 if (
Type == Intermixed)
115 if (Start == INT_MIN) {
119 }
else if (
Type == Descending && O == Start - 4) {
123 }
else if (
Type == Ascending && O == Stop + 4) {
132 int getFinalOffset()
const {
135 "MOVEM in control mode should increment the address in each iteration");
139 bool updateMask(
unsigned Value) {
142 "This is weird, there should be no intersections");
147 void setLoad() {
Access = AccessTy::Load; }
148 void setStore() {
Access = AccessTy::Store; }
150 bool isLoad()
const {
return Access == AccessTy::Load; }
175 auto MI = State.begin();
176 auto End = State.end();
180 if (std::next(
MI) == End) {
181 State = MOVEMState();
187 auto Next = std::next(
MI);
193 if (State.isLoad()) {
196 .
addImm(State.getFinalOffset())
200 .
addImm(State.getFinalOffset())
205 State = MOVEMState();
209 MOVEMState &State,
unsigned Mask,
int Offset,
unsigned Reg,
210 bool IsStore =
false) {
211 if (State.hasBase()) {
214 MOVEMState Temp = State;
215 if (State.isStore() == IsStore && State.getBase() ==
Reg &&
216 State.update(
Offset, Mask)) {
227 }
else if (
Reg ==
TRI->getStackRegister() ||
228 Reg ==
TRI->getBaseRegister() ||
229 Reg ==
TRI->getFrameRegister(*
MBB.getParent())) {
232 State.update(
Offset, Mask);
233 IsStore ? State.setStore() : State.setLoad();
254 for (
auto &
MBB : MF) {
258 auto NMI = std::next(
MI);
259 switch (
MI->getOpcode()) {
261 if (State.hasBase()) {
268 Mask =
MI->getOperand(1).getImm();
269 Reg =
MI->getOperand(0).getReg();
274 Mask =
MI->getOperand(2).getImm();
275 Reg =
MI->getOperand(1).getReg();
276 Offset =
MI->getOperand(0).getImm();
280 Mask =
MI->getOperand(0).getImm();
281 Reg =
MI->getOperand(1).getReg();
286 Mask =
MI->getOperand(0).getImm();
287 Reg =
MI->getOperand(2).getReg();
288 Offset =
MI->getOperand(1).getImm();
295 if (State.hasBase()) {
305char M68kCollapseMOVEM::ID = 0;
312 return new M68kCollapseMOVEM();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isLoad(int Opcode)
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
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,...
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
FunctionAddr VTableAddr Next