Go to the documentation of this file.
29 #define DEBUG_TYPE "mlx-expansion"
36 STATISTIC(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);
75 void MLxExpansion::clearStack() {
76 std::fill(LastMIs, LastMIs + 4,
nullptr);
100 if (
Reg.isVirtual()) {
106 if (
Reg.isVirtual()) {
142 if (
Reg.isPhysical())
164 if (
Reg.isVirtual()) {
170 if (
Reg.isVirtual()) {
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();
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 getOpcode() const
Return the opcode number for this descriptor.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder & UseMI
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual const TargetInstrInfo * getInstrInfo() const
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...
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
FunctionPass * createMLxExpansionPass()
unsigned getDeadRegState(bool B)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
unsigned const TargetRegisterInfo * TRI
bool isInsertSubreg() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getDefRegState(bool B)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isFpMulInstruction(unsigned Opcode)
const MachineOperand & getOperand(unsigned i) const
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
const HexagonInstrInfo * TII
Describe properties that are true of each instruction in the target description file.
STATISTIC(NumFunctions, "Total number of functions")
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
initializer< Ty > init(const Ty &Val)
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.
MachineBasicBlock * getMBB() const
StringRef - Represent a constant reference to a string, i.e.
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
static cl::opt< bool > ForceExapnd("expand-all-fp-mlx", cl::init(false), cl::Hidden)
static cl::opt< unsigned > ExpandLimit("expand-limit", cl::init(~0U), cl::Hidden)
const MachineBasicBlock * getParent() const
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
Function & getFunction()
Return the LLVM function that this machine code represents.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
static bool hasRAWHazard(MachineInstr *DefMI, MachineInstr *MI, const TargetRegisterInfo &TRI)
unsigned getKillRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
MachineInstrBuilder MachineInstrBuilder & DefMI
unsigned getNumOperands() const
Retuns the total number of operands.
FunctionPass class - This class is used to implement most global optimizations.