Go to the documentation of this file.
36 #define GET_INSTRMAP_INFO
37 #include "LanaiGenInstrInfo.inc"
39 #define DEBUG_TYPE "lanai-mem-alu-combiner"
41 STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
64 return "Lanai load / store optimization pass";
76 const MbbIterator &MemInstr,
79 const MbbIterator &MemInstr,
80 const MbbIterator &AluInstr,
bool Before);
92 "Lanai memory ALU combiner pass",
false,
false)
95 bool isSpls(
uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
100 unsigned 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));
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() &&
311 ((Offset.getImm() == 0 &&
314 ((IsSpls && isInt<10>(Op2.
getImm())) ||
316 Offset.getImm() == Op2.
getImm()))
318 }
else if (Op2.
isReg()) {
320 if (Offset.isReg() && Op2.
getReg() == Offset.getReg())
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) {
345 if (
First->isDebugInstr())
348 if (isSuitableAluInstr(IsSpls,
First, *
Base, *Offset)) {
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++);
422 return new LanaiMemAluCombiner();
@ MO_Immediate
Immediate operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
static bool modifiesOp(unsigned AluOp)
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...
A description of a memory reference used in the backend.
Properties which a MachineFunction may have at a given point in time.
@ MO_Register
Register operand.
unsigned getDefRegState(bool B)
TargetInstrInfo - Interface to description of machine instruction set.
INITIALIZE_PASS(LanaiMemAluCombiner, DEBUG_TYPE, "Lanai memory ALU combiner pass", false, false) namespace
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const HexagonInstrInfo * TII
into llvm powi allowing the code generator to produce balanced multiplication trees First
MachineOperand class - Representation of each machine instruction operand.
static unsigned makePreOp(unsigned AluOp)
MachineFunctionProperties & set(Property P)
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
STATISTIC(NumFunctions, "Total number of functions")
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.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
FunctionPass * createLanaiMemAluCombinerPass()
initializer< Ty > init(const Ty &Val)
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Register getReg() const
getReg - Returns the register number.
static unsigned makePostOp(unsigned AluOp)
StringRef - Represent a constant reference to a string, i.e.
void initializeLanaiMemAluCombinerPass(PassRegistry &)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr bool isInt< 16 >(int64_t x)
Iterator for intrusive lists based on ilist_node.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
unsigned getKillRegState(bool B)
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.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB