19 #define DEBUG_TYPE "packets"
57 cl::desc(
"Allow non-solo packetization of volatile memory references"));
83 const char *getPassName()
const {
84 return "Hexagon Packetizer";
96 bool PromotedToDotNew;
99 bool GlueAllocframeStore;
102 bool GlueToNewValueJump;
110 bool FoundSequentialDependence;
116 std::vector<MachineInstr*> IgnoreDepMIs;
125 void initPacketizerState();
136 bool isLegalToPacketizeTogether(
SUnit *SUI,
SUnit *SUJ);
140 bool isLegalToPruneDependencies(
SUnit *SUI,
SUnit *SUJ);
150 std::map <MachineInstr*, SUnit*> MIToSUnit,
155 std::map <MachineInstr*, SUnit*> MIToSUnit,
159 std::map <MachineInstr*, SUnit*> MIToSUnit);
162 std::map <MachineInstr*, SUnit*> MIToSUnit);
164 unsigned, std::map <MachineInstr*, SUnit*>);
185 HexagonPacketizerList::HexagonPacketizerList(
197 &getAnalysis<MachineBranchProbabilityInfo>();
199 HexagonPacketizerList
Packetizer(Fn, MLI, MDT, MBPI);
202 assert(
Packetizer.getResourceTracker() &&
"Empty DFA table!");
215 MBB != MBBe; ++MBB) {
222 MBB->erase(DeleteMI);
232 MBB != MBBe; ++MBB) {
234 unsigned RemainingCount = MBB->size();
236 RegionEnd != MBB->begin();) {
240 for(;I != MBB->begin(); --
I, --RemainingCount) {
247 if (I == RegionEnd) {
268 return ((MI->
getOpcode() == Hexagon::CALLR) ||
274 void HexagonPacketizerList::reserveResourcesForConstExt(
MachineInstr* MI) {
280 if (ResourceTracker->canReserveResources(PseudoMI)) {
281 ResourceTracker->reserveResources(PseudoMI);
290 bool HexagonPacketizerList::canReserveResourcesForConstExt(
MachineInstr *MI) {
293 "Should only be called for constant extended instructions");
297 bool CanReserve = ResourceTracker->canReserveResources(PseudoMI);
304 bool HexagonPacketizerList::tryAllocateResourcesForConstExt(
MachineInstr* MI) {
310 if (ResourceTracker->canReserveResources(PseudoMI)) {
311 ResourceTracker->reserveResources(PseudoMI);
321 bool HexagonPacketizerList::IsCallDependent(
MachineInstr* MI,
342 if (RC == &Hexagon::PredRegsRegClass) {
370 return (MI->
getOpcode() == Hexagon::JMP);
386 return (MI->
getOpcode() == Hexagon::LOOP0_i ||
395 unsigned CalleeSavedReg = *CSR;
404 bool HexagonPacketizerList::isNewifiable(
MachineInstr* MI) {
412 bool HexagonPacketizerList::isCondInst (
MachineInstr* MI) {
431 bool HexagonPacketizerList::PromoteToDotNew(
MachineInstr* MI,
439 if (RC == &Hexagon::PredRegsRegClass)
443 MI->
setDesc(QII->get(NewOpcode));
448 bool HexagonPacketizerList::DemoteToDotOld(
MachineInstr* MI) {
451 MI->
setDesc(QII->get(NewOpcode));
499 "Post increment operand has be to a register.");
505 "Post increment operand has be to a register.");
510 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
538 bool HexagonPacketizerList::CanPromoteToNewValueStore(
MachineInstr *MI,
540 std::map <MachineInstr*, SUnit*> MIToSUnit) {
560 for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(),
561 VE = CurrentPacketMIs.end();
563 SUnit* PacketSU = MIToSUnit[*VI];
572 if (PacketRC == &Hexagon::DoubleRegsRegClass) {
605 unsigned predRegNumSrc = 0;
606 unsigned predRegNumDst = 0;
610 for(
unsigned opNum = 0; opNum < PacketMI->
getNumOperands(); opNum++) {
613 predRegClass = QRI->getMinimalPhysRegClass(predRegNumSrc);
614 if (predRegClass == &Hexagon::PredRegsRegClass) {
618 assert ((predRegClass == &Hexagon::PredRegsRegClass ) &&
619 (
"predicate register not found in a predicated PacketMI instruction"));
625 predRegClass = QRI->getMinimalPhysRegClass(predRegNumDst);
626 if (predRegClass == &Hexagon::PredRegsRegClass) {
630 assert ((predRegClass == &Hexagon::PredRegsRegClass ) &&
631 (
"predicate register not found in a predicated MI instruction"));
642 if (( predRegNumDst != predRegNumSrc) ||
657 std::vector<MachineInstr*>::iterator VI;
658 std::vector<MachineInstr*>::iterator VE;
659 unsigned StartCheck = 0;
661 for (VI=CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end();
663 SUnit* TempSU = MIToSUnit[*VI];
669 if (TempMI != PacketMI && !StartCheck)
673 if (TempMI == PacketMI)
693 for(
unsigned opNum = 0; opNum < MI->
getNumOperands()-1; opNum++) {
703 for(
unsigned opNum = 0; opNum < PacketMI->
getNumOperands(); opNum++) {
719 bool HexagonPacketizerList::CanPromoteToNewValue(
MachineInstr *MI,
720 SUnit *PacketSU,
unsigned DepReg,
721 std::map <MachineInstr*, SUnit*> MIToSUnit,
735 if (CanPromoteToNewValueStore(MI, PacketMI, DepReg, MIToSUnit))
748 bool HexagonPacketizerList::CanPromoteToDotNew(
MachineInstr *MI,
749 SUnit *PacketSU,
unsigned DepReg,
750 std::map <MachineInstr*, SUnit*> MIToSUnit,
759 if (!isNewifiable(MI))
763 if (RC == &Hexagon::PredRegsRegClass && isCondInst(MI))
765 else if (RC != &Hexagon::PredRegsRegClass &&
776 bool ResourcesAvailable = ResourceTracker->canReserveResources(NewMI);
779 if (!ResourcesAvailable)
784 if (!CanPromoteToNewValue(MI, PacketSU, DepReg, MIToSUnit, MII)) {
805 bool HexagonPacketizerList::RestrictingDepExistInPacket (
MachineInstr* MI,
807 std::map <MachineInstr*, SUnit*> MIToSUnit) {
810 SUnit* PacketSUDep = MIToSUnit[
MI];
812 for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(),
813 VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) {
819 SUnit* PacketSU = MIToSUnit[*VIN];
825 if (PacketSU->
isSucc(PacketSUDep)) {
826 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
827 if ((PacketSU->
Succs[i].getSUnit() == PacketSUDep) &&
829 (PacketSU->
Succs[i].getReg() == DepReg)) {
846 assert(QII->
isPredicated(MI) &&
"Must be predicated instruction");
852 Hexagon::PredRegsRegClass.contains(Op.
getReg()))
863 bool HexagonPacketizerList::ArePredicatesComplements (
MachineInstr* MI1,
864 MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) {
875 SUnit* SU = MIToSUnit[MI1];
896 for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(),
897 VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) {
900 SUnit* PacketSU = MIToSUnit[*VIN];
903 if (PacketSU->
isSucc(SU)) {
904 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
910 if (PacketSU->
Succs[i].getSUnit() == SU &&
912 Hexagon::PredRegsRegClass.contains(
913 PacketSU->
Succs[i].getReg()) &&
920 RestrictingDepExistInPacket(*VIN,PacketSU->
Succs[i].getReg(),
936 return ((PReg1 == PReg2) &&
937 Hexagon::PredRegsRegClass.contains(PReg1) &&
938 Hexagon::PredRegsRegClass.contains(PReg2) &&
944 void HexagonPacketizerList::initPacketizerState() {
947 PromotedToDotNew =
false;
948 GlueToNewValueJump =
false;
949 GlueAllocframeStore =
false;
950 FoundSequentialDependence =
false;
956 bool HexagonPacketizerList::ignorePseudoInstruction(
MachineInstr *MI,
970 ResourceTracker->getInstrItins()->beginStage(SchedClass);
971 unsigned FuncUnits = IS->
getUnits();
977 bool HexagonPacketizerList::isSoloInstruction(
MachineInstr *MI) {
998 bool HexagonPacketizerList::isLegalToPacketizeTogether(
SUnit *SUI,
SUnit *SUJ) {
1001 assert(I && J &&
"Unable to packetize null instruction!");
1017 if (isSoloInstruction(I))
1087 bool secondRegMatch =
false;
1088 bool maintainNewValueJump =
false;
1092 secondRegMatch =
true;
1093 maintainNewValueJump =
true;
1096 if (!secondRegMatch &&
1098 maintainNewValueJump =
true;
1101 for (std::vector<MachineInstr*>::iterator
1102 VI = CurrentPacketMIs.begin(),
1103 VE = CurrentPacketMIs.end();
1104 (VI != VE && maintainNewValueJump); ++VI) {
1105 SUnit* PacketSU = MIToSUnit[*VI];
1135 GlueToNewValueJump =
true;
1142 for (
unsigned i = 0;
1143 (i < SUJ->
Succs.size()) && !FoundSequentialDependence;
1146 if (SUJ->
Succs[i].getSUnit() != SUI) {
1175 unsigned DepReg = 0;
1178 DepReg = SUJ->
Succs[i].getReg();
1179 RC = QRI->getMinimalPhysRegClass(DepReg);
1183 !IsCallDependent(I, DepType, SUJ->
Succs[i].getReg()))) {
1189 CanPromoteToDotNew(I, SUJ, DepReg, MIToSUnit, II, RC) &&
1190 PromoteToDotNew(I, DepType, II, RC)) {
1191 PromotedToDotNew =
true;
1204 ArePredicatesComplements(I, J, MIToSUnit)) {
1244 unsigned DepReg = SUJ->
Succs[i].getReg();
1249 FoundSequentialDependence =
true;
1274 FoundSequentialDependence =
true;
1285 && J->
getOpcode() == Hexagon::ALLOCFRAME
1294 GlueAllocframeStore =
true;
1308 FoundSequentialDependence =
true;
1313 if (FoundSequentialDependence) {
1323 bool HexagonPacketizerList::isLegalToPruneDependencies(
SUnit *SUI,
SUnit *SUJ) {
1325 assert(I && SUJ->
getInstr() &&
"Unable to packetize null instruction!");
1333 if (PromotedToDotNew) {
1340 if (GlueAllocframeStore) {
1358 if (GlueToNewValueJump) {
1362 assert(ResourceTracker->canReserveResources(MI));
1363 ResourceTracker->reserveResources(MI);
1365 !tryAllocateResourcesForConstExt(MI)) {
1367 ResourceTracker->reserveResources(MI);
1368 assert(canReserveResourcesForConstExt(MI) &&
1369 "Ensure that there is a slot");
1370 reserveResourcesForConstExt(MI);
1372 assert(canReserveResourcesForConstExt(MI) &&
1373 "Ensure that there is a slot");
1374 reserveResourcesForConstExt(nvjMI);
1375 assert(ResourceTracker->canReserveResources(nvjMI) &&
1376 "Ensure that there is a slot");
1381 && (!tryAllocateResourcesForConstExt(nvjMI)
1382 || !ResourceTracker->canReserveResources(nvjMI)))
1385 !ResourceTracker->canReserveResources(nvjMI)))
1391 ResourceTracker->reserveResources(MI);
1393 reserveResourcesForConstExt(nvjMI);
1396 ResourceTracker->reserveResources(nvjMI);
1397 CurrentPacketMIs.push_back(MI);
1398 CurrentPacketMIs.push_back(nvjMI);
1401 && ( !tryAllocateResourcesForConstExt(MI)
1402 || !ResourceTracker->canReserveResources(MI)))
1407 if (PromotedToDotNew) {
1410 reserveResourcesForConstExt(MI);
1414 ResourceTracker->reserveResources(MI);
1415 CurrentPacketMIs.push_back(MI);
1425 return new HexagonPacketizer();
bool isConditionalLoad(const MachineInstr *MI) const
const MachineFunction * getParent() const
mop_iterator operands_end()
AnalysisUsage & addPreserved()
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImp=false)
static PassRegistry * getPassRegistry()
bool isSucc(SUnit *N)
isSucc - Test if node N is a successor of this node.
static PredicateKind getPredicateSense(MachineInstr *MI, const HexagonInstrInfo *QII)
static bool IsLoopN(MachineInstr *MI)
bool isReturn() const
Return true if the instruction is a return.
bool mayStore() const
Return true if this instruction could possibly modify memory. Instructions with this flag set are not...
MachineInstr * getInstr() const
bool hasOrderedMemoryRef() const
static bool IsIndirectCall(MachineInstr *MI)
static bool IsControlFlow(MachineInstr *MI)
static cl::opt< bool > PacketizeVolatiles("hexagon-packetize-volatiles", cl::ZeroOrMore, cl::Hidden, cl::init(true), cl::desc("Allow non-solo packetization of volatile memory references"))
const MCInstrDesc & getDesc() const
virtual bool isPredicated(const MachineInstr *MI) const
virtual bool isSchedulingBoundary(const MachineInstr *MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
static MachineOperand & GetStoreValueOperand(MachineInstr *MI)
bool isConstExtended(MachineInstr *MI) const
Kind
Kind - These are the different kinds of scheduling dependencies.
bool isPostIncrement(const MachineInstr *MI) const
A register anti-dependedence (aka WAR).
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF=0) const =0
bool isConditionalTransfer(const MachineInstr *MI) const
unsigned getStackRegister() const
uint64_t getStackSize() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isMemOp(const MachineInstr *MI) const
const HexagonInstrInfo * TII
int GetDotOldOp(const int opc) const
#define llvm_unreachable(msg)
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch. Predicates below can be use...
bool isCall() const
Return true if the instruction is a call.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Regular data dependence (aka true-dependence).
unsigned getUnits() const
getUnits - returns the choice of FUs
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block. Typically this is things l...
ID
LLVM Calling Convention Representation.
static bool IsDirectJump(MachineInstr *MI)
unsigned getNumOperands() const
A register output-dependence (aka WAW).
bool isValidOffset(const int Opcode, const int Offset) const
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=NULL) const
void initializeHexagonPacketizerPass(PassRegistry &)
bool isBarrier() const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
static unsigned getPredicatedRegister(MachineInstr *MI, const HexagonInstrInfo *QII)
Gets the predicate register of a predicated instruction.
const MachineBasicBlock * getParent() const
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
FunctionPass * createHexagonPacketizer()
const MachineOperand & getOperand(unsigned i) const
bool isSaveCalleeSavedRegsCall(const MachineInstr *MI) const
bool isDeallocRet(const MachineInstr *MI) const
static MachineOperand & GetPostIncrementOperand(MachineInstr *MI, const HexagonInstrInfo *QII)
bool isNewValueInst(const MachineInstr *MI) const
static bool IsSchedBarrier(MachineInstr *MI)
void setImm(int64_t immVal)
virtual bool isPredicatedTrue(const MachineInstr *MI) const
bool isConditionalStore(const MachineInstr *MI) const
unsigned getRARegister() const
#define INITIALIZE_AG_DEPENDENCY(depName)
int GetDotNewOp(const MachineInstr *MI) const
void DeleteMachineInstr(MachineInstr *MI)
Any other ordering dependency.
virtual const TargetInstrInfo * getInstrInfo() const
#define HEXAGON_LRFP_SIZE
void setDesc(const MCInstrDesc &tid)
INITIALIZE_PASS_BEGIN(HexagonPacketizer,"packets","Hexagon Packetizer", false, false) INITIALIZE_PASS_END(HexagonPacketizer
bool mayLoad() const
Return true if this instruction could possibly read memory. Instructions with this flag set are not n...
static bool IsRegDependence(const SDep::Kind DepType)
MachineFrameInfo * getFrameInfo()
int GetDotNewPredOp(MachineInstr *MI, const MachineBranchProbabilityInfo *MBPI) const
unsigned getFrameRegister(const MachineFunction &MF) const
bool isExtended(const MachineInstr *MI) const
unsigned getSchedClass() const
Return the scheduling class for this instruction. The scheduling class is an index into the InstrItin...
virtual void getAnalysisUsage(AnalysisUsage &AU) const
bool isConditionalALU32(const MachineInstr *MI) const
const TargetMachine & getTarget() const
HexagonSubtarget & Subtarget
unsigned getReg() const
getReg - Returns the register number.
mop_iterator operands_begin()
SmallVector< SDep, 4 > Succs
bool isNewValueJump(const MachineInstr *MI) const
BasicBlockListType::iterator iterator
ItTy prior(ItTy it, Dist n)
static bool DoesModifyCalleeSavedReg(MachineInstr *MI, const TargetRegisterInfo *TRI)
bool isDotNewInst(const MachineInstr *MI) const
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
DebugLoc getDebugLoc() const
SUnit - Scheduling unit. This is a node in the scheduling DAG.
bool mayBeNewStore(const MachineInstr *MI) const