53 #define DEBUG_TYPE "packets"
57 cl::desc(
"Allow non-solo packetization of volatile memory references"));
84 const char *getPassName()
const override {
85 return "Hexagon Packetizer";
97 bool PromotedToDotNew;
100 bool GlueAllocframeStore;
103 bool GlueToNewValueJump;
111 bool FoundSequentialDependence;
117 std::vector<MachineInstr*> IgnoreDepMIs;
125 void initPacketizerState()
override;
137 bool isLegalToPacketizeTogether(
SUnit *SUI,
SUnit *SUJ)
override;
141 bool isLegalToPruneDependencies(
SUnit *SUI,
SUnit *SUJ)
override;
150 const std::map<MachineInstr *, SUnit *> &MIToSUnit,
155 const std::map<MachineInstr *, SUnit *> &MIToSUnit,
157 bool CanPromoteToNewValueStore(
159 const std::map<MachineInstr *, SUnit *> &MIToSUnit);
161 bool ArePredicatesComplements(
163 const std::map<MachineInstr *, SUnit *> &MIToSUnit);
164 bool RestrictingDepExistInPacket(
MachineInstr *,
unsigned,
165 const std::map<MachineInstr *, SUnit *> &);
186 HexagonPacketizerList::HexagonPacketizerList(
197 &getAnalysis<MachineBranchProbabilityInfo>();
199 HexagonPacketizerList
Packetizer(Fn, MLI, 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) {
248 RegionEnd = std::prev(RegionEnd);
253 if (I == std::prev(RegionEnd)) {
254 RegionEnd = std::prev(RegionEnd);
268 return MI->
getOpcode() == Hexagon::J2_callr;
273 void HexagonPacketizerList::reserveResourcesForConstExt(
MachineInstr* MI) {
275 MachineInstr *PseudoMI = MF.CreateMachineInstr(QII->get(Hexagon::A4_ext),
278 if (ResourceTracker->canReserveResources(PseudoMI)) {
279 ResourceTracker->reserveResources(PseudoMI);
288 bool HexagonPacketizerList::canReserveResourcesForConstExt(
MachineInstr *MI) {
291 "Should only be called for constant extended instructions");
292 MachineInstr *PseudoMI = MF.CreateMachineInstr(QII->get(Hexagon::A4_ext),
294 bool CanReserve = ResourceTracker->canReserveResources(PseudoMI);
295 MF.DeleteMachineInstr(PseudoMI);
301 bool HexagonPacketizerList::tryAllocateResourcesForConstExt(
MachineInstr* MI) {
303 MachineInstr *PseudoMI = MF.CreateMachineInstr(QII->get(Hexagon::A4_ext),
306 if (ResourceTracker->canReserveResources(PseudoMI)) {
307 ResourceTracker->reserveResources(PseudoMI);
317 bool HexagonPacketizerList::IsCallDependent(
MachineInstr* MI,
338 if (RC == &Hexagon::PredRegsRegClass) {
366 return (MI->
getOpcode() == Hexagon::J2_jump);
371 case Hexagon::Y2_barrier:
382 return (MI->
getOpcode() == Hexagon::J2_loop0i ||
393 unsigned CalleeSavedReg = *CSR;
402 bool HexagonPacketizerList::isNewifiable(
MachineInstr* MI) {
407 bool HexagonPacketizerList::isCondInst (
MachineInstr* MI) {
426 bool HexagonPacketizerList::PromoteToDotNew(
MachineInstr* MI,
434 if (RC == &Hexagon::PredRegsRegClass)
438 MI->
setDesc(QII->get(NewOpcode));
443 bool HexagonPacketizerList::DemoteToDotOld(
MachineInstr* MI) {
446 MI->
setDesc(QII->get(NewOpcode));
494 "Post increment operand has be to a register.");
500 "Post increment operand has be to a register.");
505 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
533 bool HexagonPacketizerList::CanPromoteToNewValueStore(
535 const std::map<MachineInstr *, SUnit *> &MIToSUnit) {
555 for (std::vector<MachineInstr*>::iterator
VI = CurrentPacketMIs.begin(),
556 VE = CurrentPacketMIs.end();
558 SUnit *PacketSU = MIToSUnit.find(*VI)->second;
567 if (PacketRC == &Hexagon::DoubleRegsRegClass) {
600 unsigned predRegNumSrc = 0;
601 unsigned predRegNumDst = 0;
605 for(
unsigned opNum = 0; opNum < PacketMI->
getNumOperands(); opNum++) {
608 predRegClass = QRI->getMinimalPhysRegClass(predRegNumSrc);
609 if (predRegClass == &Hexagon::PredRegsRegClass) {
613 assert ((predRegClass == &Hexagon::PredRegsRegClass ) &&
614 (
"predicate register not found in a predicated PacketMI instruction"));
620 predRegClass = QRI->getMinimalPhysRegClass(predRegNumDst);
621 if (predRegClass == &Hexagon::PredRegsRegClass) {
625 assert ((predRegClass == &Hexagon::PredRegsRegClass ) &&
626 (
"predicate register not found in a predicated MI instruction"));
637 if (( predRegNumDst != predRegNumSrc) ||
652 std::vector<MachineInstr*>::iterator
VI;
653 std::vector<MachineInstr*>::iterator VE;
654 unsigned StartCheck = 0;
656 for (VI=CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end();
658 SUnit *TempSU = MIToSUnit.find(*VI)->second;
664 if (TempMI != PacketMI && !StartCheck)
668 if (TempMI == PacketMI)
688 for(
unsigned opNum = 0; opNum < MI->
getNumOperands()-1; opNum++) {
698 for(
unsigned opNum = 0; opNum < PacketMI->
getNumOperands(); opNum++) {
714 bool HexagonPacketizerList::CanPromoteToNewValue(
716 const std::map<MachineInstr *, SUnit *> &MIToSUnit,
726 if (CanPromoteToNewValueStore(MI, PacketMI, DepReg, MIToSUnit))
739 bool HexagonPacketizerList::CanPromoteToDotNew(
741 const std::map<MachineInstr *, SUnit *> &MIToSUnit,
748 if (!isNewifiable(MI))
752 if (RC == &Hexagon::PredRegsRegClass && isCondInst(MI))
754 else if (RC != &Hexagon::PredRegsRegClass &&
765 bool ResourcesAvailable = ResourceTracker->canReserveResources(NewMI);
768 if (!ResourcesAvailable)
773 if (!CanPromoteToNewValue(MI, PacketSU, DepReg, MIToSUnit, MII)) {
794 bool HexagonPacketizerList::RestrictingDepExistInPacket(
796 const std::map<MachineInstr *, SUnit *> &MIToSUnit) {
799 SUnit *PacketSUDep = MIToSUnit.find(MI)->second;
801 for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(),
802 VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) {
808 SUnit *PacketSU = MIToSUnit.find(*VIN)->second;
814 if (PacketSU->
isSucc(PacketSUDep)) {
815 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
816 if ((PacketSU->
Succs[i].getSUnit() == PacketSUDep) &&
818 (PacketSU->
Succs[i].getReg() == DepReg)) {
835 assert(QII->
isPredicated(MI) &&
"Must be predicated instruction");
841 Hexagon::PredRegsRegClass.contains(Op.
getReg()))
852 bool HexagonPacketizerList::ArePredicatesComplements(
854 const std::map<MachineInstr *, SUnit *> &MIToSUnit) {
865 SUnit *SU = MIToSUnit.find(MI1)->second;
886 for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(),
887 VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) {
890 SUnit *PacketSU = MIToSUnit.find(*VIN)->second;
894 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
900 if (PacketSU->
Succs[i].getSUnit() == SU &&
902 Hexagon::PredRegsRegClass.contains(
903 PacketSU->
Succs[i].getReg()) &&
910 RestrictingDepExistInPacket(*VIN,PacketSU->
Succs[i].getReg(),
926 return ((PReg1 == PReg2) &&
927 Hexagon::PredRegsRegClass.
contains(PReg1) &&
928 Hexagon::PredRegsRegClass.
contains(PReg2) &&
934 void HexagonPacketizerList::initPacketizerState() {
937 PromotedToDotNew =
false;
938 GlueToNewValueJump =
false;
939 GlueAllocframeStore =
false;
940 FoundSequentialDependence =
false;
946 bool HexagonPacketizerList::ignorePseudoInstruction(
MachineInstr *MI,
963 ResourceTracker->getInstrItins()->beginStage(SchedClass);
964 unsigned FuncUnits = IS->
getUnits();
970 bool HexagonPacketizerList::isSoloInstruction(
MachineInstr *MI) {
990 bool HexagonPacketizerList::isLegalToPacketizeTogether(
SUnit *SUI,
SUnit *SUJ) {
993 assert(I && J &&
"Unable to packetize null instruction!");
1000 const unsigned FrameSize = MF.getFrameInfo()->getStackSize();
1009 if (isSoloInstruction(I))
1078 bool secondRegMatch =
false;
1079 bool maintainNewValueJump =
false;
1083 secondRegMatch =
true;
1084 maintainNewValueJump =
true;
1087 if (!secondRegMatch &&
1089 maintainNewValueJump =
true;
1092 for (std::vector<MachineInstr*>::iterator
1093 VI = CurrentPacketMIs.begin(),
1094 VE = CurrentPacketMIs.end();
1095 (VI != VE && maintainNewValueJump); ++
VI) {
1096 SUnit *PacketSU = MIToSUnit.find(*VI)->second;
1126 GlueToNewValueJump =
true;
1132 for (
unsigned i = 0;
1133 (i < SUJ->
Succs.size()) && !FoundSequentialDependence;
1136 if (SUJ->
Succs[i].getSUnit() != SUI) {
1165 unsigned DepReg = 0;
1168 DepReg = SUJ->
Succs[i].getReg();
1169 RC = QRI->getMinimalPhysRegClass(DepReg);
1173 !IsCallDependent(I, DepType, SUJ->
Succs[i].getReg()))) {
1179 CanPromoteToDotNew(I, SUJ, DepReg, MIToSUnit, II, RC) &&
1180 PromoteToDotNew(I, DepType, II, RC)) {
1181 PromotedToDotNew =
true;
1194 ArePredicatesComplements(I, J, MIToSUnit)) {
1234 unsigned DepReg = SUJ->
Succs[i].getReg();
1239 FoundSequentialDependence =
true;
1262 FoundSequentialDependence =
true;
1272 && J->
getOpcode() == Hexagon::S2_allocframe
1273 && (I->
getOpcode() == Hexagon::S2_storerd_io
1274 || I->
getOpcode() == Hexagon::S2_storeri_io
1275 || I->
getOpcode() == Hexagon::S2_storerb_io)
1281 GlueAllocframeStore =
true;
1295 FoundSequentialDependence =
true;
1300 if (FoundSequentialDependence) {
1310 bool HexagonPacketizerList::isLegalToPruneDependencies(
SUnit *SUI,
SUnit *SUJ) {
1312 assert(I && SUJ->
getInstr() &&
"Unable to packetize null instruction!");
1314 const unsigned FrameSize = MF.getFrameInfo()->getStackSize();
1320 if (PromotedToDotNew) {
1327 if (GlueAllocframeStore) {
1345 if (GlueToNewValueJump) {
1349 assert(ResourceTracker->canReserveResources(MI));
1350 ResourceTracker->reserveResources(MI);
1352 !tryAllocateResourcesForConstExt(MI)) {
1354 ResourceTracker->reserveResources(MI);
1355 assert(canReserveResourcesForConstExt(MI) &&
1356 "Ensure that there is a slot");
1357 reserveResourcesForConstExt(MI);
1359 assert(canReserveResourcesForConstExt(MI) &&
1360 "Ensure that there is a slot");
1361 reserveResourcesForConstExt(nvjMI);
1362 assert(ResourceTracker->canReserveResources(nvjMI) &&
1363 "Ensure that there is a slot");
1368 && (!tryAllocateResourcesForConstExt(nvjMI)
1369 || !ResourceTracker->canReserveResources(nvjMI)))
1372 !ResourceTracker->canReserveResources(nvjMI)))
1378 ResourceTracker->reserveResources(MI);
1380 reserveResourcesForConstExt(nvjMI);
1383 ResourceTracker->reserveResources(nvjMI);
1384 CurrentPacketMIs.push_back(MI);
1385 CurrentPacketMIs.push_back(nvjMI);
1388 && ( !tryAllocateResourcesForConstExt(MI)
1389 || !ResourceTracker->canReserveResources(MI)))
1394 if (PromotedToDotNew) {
1397 reserveResourcesForConstExt(MI);
1401 ResourceTracker->reserveResources(MI);
1402 CurrentPacketMIs.push_back(MI);
1412 return new HexagonPacketizer();
bool isConditionalLoad(const MachineInstr *MI) const
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
mop_iterator operands_end()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
MachineInstr * CreateMachineInstr(const MCInstrDesc &MCID, DebugLoc DL, bool NoImp=false)
CreateMachineInstr - Allocate a new MachineInstr.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
unsigned getFrameRegister(const MachineFunction &MF) const override
bool isSucc(SUnit *N)
isSucc - Test if node N is a successor of this node.
static PredicateKind getPredicateSense(MachineInstr *MI, const HexagonInstrInfo *QII)
Returns true if an instruction is predicated on p0 and false if it's predicated on !p0...
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.
Describe properties that are true of each instruction in the target description file.
MachineInstr * getInstr() const
getInstr - Return the representative MachineInstr for this SUnit.
unsigned getRARegister() const
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
static bool IsIndirectCall(MachineInstr *MI)
static bool IsControlFlow(MachineInstr *MI)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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
Returns the target instruction descriptor of this MachineInstr.
virtual bool isSchedulingBoundary(const MachineInstr *MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const
Test if the given instruction should be considered a scheduling boundary.
bool isCFIInstruction() const
static MachineOperand & GetStoreValueOperand(MachineInstr *MI)
Kind
Kind - These are the different kinds of scheduling dependencies.
bool isPostIncrement(const MachineInstr *MI) const
A register anti-dependedence (aka WAR).
bool isConditionalTransfer(const MachineInstr *MI) const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool isMemOp(const MachineInstr *MI) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isPredicated(const MachineInstr *MI) const override
int GetDotOldOp(const int opc) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
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
Returns the choice of FUs.
bool isTerminator() const
Returns true if this instruction part of the terminator for a basic block.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool IsDirectJump(MachineInstr *MI)
INLINEASM - Represents an inline asm block.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
A register output-dependence (aka WAW).
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.
virtual const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const =0
getCalleeSavedRegs - Return a null-terminated list of all of the callee saved registers on this targe...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
initializer< Ty > init(const Ty &Val)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
FunctionPass * createHexagonPacketizer()
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bundle_iterator - MachineBasicBlock iterator that automatically skips over MIs that are inside bundle...
const MachineOperand & getOperand(unsigned i) const
bool isSaveCalleeSavedRegsCall(const MachineInstr *MI) const
Represent the analysis usage information of a pass.
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)
bool isPredicatedTrue(const MachineInstr *MI) const
FunctionPass class - This class is used to implement most global optimizations.
bool isConstExtended(const MachineInstr *MI) const
bool isConditionalStore(const MachineInstr *MI) const
#define INITIALIZE_AG_DEPENDENCY(depName)
int GetDotNewOp(const MachineInstr *MI) const
void DeleteMachineInstr(MachineInstr *MI)
DeleteMachineInstr - Delete the given MachineInstr.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Any other ordering dependency.
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
#define HEXAGON_LRFP_SIZE
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
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.
static bool IsRegDependence(const SDep::Kind DepType)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
int GetDotNewPredOp(MachineInstr *MI, const MachineBranchProbabilityInfo *MBPI) const
bool isExtended(const MachineInstr *MI) const
Representation of each machine instruction.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
These values represent a non-pipelined step in the execution of an instruction.
bool isConditionalALU32(const MachineInstr *MI) const
unsigned getStackRegister() const
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
mop_iterator operands_begin()
SmallVector< SDep, 4 > Succs
bool isNewValueJump(const MachineInstr *MI) const
BasicBlockListType::iterator iterator
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static bool DoesModifyCalleeSavedReg(MachineInstr *MI, const TargetRegisterInfo *TRI)
DoesModifyCalleeSavedReg - Returns true if the instruction modifies a callee-saved register...
Dependence - This class represents a dependence between two memory memory references in a function...
bool isValidOffset(unsigned Opcode, int Offset, bool Extend=true) const
bool isDotNewInst(const MachineInstr *MI) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool modifiesRegister(unsigned Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register...
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
SUnit - Scheduling unit. This is a node in the scheduling DAG.
bool mayBeNewStore(const MachineInstr *MI) const