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

1

2

3

4

5

6

7

8

9

10

11

12

13

22

23using namespace llvm;

24

25#define DEBUG_TYPE "si-late-branch-lowering"

26

27namespace {

28

29class SILateBranchLowering {

30private:

36

38 bool DynamicVGPR);

40

41public:

43 : ST(ST), TII(ST.getInstrInfo()), TRI(&TII->getRegisterInfo()), MDT(MDT),

45

47};

48

50public:

51 static char ID;

53

56 auto *MDT = &getAnalysis().getDomTree();

57 return SILateBranchLowering(ST, MDT).run(MF);

58 }

59

60 StringRef getPassName() const override {

61 return "SI Final Branch Preparation";

62 }

63

64 void getAnalysisUsage(AnalysisUsage &AU) const override {

68 }

69};

70

71}

72

73char SILateBranchLoweringLegacy::ID = 0;

74

76 "SI insert s_cbranch_execz instructions", false, false)

79 "SI insert s_cbranch_execz instructions", false, false)

80

82

86 const Function &F = MF.getFunction();

88

89

92 bool HasExports = HasColorExports || HasDepthExports;

93

94

96

97 if (IsPS && (HasExports || MustExport)) {

98

101 ST.hasNullExportTarget()

113 }

114

115

117}

118

122

123

127 DTUpdates.push_back({DomTreeT::Insert, SplitBB, Succ});

128 DTUpdates.push_back({DomTreeT::Delete, &MBB, Succ});

129 }

130 DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB});

132}

133

136 if (Op.isReg())

138 else

140}

141

142void SILateBranchLowering::expandChainCall(MachineInstr &MI,

144 bool DynamicVGPR) {

145

146

147 int ExecIdx =

148 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::exec);

149 assert(ExecIdx != -1 && "Missing EXEC operand");

151 if (DynamicVGPR) {

152

153

154

155

156

157

158

159 auto AllocMI =

162 *TII->getNamedOperand(MI, AMDGPU::OpName::numvgprs));

163

164 auto SelectCallee =

166 .addDef(TII->getNamedOperand(MI, AMDGPU::OpName::src0)->getReg());

168 *TII->getNamedOperand(MI, AMDGPU::OpName::src0));

170 *TII->getNamedOperand(MI, AMDGPU::OpName::fbcallee));

171

174

176 *TII->getNamedOperand(MI, AMDGPU::OpName::exec));

178 *TII->getNamedOperand(MI, AMDGPU::OpName::fbexec));

179 } else {

180 auto SetExec =

183 *TII->getNamedOperand(MI, AMDGPU::OpName::exec));

184 }

185

186 for (int OpIdx = MI.getNumExplicitOperands() - 1; OpIdx >= ExecIdx; --OpIdx)

188

189 MI.setDesc(TII->get(AMDGPU::SI_TCRETURN_CHAIN));

190}

191

192void SILateBranchLowering::earlyTerm(MachineInstr &MI,

193 MachineBasicBlock *EarlyExitBlock) {

194 MachineBasicBlock &MBB = *MI.getParent();

196

198 .addMBB(EarlyExitBlock);

199 auto Next = std::next(MI.getIterator());

200

203

206}

207

208PreservedAnalyses

213 if (!SILateBranchLowering(ST, MDT).run(MF))

215

218}

219

223 bool MadeChange = false;

224

227 switch (MI.getOpcode()) {

228 case AMDGPU::S_BRANCH:

229

230

231 if (MBB.isLayoutSuccessor(MI.getOperand(0).getMBB())) {

233 MI.eraseFromParent();

234 MadeChange = true;

235 }

236 break;

237

238 case AMDGPU::SI_CS_CHAIN_TC_W32:

239 case AMDGPU::SI_CS_CHAIN_TC_W64:

240 expandChainCall(MI, ST, false);

241 MadeChange = true;

242 break;

243 case AMDGPU::SI_CS_CHAIN_TC_W32_DVGPR:

244 case AMDGPU::SI_CS_CHAIN_TC_W64_DVGPR:

245 expandChainCall(MI, ST, true);

246 MadeChange = true;

247 break;

248

249 case AMDGPU::SI_EARLY_TERMINATE_SCC0:

251 break;

252

253 case AMDGPU::SI_RETURN_TO_EPILOG:

255 break;

256

257 default:

258 break;

259 }

