37 #define GET_INSTRMAP_INFO
38 #include "LanaiGenInstrInfo.inc"
40 #define DEBUG_TYPE "lanai-mem-alu-combiner"
42 STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
65 return "Lanai load / store optimization pass";
77 const MbbIterator &MemInstr,
80 const MbbIterator &MemInstr,
81 const MbbIterator &AluInstr,
bool Before);
93 "Lanai memory ALU combiner pass",
false,
false)
96 bool isSpls(uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
101 unsigned mergedOpcode(
unsigned OldOpcode,
bool ImmediateOffset) {
106 return Lanai::LDW_RI;
107 return Lanai::LDW_RR;
111 return Lanai::LDHs_RI;
112 return Lanai::LDHs_RR;
116 return Lanai::LDHz_RI;
117 return Lanai::LDHz_RR;
121 return Lanai::LDBs_RI;
122 return Lanai::LDBs_RR;
126 return Lanai::LDBz_RI;
127 return Lanai::LDBz_RR;
136 return Lanai::STB_RI;
137 return Lanai::STB_RR;
141 return Lanai::STH_RI;
142 return Lanai::STH_RR;
156 if (mergedOpcode(MI.
getOpcode(),
false) == 0)
185 return ((Op.
isReg() && Op.
getReg() == Lanai::R0) ||
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_begin(),
281 MemInstr->memoperands_end());
286 bool isSuitableAluInstr(
bool IsSpls,
const MbbIterator &AluIter,
290 if (AluIter->getNumOperands() != 3)
299 if (!isSameOperand(Dest, Base) || !isSameOperand(Dest, Op1))
305 if (AluIter->getOpcode() != Lanai::ADD_I_LO)
308 if (Offset.
isReg() && Offset.
getReg() == Lanai::R0)
311 if (Offset.
isImm() &&
315 ((IsSpls && isInt<10>(Op2.
getImm())) ||
319 }
else if (Op2.
isReg()) {
330 MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(
334 bool IsSpls = isSpls(MemInstr->getOpcode());
336 MbbIterator First = MemInstr;
337 MbbIterator Last = Decrement ? BB->
begin() : BB->
end();
339 while (First != Last) {
340 Decrement ? --First : ++First;
346 if (First->isDebugValue())
349 if (isSuitableAluInstr(IsSpls, First, *Base, *Offset)) {
355 if (InstrUsesReg(First, Base))
357 if (Offset->
isReg() && InstrUsesReg(First, Offset))
366 bool Modified =
false;
368 MbbIterator MBBIter = BB->
begin(),
End = BB->
end();
369 while (MBBIter !=
End) {
370 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);
374 unsigned int DestReg = MBBIter->getOperand(0).
getReg(),
375 BaseReg = MBBIter->getOperand(1).getReg();
376 assert(AluOperand.
isImm() &&
"Unexpected memory operator type");
382 for (
int Inc = 0; Inc <= 1; ++Inc) {
383 MbbIterator AluIter =
384 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);
385 if (AluIter != MBBIter) {
386 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);
388 ++NumLdStAluCombined;
394 BB->
erase(MBBIter++);
415 bool Modified =
false;
416 for (MfIterator MFI = MF.
begin(); MFI != MF.
end(); ++MFI) {
417 Modified |= combineMemAluInBasicBlock(&*MFI);
424 return new LanaiMemAluCombiner();
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
static bool modifiesOp(unsigned AluOp)
void initializeLanaiMemAluCombinerPass(PassRegistry &)
constexpr bool isInt< 16 >(int64_t x)
FunctionPass * createLanaiMemAluCombinerPass()
static unsigned makePostOp(unsigned AluOp)
A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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)
unsigned getKillRegState(bool B)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getDefRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
This file declares the machine register scavenger class.
INITIALIZE_PASS(LanaiMemAluCombiner, DEBUG_TYPE,"Lanai memory ALU combiner pass", false, false) namespace
static const unsigned End
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
FunctionPass class - This class is used to implement most global optimizations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
static unsigned makePreOp(unsigned AluOp)
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
Assign this MachineInstr's memory reference descriptor list.
Properties which a MachineFunction may have at a given point in time.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.