42 "disable-ppc-vsx-fma-mutation",
46#define DEBUG_TYPE "ppc-vsx-fma-mutate"
48namespace llvm {
namespace PPC {
117 if (!AddendMI || AddendMI->
getParent() !=
MI.getParent())
128 MRI.getRegClass(AddendSrcReg))
134 ->contains(AddendSrcReg))
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;
188 && Reg2 != OldFMAReg) {
192 && Reg3 != OldFMAReg) {
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();
232 if (!
MRI.constrainRegClass(KilledProdReg,
233 MRI.getRegClass(OldFMAReg)))
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);
278 for (
auto UI =
MRI.reg_nodbg_begin(OldFMAReg), UE =
MRI.reg_nodbg_end();
285 if (
UseMI == AddendMI)
336 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
340 bool Changed =
false;
365 "PowerPC VSX FMA Mutation",
false,
false)
374char PPCVSXFMAMutate::
ID = 0;
376 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)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
Represent the analysis usage information of a pass.
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.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
LiveInterval - This class represents the liveness of a register, or stack slot.
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
bool isKill() const
Return true if the live-in value is killed by this instruction.
This class represents the liveness of a register, stack slot, etc.
bool liveAt(SlotIndex index) const
void removeValNo(VNInfo *ValNo)
removeValNo - Remove all the segments defined by the specified value#.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
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.
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.
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.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const PPCInstrInfo * getInstrInfo() const override
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Wrapper class representing virtual and physical registers.
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 - An opaque wrapper around machine indexes.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VNInfo - Value Number Information.
SlotIndex def
The index of the defining instruction.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
int getAltVSXFMAOpcode(uint16_t Opcode)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createPPCVSXFMAMutatePass()
void initializePPCVSXFMAMutatePass(PassRegistry &)
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...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.