38#define GET_INSTRMAP_INFO
39#include "LanaiGenInstrInfo.inc"
41#define DEBUG_TYPE "lanai-mem-alu-combiner"
43STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
49class LanaiMemAluCombinerImpl {
55 const MbbIterator &MemInstr,
58 const MbbIterator &MemInstr,
59 const MbbIterator &AluInstr,
bool Before);
70 explicit LanaiMemAluCombinerLegacy() : MachineFunctionPass(ID) {}
72 StringRef getPassName()
const override {
73 return "Lanai load / store optimization pass";
76 MachineFunctionProperties getRequiredProperties()
const override {
77 return MachineFunctionProperties().setNoVRegs();
84char LanaiMemAluCombinerLegacy::ID = 0;
87 "Lanai memory ALU combiner pass",
false,
false)
90bool isSpls(
uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
95unsigned mergedOpcode(
unsigned OldOpcode,
bool ImmediateOffset) {
100 return Lanai::LDW_RI;
101 return Lanai::LDW_RR;
105 return Lanai::LDHs_RI;
106 return Lanai::LDHs_RR;
110 return Lanai::LDHz_RI;
111 return Lanai::LDHz_RR;
115 return Lanai::LDBs_RI;
116 return Lanai::LDBs_RR;
120 return Lanai::LDBz_RI;
121 return Lanai::LDBz_RR;
130 return Lanai::STB_RI;
131 return Lanai::STB_RR;
135 return Lanai::STH_RI;
136 return Lanai::STH_RR;
145 if (!
MI.hasOneMemOperand())
150 if (mergedOpcode(
MI.getOpcode(),
false) == 0)
180 return ((
Op.isReg() &&
Op.getReg() == Lanai::R0) ||
181 (
Op.isImm() &&
Op.getImm() == 0));
187 Mop != Instr->operands_end(); ++Mop) {
188 if (isSameOperand(*Mop, *
Reg))
199 case Lanai::ADD_I_LO:
202 case Lanai::SUB_I_LO:
205 case Lanai::AND_I_LO:
211 case Lanai::XOR_I_LO:
231void LanaiMemAluCombinerImpl::insertMergedInstruction(
233 const MbbIterator &AluInstr,
bool Before) {
242 "Unsupported operand type in merge");
245 LPAC::AluCode AluOpcode = mergedAluCode(AluInstr->getOpcode());
246 unsigned NewOpc = mergedOpcode(MemInstr->getOpcode(), AluOffset.
isImm());
249 assert(NewOpc != 0 &&
"Unknown merged node opcode");
253 BuildMI(*BB, MemInstr, MemInstr->getDebugLoc(),
TII->get(NewOpc));
258 if (AluOffset.
isReg())
260 else if (AluOffset.
isImm())
268 if (Before || !isZeroOperand(MemOffset))
274 InstrBuilder.
setMemRefs(MemInstr->memoperands());
279bool isSuitableAluInstr(
bool IsSpls,
const MbbIterator &AluIter,
283 if (AluIter->getNumOperands() != 3)
292 if (!isSameOperand(Dest,
Base) || !isSameOperand(Dest, Op1))
298 if (AluIter->getOpcode() != Lanai::ADD_I_LO)
312 }
else if (Op2.
isReg()) {
323MbbIterator LanaiMemAluCombinerImpl::findClosestSuitableAluInstr(
327 bool IsSpls = isSpls(MemInstr->getOpcode());
329 MbbIterator
First = MemInstr;
339 if (
First->isDebugInstr())
361 MbbIterator MBBIter = BB->
begin(),
End = BB->
end();
362 while (MBBIter !=
End) {
363 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);
367 unsigned int DestReg = MBBIter->getOperand(0).
getReg(),
368 BaseReg = MBBIter->getOperand(1).getReg();
369 assert(AluOperand.
isImm() &&
"Unexpected memory operator type");
375 for (
int Inc = 0; Inc <= 1; ++Inc) {
376 MbbIterator AluIter =
377 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);
378 if (AluIter != MBBIter) {
379 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);
381 ++NumLdStAluCombined;
387 BB->
erase(MBBIter++);
403bool LanaiMemAluCombinerImpl::runOnMachineFunction(
MachineFunction &MF) {
405 if (!STI.
getCLOpts().enable_mem_alu_combiner)
417 return new LanaiMemAluCombinerLegacy();
420bool LanaiMemAluCombinerLegacy::runOnMachineFunction(
MachineFunction &MF) {
421 LanaiMemAluCombinerImpl Impl;
422 return Impl.runOnMachineFunction(MF);
428 LanaiMemAluCombinerImpl Impl;
429 return Impl.runOnMachineFunction(MF)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
#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)
const LanaiOptions & getCLOpts() const
const LanaiInstrInfo * getInstrInfo() const override
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)
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
@ End
Run the machine verifier once, at the end of the pipeline.