32#define DEBUG_TYPE "m68k-collapse-movem"
33#define PASS_NAME "M68k MOVEM collapser pass"
37enum UpdateType { Ascending, Descending, Intermixed };
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 if (State.isLoad()) {
190 .
addImm(State.getFinalOffset())
194 .
addImm(State.getFinalOffset())
203 while (
MI != NewMI) {
204 auto Next = std::next(
MI);
210 State = MOVEMState();
214 MOVEMState &State,
unsigned Mask,
int Offset,
unsigned Reg,
215 bool IsStore =
false) {
216 if (State.hasBase()) {
219 MOVEMState Temp = State;
220 if (State.isStore() == IsStore && State.getBase() ==
Reg &&
221 State.update(
Offset, Mask)) {
232 }
else if (
Reg ==
TRI->getStackRegister() ||
233 Reg ==
TRI->getBaseRegister() ||
234 Reg ==
TRI->getFrameRegister(*
MBB.getParent())) {
237 State.update(
Offset, Mask);
238 IsStore ? State.setStore() : State.setLoad();
259 for (
auto &
MBB : MF) {
263 auto NMI = std::next(
MI);
264 switch (
MI->getOpcode()) {
266 if (State.hasBase()) {
273 Mask =
MI->getOperand(1).getImm();
274 Reg =
MI->getOperand(0).getReg();
279 Mask =
MI->getOperand(2).getImm();
280 Reg =
MI->getOperand(1).getReg();
281 Offset =
MI->getOperand(0).getImm();
285 Mask =
MI->getOperand(0).getImm();
286 Reg =
MI->getOperand(1).getReg();
291 Mask =
MI->getOperand(0).getImm();
292 Reg =
MI->getOperand(2).getReg();
293 Offset =
MI->getOperand(1).getImm();
300 if (State.hasBase()) {
310char M68kCollapseMOVEM::ID = 0;
317 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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
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.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next