27 #define DEBUG_TYPE "a15-sd-optimizer"
56 virtual const char *getPassName()
const {
57 return "ARM A15 S->D optimizer";
73 unsigned Reg,
unsigned Lane,
79 unsigned DReg,
unsigned Lane,
85 unsigned Ssub0,
unsigned Ssub1);
90 unsigned Reg1,
unsigned Reg2);
94 DebugLoc DL,
unsigned DReg,
unsigned Lane,
107 unsigned getDPRLaneFromSPR(
unsigned SReg);
120 unsigned optimizeAllLanesPattern(
MachineInstr *MI,
unsigned Reg);
122 unsigned getPrefSPRLane(
unsigned SReg);
132 std::map<MachineInstr*, unsigned> Replacements;
133 std::set<MachineInstr *> DeadInstr;
151 unsigned A15SDOptimizer::getDPRLaneFromSPR(
unsigned SReg) {
152 unsigned DReg = TRI->getMatchingSuperReg(SReg, ARM::ssub_1,
154 if (DReg != ARM::NoRegister)
return ARM::ssub_1;
160 unsigned A15SDOptimizer::getPrefSPRLane(
unsigned SReg) {
161 if (!TRI->isVirtualRegister(SReg))
162 return getDPRLaneFromSPR(SReg);
165 if (!MI)
return ARM::ssub_0;
168 assert(MO->
isReg() &&
"Non register operand found!");
169 if (!MO)
return ARM::ssub_0;
172 &ARM::SPRRegClass)) {
177 if (MO->
getSubReg() == ARM::ssub_1)
return ARM::ssub_1;
180 return getDPRLaneFromSPR(SReg);
185 void A15SDOptimizer::eraseInstrWithNoUses(
MachineInstr *MI) {
189 DEBUG(
dbgs() <<
"Deleting base instruction " << *MI <<
"\n");
192 while (Front.
size() != 0) {
202 unsigned Reg = MO.
getReg();
203 if (!TRI->isVirtualRegister(Reg))
214 if (DeadInstr.find(Def) != DeadInstr.end())
225 unsigned DefReg = MODef.
getReg();
226 if (!TRI->isVirtualRegister(DefReg)) {
236 if (DeadInstr.find(&*II) == DeadInstr.end()) {
243 if (!IsDead)
continue;
245 DEBUG(
dbgs() <<
"Deleting instruction " << *Def <<
"\n");
246 DeadInstr.insert(Def);
253 unsigned A15SDOptimizer::optimizeSDPattern(
MachineInstr *MI) {
262 if (TRI->isVirtualRegister(DPRReg) && TRI->isVirtualRegister(SPRReg)) {
266 if (DPRMI && SPRMI) {
277 DEBUG(
dbgs() <<
"Found a subreg copy: " << *SPRMI);
285 DEBUG(
dbgs() <<
"Subreg copy is compatible - returning ");
287 eraseInstrWithNoUses(MI);
300 &ARM::SPRRegClass)) {
303 unsigned NumImplicit = 0, NumTotal = 0;
304 unsigned NonImplicitReg = ~0U;
312 if (!TRI->isVirtualRegister(OpReg))
324 if (NumImplicit == NumTotal - 1)
325 return optimizeAllLanesPattern(MI, NonImplicitReg);
330 assert(0 &&
"Unhandled update pattern!");
336 bool A15SDOptimizer::hasPartialWrite(
MachineInstr *MI) {
362 return elideCopies(Def);
367 void A15SDOptimizer::elideCopiesAndPHIs(
MachineInstr *MI,
371 std::set<MachineInstr *> Reached;
374 while (Front.
size() != 0) {
379 if (Reached.find(MI) != Reached.end())
385 if (!TRI->isVirtualRegister(Reg)) {
401 DEBUG(
dbgs() <<
"Found partial copy" << *MI <<
"\n");
420 if (!usesRegClass(MO, &ARM::DPRRegClass) &&
421 !usesRegClass(MO, &ARM::QPRRegClass))
434 unsigned Reg,
unsigned Lane,
bool QPR) {
435 unsigned Out =
MRI->createVirtualRegister(QPR ? &ARM::QPRRegClass :
440 TII->get(QPR ? ARM::VDUPLN32q : ARM::VDUPLN32d),
453 unsigned DReg,
unsigned Lane,
455 unsigned Out =
MRI->createVirtualRegister(TRC);
460 .addReg(DReg, 0, Lane);
470 unsigned Reg1,
unsigned Reg2) {
471 unsigned Out =
MRI->createVirtualRegister(&ARM::QPRRegClass);
489 unsigned Ssub0,
unsigned Ssub1) {
490 unsigned Out =
MRI->createVirtualRegister(&ARM::DPRRegClass);
494 TII->get(ARM::VEXTd32), Out)
504 DebugLoc DL,
unsigned DReg,
unsigned Lane,
506 unsigned Out =
MRI->createVirtualRegister(&ARM::DPR_VFP2RegClass);
522 unsigned Out =
MRI->createVirtualRegister(&ARM::DPRRegClass);
534 A15SDOptimizer::optimizeAllLanesPattern(
MachineInstr *MI,
unsigned Reg) {
542 unsigned DSub0 = createExtractSubreg(MBB, InsertPt, DL, Reg,
543 ARM::dsub_0, &ARM::DPRRegClass);
544 unsigned DSub1 = createExtractSubreg(MBB, InsertPt, DL, Reg,
545 ARM::dsub_1, &ARM::DPRRegClass);
547 unsigned Out1 = createDupLane(MBB, InsertPt, DL, DSub0, 0);
548 unsigned Out2 = createDupLane(MBB, InsertPt, DL, DSub0, 1);
549 Out = createVExt(MBB, InsertPt, DL, Out1, Out2);
551 unsigned Out3 = createDupLane(MBB, InsertPt, DL, DSub1, 0);
552 unsigned Out4 = createDupLane(MBB, InsertPt, DL, DSub1, 1);
553 Out2 = createVExt(MBB, InsertPt, DL, Out3, Out4);
555 Out = createRegSequence(MBB, InsertPt, DL, Out, Out2);
557 }
else if (
MRI->
getRegClass(Reg)->hasSuperClassEq(&ARM::DPRRegClass)) {
558 unsigned Out1 = createDupLane(MBB, InsertPt, DL, Reg, 0);
559 unsigned Out2 = createDupLane(MBB, InsertPt, DL, Reg, 1);
560 Out = createVExt(MBB, InsertPt, DL, Out1, Out2);
563 assert(
MRI->
getRegClass(Reg)->hasSuperClassEq(&ARM::SPRRegClass) &&
564 "Found unexpected regclass!");
566 unsigned PrefLane = getPrefSPRLane(Reg);
569 case ARM::ssub_0: Lane = 0;
break;
570 case ARM::ssub_1: Lane = 1;
break;
574 bool UsesQPR = usesRegClass(MI->
getOperand(0), &ARM::QPRRegClass);
576 Out = createImplicitDef(MBB, InsertPt, DL);
577 Out = createInsertSubreg(MBB, InsertPt, DL, Out, PrefLane, Reg);
578 Out = createDupLane(MBB, InsertPt, DL, Out, Lane, UsesQPR);
579 eraseInstrWithNoUses(MI);
584 bool A15SDOptimizer::runOnInstruction(
MachineInstr *MI) {
616 bool Modified =
false;
625 if (!TRI->isVirtualRegister(*
I))
631 elideCopiesAndPHIs(Def, DefSrcs);
634 EE = DefSrcs.
end(); II != EE; ++II) {
639 if (Replacements.find(MI) != Replacements.end())
643 if (!hasPartialWrite(MI))
650 E =
MRI->use_end();
I != E; ++
I)
654 unsigned NewReg = optimizeSDPattern(MI);
659 E = Uses.
end();
I != E; ++
I) {
670 (*I)->substVirtReg(NewReg, 0, *TRI);
673 Replacements[
MI] = NewReg;
683 bool Modified =
false;
688 Replacements.clear();
695 Modified |= runOnInstruction(MI++);
700 for (std::set<MachineInstr *>::iterator
I = DeadInstr.begin(),
703 (*I)->eraseFromParent();
710 return new A15SDOptimizer();
void push_back(const T &Elt)
FunctionPass * createA15SDOptimizerPass()
MachineInstr * getParent()
static bool isVirtualRegister(unsigned Reg)
iterator insert(iterator I, const T &Elt)
bool hasSuperClassEq(const TargetRegisterClass *RC) const
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
const HexagonInstrInfo * TII
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
ID
LLVM Calling Convention Representation.
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
const MachineBasicBlock * getParent() const
bool isImplicitDef() const
bool isInsertSubreg() const
bundle_iterator< MachineInstr, instr_iterator > iterator
MachineOperand * findRegisterDefOperand(unsigned Reg, bool isDead=false, const TargetRegisterInfo *TRI=NULL)
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value. See class MCOperandInfo.
const MachineOperand & getOperand(unsigned i) const
unsigned getNumExplicitOperands() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
unsigned getSubReg() const
virtual const TargetInstrInfo * getInstrInfo() const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
MachineRegisterInfo & getRegInfo()
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
unsigned getReg() const
getReg - Returns the register number.
BasicBlockListType::iterator iterator
const MCRegisterInfo & MRI
StringRef getName() const
bool isRegSequence() const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
DebugLoc getDebugLoc() const
bool contains(unsigned Reg) const