36#define GET_INSTRMAP_INFO
37#include "LanaiGenInstrInfo.inc"
39#define DEBUG_TYPE "lanai-mem-alu-combiner"
41STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
64 return "Lanai load / store optimization pass";
71 MachineFunctionProperties::Property::NoVRegs);
76 const MbbIterator &MemInstr,
79 const MbbIterator &MemInstr,
80 const MbbIterator &AluInstr,
bool Before);
89char LanaiMemAluCombiner::ID = 0;
92 "Lanai memory ALU combiner pass",
false,
false)
95bool isSpls(
uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
100unsigned mergedOpcode(
unsigned OldOpcode,
bool ImmediateOffset) {
105 return Lanai::LDW_RI;
106 return Lanai::LDW_RR;
110 return Lanai::LDHs_RI;
111 return Lanai::LDHs_RR;
115 return Lanai::LDHz_RI;
116 return Lanai::LDHz_RR;
120 return Lanai::LDBs_RI;
121 return Lanai::LDBs_RR;
125 return Lanai::LDBz_RI;
126 return Lanai::LDBz_RR;
135 return Lanai::STB_RI;
136 return Lanai::STB_RR;
140 return Lanai::STH_RI;
141 return Lanai::STH_RR;
150 if (!
MI.hasOneMemOperand())
155 if (mergedOpcode(
MI.getOpcode(),
false) == 0)
185 return ((
Op.isReg() &&
Op.getReg() == Lanai::R0) ||
186 (
Op.isImm() &&
Op.getImm() == 0));
190bool InstrUsesReg(
const MbbIterator &Instr,
const MachineOperand *Reg) {
192 Mop != Instr->operands_end(); ++Mop) {
193 if (isSameOperand(*Mop, *Reg))
204 case Lanai::ADD_I_LO:
207 case Lanai::SUB_I_LO:
210 case Lanai::AND_I_LO:
216 case Lanai::XOR_I_LO:
237 const MbbIterator &MemInstr,
238 const MbbIterator &AluInstr,
248 "Unsupported operand type in merge");
251 LPAC::AluCode AluOpcode = mergedAluCode(AluInstr->getOpcode());
252 unsigned NewOpc = mergedOpcode(MemInstr->getOpcode(), AluOffset.
isImm());
255 assert(NewOpc != 0 &&
"Unknown merged node opcode");
259 BuildMI(*BB, MemInstr, MemInstr->getDebugLoc(),
TII->get(NewOpc));
264 if (AluOffset.
isReg())
266 else if (AluOffset.
isImm())
274 if (
Before || !isZeroOperand(MemOffset))
280 InstrBuilder.
setMemRefs(MemInstr->memoperands());
285bool isSuitableAluInstr(
bool IsSpls,
const MbbIterator &AluIter,
289 if (AluIter->getNumOperands() != 3)
298 if (!isSameOperand(Dest,
Base) || !isSameOperand(Dest, Op1))
304 if (AluIter->getOpcode() != Lanai::ADD_I_LO)
314 ((IsSpls && isInt<10>(Op2.
getImm())) ||
315 (!IsSpls && isInt<16>(Op2.
getImm())))) ||
318 }
else if (Op2.
isReg()) {
329MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(
333 bool IsSpls = isSpls(MemInstr->getOpcode());
335 MbbIterator
First = MemInstr;
345 if (
First->isDebugInstr())
367 MbbIterator MBBIter = BB->
begin(),
End = BB->
end();
368 while (MBBIter !=
End) {
369 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);
373 unsigned int DestReg = MBBIter->getOperand(0).
getReg(),
374 BaseReg = MBBIter->getOperand(1).getReg();
375 assert(AluOperand.
isImm() &&
"Unexpected memory operator type");
381 for (
int Inc = 0; Inc <= 1; ++Inc) {
382 MbbIterator AluIter =
383 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);
384 if (AluIter != MBBIter) {
385 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);
387 ++NumLdStAluCombined;
393 BB->
erase(MBBIter++);
422 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 SmallSet class.
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 &)