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

1

2

3

4

5

6

7

8

9

10

11

12

21

22using namespace llvm;

23

24#define DEBUG_TYPE "aarch64-sme-peephole-opt"

25

26namespace {

27

29 static char ID;

30

32

34

35 StringRef getPassName() const override {

36 return "SME Peephole Optimization pass";

37 }

38

39 void getAnalysisUsage(AnalysisUsage &AU) const override {

42 }

43

45 bool &HasRemovedAllSMChanges) const;

47};

48

49char SMEPeepholeOpt::ID = 0;

50

51}

52

54 return MI->getOpcode() == AArch64::MSRpstatePseudo;

55}

56

59

60

62 return false;

63

64

66 return false;

67

70 return false;

71

72 if (!IsConditional)

73 return true;

74

75

77 return false;

78

79

81 return false;

82

83

84

85

86

91 return false;

92 }

93

94 return true;

95}

96

98 assert((MI->getOpcode() == AArch64::MSRpstatesvcrImm1 ||

99 MI->getOpcode() == AArch64::MSRpstatePseudo) &&

100 "Expected MI to be a smstart/smstop instruction");

101 return MI->getOperand(0).getImm() == AArch64SVCR::SVCRSM ||

102 MI->getOperand(0).getImm() == AArch64SVCR::SVCRSMZA;

103}

104

109 return false;

110

112 if (R.isPhysical())

114 return AArch64::ZPRRegClass.contains(SR) ||

115 AArch64::PPRRegClass.contains(SR);

116 });

117

119 return TRI.getCommonSubClass(&AArch64::ZPRRegClass, RC) ||

120 TRI.getCommonSubClass(&AArch64::PPRRegClass, RC);

121}

122

123bool SMEPeepholeOpt::optimizeStartStopPairs(

126 const TargetRegisterInfo &TRI =

128

130 MachineInstr *Prev = nullptr;

131

132

133

134

135

136 unsigned NumSMChanges = 0;

137 unsigned NumSMChangesRemoved = 0;

139 switch (MI.getOpcode()) {

140 case AArch64::MSRpstatesvcrImm1:

141 case AArch64::MSRpstatePseudo: {

143 NumSMChanges++;

144

145 if (!Prev)

146 Prev = &MI;

148

149

151 MI.eraseFromParent();

152 Prev = nullptr;

154 NumSMChangesRemoved += 2;

155 } else {

156 Prev = &MI;

157 }

158 continue;

159 }

160 default:

161 if (!Prev)

162

163 continue;

164 break;

165 }

166

167

168

169 switch (MI.getOpcode()) {

170 default:

171 Prev = nullptr;

172 break;

173 case AArch64::COALESCER_BARRIER_FPR16:

174 case AArch64::COALESCER_BARRIER_FPR32:

175 case AArch64::COALESCER_BARRIER_FPR64:

176 case AArch64::COALESCER_BARRIER_FPR128:

177 case AArch64::COPY:

178

179

180

181

182

185 Prev = nullptr;

186 break;

187 case AArch64::RestoreZAPseudo:

188 case AArch64::InOutZAUsePseudo:

189 case AArch64::CommitZASavePseudo:

190 case AArch64::SMEStateAllocPseudo:

191 case AArch64::RequiresZASavePseudo:

192

193

194

196 Prev = nullptr;

197 break;

198 case AArch64::ADJCALLSTACKDOWN:

199 case AArch64::ADJCALLSTACKUP:

200 case AArch64::ANDXri:

201 case AArch64::ADDXri:

202

203 break;

204 case AArch64::MSRpstatesvcrImm1:

205 case AArch64::MSRpstatePseudo:

207 }

208 }

209

210 HasRemovedAllSMChanges =

211 NumSMChanges && (NumSMChanges == NumSMChangesRemoved);

