36#define GET_INSTRMAP_INFO
37#include "LanaiGenInstrInfo.inc"
39#define DEBUG_TYPE "lanai-mem-alu-combiner"
41STATISTIC(NumLdStAluCombined,
"Number of memory and ALU instructions combined");
57 StringRef getPassName()
const override {
58 return "Lanai load / store optimization pass";
61 bool runOnMachineFunction(MachineFunction &
F)
override;
63 MachineFunctionProperties getRequiredProperties()
const override {
64 return MachineFunctionProperties().setNoVRegs();
68 MbbIterator findClosestSuitableAluInstr(MachineBasicBlock *BB,
69 const MbbIterator &MemInstr,
71 void insertMergedInstruction(MachineBasicBlock *BB,
72 const MbbIterator &MemInstr,
73 const MbbIterator &AluInstr,
bool Before);
74 bool combineMemAluInBasicBlock(MachineBasicBlock *BB);
78 const TargetInstrInfo *TII;
82char LanaiMemAluCombiner::ID = 0;
85 "Lanai memory ALU combiner pass",
false,
false)
88bool isSpls(
uint16_t Opcode) {
return Lanai::splsIdempotent(Opcode) == Opcode; }
93unsigned mergedOpcode(
unsigned OldOpcode,
bool ImmediateOffset) {
103 return Lanai::LDHs_RI;
104 return Lanai::LDHs_RR;
108 return Lanai::LDHz_RI;
109 return Lanai::LDHz_RR;
113 return Lanai::LDBs_RI;
114 return Lanai::LDBs_RR;
118 return Lanai::LDBz_RI;
119 return Lanai::LDBz_RR;
128 return Lanai::STB_RI;
129 return Lanai::STB_RR;
133 return Lanai::STH_RI;
134 return Lanai::STH_RR;
143 if (!
MI.hasOneMemOperand())
148 if (mergedOpcode(
MI.getOpcode(),
false) == 0)
178 return ((
Op.isReg() &&
Op.getReg() == Lanai::R0) ||
179 (
Op.isImm() &&
Op.getImm() == 0));
185 Mop != Instr->operands_end(); ++Mop) {
186 if (isSameOperand(*Mop, *
Reg))
197 case Lanai::ADD_I_LO:
200 case Lanai::SUB_I_LO:
203 case Lanai::AND_I_LO:
209 case Lanai::XOR_I_LO:
230 const MbbIterator &MemInstr,
231 const MbbIterator &AluInstr,
241 "Unsupported operand type in merge");
244 LPAC::AluCode AluOpcode = mergedAluCode(AluInstr->getOpcode());
245 unsigned NewOpc = mergedOpcode(MemInstr->getOpcode(), AluOffset.
isImm());
248 assert(NewOpc != 0 &&
"Unknown merged node opcode");
252 BuildMI(*BB, MemInstr, MemInstr->getDebugLoc(),
TII->get(NewOpc));
257 if (AluOffset.
isReg())
259 else if (AluOffset.
isImm())
267 if (Before || !isZeroOperand(MemOffset))
273 InstrBuilder.
setMemRefs(MemInstr->memoperands());
278bool isSuitableAluInstr(
bool IsSpls,
const MbbIterator &AluIter,
282 if (AluIter->getNumOperands() != 3)
291 if (!isSameOperand(Dest,
Base) || !isSameOperand(Dest, Op1))
297 if (AluIter->getOpcode() != Lanai::ADD_I_LO)
311 }
else if (Op2.
isReg()) {
322MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(
326 bool IsSpls = isSpls(MemInstr->getOpcode());
328 MbbIterator
First = MemInstr;
338 if (
First->isDebugInstr())
360 MbbIterator MBBIter = BB->
begin(), End = BB->
end();
361 while (MBBIter != End) {
362 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);
366 unsigned int DestReg = MBBIter->getOperand(0).
getReg(),
367 BaseReg = MBBIter->getOperand(1).getReg();
368 assert(AluOperand.
isImm() &&
"Unexpected memory operator type");
374 for (
int Inc = 0; Inc <= 1; ++Inc) {
375 MbbIterator AluIter =
376 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);
377 if (AluIter != MBBIter) {
378 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);
380 ++NumLdStAluCombined;
386 BB->
erase(MBBIter++);
415 return new LanaiMemAluCombiner();
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)
FunctionPass class - This class is used to implement most global optimizations.
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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register 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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
FunctionPass * createLanaiMemAluCombinerPass()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
DWARFExpression::Operation Op