23#define DEBUG_TYPE "si-mode-register"
25STATISTIC(NumSetregInserted,
"Number of setreg of mode register inserted.");
57 unsigned NewMode = (
Mode & NewMask);
58 return Status(NewMask, NewMode);
114 std::vector<std::unique_ptr<BlockData>> BlockInfo;
115 std::queue<MachineBasicBlock *> Phase2List;
126 bool Changed =
false;
152 "Insert required mode register values",
false,
false)
154char SIModeRegister::
ID = 0;
166 if (
TII->usesFPDPRounding(
MI) ||
167 MI.getOpcode() == AMDGPU::FPTRUNC_UPWARD_PSEUDO ||
168 MI.getOpcode() == AMDGPU::FPTRUNC_DOWNWARD_PSEUDO) {
169 switch (
MI.getOpcode()) {
170 case AMDGPU::V_INTERP_P1LL_F16:
171 case AMDGPU::V_INTERP_P1LV_F16:
172 case AMDGPU::V_INTERP_P2_F16:
176 case AMDGPU::FPTRUNC_UPWARD_PSEUDO: {
178 if (
TII->getSubtarget().hasTrue16BitInsts()) {
181 MI.setDesc(
TII->get(AMDGPU::V_CVT_F16_F32_t16_e64));
189 MI.setDesc(
TII->get(AMDGPU::V_CVT_F16_F32_e32));
193 case AMDGPU::FPTRUNC_DOWNWARD_PSEUDO: {
195 if (
TII->getSubtarget().hasTrue16BitInsts()) {
198 MI.setDesc(
TII->get(AMDGPU::V_CVT_F16_F32_t16_e64));
206 MI.setDesc(
TII->get(AMDGPU::V_CVT_F16_F32_e32));
211 return DefaultStatus;
224 while (InstrMode.
Mask) {
225 unsigned Offset = llvm::countr_zero<unsigned>(InstrMode.
Mask);
260 auto NewInfo = std::make_unique<BlockData>();
267 bool RequirePending =
true;
271 if (
MI.getOpcode() == AMDGPU::S_SETREG_B32 ||
272 MI.getOpcode() == AMDGPU::S_SETREG_B32_mode ||
273 MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 ||
274 MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32_mode) {
278 unsigned Dst =
TII->getNamedOperand(
MI, AMDGPU::OpName::simm16)->getImm();
291 if (InsertionPoint) {
292 insertSetreg(
MBB, InsertionPoint,
TII, IPChange.
delta(NewInfo->Change));
293 InsertionPoint =
nullptr;
298 if (
MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 ||
299 MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32_mode) {
300 unsigned Val =
TII->getNamedOperand(
MI, AMDGPU::OpName::imm)->getImm();
305 RequirePending =
false;
306 NewInfo->Change = NewInfo->Change.merge(Setreg);
308 NewInfo->Change = NewInfo->Change.mergeUnknown(Mask);
310 }
else if (!NewInfo->Change.isCompatible(InstrMode)) {
313 if (InsertionPoint) {
318 if (RequirePending) {
322 NewInfo->FirstInsertionPoint = InsertionPoint;
323 NewInfo->Require = NewInfo->Change;
324 RequirePending =
false;
326 insertSetreg(
MBB, InsertionPoint,
TII,
327 IPChange.
delta(NewInfo->Change));
328 IPChange = NewInfo->Change;
331 InsertionPoint = &
MI;
333 NewInfo->Change = NewInfo->Change.merge(InstrMode);
337 InsertionPoint = &
MI;
338 IPChange = NewInfo->Change;
339 NewInfo->Change = NewInfo->Change.
merge(InstrMode);
343 if (RequirePending) {
346 NewInfo->FirstInsertionPoint = InsertionPoint;
347 NewInfo->Require = NewInfo->Change;
348 }
else if (InsertionPoint) {
350 insertSetreg(
MBB, InsertionPoint,
TII, IPChange.
delta(NewInfo->Change));
352 NewInfo->Exit = NewInfo->Change;
362 bool RevisitRequired =
false;
363 bool ExitSet =
false;
367 BlockInfo[ThisBlock]->Pred = DefaultStatus;
382 unsigned PredBlock =
PB.getNumber();
383 if ((ThisBlock == PredBlock) && (std::next(
P) ==
E)) {
384 BlockInfo[ThisBlock]->Pred = DefaultStatus;
386 }
else if (BlockInfo[PredBlock]->ExitSet) {
387 BlockInfo[ThisBlock]->Pred = BlockInfo[PredBlock]->Exit;
389 }
else if (PredBlock != ThisBlock)
390 RevisitRequired =
true;
392 for (
P = std::next(
P);
P !=
E;
P = std::next(
P)) {
395 if (BlockInfo[PredBlock]->ExitSet) {
396 if (BlockInfo[ThisBlock]->ExitSet) {
397 BlockInfo[ThisBlock]->Pred =
398 BlockInfo[ThisBlock]->Pred.intersect(BlockInfo[PredBlock]->Exit);
400 BlockInfo[ThisBlock]->Pred = BlockInfo[PredBlock]->Exit;
403 }
else if (PredBlock != ThisBlock)
404 RevisitRequired =
true;
408 BlockInfo[ThisBlock]->Pred.
merge(BlockInfo[ThisBlock]->Change);
409 if (BlockInfo[ThisBlock]->Exit != TmpStatus) {
410 BlockInfo[ThisBlock]->Exit = TmpStatus;
414 Phase2List.push(Succ);
416 BlockInfo[ThisBlock]->ExitSet = ExitSet;
418 Phase2List.push(&
MBB);
427 if (!BlockInfo[ThisBlock]->Pred.isCompatible(BlockInfo[ThisBlock]->Require)) {
429 BlockInfo[ThisBlock]->Pred.
delta(BlockInfo[ThisBlock]->Require);
430 if (BlockInfo[ThisBlock]->FirstInsertionPoint)
431 insertSetreg(
MBB, BlockInfo[ThisBlock]->FirstInsertionPoint,
TII, Delta);
447 processBlockPhase1(BB,
TII);
453 Phase2List.push(&BB);
454 while (!Phase2List.empty()) {
455 processBlockPhase2(*Phase2List.front(),
TII);
462 processBlockPhase3(BB,
TII);
Provides AMDGPU specific target descriptions.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define FP_ROUND_MODE_DP(x)
#define FP_ROUND_ROUND_TO_INF
#define FP_ROUND_ROUND_TO_NEAREST
#define FP_ROUND_ROUND_TO_ZERO
#define FP_ROUND_ROUND_TO_NEGINF
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
MachineInstr * FirstInsertionPoint
Represent the analysis usage information of a pass.
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.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
pred_iterator pred_begin()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
MachineInstr & instr_front()
std::vector< MachineBasicBlock * >::iterator pred_iterator
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
LLVM Value Representation.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
FunctionPass * createSIModeRegisterPass()
Status delta(const Status &S) const
Status(unsigned NewMask, unsigned NewMode)
bool isCombinable(Status &S)
bool operator==(const Status &S) const
bool isCompatible(Status &S)
Status merge(const Status &S) const
Status intersect(const Status &S) const
bool operator!=(const Status &S) const
Status mergeUnknown(unsigned newMask)