38 switch (
MI.getOpcode()) {
39 case R600::INTERP_PAIR_XY:
40 case R600::INTERP_PAIR_ZW:
41 case R600::INTERP_VEC_LOAD:
52 if (
TII->isLDSRetInstr(
MI.getOpcode()))
55 if (
TII->isVector(
MI) ||
TII->isCubeOp(
MI.getOpcode()) ||
56 TII->isReductionOp(
MI.getOpcode()))
59 unsigned NumLiteral = 0;
61 E =
MI.operands_end();
64 if (MO.
isReg() && MO.
getReg() == R600::ALU_LITERAL_X)
67 return 1 + NumLiteral;
71 if (
TII->isALUInstr(
MI.getOpcode()))
73 if (
TII->isVector(
MI) ||
TII->isCubeOp(
MI.getOpcode()))
75 switch (
MI.getOpcode()) {
77 case R600::INTERP_PAIR_XY:
78 case R600::INTERP_PAIR_ZW:
79 case R600::INTERP_VEC_LOAD:
89 switch (
MI.getOpcode()) {
92 case R600::IMPLICIT_DEF:
99 std::pair<unsigned, unsigned> getAccessedBankLine(
unsigned Sel)
const {
103 return std::pair<unsigned, unsigned>(
104 ((Sel >> 2) - 512) >> 12,
110 ((((Sel >> 2) - 512) & 4095) >> 5) << 1);
115 std::vector<std::pair<unsigned, unsigned>> &CachedConsts,
116 bool UpdateInstr =
true)
const {
117 std::vector<std::pair<unsigned, unsigned>> UsedKCache;
119 if (!
TII->isALUInstr(
MI.getOpcode()) &&
MI.getOpcode() != R600::DOT_4)
125 (
TII->isALUInstr(
MI.getOpcode()) ||
MI.getOpcode() == R600::DOT_4) &&
126 "Can't assign Const");
127 for (
unsigned i = 0, n = Consts.
size(); i < n; ++i) {
128 if (Consts[i].first->getReg() != R600::ALU_CONST)
130 unsigned Sel = Consts[i].second;
131 unsigned Chan = Sel & 3,
Index = ((Sel >> 2) - 512) & 31;
132 unsigned KCacheIndex =
Index * 4 + Chan;
133 const std::pair<unsigned, unsigned> &BankLine = getAccessedBankLine(Sel);
134 if (CachedConsts.empty()) {
135 CachedConsts.push_back(BankLine);
136 UsedKCache.push_back(std::pair<unsigned, unsigned>(0, KCacheIndex));
139 if (CachedConsts[0] == BankLine) {
140 UsedKCache.push_back(std::pair<unsigned, unsigned>(0, KCacheIndex));
143 if (CachedConsts.size() == 1) {
144 CachedConsts.push_back(BankLine);
145 UsedKCache.push_back(std::pair<unsigned, unsigned>(1, KCacheIndex));
148 if (CachedConsts[1] == BankLine) {
149 UsedKCache.push_back(std::pair<unsigned, unsigned>(1, KCacheIndex));
158 for (
unsigned i = 0, j = 0, n = Consts.
size(); i < n; ++i) {
159 if (Consts[i].first->getReg() != R600::ALU_CONST)
161 switch(UsedKCache[j].first) {
163 Consts[i].first->setReg(
164 R600::R600_KC0RegClass.getRegister(UsedKCache[j].second));
167 Consts[i].first->setReg(
168 R600::R600_KC1RegClass.getRegister(UsedKCache[j].second));
178 bool canClauseLocalKillFitInClause(
179 unsigned AluInstCount,
180 std::vector<std::pair<unsigned, unsigned>> KCacheBanks,
186 MOI =
Def->operands_begin(),
187 MOE =
Def->operands_end(); MOI != MOE; ++MOI) {
188 if (!MOI->isReg() || !MOI->isDef() ||
189 TRI.isPhysRegLiveAcrossClauses(MOI->getReg()))
194 unsigned LastUseCount = 0;
196 AluInstCount += OccupiedDwords(*UseI);
198 if (!SubstituteKCacheBank(*UseI, KCacheBanks,
false))
204 if (AluInstCount >=
TII->getMaxAlusPerClause())
213 if (UseI->readsRegister(MOI->getReg(), &
TRI))
214 LastUseCount = AluInstCount;
217 if (UseI != Def && UseI->killsRegister(MOI->getReg(), &
TRI))
221 return LastUseCount <=
TII->getMaxAlusPerClause();
230 std::vector<std::pair<unsigned, unsigned>> KCacheBanks;
231 bool PushBeforeModifier =
false;
232 unsigned AluInstCount = 0;
234 if (IsTrivialInst(*
I))
238 if (AluInstCount >
TII->getMaxAlusPerClause())
240 if (
I->getOpcode() == R600::PRED_X) {
247 if (AluInstCount > 0)
250 PushBeforeModifier =
true;
261 if (
TII->mustBeLastInClause(
I->getOpcode())) {
268 if (!canClauseLocalKillFitInClause(AluInstCount, KCacheBanks,
I,
E))
271 if (!SubstituteKCacheBank(*
I, KCacheBanks))
273 AluInstCount += OccupiedDwords(*
I);
275 unsigned Opcode = PushBeforeModifier ?
276 R600::CF_ALU_PUSH_BEFORE : R600::CF_ALU;
283 .
addImm(KCacheBanks.empty()?0:KCacheBanks[0].first)
284 .
addImm((KCacheBanks.size() < 2)?0:KCacheBanks[1].first)
285 .
addImm(KCacheBanks.empty()?0:2)
286 .
addImm((KCacheBanks.size() < 2)?0:2)
287 .
addImm(KCacheBanks.empty()?0:KCacheBanks[0].second)
288 .
addImm((KCacheBanks.size() < 2)?0:KCacheBanks[1].second)
303 TII =
ST.getInstrInfo();
307 if (
I !=
MBB.
end() &&
I->getOpcode() == R600::CF_ALU)
311 auto next = MakeALUClause(
MBB,
I);
322 return "R600 Emit Clause Markers Pass";
326char R600EmitClauseMarkers::ID = 0;
331 "R600 Emit Clause Markers",
false,
false)
336 return new R600EmitClauseMarkers();
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#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.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions.
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.
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.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
#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.
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.
void initializeR600EmitClauseMarkersPass(PassRegistry &)
FunctionPass * createR600EmitClauseMarkers()