41 "disable-ppc-vsx-fma-mutation",
45#define DEBUG_TYPE "ppc-vsx-fma-mutate"
60 const PPCInstrInfo *TII;
63 bool processBlock(MachineBasicBlock &
MBB) {
67 const TargetRegisterInfo *
TRI = &TII->getRegisterInfo();
70 MachineInstr &
MI = *
I;
101 SlotIndex FMAIdx = LIS->getInstructionIndex(
MI);
103 VNInfo *AddendValNo =
104 LIS->getInterval(
MI.getOperand(1).getReg()).Query(FMAIdx).valueIn();
110 MachineInstr *AddendMI = LIS->getInstructionFromIndex(AddendValNo->
def);
114 if (!AddendMI || AddendMI->
getParent() !=
MI.getParent())
125 MRI.getRegClass(AddendSrcReg))
131 ->contains(AddendSrcReg))
153 bool OtherUsers =
false, KillsAddendSrc =
false;
160 if (J->modifiesRegister(AddendSrcReg,
TRI) ||
161 J->killsRegister(AddendSrcReg,
TRI)) {
162 KillsAddendSrc =
true;
167 if (OtherUsers || KillsAddendSrc)
178 Register OldFMAReg =
MI.getOperand(0).getReg();
181 unsigned KilledProdOp = 0, OtherProdOp = 0;
184 if (LIS->getInterval(Reg2).Query(FMAIdx).isKill()
185 && Reg2 != OldFMAReg) {
188 }
else if (LIS->getInterval(Reg3).Query(FMAIdx).isKill()
189 && Reg3 != OldFMAReg) {
205 !LIS->getInterval(AddendSrcReg).liveAt(FMAIdx))
210 Register KilledProdReg =
MI.getOperand(KilledProdOp).getReg();
211 Register OtherProdReg =
MI.getOperand(OtherProdOp).getReg();
214 unsigned KilledProdSubReg =
MI.getOperand(KilledProdOp).getSubReg();
215 unsigned OtherProdSubReg =
MI.getOperand(OtherProdOp).getSubReg();
218 bool KilledProdRegKill =
MI.getOperand(KilledProdOp).isKill();
219 bool OtherProdRegKill =
MI.getOperand(OtherProdOp).isKill();
222 bool KilledProdRegUndef =
MI.getOperand(KilledProdOp).isUndef();
223 bool OtherProdRegUndef =
MI.getOperand(OtherProdOp).isUndef();
229 if (!
MRI.constrainRegClass(KilledProdReg,
230 MRI.getRegClass(OldFMAReg)))
234 "Addend copy not tied to old FMA output!");
238 MI.getOperand(0).setReg(KilledProdReg);
239 MI.getOperand(1).setReg(KilledProdReg);
240 MI.getOperand(3).setReg(AddendSrcReg);
242 MI.getOperand(0).setSubReg(KilledProdSubReg);
243 MI.getOperand(1).setSubReg(KilledProdSubReg);
246 MI.getOperand(1).setIsKill(KilledProdRegKill);
247 MI.getOperand(3).setIsKill(AddRegKill);
249 MI.getOperand(1).setIsUndef(KilledProdRegUndef);
250 MI.getOperand(3).setIsUndef(AddRegUndef);
252 MI.setDesc(TII->get(AltOpc));
257 MI.getOperand(2).setReg(AddendSrcReg);
259 MI.getOperand(2).setIsKill(AddRegKill);
260 MI.getOperand(2).setIsUndef(AddRegUndef);
262 MI.getOperand(2).setReg(OtherProdReg);
263 MI.getOperand(2).setSubReg(OtherProdSubReg);
264 MI.getOperand(2).setIsKill(OtherProdRegKill);
265 MI.getOperand(2).setIsUndef(OtherProdRegUndef);
273 LiveInterval &FMAInt = LIS->getInterval(OldFMAReg);
275 for (
auto UI =
MRI.reg_nodbg_begin(OldFMAReg), UE =
MRI.reg_nodbg_end();
277 MachineOperand &UseMO = *UI;
282 if (
UseMI == AddendMI)
289 LIS->removeInterval(KilledProdReg);
290 LiveInterval &NewFMAInt =
291 LIS->createAndComputeVirtRegInterval(KilledProdReg);
301 LiveRange &AddendSrcRange = LIS->getRegUnit(Unit);
313 LIS->RemoveMachineInstrFromMaps(*AddendMI);
323 bool runOnMachineFunction(MachineFunction &MF)
override {
329 const PPCSubtarget &STI = MF.
getSubtarget<PPCSubtarget>();
333 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
349 void getAnalysisUsage(AnalysisUsage &AU)
const override {
362 "PowerPC VSX FMA Mutation",
false,
false)
371char PPCVSXFMAMutate::
ID = 0;
373 return new PPCVSXFMAMutate();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
static const MachineInstrBuilder & AddSubReg(const MachineInstrBuilder &MIB, MCRegister Reg, unsigned SubIdx, unsigned 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.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
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
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
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.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Define some predicates that are used for node matching.
int getAltVSXFMAOpcode(uint16_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.
unsigned MCRegUnit
Register units are used to compute register aliasing.