31 #define DEBUG_TYPE "aarch64-fix-cortex-a53-835769"
33 STATISTIC(NumNopsAdded,
"Number of Nops added to work around erratum 835769");
44 case AArch64::PRFMroW:
45 case AArch64::PRFMroX:
62 case AArch64::MSUBXrrr:
63 case AArch64::MADDXrrr:
64 case AArch64::SMADDLrrr:
65 case AArch64::SMSUBLrrr:
66 case AArch64::UMADDLrrr:
67 case AArch64::UMSUBLrrr:
97 return "Workaround A53 erratum 835769 pass";
113 "AArch64 fix for A53 erratum 835769",
false,
false)
119 DEBUG(
dbgs() <<
"***** AArch64A53Fix835769 *****\n");
120 bool Changed =
false;
121 TII = F.getSubtarget().getInstrInfo();
123 for (
auto &
MBB : F) {
145 if (S == PrevBB && !TII->
analyzeBranch(*PrevBB, TBB, FBB, Cond) && !TBB &&
176 if (MI == &MBB.
front()) {
178 assert(I &&
"Expected instruction");
184 BuildMI(MBB, MI, DL, TII->
get(AArch64::HINT)).addImm(0);
192 bool Changed =
false;
193 DEBUG(
dbgs() <<
"Running on MBB: " << MBB <<
" - scanning instructions...\n");
199 std::vector<MachineInstr*> Sequences;
207 for (
auto &
MI : MBB) {
211 DEBUG(
dbgs() <<
" PrevInstr: " << *PrevInstr
212 <<
" CurrInstr: " << *CurrInstr
213 <<
" isFirstInstructionInSequence(PrevInstr): "
215 <<
" isSecondInstructionInSequence(CurrInstr): "
219 DEBUG(
dbgs() <<
" ** pattern found at Idx " << Idx <<
"!\n");
220 Sequences.push_back(CurrInstr);
224 PrevInstr = CurrInstr;
228 DEBUG(
dbgs() <<
"Scan complete, " << Sequences.size()
229 <<
" occurrences of pattern found.\n");
232 for (
auto &
MI : Sequences) {
243 return new AArch64A53Fix835769();
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void initializeAArch64A53Fix835769Pass(PassRegistry &)
STATISTIC(NumFunctions,"Total number of functions")
static MachineBasicBlock * getBBFallenThrough(MachineBasicBlock *MBB, const TargetInstrInfo *TII)
bool isPseudo(QueryType Type=IgnoreBundle) const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction...
static MachineInstr * getLastNonPseudo(MachineBasicBlock &MBB, const TargetInstrInfo *TII)
static bool runOnBasicBlock(BasicBlock &BB)
INITIALIZE_PASS(AArch64A53Fix835769,"aarch64-fix-cortex-a53-835769-pass","AArch64 fix for A53 erratum 835769", false, false) bool AArch64A53Fix835769
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
static bool isSecondInstructionInSequence(MachineInstr *MI)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
reverse_iterator rbegin()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
virtual MachineFunctionProperties getRequiredProperties() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
iterator_range< pred_iterator > predecessors()
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass * createAArch64A53Fix835769()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
static bool isFirstInstructionInSequence(MachineInstr *MI)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
Properties which a MachineFunction may have at a given point in time.
static void insertNopBeforeInstruction(MachineBasicBlock &MBB, MachineInstr *MI, const TargetInstrInfo *TII)