LLVM: lib/Target/AMDGPU/R600ClauseMergePass.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
19
20using namespace llvm;
21
22#define DEBUG_TYPE "r600mergeclause"
23
24namespace {
25
27 switch (MI.getOpcode()) {
28 case R600::CF_ALU:
29 case R600::CF_ALU_PUSH_BEFORE:
30 return true;
31 default:
32 return false;
33 }
34}
35
37
38private:
40
43
44
45
46
47
48 void cleanPotentialDisabledCFAlu(MachineInstr &CFAlu) const;
49
50
51
54
55public:
56 static char ID;
57
59
61
63};
64
65}
66
68 "R600 Clause Merge", false, false)
71
72char R600ClauseMergePass::ID = 0;
73
75
78 return MI
79 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::COUNT))
80 .getImm();
81}
82
83bool R600ClauseMergePass::isCFAluEnabled(const MachineInstr &MI) const {
85 return MI
86 .getOperand(TII->getOperandIdx(MI.getOpcode(), R600::OpName::Enabled))
87 .getImm();
88}
89
90void R600ClauseMergePass::cleanPotentialDisabledCFAlu(
92 int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
94 I++;
95 do {
96 while (I != E && !isCFAlu(*I))
97 I++;
98 if (I == E)
99 return;
101 if (isCFAluEnabled(MI))
102 break;
103 CFAlu.getOperand(CntIdx).setImm(getCFAluSize(CFAlu) + getCFAluSize(MI));
104 MI.eraseFromParent();
105 } while (I != E);
106}
107
108bool R600ClauseMergePass::mergeIfPossible(MachineInstr &RootCFAlu,
110 assert(isCFAlu(RootCFAlu) && isCFAlu(LatrCFAlu));
111 int CntIdx = TII->getOperandIdx(R600::CF_ALU, R600::OpName::COUNT);
112 unsigned RootInstCount = getCFAluSize(RootCFAlu),
113 LaterInstCount = getCFAluSize(LatrCFAlu);
114 unsigned CumuledInsts = RootInstCount + LaterInstCount;
115 if (CumuledInsts >= TII->getMaxAlusPerClause()) {
117 return false;
118 }
119 if (RootCFAlu.getOpcode() == R600::CF_ALU_PUSH_BEFORE)
120 return false;
121
122 int Mode0Idx =
123 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE0);
124 int KBank0Idx =
125 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK0);
126 int KBank0LineIdx =
127 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR0);
135 return false;
136 }
137
138 int Mode1Idx =
139 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_MODE1);
140 int KBank1Idx =
141 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_BANK1);
142 int KBank1LineIdx =
143 TII->getOperandIdx(R600::CF_ALU, R600::OpName::KCACHE_ADDR1);
151 return false;
152 }
160 }
168 }
171 return true;
172}
173
174bool R600ClauseMergePass::runOnMachineFunction(MachineFunction &MF) {
176 return false;
177
180
184 while (I != E) {
186 if ((->canBeConsideredALU(MI) && !isCFAlu(MI)) ||
187 TII->mustBeLastInClause(MI.getOpcode()))
188 LatestCFAlu = E;
189 if (!isCFAlu(MI))
190 continue;
191 cleanPotentialDisabledCFAlu(MI);
192
193 if (LatestCFAlu != E && mergeIfPossible(*LatestCFAlu, MI)) {
194 MI.eraseFromParent();
195 } else {
196 assert(MI.getOperand(8).getImm() && "CF ALU instruction disabled");
197 LatestCFAlu = MI;
198 }
199 }
200 }
201 return false;
202}
203
204StringRef R600ClauseMergePass::getPassName() const {
205 return "R600 Merge Clause Markers Pass";
206}
207
209 return new R600ClauseMergePass();
210}
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Provides R600 specific target descriptions.
AMDGPU R600 specific subclass of TargetSubtarget.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass class - This class is used to implement most global optimizations.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const MachineOperand & getOperand(unsigned i) const
void setImm(int64_t immVal)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
StringRef - Represent a constant reference to a string, i.e.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
char & R600ClauseMergePassID
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createR600ClauseMergePass()