LLVM: lib/Target/AArch64/AArch64A53Fix835769.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

27

28using namespace llvm;

29

30#define DEBUG_TYPE "aarch64-fix-cortex-a53-835769"

31

32STATISTIC(NumNopsAdded, "Number of Nops added to work around erratum 835769");

33

34

35

36

37

38

40

41 switch (MI->getOpcode()) {

42 case AArch64::PRFMl:

43 case AArch64::PRFMroW:

44 case AArch64::PRFMroX:

45 case AArch64::PRFMui:

46 case AArch64::PRFUMi:

47 return true;

48 default:

49 return MI->mayLoadOrStore();

50 }

51}

52

53

54

56

57

58 switch (MI->getOpcode()) {

59

60

61 case AArch64::MSUBXrrr:

62 case AArch64::MADDXrrr:

63 case AArch64::SMADDLrrr:

64 case AArch64::SMSUBLrrr:

65 case AArch64::UMADDLrrr:

66 case AArch64::UMSUBLrrr:

67

68

69 return MI->getOperand(3).getReg() != AArch64::XZR;

70 default:

71 return false;

72 }

73}

74

75

76

77

78namespace {

80 const TargetInstrInfo *TII;

81

82public:

83 static char ID;

84 explicit AArch64A53Fix835769() : MachineFunctionPass(ID) {}

85

86 bool runOnMachineFunction(MachineFunction &F) override;

87

88 MachineFunctionProperties getRequiredProperties() const override {

89 return MachineFunctionProperties().setNoVRegs();

90 }

91

92 StringRef getPassName() const override {

93 return "Workaround A53 erratum 835769 pass";

94 }

95

96 void getAnalysisUsage(AnalysisUsage &AU) const override {

99 }

100

101private:

103};

104char AArch64A53Fix835769::ID = 0;

105

106}

107

108INITIALIZE_PASS(AArch64A53Fix835769, "aarch64-fix-cortex-a53-835769-pass",

109 "AArch64 fix for A53 erratum 835769", false, false)

110

111

112

114AArch64A53Fix835769::runOnMachineFunction(MachineFunction &F) {

115 LLVM_DEBUG(dbgs() << "***** AArch64A53Fix835769 *****\n");

117

118 if (!STI.fixCortexA53_835769())

119 return false;

120

122 TII = STI.getInstrInfo();

123

124 for (auto &MBB : F) {

126 }

128}

129

130

131

134

136

137

138 if (MBBI == MBB->getParent()->begin())

139 return nullptr;

140

143

146 if (S == PrevBB && TII->analyzeBranch(*PrevBB, TBB, FBB, Cond) && TBB &&

147 !FBB)

148 return S;

149

150 return nullptr;

151}

152

153

154

155

156

160

161

162

165 if (I.isPseudo())

166 return &I;

167 }

168

169

170 return nullptr;

171}

172

175

176

177 if (MI == &MBB.front()) {

179 assert(I && "Expected instruction");

182 }

183 else {

186 }

187

188 ++NumNopsAdded;

189}

190

191bool

195 << " - scanning instructions...\n");

196

197

198

199

200

201 std::vector<MachineInstr*> Sequences;

202 unsigned Idx = 0;

203 MachineInstr *PrevInstr = nullptr;

204

205

206

208

209 for (auto &MI : MBB) {

210 MachineInstr *CurrInstr = &MI;

212 if (PrevInstr) {

214 << " CurrInstr: " << *CurrInstr

215 << " isFirstInstructionInSequence(PrevInstr): "

217 << " isSecondInstructionInSequence(CurrInstr): "

221 LLVM_DEBUG(dbgs() << " ** pattern found at Idx " << Idx << "!\n");

222 (void) Idx;

223 Sequences.push_back(CurrInstr);

224 }

225 }

227 PrevInstr = CurrInstr;

228 ++Idx;

229 }

230

231 LLVM_DEBUG(dbgs() << "Scan complete, " << Sequences.size()

232 << " occurrences of pattern found.\n");

233

234

235 for (auto &MI : Sequences) {

238 }

239

241}

242

243

244

246 return new AArch64A53Fix835769();

247}

static MachineBasicBlock * getBBFallenThrough(MachineBasicBlock *MBB, const TargetInstrInfo *TII)

Definition AArch64A53Fix835769.cpp:132

static MachineInstr * getLastNonPseudo(MachineBasicBlock &MBB, const TargetInstrInfo *TII)

Definition AArch64A53Fix835769.cpp:157

static void insertNopBeforeInstruction(MachineBasicBlock &MBB, MachineInstr *MI, const TargetInstrInfo *TII)

Definition AArch64A53Fix835769.cpp:173

static bool isFirstInstructionInSequence(MachineInstr *MI)

Definition AArch64A53Fix835769.cpp:39

static bool isSecondInstructionInSequence(MachineInstr *MI)

Definition AArch64A53Fix835769.cpp:55

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

static bool runOnBasicBlock(MachineBasicBlock *MBB, unsigned BasicBlockNum, VRegRenamer &Renamer)

#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

FunctionPass class - This class is used to implement most global optimizations.

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.

BasicBlockListType::iterator iterator

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

Representation of each machine instruction.

bool isPseudo(QueryType Type=IgnoreBundle) const

Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

TargetInstrInfo - Interface to description of machine instruction set.

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

auto reverse(ContainerTy &&C)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionPass * createAArch64A53Fix835769()

Definition AArch64A53Fix835769.cpp:245