47 "disable-ppc-vsx-fma-mutation",
51#define DEBUG_TYPE "ppc-vsx-fma-mutate"
53namespace llvm {
namespace PPC {
122 if (!AddendMI || AddendMI->
getParent() !=
MI.getParent())
133 MRI.getRegClass(AddendSrcReg))
139 ->contains(AddendSrcReg))
161 bool OtherUsers =
false, KillsAddendSrc =
false;
168 if (J->modifiesRegister(AddendSrcReg,
TRI) ||
169 J->killsRegister(AddendSrcReg,
TRI)) {
170 KillsAddendSrc =
true;
175 if (OtherUsers || KillsAddendSrc)
186 Register OldFMAReg =
MI.getOperand(0).getReg();
189 unsigned KilledProdOp = 0, OtherProdOp = 0;
193 && Reg2 != OldFMAReg) {
197 && Reg3 != OldFMAReg) {
218 Register KilledProdReg =
MI.getOperand(KilledProdOp).getReg();
219 Register OtherProdReg =
MI.getOperand(OtherProdOp).getReg();
222 unsigned KilledProdSubReg =
MI.getOperand(KilledProdOp).getSubReg();
223 unsigned OtherProdSubReg =
MI.getOperand(OtherProdOp).getSubReg();
226 bool KilledProdRegKill =
MI.getOperand(KilledProdOp).isKill();
227 bool OtherProdRegKill =
MI.getOperand(OtherProdOp).isKill();
230 bool KilledProdRegUndef =
MI.getOperand(KilledProdOp).isUndef();
231 bool OtherProdRegUndef =
MI.getOperand(OtherProdOp).isUndef();
237 if (!
MRI.constrainRegClass(KilledProdReg,
238 MRI.getRegClass(OldFMAReg)))
242 "Addend copy not tied to old FMA output!");
246 MI.getOperand(0).setReg(KilledProdReg);
247 MI.getOperand(1).setReg(KilledProdReg);
248 MI.getOperand(3).setReg(AddendSrcReg);
250 MI.getOperand(0).setSubReg(KilledProdSubReg);
251 MI.getOperand(1).setSubReg(KilledProdSubReg);
254 MI.getOperand(1).setIsKill(KilledProdRegKill);
255 MI.getOperand(3).setIsKill(AddRegKill);
257 MI.getOperand(1).setIsUndef(KilledProdRegUndef);
258 MI.getOperand(3).setIsUndef(AddRegUndef);
260 MI.setDesc(
TII->get(AltOpc));
265 MI.getOperand(2).setReg(AddendSrcReg);
267 MI.getOperand(2).setIsKill(AddRegKill);
268 MI.getOperand(2).setIsUndef(AddRegUndef);
270 MI.getOperand(2).setReg(OtherProdReg);
271 MI.getOperand(2).setSubReg(OtherProdSubReg);
272 MI.getOperand(2).setIsKill(OtherProdRegKill);
273 MI.getOperand(2).setIsUndef(OtherProdRegUndef);
283 for (
auto UI =
MRI.reg_nodbg_begin(OldFMAReg), UE =
MRI.reg_nodbg_end();
290 if (
UseMI == AddendMI)
300 for (
auto &AI : FMAInt) {
302 if (AI.valno == AddendValNo)
324 FMAInt.removeValNo(FMAValNo);
350 LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
354 bool Changed =
false;
379 "PowerPC VSX FMA Mutation",
false,
false)
388char PPCVSXFMAMutate::
ID = 0;
390 return new PPCVSXFMAMutate();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
static const MachineInstrBuilder & AddSubReg(const MachineInstrBuilder &MIB, unsigned 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)
VNInfo::Allocator & getVNInfoAllocator()
LiveRange & getRegUnit(unsigned Unit)
Return the live range for register unit Unit.
LiveInterval & getInterval(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.
iterator addSegment(Segment S)
Add the specified Segment to this range, merging segments as appropriate.
bool liveAt(SlotIndex index) const
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 * getNextValue(SlotIndex Def, VNInfo::Allocator &VNInfoAllocator)
getNextValue - Create a new value number and return it.
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.
This represents a simple continuous liveness interval for a value.