260 }

261 }

262

263

264 if (!EarlyTermInstrs.empty()) {

265 MachineBasicBlock *EarlyExitBlock = MF.CreateMachineBasicBlock();

267

268 MF.insert(MF.end(), EarlyExitBlock);

273

274 for (MachineInstr *Instr : EarlyTermInstrs) {

275

276 if (MF.getFunction().getCallingConv() != CallingConv::AMDGPU_GS)

277 earlyTerm(*Instr, EarlyExitBlock);

278 Instr->eraseFromParent();

279 }

280

281 EarlyTermInstrs.clear();

282 MadeChange = true;

283 }

284

285

286 if (!EpilogInstrs.empty()) {

287 MachineBasicBlock *EmptyMBBAtEnd = nullptr;

288 assert(!MF.getInfo()->returnsVoid());

289

290

291

292 if (EpilogInstrs.size() > 1) {

293 EmptyMBBAtEnd = MF.CreateMachineBasicBlock();

294 MF.insert(MF.end(), EmptyMBBAtEnd);

295 }

296

297 for (auto *MI : EpilogInstrs) {

298 auto *MBB = MI->getParent();

300 continue;

301

302

303

304 if (!EmptyMBBAtEnd) {

305 EmptyMBBAtEnd = MF.CreateMachineBasicBlock();

306 MF.insert(MF.end(), EmptyMBBAtEnd);

307 }

308

312 .addMBB(EmptyMBBAtEnd);

313 MI->eraseFromParent();

314 MadeChange = true;

315 }

316

317 EpilogInstrs.clear();

318 }

319

320 return MadeChange;

321}

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

const TargetInstrInfo & TII

Provides AMDGPU specific target descriptions.

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

AMD GCN specific subclass of TargetSubtarget.

Register const TargetRegisterInfo * TRI

MachineInstr unsigned OpIdx

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

static void generateEndPgm(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, const SIInstrInfo *TII, MachineFunction &MF)

Definition SILateBranchLowering.cpp:83

static void copyOpWithoutRegFlags(MachineInstrBuilder &MIB, MachineOperand &Op)

Definition SILateBranchLowering.cpp:134

static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI, MachineDominatorTree *MDT)

Definition SILateBranchLowering.cpp:119

const unsigned CSelectOpc

static const LaneMaskConstants & get(const GCNSubtarget &ST)

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()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

void applyUpdates(ArrayRef< UpdateType > Updates)

Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...

void insertEdge(NodeT *From, NodeT *To)

Inform the dominator tree about a CFG edge insertion and update the tree.

const MCInstrDesc & get(unsigned Opcode) const

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

LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)

Insert MI into the instruction list before I, possibly inside a bundle.

LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())

Add Succ as a successor of this MachineBasicBlock.

iterator_range< succ_iterator > successors()

Analysis pass which computes a MachineDominatorTree.

Analysis pass which computes a MachineDominatorTree.

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

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.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

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

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

PreservedAnalyses & preserve()

Mark an analysis as preserved.

PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)

Definition SILateBranchLowering.cpp:209

void push_back(const T &Elt)

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

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

Target - Wrapper for Target specific information.

bool getHasColorExport(const Function &F)

bool getHasDepthExport(const Function &F)

bool isGFX10Plus(const MCSubtargetInfo &STI)

unsigned ID

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

@ AMDGPU_PS

Used for Mesa/AMDPAL pixel shaders.

@ Undef

Value of the register doesn't matter.

NodeAddr< InstrNode * > Instr

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

AnalysisManager< MachineFunction > MachineFunctionAnalysisManager

LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()

Returns the minimum set of Analyses that all machine function passes must preserve.

char & SILateBranchLoweringPassID

Definition SILateBranchLowering.cpp:81

DominatorTreeBase< T, false > DomTreeBase

FunctionAddr VTableAddr Next

DWARFExpression::Operation Op