29#define DEBUG_TYPE "mlx-expansion"
36STATISTIC(NumExpand,
"Number of fp MLA / MLS instructions expanded");
46 return "ARM MLA / MLS expansion pass";
68 unsigned MulOpc,
unsigned AddSubOpc,
69 bool NegAcc,
bool HasLane);
72 char MLxExpansion::ID = 0;
75void MLxExpansion::clearStack() {
76 std::fill(LastMIs, LastMIs + 4,
nullptr);
100 if (
Reg.isVirtual()) {
106 if (
Reg.isVirtual()) {
118 if (
Reg.isPhysical() || !
MRI->hasOneNonDBGUse(Reg))
128 if (
Reg.isPhysical() || !
MRI->hasOneNonDBGUse(Reg))
130 UseMI = &*
MRI->use_instr_nodbg_begin(Reg);
142 if (
Reg.isPhysical())
164 if (
Reg.isVirtual()) {
170 if (
Reg.isVirtual()) {
182bool MLxExpansion::hasRAWHazard(
unsigned Reg,
MachineInstr *
MI)
const {
189 if (Opcode == ARM::VMOVRS || Opcode == ARM::VMOVRRD)
192 return MI->readsRegister(Reg,
TRI);
227 IgnoreStall.insert(
DefMI);
237 if (IgnoreStall.count(
MI))
245 unsigned Limit1 = isLikeA9 ? 1 : 4;
246 unsigned Limit2 = isLikeA9 ? 1 : 4;
247 for (
unsigned i = 1; i <= 4; ++i) {
248 int Idx = ((int)MIIdx - i + 4) % 4;
270 unsigned MulOpc,
unsigned AddSubOpc,
271 bool NegAcc,
bool HasLane) {
273 bool DstDead =
MI->getOperand(0).isDead();
275 Register Src1Reg =
MI->getOperand(2).getReg();
276 Register Src2Reg =
MI->getOperand(3).getReg();
277 bool Src1Kill =
MI->getOperand(2).isKill();
278 bool Src2Kill =
MI->getOperand(3).isKill();
279 unsigned LaneImm = HasLane ?
MI->getOperand(4).getImm() : 0;
280 unsigned NextOp = HasLane ? 5 : 4;
282 Register PredReg =
MI->getOperand(++NextOp).getReg();
288 MRI->createVirtualRegister(
TII->getRegClass(MCID1, 0,
TRI, MF));
301 bool AccKill =
MRI->hasOneNonDBGUse(AccReg);
310 dbgs() <<
"Expanding: " << *
MI;
313 MII = std::prev(MII);
315 MII = std::prev(MII);
317 dbgs() <<
" " << MI1;
318 dbgs() <<
" " << MI2;
321 MI->eraseFromParent();
326 bool Changed =
false;
336 if (
MI->isPosition() ||
MI->isImplicitDef() ||
MI->isCopy())
340 if (
MI->isBarrier()) {
354 unsigned MulOpc, AddSubOpc;
355 bool NegAcc, HasLane;
357 MulOpc, AddSubOpc, NegAcc, HasLane) ||
361 ExpandFPMLxInstruction(
MBB,
MI, MulOpc, AddSubOpc, NegAcc, HasLane);
378 if (!STI->expandMLx())
391 return new MLxExpansion();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI, const TargetRegisterInfo &TRI)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
static cl::opt< unsigned > ExpandLimit("expand-limit", cl::init(~0U), cl::Hidden)
static bool isFpMulInstruction(unsigned Opcode)
static cl::opt< bool > ForceExapnd("expand-all-fp-mlx", cl::init(false), cl::Hidden)
unsigned const TargetRegisterInfo * TRI
This file defines the SmallPtrSet 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.
Describe properties that are true of each instruction in the target description file.
unsigned getOpcode() const
Return the opcode number for this descriptor.
reverse_iterator rbegin()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool isCopyLike() const
Return true if the instruction behaves like a copy.
unsigned getNumOperands() const
Retuns the total number of operands.
bool isInsertSubreg() const
const MachineOperand & getOperand(unsigned i) const
MachineBasicBlock * getMBB() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Reg
All possible values of the reg field in the ModR/M byte.
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.
unsigned getDeadRegState(bool B)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
FunctionPass * createMLxExpansionPass()