44 "disable-ppc-vsx-fma-mutation",
48#define DEBUG_TYPE "ppc-vsx-fma-mutate"
63 const PPCInstrInfo *TII;
66 bool processBlock(MachineBasicBlock &
MBB) {
70 const TargetRegisterInfo *
TRI = &TII->getRegisterInfo();
73 MachineInstr &
MI = *
I;
104 SlotIndex FMAIdx = LIS->getInstructionIndex(
MI);
106 VNInfo *AddendValNo =
107 LIS->getInterval(
MI.getOperand(1).getReg()).Query(FMAIdx).valueIn();
113 MachineInstr *AddendMI = LIS->getInstructionFromIndex(AddendValNo->
def);
117 if (!AddendMI || AddendMI->
getParent() !=
MI.getParent())
156 bool OtherUsers =
false, KillsAddendSrc =
false;
163 if (J->modifiesRegister(AddendSrcReg,
TRI) ||
164 J->killsRegister(AddendSrcReg,
TRI)) {
165 KillsAddendSrc =
true;
170 if (OtherUsers || KillsAddendSrc)
181 Register OldFMAReg =
MI.getOperand(0).getReg();
184 unsigned KilledProdOp = 0, OtherProdOp = 0;
187 if (LIS->getInterval(Reg2).Query(FMAIdx).isKill()
188 && Reg2 != OldFMAReg) {
191 }
else if (LIS->getInterval(Reg3).Query(FMAIdx).isKill()
192 && Reg3 != OldFMAReg) {
208 !LIS->getInterval(AddendSrcReg).liveAt(FMAIdx))
213 Register KilledProdReg =
MI.getOperand(KilledProdOp).getReg();
214 Register OtherProdReg =
MI.getOperand(OtherProdOp).getReg();
217 unsigned KilledProdSubReg =
MI.getOperand(KilledProdOp).getSubReg();
218 unsigned OtherProdSubReg =
MI.getOperand(OtherProdOp).getSubReg();
221 bool KilledProdRegKill =
MI.getOperand(KilledProdOp).isKill();
222 bool OtherProdRegKill =
MI.getOperand(OtherProdOp).isKill();
225 bool KilledProdRegUndef =
MI.getOperand(KilledProdOp).isUndef();
226 bool OtherProdRegUndef =
MI.getOperand(OtherProdOp).isUndef();
237 "Addend copy not tied to old FMA output!");
241 MI.getOperand(0).setReg(KilledProdReg);
242 MI.getOperand(1).setReg(KilledProdReg);
243 MI.getOperand(3).setReg(AddendSrcReg);
245 MI.getOperand(0).setSubReg(KilledProdSubReg);
246 MI.getOperand(1).setSubReg(KilledProdSubReg);
249 MI.getOperand(1).setIsKill(KilledProdRegKill);
250 MI.getOperand(3).setIsKill(AddRegKill);
252 MI.getOperand(1).setIsUndef(KilledProdRegUndef);
253 MI.getOperand(3).setIsUndef(AddRegUndef);
255 MI.setDesc(TII->get(AltOpc));
260 MI.getOperand(2).setReg(AddendSrcReg);
262 MI.getOperand(2).setIsKill(AddRegKill);
263 MI.getOperand(2).setIsUndef(AddRegUndef);
265 MI.getOperand(2).setReg(OtherProdReg);
266 MI.getOperand(2).setSubReg(OtherProdSubReg);
267 MI.getOperand(2).setIsKill(OtherProdRegKill);
268 MI.getOperand(2).setIsUndef(OtherProdRegUndef);
276 LiveInterval &FMAInt = LIS->getInterval(OldFMAReg);
280 MachineOperand &UseMO = *UI;
285 if (
UseMI == AddendMI)
292 LIS->removeInterval(KilledProdReg);
293 LiveInterval &NewFMAInt =
294 LIS->createAndComputeVirtRegInterval(KilledProdReg);
303 for (MCRegUnit Unit :
TRI->regunits(AddendSrcReg.
asMCReg())) {
304 LiveRange &AddendSrcRange = LIS->getRegUnit(Unit);
316 LIS->RemoveMachineInstrFromMaps(*AddendMI);
326 bool runOnMachineFunction(MachineFunction &MF)
override {
332 const PPCSubtarget &STI = MF.
getSubtarget<PPCSubtarget>();
336 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
352 void getAnalysisUsage(AnalysisUsage &AU)
const override {
357 AU.
addPreserved<MachineBlockFrequencyInfoWrapperPass>();
365 "PowerPC VSX FMA Mutation",
false,
false)
373char PPCVSXFMAMutate::ID = 0;
375 return new PPCVSXFMAMutate();
MachineInstrBuilder & UseMI
static const MachineInstrBuilder & AddSubReg(const MachineInstrBuilder &MIB, MCRegister Reg, unsigned SubIdx, RegState State, const TargetRegisterInfo *TRI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static cl::opt< bool > DisableVSXFMAMutate("disable-ppc-vsx-fma-mutation", cl::desc("Disable VSX FMA instruction mutation"), cl::init(true), cl::Hidden)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
SI Optimize VGPR LiveRange
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
FunctionPass class - This class is used to implement most global optimizations.
LLVM_ABI void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
LLVM_ABI std::pair< VNInfo *, bool > extendInBlock(ArrayRef< SlotIndex > Undefs, SlotIndex StartIdx, SlotIndex Kill)
Attempt to extend a value defined after StartIdx to include Use.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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 MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getSubReg() const
LLVM_ABI void substVirtReg(Register Reg, unsigned SubIdx, const TargetRegisterInfo &)
substVirtReg - Substitute the current register with the virtual subregister Reg:SubReg.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
reg_nodbg_iterator reg_nodbg_begin(Register RegNo) const
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
static reg_nodbg_iterator reg_nodbg_end()
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
const PPCInstrInfo * getInstrInfo() const override
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex def
The index of the defining instruction.
Define some predicates that are used for node matching.
int32_t getAltVSXFMAOpcode(uint32_t Opcode)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createPPCVSXFMAMutatePass()
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.