LLVM: lib/Target/AMDGPU/GCNPreRAOptimizations.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

41

42using namespace llvm;

43

44#define DEBUG_TYPE "amdgpu-pre-ra-optimizations"

45

46namespace {

47

48class GCNPreRAOptimizationsImpl {

49private:

54

56

57public:

58 GCNPreRAOptimizationsImpl(LiveIntervals *LS) : LIS(LS) {}

60};

61

63public:

64 static char ID;

65

68 }

69

71

72 StringRef getPassName() const override {

73 return "AMDGPU Pre-RA optimizations";

74 }

75

76 void getAnalysisUsage(AnalysisUsage &AU) const override {

80 }

81};

82}

83

85 "AMDGPU Pre-RA optimizations", false, false)

89

90char GCNPreRAOptimizationsLegacy::ID = 0;

91

93

95 return new GCNPreRAOptimizationsLegacy();

96}

97

98bool GCNPreRAOptimizationsImpl::processReg(Register Reg) {

104 bool IsAGPRDst = TRI->isAGPRClass(MRI->getRegClass(Reg));

105

107 switch (I.getOpcode()) {

108 default:

109 return false;

110 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:

111 break;

112 case AMDGPU::COPY: {

113

114

115

116

117 if (!IsAGPRDst)

118 return false;

119

120 Register SrcReg = I.getOperand(1).getReg();

121

123 break;

124

125

126 bool IsAGPRSrc = TRI->isAGPRClass(MRI->getRegClass(SrcReg));

127 if (!IsAGPRSrc)

128 break;

129

130

131

132

133 Register SrcSubReg = I.getOperand(1).getSubReg();

134 for (auto &Def : MRI->def_instructions(SrcReg)) {

135 if (SrcSubReg != Def.getOperand(0).getSubReg())

136 continue;

137

138 if (Def.getOpcode() == AMDGPU::V_ACCVGPR_WRITE_B32_e64) {

140

141

142

143

145

146 I.getOperand(1).setReg(DefSrcMO.getReg());

147 I.getOperand(1).setSubReg(DefSrcMO.getSubReg());

148

149

150

152 ModifiedRegs.insert(SrcReg);

153

155 }

156

157

158 break;

159 }

160 }

161 break;

162 }

163 case AMDGPU::S_MOV_B32:

164 if (I.getOperand(0).getReg() != Reg || I.getOperand(1).isImm() ||

165 I.getNumOperands() != 2)

166 return false;

167

168 switch (I.getOperand(0).getSubReg()) {

169 default:

170 return false;

171 case AMDGPU::sub0:

172 if (Def0)

173 return false;

174 Def0 = &I;

175 Init |= Lo_32(I.getOperand(1).getImm());

176 break;

177 case AMDGPU::sub1:

178 if (Def1)

179 return false;

180 Def1 = &I;

181 Init |= static_cast<uint64_t>(I.getOperand(1).getImm()) << 32;

182 break;

183 }

184 break;

185 }

186 }

187

188

189 if (IsAGPRDst) {

191 for (Register RegToUpdate : ModifiedRegs) {

194 }

195 }

196

198 }

199

200

203

204 LLVM_DEBUG(dbgs() << "Combining:\n " << *Def0 << " " << *Def1

205 << " =>\n");

206

210

214 TII->get(AMDGPU::S_MOV_B64_IMM_PSEUDO), Reg)

216

222

224

225 return true;

226}

227

228bool GCNPreRAOptimizationsLegacy::runOnMachineFunction(MachineFunction &MF) {

230 return false;

231 LiveIntervals *LIS = &getAnalysis().getLIS();

232 return GCNPreRAOptimizationsImpl(LIS).run(MF);

233}

234

235PreservedAnalyses

239 GCNPreRAOptimizationsImpl(LIS).run(MF);

241}

242

243bool GCNPreRAOptimizationsImpl::run(MachineFunction &MF) {

245 TII = ST.getInstrInfo();

247 TRI = ST.getRegisterInfo();

248

250

251 for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {

254 continue;

257 (ST.hasGFX90AInsts() || TRI->isAGPRClass(RC)))

258 continue;

259

260 Changed |= processReg(Reg);

261 }

262

263 if (!ST.useRealTrue16Insts())

265

266

269 if (MI.getOpcode() != AMDGPU::COPY)

270 continue;

271 Register Dst = MI.getOperand(0).getReg();

272 Register Src = MI.getOperand(1).getReg();

273 if (Dst.isVirtual() &&

274 MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass &&

275 Src.isPhysical() &&

276 TRI->getRegClassForReg(*MRI, Src) == &AMDGPU::VGPR_32RegClass)

277 MRI->setRegAllocationHint(Dst, 0, TRI->getSubReg(Src, AMDGPU::lo16));

278 if (Src.isVirtual() &&

279 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass &&

280 Dst.isPhysical() &&

281 TRI->getRegClassForReg(*MRI, Dst) == &AMDGPU::VGPR_32RegClass)

282 MRI->setRegAllocationHint(Src, 0, TRI->getSubReg(Dst, AMDGPU::lo16));

283 if (!Dst.isVirtual() || !Src.isVirtual())

284 continue;

285 if (MRI->getRegClass(Dst) == &AMDGPU::VGPR_32RegClass &&

286 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass) {

289 }

290 if (MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass &&

291 MRI->getRegClass(Src) == &AMDGPU::VGPR_32RegClass)

293 }

294 }

295

297}

unsigned const MachineRegisterInfo * MRI

const TargetInstrInfo & TII

Provides AMDGPU specific target descriptions.

AMD GCN specific subclass of TargetSubtarget.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

Interface definition for SIRegisterInfo.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

void setPreservesAll()

Set by analyses that do not transform their input at all.

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

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

Definition GCNPreRAOptimizations.cpp:236

LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

bool hasInterval(Register Reg) const

SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)

SlotIndex getInstructionIndex(const MachineInstr &Instr) const

Returns the base index of the given instruction.

void RemoveMachineInstrFromMaps(MachineInstr &MI)

void removeInterval(Register Reg)

Interval removal.

LiveInterval & createAndComputeVirtRegInterval(Register Reg)

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

unsigned getSizeInBits() const

Return the size of the physical register in bits if we are able to determine it.

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.

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

LLVM_ABI void eraseFromParent()

Unlink 'this' from the containing basic block and delete it.

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.

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

static LLVM_ABI PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Wrapper class representing virtual and physical registers.

static Register index2VirtReg(unsigned Index)

Convert a 0-based index to a virtual register number.

constexpr bool isVirtual() const

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

static bool isEarlierInstr(SlotIndex A, SlotIndex B)

isEarlierInstr - Return true if A refers to an instruction earlier than B.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

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

const MCRegisterClass * MC

unsigned ID

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

This is an optimization pass for GlobalISel generic memory operations.

char & GCNPreRAOptimizationsID

Definition GCNPreRAOptimizations.cpp:92

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

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

void initializeGCNPreRAOptimizationsLegacyPass(PassRegistry &)

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

LLVM_ABI raw_ostream & dbgs()

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

constexpr uint32_t Lo_32(uint64_t Value)

Return the low 32 bits of a 64 bit value.

FunctionPass * createGCNPreRAOptimizationsLegacyPass()

Definition GCNPreRAOptimizations.cpp:94

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.