35#define GET_INSTRMAP_INFO
36#include "LanaiGenInstrInfo.inc"
38#define DEBUG_TYPE "lanai-mem-alu-combiner"
40STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
63 return "Lanai load / store optimization pass";
70 MachineFunctionProperties::Property::NoVRegs);
75 const MbbIterator &MemInstr,
78 const MbbIterator &MemInstr,
79 const MbbIterator &AluInstr,
bool Before);
88char LanaiMemAluCombiner::ID = 0;
91 "Lanai memory ALU combiner pass",
false,
false)
94bool isSpls(
uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
99unsigned mergedOpcode(
unsigned OldOpcode,
bool ImmediateOffset) {
104 return Lanai::LDW_RI;
105 return Lanai::LDW_RR;
109 return Lanai::LDHs_RI;
110 return Lanai::LDHs_RR;
114 return Lanai::LDHz_RI;
115 return Lanai::LDHz_RR;
119 return Lanai::LDBs_RI;
120 return Lanai::LDBs_RR;
124 return Lanai::LDBz_RI;
125 return Lanai::LDBz_RR;
134 return Lanai::STB_RI;
135 return Lanai::STB_RR;
139 return Lanai::STH_RI;
140 return Lanai::STH_RR;
149 if (!
MI.hasOneMemOperand())
154 if (mergedOpcode(
MI.getOpcode(),
false) == 0)
184 return ((
Op.isReg() &&
Op.getReg() == Lanai::R0) ||
185 (
Op.isImm() &&
Op.getImm() == 0));
189bool InstrUsesReg(
const MbbIterator &Instr,
const MachineOperand *Reg) {
191 Mop != Instr->operands_end(); ++Mop) {
192 if (isSameOperand(*Mop, *Reg))
203 case Lanai::ADD_I_LO:
206 case Lanai::SUB_I_LO:
209 case Lanai::AND_I_LO:
215 case Lanai::XOR_I_LO:
236 const MbbIterator &MemInstr,
237 const MbbIterator &AluInstr,
247 "Unsupported operand type in merge");
250 LPAC::AluCode AluOpcode = mergedAluCode(AluInstr->getOpcode());
251 unsigned NewOpc = mergedOpcode(MemInstr->getOpcode(), AluOffset.
isImm());
254 assert(NewOpc != 0 &&
"Unknown merged node opcode");
258 BuildMI(*BB, MemInstr, MemInstr->getDebugLoc(),
TII->get(NewOpc));
263 if (AluOffset.
isReg())
265 else if (AluOffset.
isImm())
273 if (
Before || !isZeroOperand(MemOffset))
279 InstrBuilder.
setMemRefs(MemInstr->memoperands());
284bool isSuitableAluInstr(
bool IsSpls,
const MbbIterator &AluIter,
288 if (AluIter->getNumOperands() != 3)
297 if (!isSameOperand(Dest,
Base) || !isSameOperand(Dest, Op1))
303 if (AluIter->getOpcode() != Lanai::ADD_I_LO)
313 ((IsSpls && isInt<10>(Op2.
getImm())) ||
314 (!IsSpls && isInt<16>(Op2.
getImm())))) ||
317 }
else if (Op2.
isReg()) {
328MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(
332 bool IsSpls = isSpls(MemInstr->getOpcode());
334 MbbIterator
First = MemInstr;
344 if (
First->isDebugInstr())
366 MbbIterator MBBIter = BB->
begin(),
End = BB->
end();
367 while (MBBIter !=
End) {
368 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);
372 unsigned int DestReg = MBBIter->getOperand(0).
getReg(),
373 BaseReg = MBBIter->getOperand(1).getReg();
374 assert(AluOperand.
isImm() &&
"Unexpected memory operator type");
380 for (
int Inc = 0; Inc <= 1; ++Inc) {
381 MbbIterator AluIter =
382 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);
383 if (AluIter != MBBIter) {
384 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);
386 ++NumLdStAluCombined;
392 BB->
erase(MBBIter++);
421 return new LanaiMemAluCombiner();
const HexagonInstrInfo * TII
static llvm::cl::opt< bool > DisableMemAluCombiner("disable-lanai-mem-alu-combiner", llvm::cl::init(false), llvm::cl::desc("Do not combine ALU and memory operators"), llvm::cl::Hidden)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
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...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
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.
Representation of each machine instruction.
A description of a memory reference used in the backend.
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_Register
Register operand.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static unsigned makePostOp(unsigned AluOp)
static unsigned makePreOp(unsigned AluOp)
static bool modifiesOp(unsigned AluOp)
initializer< Ty > init(const Ty &Val)
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 * createLanaiMemAluCombinerPass()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
void initializeLanaiMemAluCombinerPass(PassRegistry &)