30 #define DEBUG_TYPE "vec-merger"
50 E = MRI.
def_end(); It != E; ++It) {
51 return (*It).isImplicitDef();
64 std::vector<unsigned> UndefReg;
67 for (
unsigned i = 1, e = Instr->getNumOperands(); i < e; i+=2) {
69 unsigned Chan = Instr->getOperand(i + 1).
getImm();
70 if (isImplicitlyDef(MRI, MO.
getReg()))
71 UndefReg.push_back(Chan);
73 RegToChan[MO.
getReg()] = Chan;
79 return RSI.Instr == Instr;
88 bool areAllUsesSwizzeable(
unsigned Reg)
const;
90 const std::vector<std::pair<unsigned, unsigned> > &)
const;
91 bool tryMergeVector(
const RegSeqInfo *, RegSeqInfo *,
92 std::vector<std::pair<unsigned, unsigned> > &Remap)
const;
93 bool tryMergeUsingCommonSlot(RegSeqInfo &RSI, RegSeqInfo &CompatibleRSI,
94 std::vector<std::pair<unsigned, unsigned> > &RemapChan);
95 bool tryMergeUsingFreeSlot(RegSeqInfo &RSI, RegSeqInfo &CompatibleRSI,
96 std::vector<std::pair<unsigned, unsigned> > &RemapChan);
98 const RegSeqInfo *BaseVec,
99 const std::vector<std::pair<unsigned, unsigned> > &RemapChan)
const;
101 void trackRSI(
const RegSeqInfo &RSI);
105 InstructionSetMap PreviousRegSeqByReg;
106 InstructionSetMap PreviousRegSeqByUndefCount;
121 const char *getPassName()
const {
122 return "R600 Vector Registers Merge Pass";
135 case AMDGPU::R600_ExportSwz:
136 case AMDGPU::EG_ExportSwz:
143 bool R600VectorRegMerger::tryMergeVector(
const RegSeqInfo *Untouched,
144 RegSeqInfo *ToMerge, std::vector< std::pair<unsigned, unsigned> > &Remap)
146 unsigned CurrentUndexIdx = 0;
148 E = ToMerge->RegToChan.end(); It != E; ++It) {
150 Untouched->RegToChan.find((*It).first);
151 if (PosInUntouched != Untouched->RegToChan.end()) {
152 Remap.push_back(std::pair<unsigned, unsigned>
153 ((*It).second, (*PosInUntouched).second));
156 if (CurrentUndexIdx >= Untouched->UndefReg.size())
158 Remap.push_back(std::pair<unsigned, unsigned>
159 ((*It).second, Untouched->UndefReg[CurrentUndexIdx++]));
166 unsigned getReassignedChan(
167 const std::vector<std::pair<unsigned, unsigned> > &RemapChan,
169 for (
unsigned j = 0, je = RemapChan.size(); j < je; j++) {
170 if (RemapChan[j].first == Chan)
171 return RemapChan[j].second;
177 RegSeqInfo *RSI,
const RegSeqInfo *BaseRSI,
178 const std::vector<std::pair<unsigned, unsigned> > &RemapChan)
const {
179 unsigned Reg = RSI->Instr->getOperand(0).getReg();
184 unsigned SrcVec = BaseRSI->Instr->getOperand(0).getReg();
186 std::vector<unsigned> UpdatedUndef = BaseRSI->UndefReg;
188 E = RSI->RegToChan.end(); It != E; ++It) {
190 unsigned SubReg = (*It).first;
191 unsigned Swizzle = (*It).second;
192 unsigned Chan = getReassignedChan(RemapChan, Swizzle);
199 UpdatedRegToChan[SubReg] = Chan;
200 std::vector<unsigned>::iterator ChanPos =
201 std::find(UpdatedUndef.begin(), UpdatedUndef.end(), Chan);
202 if (ChanPos != UpdatedUndef.end())
203 UpdatedUndef.erase(ChanPos);
204 assert(std::find(UpdatedUndef.begin(), UpdatedUndef.end(), Chan) ==
205 UpdatedUndef.end() &&
206 "UpdatedUndef shouldn't contain Chan more than once!");
217 E = MRI->
use_end(); It != E; ++It) {
219 SwizzleInput(*It, RemapChan);
222 RSI->Instr->eraseFromParent();
226 RSI->RegToChan = UpdatedRegToChan;
227 RSI->UndefReg = UpdatedUndef;
233 for (InstructionSetMap::iterator It = PreviousRegSeqByReg.begin(),
234 E = PreviousRegSeqByReg.end(); It != E; ++It) {
235 std::vector<MachineInstr *> &MIs = (*It).second;
236 MIs.erase(std::find(MIs.begin(), MIs.end(),
MI), MIs.end());
238 for (InstructionSetMap::iterator It = PreviousRegSeqByUndefCount.begin(),
239 E = PreviousRegSeqByUndefCount.end(); It != E; ++It) {
240 std::vector<MachineInstr *> &MIs = (*It).second;
241 MIs.erase(std::find(MIs.begin(), MIs.end(),
MI), MIs.end());
245 void R600VectorRegMerger::SwizzleInput(
MachineInstr &MI,
246 const std::vector<std::pair<unsigned, unsigned> > &RemapChan)
const {
252 for (
unsigned i = 0; i < 4; i++) {
254 for (
unsigned j = 0, e = RemapChan.size(); j < e; j++) {
255 if (RemapChan[j].first == Swizzle) {
263 bool R600VectorRegMerger::areAllUsesSwizzeable(
unsigned Reg)
const {
265 E = MRI->
use_end(); It != E; ++It) {
266 if (!canSwizzle(*It))
272 bool R600VectorRegMerger::tryMergeUsingCommonSlot(RegSeqInfo &RSI,
273 RegSeqInfo &CompatibleRSI,
274 std::vector<std::pair<unsigned, unsigned> > &RemapChan) {
276 MOE = RSI.Instr->operands_end(); MOp != MOE; ++MOp) {
279 if (PreviousRegSeqByReg[MOp->getReg()].empty())
281 std::vector<MachineInstr *> MIs = PreviousRegSeqByReg[MOp->getReg()];
282 for (
unsigned i = 0, e = MIs.size(); i < e; i++) {
283 CompatibleRSI = PreviousRegSeq[MIs[i]];
284 if (RSI == CompatibleRSI)
286 if (tryMergeVector(&CompatibleRSI, &RSI, RemapChan))
293 bool R600VectorRegMerger::tryMergeUsingFreeSlot(RegSeqInfo &RSI,
294 RegSeqInfo &CompatibleRSI,
295 std::vector<std::pair<unsigned, unsigned> > &RemapChan) {
296 unsigned NeededUndefs = 4 - RSI.UndefReg.size();
297 if (PreviousRegSeqByUndefCount[NeededUndefs].empty())
299 std::vector<MachineInstr *> &MIs =
300 PreviousRegSeqByUndefCount[NeededUndefs];
301 CompatibleRSI = PreviousRegSeq[MIs.back()];
302 tryMergeVector(&CompatibleRSI, &RSI, RemapChan);
306 void R600VectorRegMerger::trackRSI(
const RegSeqInfo &RSI) {
308 It = RSI.RegToChan.begin(), E = RSI.RegToChan.end(); It != E; ++It) {
309 PreviousRegSeqByReg[(*It).first].push_back(RSI.Instr);
311 PreviousRegSeqByUndefCount[RSI.UndefReg.size()].push_back(RSI.Instr);
312 PreviousRegSeq[RSI.Instr] = RSI;
319 MBB != MBBe; ++MBB) {
321 PreviousRegSeq.
clear();
322 PreviousRegSeqByReg.clear();
323 PreviousRegSeqByUndefCount.clear();
332 E = MRI->
def_end(); It != E; ++It) {
340 RegSeqInfo RSI(*MRI, MI);
344 if (!areAllUsesSwizzeable(Reg))
351 RegSeqInfo CandidateRSI;
352 std::vector<std::pair<unsigned, unsigned> > RemapChan;
353 DEBUG(
dbgs() <<
"Using common slots...\n";);
354 if (tryMergeUsingCommonSlot(RSI, CandidateRSI, RemapChan)) {
356 RemoveMI(CandidateRSI.Instr);
357 MII = RebuildVector(&RSI, &CandidateRSI, RemapChan);
361 DEBUG(
dbgs() <<
"Using free slots...\n";);
363 if (tryMergeUsingFreeSlot(RSI, CandidateRSI, RemapChan)) {
364 RemoveMI(CandidateRSI.Instr);
365 MII = RebuildVector(&RSI, &CandidateRSI, RemapChan);
379 return new R600VectorRegMerger(tm);
const MachineFunction * getParent() const
AnalysisUsage & addPreserved()
Interface definition for R600InstrInfo.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
AnalysisUsage & addRequired()
static use_iterator use_end()
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
FunctionPass * createR600VectorRegMerger(TargetMachine &tm)
ID
LLVM Calling Convention Representation.
const MachineInstrBuilder & addImm(int64_t Val) const
bundle_iterator< MachineInstr, instr_iterator > iterator
bool isReserved(unsigned PhysReg) const
const MachineOperand & getOperand(unsigned i) const
void setImm(int64_t immVal)
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual const TargetInstrInfo * getInstrInfo() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
def_iterator def_begin(unsigned RegNo) const
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
use_iterator use_begin(unsigned RegNo) const
const TargetMachine & getTarget() const
static std::vector< std::pair< int, unsigned > > Swizzle(std::vector< std::pair< int, unsigned > > Src, R600InstrInfo::BankSwizzle Swz)
unsigned getReg() const
getReg - Returns the register number.
static def_iterator def_end()
BasicBlockListType::iterator iterator
const MCRegisterInfo & MRI
bool operator==(uint64_t V1, const APInt &V2)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const