Go to the documentation of this file.
32 #define DEBUG_TYPE "M68k-collapse-movem"
36 enum UpdateType { Ascending, Descending, Intermixed };
55 : Begin(
nullptr), End(
nullptr),
Base(0), Start(INT_MIN), Stop(INT_MAX),
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) {
136 "This is weird, there should be no intersections");
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()) {
298 StringRef getPassName()
const override {
return "M68k MOVEM collapser pass"; }
306 return new M68kCollapseMOVEM();
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Reg
All possible values of the reg field in the ModR/M byte.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
The instances of the Type class are immutable: once they are created, they are never changed.
const_iterator end(StringRef path)
Get end iterator over path.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const M68kRegisterInfo * getRegisterInfo() const override
unsigned const TargetRegisterInfo * TRI
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
const M68kInstrInfo * getInstrInfo() const override
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass * createM68kCollapseMOVEMPass()
Finds sequential MOVEM instruction and collapse them into a single one.
const HexagonInstrInfo * TII
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
constexpr bool isUInt< 16 >(uint64_t x)
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
const M68kFrameLowering * getFrameLowering() const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
static bool isStore(int Opcode)
StringRef - Represent a constant reference to a string, i.e.
static bool isLoad(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass class - This class is used to implement most global optimizations.
LLVM Value Representation.