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());
285 bool 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)
307 if (Offset.
isReg() && Offset.
getReg() == Lanai::R0)
310 if (Offset.
isImm() &&
314 ((IsSpls && isInt<10>(Op2.
getImm())) ||
318 }
else if (Op2.
isReg()) {
329 MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(
333 bool IsSpls = isSpls(MemInstr->getOpcode());
335 MbbIterator First = MemInstr;
336 MbbIterator Last = Decrement ? BB->
begin() : BB->
end();
338 while (First != Last) {
339 Decrement ? --First : ++First;
345 if (First->isDebugInstr())
348 if (isSuitableAluInstr(IsSpls, First, *Base, *Offset)) {
354 if (InstrUsesReg(First, Base))
356 if (Offset->
isReg() && InstrUsesReg(First, Offset))
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++);
415 for (MfIterator MFI = MF.
begin(); MFI != MF.
end(); ++MFI) {
416 Modified |= combineMemAluInBasicBlock(&*MFI);
423 return new LanaiMemAluCombiner();
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand *> MMOs) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
static bool modifiesOp(unsigned AluOp)
void initializeLanaiMemAluCombinerPass(PassRegistry &)
unsigned getReg() const
getReg - Returns the register number.
constexpr bool isInt< 16 >(int64_t x)
STATISTIC(NumFunctions, "Total number of functions")
INITIALIZE_PASS(LanaiMemAluCombiner, DEBUG_TYPE, "Lanai memory ALU combiner pass", false, false) namespace
FunctionPass * createLanaiMemAluCombinerPass()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
static unsigned makePostOp(unsigned AluOp)
A description of a memory reference used in the backend.
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...
const HexagonInstrInfo * TII
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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)
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
MachineOperand class - Representation of each machine instruction operand.
static unsigned makePreOp(unsigned AluOp)
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
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...
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Properties which a MachineFunction may have at a given point in time.