39#define GET_INSTRMAP_INFO
40#include "LanaiGenInstrInfo.inc"
42#define DEBUG_TYPE "lanai-mem-alu-combiner"
44STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
55class LanaiMemAluCombinerImpl {
61 const MbbIterator &MemInstr,
64 const MbbIterator &MemInstr,
65 const MbbIterator &AluInstr,
bool Before);
76 explicit LanaiMemAluCombinerLegacy() : MachineFunctionPass(ID) {}
78 StringRef getPassName()
const override {
79 return "Lanai load / store optimization pass";
82 MachineFunctionProperties getRequiredProperties()
const override {
83 return MachineFunctionProperties().setNoVRegs();
86 bool runOnMachineFunction(MachineFunction &MF)
override;
90char LanaiMemAluCombinerLegacy::ID = 0;
93 "Lanai memory ALU combiner pass",
false,
false)
96bool isSpls(
uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
101unsigned 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;
151 if (!
MI.hasOneMemOperand())
156 if (mergedOpcode(
MI.getOpcode(),
false) == 0)
186 return ((
Op.isReg() &&
Op.getReg() == Lanai::R0) ||
187 (
Op.isImm() &&
Op.getImm() == 0));
193 Mop != Instr->operands_end(); ++Mop) {
194 if (isSameOperand(*Mop, *
Reg))
205 case Lanai::ADD_I_LO:
208 case Lanai::SUB_I_LO:
211 case Lanai::AND_I_LO:
217 case Lanai::XOR_I_LO:
237void LanaiMemAluCombinerImpl::insertMergedInstruction(
239 const MbbIterator &AluInstr,
bool Before) {
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)
318 }
else if (Op2.
isReg()) {
329MbbIterator LanaiMemAluCombinerImpl::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++);
409bool LanaiMemAluCombinerImpl::runOnMachineFunction(
MachineFunction &MF) {
422 return new LanaiMemAluCombinerLegacy();
425bool LanaiMemAluCombinerLegacy::runOnMachineFunction(
MachineFunction &MF) {
426 LanaiMemAluCombinerImpl Impl;
427 return Impl.runOnMachineFunction(MF);
433 LanaiMemAluCombinerImpl Impl;
434 return Impl.runOnMachineFunction(MF)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represents analyses that only rely on functions' control flow.
FunctionPass class - This class is used to implement most global optimizations.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
BasicBlockListType::iterator iterator
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
const MachineOperand * const_mop_iterator
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
TargetInstrInfo - Interface to description of machine instruction set.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
constexpr RegState getKillRegState(bool B)
FunctionPass * createLanaiMemAluCombinerLegacyPass()
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
constexpr RegState getDefRegState(bool B)
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
DWARFExpression::Operation Op