45 #define DEBUG_TYPE "vec-merger"
53 return (*It).isImplicitDef();
66 std::vector<unsigned> UndefReg;
69 for (
unsigned i = 1, e = Instr->getNumOperands(); i < e; i+=2) {
71 unsigned Chan = Instr->getOperand(i + 1).
getImm();
72 if (isImplicitlyDef(MRI, MO.
getReg()))
73 UndefReg.push_back(Chan);
75 RegToChan[MO.
getReg()] = Chan;
81 return RSI.Instr == Instr;
90 bool areAllUsesSwizzeable(
unsigned Reg)
const;
92 const std::vector<std::pair<unsigned, unsigned> > &)
const;
93 bool tryMergeVector(
const RegSeqInfo *, RegSeqInfo *,
94 std::vector<std::pair<unsigned, unsigned> > &Remap)
const;
95 bool tryMergeUsingCommonSlot(RegSeqInfo &
RSI, RegSeqInfo &CompatibleRSI,
96 std::vector<std::pair<unsigned, unsigned> > &RemapChan);
97 bool tryMergeUsingFreeSlot(RegSeqInfo &RSI, RegSeqInfo &CompatibleRSI,
98 std::vector<std::pair<unsigned, unsigned> > &RemapChan);
100 const RegSeqInfo *BaseVec,
101 const std::vector<std::pair<unsigned, unsigned> > &RemapChan)
const;
103 void trackRSI(
const RegSeqInfo &RSI);
107 InstructionSetMap PreviousRegSeqByReg;
108 InstructionSetMap PreviousRegSeqByUndefCount;
123 const char *getPassName()
const override {
124 return "R600 Vector Registers Merge Pass";
137 case AMDGPU::R600_ExportSwz:
138 case AMDGPU::EG_ExportSwz:
145 bool R600VectorRegMerger::tryMergeVector(
const RegSeqInfo *Untouched,
146 RegSeqInfo *ToMerge, std::vector< std::pair<unsigned, unsigned> > &Remap)
148 unsigned CurrentUndexIdx = 0;
150 E = ToMerge->RegToChan.end(); It != E; ++It) {
152 Untouched->RegToChan.find((*It).first);
153 if (PosInUntouched != Untouched->RegToChan.end()) {
154 Remap.push_back(std::pair<unsigned, unsigned>
155 ((*It).second, (*PosInUntouched).second));
158 if (CurrentUndexIdx >= Untouched->UndefReg.size())
160 Remap.push_back(std::pair<unsigned, unsigned>
161 ((*It).second, Untouched->UndefReg[CurrentUndexIdx++]));
168 unsigned getReassignedChan(
169 const std::vector<std::pair<unsigned, unsigned> > &RemapChan,
171 for (
unsigned j = 0, je = RemapChan.size(); j < je; j++) {
172 if (RemapChan[j].first == Chan)
173 return RemapChan[j].second;
179 RegSeqInfo *
RSI,
const RegSeqInfo *BaseRSI,
180 const std::vector<std::pair<unsigned, unsigned> > &RemapChan)
const {
181 unsigned Reg = RSI->Instr->getOperand(0).getReg();
186 unsigned SrcVec = BaseRSI->Instr->getOperand(0).getReg();
188 std::vector<unsigned> UpdatedUndef = BaseRSI->UndefReg;
190 E = RSI->RegToChan.end(); It != E; ++It) {
192 unsigned SubReg = (*It).first;
193 unsigned Swizzle = (*It).second;
194 unsigned Chan = getReassignedChan(RemapChan, Swizzle);
201 UpdatedRegToChan[SubReg] = Chan;
202 std::vector<unsigned>::iterator ChanPos =
203 std::find(UpdatedUndef.begin(), UpdatedUndef.end(), Chan);
204 if (ChanPos != UpdatedUndef.end())
205 UpdatedUndef.erase(ChanPos);
206 assert(std::find(UpdatedUndef.begin(), UpdatedUndef.end(), Chan) ==
207 UpdatedUndef.end() &&
208 "UpdatedUndef shouldn't contain Chan more than once!");
221 SwizzleInput(*It, RemapChan);
224 RSI->Instr->eraseFromParent();
228 RSI->RegToChan = UpdatedRegToChan;
229 RSI->UndefReg = UpdatedUndef;
235 for (InstructionSetMap::iterator It = PreviousRegSeqByReg.begin(),
236 E = PreviousRegSeqByReg.end(); It != E; ++It) {
237 std::vector<MachineInstr *> &MIs = (*It).second;
238 MIs.erase(std::find(MIs.begin(), MIs.end(),
MI), MIs.end());
240 for (InstructionSetMap::iterator It = PreviousRegSeqByUndefCount.begin(),
241 E = PreviousRegSeqByUndefCount.end(); It != E; ++It) {
242 std::vector<MachineInstr *> &MIs = (*It).second;
243 MIs.erase(std::find(MIs.begin(), MIs.end(),
MI), MIs.end());
247 void R600VectorRegMerger::SwizzleInput(
MachineInstr &MI,
248 const std::vector<std::pair<unsigned, unsigned> > &RemapChan)
const {
254 for (
unsigned i = 0; i < 4; i++) {
256 for (
unsigned j = 0, e = RemapChan.size(); j < e; j++) {
257 if (RemapChan[j].first == Swizzle) {
265 bool R600VectorRegMerger::areAllUsesSwizzeable(
unsigned Reg)
const {
268 if (!canSwizzle(*It))
274 bool R600VectorRegMerger::tryMergeUsingCommonSlot(RegSeqInfo &RSI,
275 RegSeqInfo &CompatibleRSI,
276 std::vector<std::pair<unsigned, unsigned> > &RemapChan) {
278 MOE = RSI.Instr->operands_end(); MOp != MOE; ++MOp) {
281 if (PreviousRegSeqByReg[MOp->getReg()].empty())
283 for (
MachineInstr *MI : PreviousRegSeqByReg[MOp->getReg()]) {
284 CompatibleRSI = PreviousRegSeq[
MI];
285 if (RSI == CompatibleRSI)
287 if (tryMergeVector(&CompatibleRSI, &RSI, RemapChan))
294 bool R600VectorRegMerger::tryMergeUsingFreeSlot(RegSeqInfo &RSI,
295 RegSeqInfo &CompatibleRSI,
296 std::vector<std::pair<unsigned, unsigned> > &RemapChan) {
297 unsigned NeededUndefs = 4 - RSI.UndefReg.size();
298 if (PreviousRegSeqByUndefCount[NeededUndefs].empty())
300 std::vector<MachineInstr *> &MIs =
301 PreviousRegSeqByUndefCount[NeededUndefs];
302 CompatibleRSI = PreviousRegSeq[MIs.back()];
303 tryMergeVector(&CompatibleRSI, &RSI, RemapChan);
307 void R600VectorRegMerger::trackRSI(
const RegSeqInfo &RSI) {
309 It = RSI.RegToChan.begin(), E = RSI.RegToChan.end(); It != E; ++It) {
310 PreviousRegSeqByReg[(*It).first].push_back(RSI.Instr);
312 PreviousRegSeqByUndefCount[RSI.UndefReg.size()].push_back(RSI.Instr);
313 PreviousRegSeq[RSI.Instr] = RSI;
320 MBB != MBBe; ++MBB) {
322 PreviousRegSeq.
clear();
323 PreviousRegSeqByReg.clear();
324 PreviousRegSeqByUndefCount.clear();
327 MII != MIIE; ++MII) {
342 RegSeqInfo RSI(*MRI, MI);
346 if (!areAllUsesSwizzeable(Reg))
353 RegSeqInfo CandidateRSI;
354 std::vector<std::pair<unsigned, unsigned> > RemapChan;
355 DEBUG(
dbgs() <<
"Using common slots...\n";);
356 if (tryMergeUsingCommonSlot(RSI, CandidateRSI, RemapChan)) {
358 RemoveMI(CandidateRSI.Instr);
359 MII = RebuildVector(&RSI, &CandidateRSI, RemapChan);
363 DEBUG(
dbgs() <<
"Using free slots...\n";);
365 if (tryMergeUsingFreeSlot(RSI, CandidateRSI, RemapChan)) {
366 RemoveMI(CandidateRSI.Instr);
367 MII = RebuildVector(&RSI, &CandidateRSI, RemapChan);
381 return new R600VectorRegMerger(tm);
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
AMDGPU specific subclass of TargetSubtarget.
Interface definition for R600InstrInfo.
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
COPY - Target-independent register copy.
AnalysisUsage & addRequired()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
use_instr_iterator use_instr_begin(unsigned RegNo) const
Reg
All possible values of the reg field in the ModR/M byte.
FunctionPass * createR600VectorRegMerger(TargetMachine &tm)
const MachineInstrBuilder & addImm(int64_t Val) const
addImm - Add a new immediate operand.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
static def_instr_iterator def_instr_end()
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bundle_iterator< MachineInstr, instr_iterator > iterator
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool isReserved(unsigned PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
const MachineOperand & getOperand(unsigned i) const
INSERT_SUBREG - This instruction takes three operands: a register that has subregisters, a register providing an insert value, and a subregister index.
Represent the analysis usage information of a pass.
void setImm(int64_t immVal)
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
BuildMI - Builder interface.
REG_SEQUENCE - This variadic instruction is used to form a register that represents a consecutive seq...
MachineOperand class - Representation of each machine instruction operand.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
def_instr_iterator def_instr_begin(unsigned RegNo) const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
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.
virtual const TargetInstrInfo * getInstrInfo() const
static use_instr_iterator use_instr_end()
BasicBlockListType::iterator iterator
Primary interface to the complete machine description for the target machine.
bool operator==(uint64_t V1, const APInt &V2)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...