213}

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230bool SMEPeepholeOpt::visitRegSequence(MachineInstr &MI) {

231 assert(MI.getMF()->getRegInfo().isSSA() && "Expected to be run on SSA form!");

232

233 MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();

234 switch (MRI.getRegClass(MI.getOperand(0).getReg())->getID()) {

235 case AArch64::ZPR2RegClassID:

236 case AArch64::ZPR4RegClassID:

237 case AArch64::ZPR2Mul2RegClassID:

238 case AArch64::ZPR4Mul4RegClassID:

239 break;

240 default:

241 return false;

242 }

243

244

245

246

247 if (MI.getNumOperands() != 5 && MI.getNumOperands() != 9)

248 return false;

249

251 for (unsigned I = 1; I < MI.getNumOperands(); I += 2) {

252 MachineOperand &MO = MI.getOperand(I);

253

254 MachineOperand *Def = MRI.getOneDef(MO.getReg());

255 if (!Def || Def->getParent()->isCopy())

256 return false;

257

258 const MachineOperand &CopySrc = Def->getParent()->getOperand(1);

259 unsigned OpSubReg = CopySrc.getSubReg();

262

263 MachineOperand *CopySrcOp = MRI.getOneDef(CopySrc.getReg());

264 if (!CopySrcOp || !CopySrcOp->isReg() || OpSubReg != SubReg ||

266 return false;

267

268 const TargetRegisterClass *CopySrcClass =

269 MRI.getRegClass(CopySrcOp->getReg());

270 if (CopySrcClass != &AArch64::ZPR2StridedOrContiguousRegClass &&

271 CopySrcClass != &AArch64::ZPR4StridedOrContiguousRegClass)

272 return false;

273 }

274

275 unsigned Opc = MI.getNumOperands() == 5

276 ? AArch64::FORM_TRANSPOSED_REG_TUPLE_X2_PSEUDO

277 : AArch64::FORM_TRANSPOSED_REG_TUPLE_X4_PSEUDO;

278

279 const TargetInstrInfo *TII =

280 MI.getMF()->getSubtarget().getInstrInfo();

281 MachineInstrBuilder MIB = BuildMI(*MI.getParent(), MI, MI.getDebugLoc(),

282 TII->get(Opc), MI.getOperand(0).getReg());

283 for (unsigned I = 1; I < MI.getNumOperands(); I += 2)

284 MIB.addReg(MI.getOperand(I).getReg());

285

286 MI.eraseFromParent();

287 return true;

288}

289

291 "SME Peephole Optimization", false, false)

292

294 if (skipFunction(MF.getFunction()))

295 return false;

296

298 return false;

299

300 assert(MF.getRegInfo().isSSA() && "Expected to be run on SSA form!");

301

303 bool FunctionHasAllSMChangesRemoved = false;

304

305

306

307

309 bool BlockHasAllSMChangesRemoved;

310 Changed |= optimizeStartStopPairs(MBB, BlockHasAllSMChangesRemoved);

311 FunctionHasAllSMChangesRemoved |= BlockHasAllSMChangesRemoved;

312

315 if (MI.getOpcode() == AArch64::REG_SEQUENCE)

317 }

318 }

319

321 if (FunctionHasAllSMChangesRemoved)

323

325}

326

unsigned const MachineRegisterInfo * MRI

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

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

const HexagonInstrInfo * TII

Register const TargetRegisterInfo * TRI

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

static bool isSVERegOp(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const MachineOperand &MO)

Definition SMEPeepholeOpt.cpp:105

static bool isMatchingStartStopPair(const MachineInstr *MI1, const MachineInstr *MI2)

Definition SMEPeepholeOpt.cpp:57

static bool isConditionalStartStop(const MachineInstr *MI)

Definition SMEPeepholeOpt.cpp:53

static bool ChangesStreamingMode(const MachineInstr *MI)

Definition SMEPeepholeOpt.cpp:97

This file defines the SmallVector class.

AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...

void setHasStreamingModeChanges(bool HasChanges)

bool isStreaming() const

Returns true if the function has a streaming body.

Represent the analysis usage information of a pass.

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.

static constexpr unsigned NoRegister

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

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.

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

Representation of each machine instruction.

LLVM_ABI 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

bool isReg() const

isReg - Tests if this is a MO_Register operand.

Register getReg() const

getReg - Returns the register number.

const uint32_t * getRegMask() const

getRegMask - Returns a bit mask of registers preserved by this RegMask operand.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Wrapper class representing virtual and physical registers.

constexpr bool isPhysical() const

Return true if the specified register number is in the physical register namespace.

StringRef - Represent a constant reference to a string, i.e.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

NodeAddr< DefNode * > Def

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.

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...

FunctionPass * createSMEPeepholeOptPass()

Definition SMEPeepholeOpt.cpp:327

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...