14 #define DEBUG_TYPE "hexagon-copy-combine"
44 cl::desc(
"Disable merging into combines"));
49 cl::desc(
"Maximum distance between a tfr feeding a store we "
50 "consider the store still to be newifiable"));
62 bool ShouldCombineAggressively;
76 const char *getPassName()
const {
77 return "Hexagon Copy-To-Combine Pass";
91 unsigned I1DestReg,
unsigned I2DestReg,
112 "Hexagon Copy-To-Combine Pass",
false,
false)
116 bool ShouldCombineAggressively) {
117 switch(MI->getOpcode()) {
120 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg());
122 unsigned DestReg = MI->getOperand(0).getReg();
123 unsigned SrcReg = MI->getOperand(1).getReg();
124 return Hexagon::IntRegsRegClass.contains(DestReg) &&
125 Hexagon::IntRegsRegClass.contains(SrcReg);
128 case Hexagon::TFRI: {
131 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
132 unsigned DestReg = MI->getOperand(0).getReg();
135 return Hexagon::IntRegsRegClass.contains(DestReg) &&
136 (ShouldCombineAggressively ||
isInt<8>(MI->getOperand(1).getImm()));
139 case Hexagon::TFRI_V4: {
140 if (!ShouldCombineAggressively)
142 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isGlobal());
150 unsigned DestReg = MI->getOperand(0).getReg();
151 return Hexagon::IntRegsRegClass.contains(DestReg);
162 return I->
getOpcode() == Hexagon::TFRI &&
166 return I->
getOpcode() == Hexagon::TFRI &&
175 assert((HighRegInst->
getOpcode() == Hexagon::TFR ||
176 HighRegInst->
getOpcode() == Hexagon::TFRI ||
177 HighRegInst->
getOpcode() == Hexagon::TFRI_V4) &&
178 (LowRegInst->
getOpcode() == Hexagon::TFR ||
179 LowRegInst->
getOpcode() == Hexagon::TFRI ||
180 LowRegInst->
getOpcode() == Hexagon::TFRI_V4) &&
181 "Assume individual instructions are of a combinable type");
196 if ((HighRegInst->
getOpcode() == Hexagon::TFRI_V4 ||
198 (LowRegInst->
getOpcode() == Hexagon::TFRI_V4 ||
207 Hexagon::IntRegsRegClass.contains(Reg));
208 return (Reg - Hexagon::R0) % 2 == 0;
234 bool HexagonCopyToCombine::isSafeToMoveTogether(
MachineInstr *I1,
238 bool &DoInsertAtI1) {
258 if (!ShouldCombineAggressively)
263 unsigned KilledOperand = 0;
265 KilledOperand = I2UseReg;
268 for (;
I != End; ++
I) {
281 if (!KillingInstr && KilledOperand &&
282 I->readsRegister(KilledOperand, TRI))
290 assert(Added &&
"Must successfully update kill flag");
303 if (!ShouldCombineAggressively)
311 unsigned KilledOperand = 0;
332 (!
I->killsRegister(I1UseReg) &&
I->killsRegister(I1UseReg, TRI)))
336 if (I1UseReg &&
I->killsRegister(I1UseReg)) {
337 assert(KillingInstr == 0 &&
"Should only see one killing instruction");
338 KilledOperand = I1UseReg;
348 assert(Added &&
"Must successfully update kill flag");
350 DoInsertAtI1 =
false;
366 for (
unsigned OpdIdx = 0, OpdE = MI->
getNumOperands(); OpdIdx != OpdE;
379 if (!isCombinableInstType(DefInst, TII, ShouldCombineAggressively))
384 unsigned NumInstsToDef = 0;
391 PotentiallyNewifiableTFR.insert(DefInst);
403 unsigned Reg = Op.
getReg();
404 if (Hexagon::DoubleRegsRegClass.contains(Reg)) {
406 LastDef[*SubRegs] =
MI;
408 }
else if (Hexagon::IntRegsRegClass.contains(Reg))
418 bool HasChanged =
false;
425 ShouldCombineAggressively =
431 PotentiallyNewifiableTFR.clear();
432 findPotentialNewifiableTFRs(*BI);
441 if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I1))
445 if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))
450 bool DoInsertAtI1 =
false;
454 combine(I1, I2, MI, DoInsertAtI1);
467 bool &DoInsertAtI1) {
474 if (I2->modifiesRegister(I1DestReg, TRI))
478 if (!isCombinableInstType(I2, TII, ShouldCombineAggressively))
482 if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(I2))
485 unsigned I2DestReg = I2->getOperand(0).getReg();
489 bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;
490 bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;
491 unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;
492 if ((!IsI1LowReg && !IsI2LowReg) || !
isEvenReg(FirstRegIndex))
503 if (isSafeToMoveTogether(I1, I2, I1DestReg, I2DestReg,
523 bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;
524 unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;
527 unsigned DoubleRegDest =
528 TRI->getMatchingSuperReg(LoRegDef, Hexagon::subreg_loreg,
529 &Hexagon::DoubleRegsRegClass);
530 assert(DoubleRegDest != 0 &&
"Expect a valid register");
540 bool IsHiReg = HiOperand.
isReg();
541 bool IsLoReg = LoOperand.
isReg();
545 if (IsHiReg && IsLoReg)
546 emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
548 emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);
550 emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);
552 emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);
559 unsigned DoubleDestReg,
562 DebugLoc DL = InsertPt->getDebugLoc();
567 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
570 .addImm(LoOperand.
getImm());
574 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg)
575 .addImm(HiOperand.
getImm())
584 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
585 .addImm(HiOperand.
getImm())
586 .addImm(LoOperand.
getImm());
590 if (!isUInt<6>(LoOperand.
getImm())) {
592 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg)
593 .addImm(HiOperand.
getImm())
594 .addImm(LoOperand.
getImm());
600 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
601 .addImm(HiOperand.
getImm())
602 .addImm(LoOperand.
getImm());
606 unsigned DoubleDestReg,
609 unsigned LoReg = LoOperand.
getReg();
612 DebugLoc DL = InsertPt->getDebugLoc();
617 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg)
620 .addReg(LoReg, LoRegKillFlag);
625 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg)
626 .addImm(HiOperand.
getImm())
627 .addReg(LoReg, LoRegKillFlag);
631 unsigned DoubleDestReg,
635 unsigned HiReg = HiOperand.
getReg();
637 DebugLoc DL = InsertPt->getDebugLoc();
642 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg)
643 .addReg(HiReg, HiRegKillFlag)
651 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg)
652 .addReg(HiReg, HiRegKillFlag)
657 unsigned DoubleDestReg,
662 unsigned LoReg = LoOperand.
getReg();
663 unsigned HiReg = HiOperand.
getReg();
665 DebugLoc DL = InsertPt->getDebugLoc();
670 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rr), DoubleDestReg)
671 .addReg(HiReg, HiRegKillFlag)
672 .
addReg(LoReg, LoRegKillFlag);
676 return new HexagonCopyToCombine();
FunctionPass * createHexagonCopyToCombine()
const MachineFunction * getParent() const
INITIALIZE_PASS(HexagonCopyToCombine,"hexagon-copy-combine","Hexagon Copy-To-Combine Pass", false, false) static bool isCombinableInstType(MachineInstr *MI
const GlobalValue * getGlobal() const
static PassRegistry * getPassRegistry()
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isInt< 8 >(int64_t x)
static bool areCombinableOperations(const TargetRegisterInfo *TRI, MachineInstr *HighRegInst, MachineInstr *LowRegInst)
void initializeHexagonCopyToCombinePass(PassRegistry &)
ID
LLVM Calling Convention Representation.
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
static cl::opt< unsigned > MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store", cl::Hidden, cl::init(4), cl::desc("Maximum distance between a tfr feeding a store we ""consider the store still to be newifiable"))
CodeGenOpt::Level getOptLevel() const
unsigned getKillRegState(bool B)
const MachineBasicBlock * getParent() const
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
unsigned getTargetFlags() const
const MachineOperand & getOperand(unsigned i) const
ItTy next(ItTy it, Dist n)
static bool isUnsafeToMoveAcross(MachineInstr *I, unsigned UseReg, unsigned DestReg, const TargetRegisterInfo *TRI)
bool hasUnmodeledSideEffects() const
int64_t getOffset() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
static void removeKillInfo(MachineInstr *MI, unsigned RegNotKilled)
void setIsKill(bool Val=true)
virtual const TargetInstrInfo * getInstrInfo() const
bool killsRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
static bool isPhysicalRegister(unsigned Reg)
virtual void getAnalysisUsage(AnalysisUsage &AU) const
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
static bool isGreaterThan6BitTFRI(MachineInstr *I)
HexagonSubtarget & Subtarget
static bool isEvenReg(unsigned Reg)
unsigned getReg() const
getReg - Returns the register number.
static bool isGreaterThan8BitTFRI(MachineInstr *I)
std::reverse_iterator< iterator > reverse_iterator
BasicBlockListType::iterator iterator
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
static cl::opt< bool > IsCombinesDisabled("disable-merge-into-combines", cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::desc("Disable merging into combines"))
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
bool mayBeNewStore(const MachineInstr *MI) const