1239310Sdim//===----- HexagonPacketizer.cpp - vliw packetizer ---------------------===// 2239310Sdim// 3239310Sdim// The LLVM Compiler Infrastructure 4239310Sdim// 5239310Sdim// This file is distributed under the University of Illinois Open Source 6239310Sdim// License. See LICENSE.TXT for details. 7239310Sdim// 8239310Sdim//===----------------------------------------------------------------------===// 9239310Sdim// 10239310Sdim// This implements a simple VLIW packetizer using DFA. The packetizer works on 11239310Sdim// machine basic blocks. For each instruction I in BB, the packetizer consults 12239310Sdim// the DFA to see if machine resources are available to execute I. If so, the 13239310Sdim// packetizer checks if I depends on any instruction J in the current packet. 14239310Sdim// If no dependency is found, I is added to current packet and machine resource 15239310Sdim// is marked as taken. If any dependency is found, a target API call is made to 16239310Sdim// prune the dependence. 17239310Sdim// 18239310Sdim//===----------------------------------------------------------------------===// 19239310Sdim#define DEBUG_TYPE "packets" 20239310Sdim#include "llvm/CodeGen/DFAPacketizer.h" 21239310Sdim#include "llvm/CodeGen/Passes.h" 22239310Sdim#include "llvm/CodeGen/MachineDominators.h" 23239310Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 24239310Sdim#include "llvm/CodeGen/MachineLoopInfo.h" 25239310Sdim#include "llvm/CodeGen/ScheduleDAG.h" 26239310Sdim#include "llvm/CodeGen/ScheduleDAGInstrs.h" 27239310Sdim#include "llvm/CodeGen/LatencyPriorityQueue.h" 28239310Sdim#include "llvm/CodeGen/SchedulerRegistry.h" 29239310Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 30239310Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 31239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 32239310Sdim#include "llvm/CodeGen/MachineFunctionAnalysis.h" 33239310Sdim#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 34239310Sdim#include "llvm/Target/TargetMachine.h" 35239310Sdim#include "llvm/Target/TargetInstrInfo.h" 36239310Sdim#include "llvm/Target/TargetRegisterInfo.h" 37239310Sdim#include "llvm/ADT/DenseMap.h" 38239310Sdim#include "llvm/ADT/Statistic.h" 39239310Sdim#include "llvm/Support/MathExtras.h" 40239310Sdim#include "llvm/MC/MCInstrItineraries.h" 41239310Sdim#include "llvm/Support/Compiler.h" 42239310Sdim#include "llvm/Support/CommandLine.h" 43239310Sdim#include "llvm/Support/Debug.h" 44239310Sdim#include "Hexagon.h" 45239310Sdim#include "HexagonTargetMachine.h" 46239310Sdim#include "HexagonRegisterInfo.h" 47239310Sdim#include "HexagonSubtarget.h" 48239310Sdim#include "HexagonMachineFunctionInfo.h" 49239310Sdim 50239310Sdim#include <map> 51251662Sdim#include <vector> 52239310Sdim 53239310Sdimusing namespace llvm; 54239310Sdim 55251662Sdimstatic cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles", 56251662Sdim cl::ZeroOrMore, cl::Hidden, cl::init(true), 57251662Sdim cl::desc("Allow non-solo packetization of volatile memory references")); 58251662Sdim 59251662Sdimnamespace llvm { 60251662Sdim void initializeHexagonPacketizerPass(PassRegistry&); 61251662Sdim} 62251662Sdim 63251662Sdim 64239310Sdimnamespace { 65239310Sdim class HexagonPacketizer : public MachineFunctionPass { 66239310Sdim 67239310Sdim public: 68239310Sdim static char ID; 69251662Sdim HexagonPacketizer() : MachineFunctionPass(ID) { 70251662Sdim initializeHexagonPacketizerPass(*PassRegistry::getPassRegistry()); 71251662Sdim } 72239310Sdim 73239310Sdim void getAnalysisUsage(AnalysisUsage &AU) const { 74239310Sdim AU.setPreservesCFG(); 75239310Sdim AU.addRequired<MachineDominatorTree>(); 76251662Sdim AU.addRequired<MachineBranchProbabilityInfo>(); 77239310Sdim AU.addPreserved<MachineDominatorTree>(); 78239310Sdim AU.addRequired<MachineLoopInfo>(); 79239310Sdim AU.addPreserved<MachineLoopInfo>(); 80239310Sdim MachineFunctionPass::getAnalysisUsage(AU); 81239310Sdim } 82239310Sdim 83239310Sdim const char *getPassName() const { 84239310Sdim return "Hexagon Packetizer"; 85239310Sdim } 86239310Sdim 87239310Sdim bool runOnMachineFunction(MachineFunction &Fn); 88239310Sdim }; 89239310Sdim char HexagonPacketizer::ID = 0; 90239310Sdim 91239310Sdim class HexagonPacketizerList : public VLIWPacketizerList { 92239310Sdim 93239310Sdim private: 94239310Sdim 95239310Sdim // Has the instruction been promoted to a dot-new instruction. 96239310Sdim bool PromotedToDotNew; 97239310Sdim 98239310Sdim // Has the instruction been glued to allocframe. 99239310Sdim bool GlueAllocframeStore; 100239310Sdim 101239310Sdim // Has the feeder instruction been glued to new value jump. 102239310Sdim bool GlueToNewValueJump; 103239310Sdim 104239310Sdim // Check if there is a dependence between some instruction already in this 105239310Sdim // packet and this instruction. 106239310Sdim bool Dependence; 107239310Sdim 108239310Sdim // Only check for dependence if there are resources available to 109239310Sdim // schedule this instruction. 110239310Sdim bool FoundSequentialDependence; 111239310Sdim 112251662Sdim /// \brief A handle to the branch probability pass. 113251662Sdim const MachineBranchProbabilityInfo *MBPI; 114251662Sdim 115251662Sdim // Track MIs with ignored dependece. 116251662Sdim std::vector<MachineInstr*> IgnoreDepMIs; 117251662Sdim 118239310Sdim public: 119239310Sdim // Ctor. 120239310Sdim HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, 121251662Sdim MachineDominatorTree &MDT, 122251662Sdim const MachineBranchProbabilityInfo *MBPI); 123239310Sdim 124239310Sdim // initPacketizerState - initialize some internal flags. 125239310Sdim void initPacketizerState(); 126239310Sdim 127239310Sdim // ignorePseudoInstruction - Ignore bundling of pseudo instructions. 128239310Sdim bool ignorePseudoInstruction(MachineInstr *MI, MachineBasicBlock *MBB); 129239310Sdim 130239310Sdim // isSoloInstruction - return true if instruction MI can not be packetized 131239310Sdim // with any other instruction, which means that MI itself is a packet. 132239310Sdim bool isSoloInstruction(MachineInstr *MI); 133239310Sdim 134239310Sdim // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ 135239310Sdim // together. 136239310Sdim bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ); 137239310Sdim 138239310Sdim // isLegalToPruneDependencies - Is it legal to prune dependece between SUI 139239310Sdim // and SUJ. 140239310Sdim bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ); 141239310Sdim 142239310Sdim MachineBasicBlock::iterator addToPacket(MachineInstr *MI); 143239310Sdim private: 144239310Sdim bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg); 145239310Sdim bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType, 146251662Sdim MachineBasicBlock::iterator &MII, 147251662Sdim const TargetRegisterClass* RC); 148239310Sdim bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU, 149251662Sdim unsigned DepReg, 150251662Sdim std::map <MachineInstr*, SUnit*> MIToSUnit, 151251662Sdim MachineBasicBlock::iterator &MII, 152251662Sdim const TargetRegisterClass* RC); 153239310Sdim bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU, 154251662Sdim unsigned DepReg, 155251662Sdim std::map <MachineInstr*, SUnit*> MIToSUnit, 156251662Sdim MachineBasicBlock::iterator &MII); 157239310Sdim bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI, 158251662Sdim unsigned DepReg, 159251662Sdim std::map <MachineInstr*, SUnit*> MIToSUnit); 160239310Sdim bool DemoteToDotOld(MachineInstr* MI); 161239310Sdim bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2, 162239310Sdim std::map <MachineInstr*, SUnit*> MIToSUnit); 163239310Sdim bool RestrictingDepExistInPacket(MachineInstr*, 164239310Sdim unsigned, std::map <MachineInstr*, SUnit*>); 165239310Sdim bool isNewifiable(MachineInstr* MI); 166239310Sdim bool isCondInst(MachineInstr* MI); 167239310Sdim bool tryAllocateResourcesForConstExt(MachineInstr* MI); 168239310Sdim bool canReserveResourcesForConstExt(MachineInstr *MI); 169239310Sdim void reserveResourcesForConstExt(MachineInstr* MI); 170239310Sdim bool isNewValueInst(MachineInstr* MI); 171239310Sdim }; 172239310Sdim} 173239310Sdim 174251662SdimINITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer", 175251662Sdim false, false) 176251662SdimINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 177251662SdimINITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) 178251662SdimINITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 179251662SdimINITIALIZE_AG_DEPENDENCY(AliasAnalysis) 180251662SdimINITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer", 181251662Sdim false, false) 182251662Sdim 183251662Sdim 184239310Sdim// HexagonPacketizerList Ctor. 185239310SdimHexagonPacketizerList::HexagonPacketizerList( 186251662Sdim MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT, 187251662Sdim const MachineBranchProbabilityInfo *MBPI) 188239310Sdim : VLIWPacketizerList(MF, MLI, MDT, true){ 189251662Sdim this->MBPI = MBPI; 190239310Sdim} 191239310Sdim 192239310Sdimbool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) { 193239310Sdim const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); 194239310Sdim MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); 195239310Sdim MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); 196251662Sdim const MachineBranchProbabilityInfo *MBPI = 197251662Sdim &getAnalysis<MachineBranchProbabilityInfo>(); 198239310Sdim // Instantiate the packetizer. 199251662Sdim HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI); 200239310Sdim 201239310Sdim // DFA state table should not be empty. 202239310Sdim assert(Packetizer.getResourceTracker() && "Empty DFA table!"); 203239310Sdim 204239310Sdim // 205239310Sdim // Loop over all basic blocks and remove KILL pseudo-instructions 206239310Sdim // These instructions confuse the dependence analysis. Consider: 207239310Sdim // D0 = ... (Insn 0) 208239310Sdim // R0 = KILL R0, D0 (Insn 1) 209239310Sdim // R0 = ... (Insn 2) 210239310Sdim // Here, Insn 1 will result in the dependence graph not emitting an output 211239310Sdim // dependence between Insn 0 and Insn 2. This can lead to incorrect 212239310Sdim // packetization 213239310Sdim // 214239310Sdim for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 215239310Sdim MBB != MBBe; ++MBB) { 216239310Sdim MachineBasicBlock::iterator End = MBB->end(); 217239310Sdim MachineBasicBlock::iterator MI = MBB->begin(); 218239310Sdim while (MI != End) { 219239310Sdim if (MI->isKill()) { 220239310Sdim MachineBasicBlock::iterator DeleteMI = MI; 221239310Sdim ++MI; 222239310Sdim MBB->erase(DeleteMI); 223239310Sdim End = MBB->end(); 224239310Sdim continue; 225239310Sdim } 226239310Sdim ++MI; 227239310Sdim } 228239310Sdim } 229239310Sdim 230239310Sdim // Loop over all of the basic blocks. 231239310Sdim for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 232239310Sdim MBB != MBBe; ++MBB) { 233239310Sdim // Find scheduling regions and schedule / packetize each region. 234239310Sdim unsigned RemainingCount = MBB->size(); 235239310Sdim for(MachineBasicBlock::iterator RegionEnd = MBB->end(); 236239310Sdim RegionEnd != MBB->begin();) { 237239310Sdim // The next region starts above the previous region. Look backward in the 238239310Sdim // instruction stream until we find the nearest boundary. 239239310Sdim MachineBasicBlock::iterator I = RegionEnd; 240239310Sdim for(;I != MBB->begin(); --I, --RemainingCount) { 241239310Sdim if (TII->isSchedulingBoundary(llvm::prior(I), MBB, Fn)) 242239310Sdim break; 243239310Sdim } 244239310Sdim I = MBB->begin(); 245239310Sdim 246239310Sdim // Skip empty scheduling regions. 247239310Sdim if (I == RegionEnd) { 248239310Sdim RegionEnd = llvm::prior(RegionEnd); 249239310Sdim --RemainingCount; 250239310Sdim continue; 251239310Sdim } 252239310Sdim // Skip regions with one instruction. 253239310Sdim if (I == llvm::prior(RegionEnd)) { 254239310Sdim RegionEnd = llvm::prior(RegionEnd); 255239310Sdim continue; 256239310Sdim } 257239310Sdim 258239310Sdim Packetizer.PacketizeMIs(MBB, I, RegionEnd); 259239310Sdim RegionEnd = I; 260239310Sdim } 261239310Sdim } 262239310Sdim 263239310Sdim return true; 264239310Sdim} 265239310Sdim 266239310Sdim 267239310Sdimstatic bool IsIndirectCall(MachineInstr* MI) { 268239310Sdim return ((MI->getOpcode() == Hexagon::CALLR) || 269239310Sdim (MI->getOpcode() == Hexagon::CALLRv3)); 270239310Sdim} 271239310Sdim 272239310Sdim// Reserve resources for constant extender. Trigure an assertion if 273239310Sdim// reservation fail. 274239310Sdimvoid HexagonPacketizerList::reserveResourcesForConstExt(MachineInstr* MI) { 275239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 276249423Sdim MachineFunction *MF = MI->getParent()->getParent(); 277249423Sdim MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i), 278249423Sdim MI->getDebugLoc()); 279239310Sdim 280239310Sdim if (ResourceTracker->canReserveResources(PseudoMI)) { 281239310Sdim ResourceTracker->reserveResources(PseudoMI); 282239310Sdim MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 283239310Sdim } else { 284239310Sdim MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 285239310Sdim llvm_unreachable("can not reserve resources for constant extender."); 286239310Sdim } 287239310Sdim return; 288239310Sdim} 289239310Sdim 290239310Sdimbool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) { 291239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 292249423Sdim assert((QII->isExtended(MI) || QII->isConstExtended(MI)) && 293239310Sdim "Should only be called for constant extended instructions"); 294239310Sdim MachineFunction *MF = MI->getParent()->getParent(); 295249423Sdim MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i), 296239310Sdim MI->getDebugLoc()); 297239310Sdim bool CanReserve = ResourceTracker->canReserveResources(PseudoMI); 298239310Sdim MF->DeleteMachineInstr(PseudoMI); 299239310Sdim return CanReserve; 300239310Sdim} 301239310Sdim 302239310Sdim// Allocate resources (i.e. 4 bytes) for constant extender. If succeed, return 303239310Sdim// true, otherwise, return false. 304239310Sdimbool HexagonPacketizerList::tryAllocateResourcesForConstExt(MachineInstr* MI) { 305239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 306249423Sdim MachineFunction *MF = MI->getParent()->getParent(); 307249423Sdim MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i), 308249423Sdim MI->getDebugLoc()); 309239310Sdim 310239310Sdim if (ResourceTracker->canReserveResources(PseudoMI)) { 311239310Sdim ResourceTracker->reserveResources(PseudoMI); 312239310Sdim MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 313239310Sdim return true; 314239310Sdim } else { 315239310Sdim MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 316239310Sdim return false; 317239310Sdim } 318239310Sdim} 319239310Sdim 320239310Sdim 321239310Sdimbool HexagonPacketizerList::IsCallDependent(MachineInstr* MI, 322239310Sdim SDep::Kind DepType, 323239310Sdim unsigned DepReg) { 324239310Sdim 325239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 326239310Sdim const HexagonRegisterInfo* QRI = 327239310Sdim (const HexagonRegisterInfo *) TM.getRegisterInfo(); 328239310Sdim 329239310Sdim // Check for lr dependence 330239310Sdim if (DepReg == QRI->getRARegister()) { 331239310Sdim return true; 332239310Sdim } 333239310Sdim 334239310Sdim if (QII->isDeallocRet(MI)) { 335239310Sdim if (DepReg == QRI->getFrameRegister() || 336239310Sdim DepReg == QRI->getStackRegister()) 337239310Sdim return true; 338239310Sdim } 339239310Sdim 340239310Sdim // Check if this is a predicate dependence 341239310Sdim const TargetRegisterClass* RC = QRI->getMinimalPhysRegClass(DepReg); 342239310Sdim if (RC == &Hexagon::PredRegsRegClass) { 343239310Sdim return true; 344239310Sdim } 345239310Sdim 346239310Sdim // 347239310Sdim // Lastly check for an operand used in an indirect call 348239310Sdim // If we had an attribute for checking if an instruction is an indirect call, 349239310Sdim // then we could have avoided this relatively brittle implementation of 350239310Sdim // IsIndirectCall() 351239310Sdim // 352239310Sdim // Assumes that the first operand of the CALLr is the function address 353239310Sdim // 354239310Sdim if (IsIndirectCall(MI) && (DepType == SDep::Data)) { 355239310Sdim MachineOperand MO = MI->getOperand(0); 356239310Sdim if (MO.isReg() && MO.isUse() && (MO.getReg() == DepReg)) { 357239310Sdim return true; 358239310Sdim } 359239310Sdim } 360239310Sdim 361239310Sdim return false; 362239310Sdim} 363239310Sdim 364239310Sdimstatic bool IsRegDependence(const SDep::Kind DepType) { 365239310Sdim return (DepType == SDep::Data || DepType == SDep::Anti || 366239310Sdim DepType == SDep::Output); 367239310Sdim} 368239310Sdim 369239310Sdimstatic bool IsDirectJump(MachineInstr* MI) { 370239310Sdim return (MI->getOpcode() == Hexagon::JMP); 371239310Sdim} 372239310Sdim 373239310Sdimstatic bool IsSchedBarrier(MachineInstr* MI) { 374239310Sdim switch (MI->getOpcode()) { 375239310Sdim case Hexagon::BARRIER: 376239310Sdim return true; 377239310Sdim } 378239310Sdim return false; 379239310Sdim} 380239310Sdim 381239310Sdimstatic bool IsControlFlow(MachineInstr* MI) { 382239310Sdim return (MI->getDesc().isTerminator() || MI->getDesc().isCall()); 383239310Sdim} 384239310Sdim 385239310Sdimstatic bool IsLoopN(MachineInstr *MI) { 386239310Sdim return (MI->getOpcode() == Hexagon::LOOP0_i || 387239310Sdim MI->getOpcode() == Hexagon::LOOP0_r); 388239310Sdim} 389239310Sdim 390239310Sdim/// DoesModifyCalleeSavedReg - Returns true if the instruction modifies a 391239310Sdim/// callee-saved register. 392239310Sdimstatic bool DoesModifyCalleeSavedReg(MachineInstr *MI, 393239310Sdim const TargetRegisterInfo *TRI) { 394239310Sdim for (const uint16_t *CSR = TRI->getCalleeSavedRegs(); *CSR; ++CSR) { 395239310Sdim unsigned CalleeSavedReg = *CSR; 396239310Sdim if (MI->modifiesRegister(CalleeSavedReg, TRI)) 397239310Sdim return true; 398239310Sdim } 399239310Sdim return false; 400239310Sdim} 401239310Sdim 402239310Sdim// Returns true if an instruction can be promoted to .new predicate 403239310Sdim// or new-value store. 404239310Sdimbool HexagonPacketizerList::isNewifiable(MachineInstr* MI) { 405263508Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 406263508Sdim if ( isCondInst(MI) || QII->mayBeNewStore(MI)) 407239310Sdim return true; 408239310Sdim else 409239310Sdim return false; 410239310Sdim} 411239310Sdim 412239310Sdimbool HexagonPacketizerList::isCondInst (MachineInstr* MI) { 413239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 414239310Sdim const MCInstrDesc& TID = MI->getDesc(); 415239310Sdim // bug 5670: until that is fixed, 416239310Sdim // this portion is disabled. 417239310Sdim if ( TID.isConditionalBranch() // && !IsRegisterJump(MI)) || 418239310Sdim || QII->isConditionalTransfer(MI) 419239310Sdim || QII->isConditionalALU32(MI) 420239310Sdim || QII->isConditionalLoad(MI) 421239310Sdim || QII->isConditionalStore(MI)) { 422239310Sdim return true; 423239310Sdim } 424239310Sdim return false; 425239310Sdim} 426239310Sdim 427239310Sdim 428239310Sdim// Promote an instructiont to its .new form. 429239310Sdim// At this time, we have already made a call to CanPromoteToDotNew 430239310Sdim// and made sure that it can *indeed* be promoted. 431239310Sdimbool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI, 432239310Sdim SDep::Kind DepType, MachineBasicBlock::iterator &MII, 433239310Sdim const TargetRegisterClass* RC) { 434239310Sdim 435239310Sdim assert (DepType == SDep::Data); 436239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 437239310Sdim 438239310Sdim int NewOpcode; 439239310Sdim if (RC == &Hexagon::PredRegsRegClass) 440263508Sdim NewOpcode = QII->GetDotNewPredOp(MI, MBPI); 441239310Sdim else 442263508Sdim NewOpcode = QII->GetDotNewOp(MI); 443239310Sdim MI->setDesc(QII->get(NewOpcode)); 444239310Sdim 445239310Sdim return true; 446239310Sdim} 447239310Sdim 448239310Sdimbool HexagonPacketizerList::DemoteToDotOld(MachineInstr* MI) { 449239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 450263508Sdim int NewOpcode = QII->GetDotOldOp(MI->getOpcode()); 451239310Sdim MI->setDesc(QII->get(NewOpcode)); 452239310Sdim return true; 453239310Sdim} 454239310Sdim 455263508Sdimenum PredicateKind { 456263508Sdim PK_False, 457263508Sdim PK_True, 458263508Sdim PK_Unknown 459263508Sdim}; 460239310Sdim 461263508Sdim/// Returns true if an instruction is predicated on p0 and false if it's 462263508Sdim/// predicated on !p0. 463263508Sdimstatic PredicateKind getPredicateSense(MachineInstr* MI, 464263508Sdim const HexagonInstrInfo *QII) { 465263508Sdim if (!QII->isPredicated(MI)) 466263508Sdim return PK_Unknown; 467239310Sdim 468263508Sdim if (QII->isPredicatedTrue(MI)) 469263508Sdim return PK_True; 470239310Sdim 471263508Sdim return PK_False; 472239310Sdim} 473239310Sdim 474239310Sdimstatic MachineOperand& GetPostIncrementOperand(MachineInstr *MI, 475239310Sdim const HexagonInstrInfo *QII) { 476239310Sdim assert(QII->isPostIncrement(MI) && "Not a post increment operation."); 477239310Sdim#ifndef NDEBUG 478239310Sdim // Post Increment means duplicates. Use dense map to find duplicates in the 479239310Sdim // list. Caution: Densemap initializes with the minimum of 64 buckets, 480239310Sdim // whereas there are at most 5 operands in the post increment. 481239310Sdim DenseMap<unsigned, unsigned> DefRegsSet; 482239310Sdim for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) 483239310Sdim if (MI->getOperand(opNum).isReg() && 484239310Sdim MI->getOperand(opNum).isDef()) { 485239310Sdim DefRegsSet[MI->getOperand(opNum).getReg()] = 1; 486239310Sdim } 487239310Sdim 488239310Sdim for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) 489239310Sdim if (MI->getOperand(opNum).isReg() && 490239310Sdim MI->getOperand(opNum).isUse()) { 491239310Sdim if (DefRegsSet[MI->getOperand(opNum).getReg()]) { 492239310Sdim return MI->getOperand(opNum); 493239310Sdim } 494239310Sdim } 495239310Sdim#else 496239310Sdim if (MI->getDesc().mayLoad()) { 497239310Sdim // The 2nd operand is always the post increment operand in load. 498239310Sdim assert(MI->getOperand(1).isReg() && 499239310Sdim "Post increment operand has be to a register."); 500239310Sdim return (MI->getOperand(1)); 501239310Sdim } 502239310Sdim if (MI->getDesc().mayStore()) { 503239310Sdim // The 1st operand is always the post increment operand in store. 504239310Sdim assert(MI->getOperand(0).isReg() && 505239310Sdim "Post increment operand has be to a register."); 506239310Sdim return (MI->getOperand(0)); 507239310Sdim } 508239310Sdim#endif 509239310Sdim // we should never come here. 510239310Sdim llvm_unreachable("mayLoad or mayStore not set for Post Increment operation"); 511239310Sdim} 512239310Sdim 513239310Sdim// get the value being stored 514239310Sdimstatic MachineOperand& GetStoreValueOperand(MachineInstr *MI) { 515239310Sdim // value being stored is always the last operand. 516239310Sdim return (MI->getOperand(MI->getNumOperands()-1)); 517239310Sdim} 518239310Sdim 519239310Sdim// can be new value store? 520239310Sdim// Following restrictions are to be respected in convert a store into 521239310Sdim// a new value store. 522239310Sdim// 1. If an instruction uses auto-increment, its address register cannot 523239310Sdim// be a new-value register. Arch Spec 5.4.2.1 524239310Sdim// 2. If an instruction uses absolute-set addressing mode, 525239310Sdim// its address register cannot be a new-value register. 526239310Sdim// Arch Spec 5.4.2.1.TODO: This is not enabled as 527239310Sdim// as absolute-set address mode patters are not implemented. 528239310Sdim// 3. If an instruction produces a 64-bit result, its registers cannot be used 529239310Sdim// as new-value registers. Arch Spec 5.4.2.2. 530239310Sdim// 4. If the instruction that sets a new-value register is conditional, then 531239310Sdim// the instruction that uses the new-value register must also be conditional, 532239310Sdim// and both must always have their predicates evaluate identically. 533239310Sdim// Arch Spec 5.4.2.3. 534239310Sdim// 5. There is an implied restriction of a packet can not have another store, 535239310Sdim// if there is a new value store in the packet. Corollary, if there is 536239310Sdim// already a store in a packet, there can not be a new value store. 537239310Sdim// Arch Spec: 3.4.4.2 538239310Sdimbool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, 539239310Sdim MachineInstr *PacketMI, unsigned DepReg, 540263508Sdim std::map <MachineInstr*, SUnit*> MIToSUnit) { 541263508Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 542263508Sdim // Make sure we are looking at the store, that can be promoted. 543263508Sdim if (!QII->mayBeNewStore(MI)) 544239310Sdim return false; 545239310Sdim 546239310Sdim // Make sure there is dependency and can be new value'ed 547239310Sdim if (GetStoreValueOperand(MI).isReg() && 548239310Sdim GetStoreValueOperand(MI).getReg() != DepReg) 549239310Sdim return false; 550239310Sdim 551263508Sdim const HexagonRegisterInfo* QRI = 552239310Sdim (const HexagonRegisterInfo *) TM.getRegisterInfo(); 553239310Sdim const MCInstrDesc& MCID = PacketMI->getDesc(); 554239310Sdim // first operand is always the result 555239310Sdim 556239310Sdim const TargetRegisterClass* PacketRC = QII->getRegClass(MCID, 0, QRI, MF); 557239310Sdim 558239310Sdim // if there is already an store in the packet, no can do new value store 559239310Sdim // Arch Spec 3.4.4.2. 560239310Sdim for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(), 561239310Sdim VE = CurrentPacketMIs.end(); 562239310Sdim (VI != VE); ++VI) { 563239310Sdim SUnit* PacketSU = MIToSUnit[*VI]; 564239310Sdim if (PacketSU->getInstr()->getDesc().mayStore() || 565239310Sdim // if we have mayStore = 1 set on ALLOCFRAME and DEALLOCFRAME, 566239310Sdim // then we don't need this 567239310Sdim PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || 568239310Sdim PacketSU->getInstr()->getOpcode() == Hexagon::DEALLOCFRAME) 569239310Sdim return false; 570239310Sdim } 571239310Sdim 572239310Sdim if (PacketRC == &Hexagon::DoubleRegsRegClass) { 573239310Sdim // new value store constraint: double regs can not feed into new value store 574239310Sdim // arch spec section: 5.4.2.2 575239310Sdim return false; 576239310Sdim } 577239310Sdim 578239310Sdim // Make sure it's NOT the post increment register that we are going to 579239310Sdim // new value. 580239310Sdim if (QII->isPostIncrement(MI) && 581239310Sdim MI->getDesc().mayStore() && 582239310Sdim GetPostIncrementOperand(MI, QII).getReg() == DepReg) { 583239310Sdim return false; 584239310Sdim } 585239310Sdim 586239310Sdim if (QII->isPostIncrement(PacketMI) && 587239310Sdim PacketMI->getDesc().mayLoad() && 588239310Sdim GetPostIncrementOperand(PacketMI, QII).getReg() == DepReg) { 589239310Sdim // if source is post_inc, or absolute-set addressing, 590239310Sdim // it can not feed into new value store 591239310Sdim // r3 = memw(r2++#4) 592239310Sdim // memw(r30 + #-1404) = r2.new -> can not be new value store 593239310Sdim // arch spec section: 5.4.2.1 594239310Sdim return false; 595239310Sdim } 596239310Sdim 597239310Sdim // If the source that feeds the store is predicated, new value store must 598263508Sdim // also be predicated. 599239310Sdim if (QII->isPredicated(PacketMI)) { 600239310Sdim if (!QII->isPredicated(MI)) 601239310Sdim return false; 602239310Sdim 603239310Sdim // Check to make sure that they both will have their predicates 604239310Sdim // evaluate identically 605239310Sdim unsigned predRegNumSrc = 0; 606239310Sdim unsigned predRegNumDst = 0; 607239310Sdim const TargetRegisterClass* predRegClass = NULL; 608239310Sdim 609239310Sdim // Get predicate register used in the source instruction 610239310Sdim for(unsigned opNum = 0; opNum < PacketMI->getNumOperands(); opNum++) { 611239310Sdim if ( PacketMI->getOperand(opNum).isReg()) 612239310Sdim predRegNumSrc = PacketMI->getOperand(opNum).getReg(); 613239310Sdim predRegClass = QRI->getMinimalPhysRegClass(predRegNumSrc); 614239310Sdim if (predRegClass == &Hexagon::PredRegsRegClass) { 615239310Sdim break; 616239310Sdim } 617239310Sdim } 618239310Sdim assert ((predRegClass == &Hexagon::PredRegsRegClass ) && 619239310Sdim ("predicate register not found in a predicated PacketMI instruction")); 620239310Sdim 621239310Sdim // Get predicate register used in new-value store instruction 622239310Sdim for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { 623239310Sdim if ( MI->getOperand(opNum).isReg()) 624239310Sdim predRegNumDst = MI->getOperand(opNum).getReg(); 625239310Sdim predRegClass = QRI->getMinimalPhysRegClass(predRegNumDst); 626239310Sdim if (predRegClass == &Hexagon::PredRegsRegClass) { 627239310Sdim break; 628239310Sdim } 629239310Sdim } 630239310Sdim assert ((predRegClass == &Hexagon::PredRegsRegClass ) && 631239310Sdim ("predicate register not found in a predicated MI instruction")); 632239310Sdim 633239310Sdim // New-value register producer and user (store) need to satisfy these 634239310Sdim // constraints: 635239310Sdim // 1) Both instructions should be predicated on the same register. 636239310Sdim // 2) If producer of the new-value register is .new predicated then store 637239310Sdim // should also be .new predicated and if producer is not .new predicated 638239310Sdim // then store should not be .new predicated. 639239310Sdim // 3) Both new-value register producer and user should have same predicate 640239310Sdim // sense, i.e, either both should be negated or both should be none negated. 641239310Sdim 642239310Sdim if (( predRegNumDst != predRegNumSrc) || 643249423Sdim QII->isDotNewInst(PacketMI) != QII->isDotNewInst(MI) || 644263508Sdim getPredicateSense(MI, QII) != getPredicateSense(PacketMI, QII)) { 645239310Sdim return false; 646239310Sdim } 647239310Sdim } 648239310Sdim 649239310Sdim // Make sure that other than the new-value register no other store instruction 650239310Sdim // register has been modified in the same packet. Predicate registers can be 651239310Sdim // modified by they should not be modified between the producer and the store 652239310Sdim // instruction as it will make them both conditional on different values. 653239310Sdim // We already know this to be true for all the instructions before and 654239310Sdim // including PacketMI. Howerver, we need to perform the check for the 655239310Sdim // remaining instructions in the packet. 656239310Sdim 657239310Sdim std::vector<MachineInstr*>::iterator VI; 658239310Sdim std::vector<MachineInstr*>::iterator VE; 659239310Sdim unsigned StartCheck = 0; 660239310Sdim 661239310Sdim for (VI=CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end(); 662239310Sdim (VI != VE); ++VI) { 663239310Sdim SUnit* TempSU = MIToSUnit[*VI]; 664239310Sdim MachineInstr* TempMI = TempSU->getInstr(); 665239310Sdim 666239310Sdim // Following condition is true for all the instructions until PacketMI is 667239310Sdim // reached (StartCheck is set to 0 before the for loop). 668239310Sdim // StartCheck flag is 1 for all the instructions after PacketMI. 669239310Sdim if (TempMI != PacketMI && !StartCheck) // start processing only after 670239310Sdim continue; // encountering PacketMI 671239310Sdim 672239310Sdim StartCheck = 1; 673239310Sdim if (TempMI == PacketMI) // We don't want to check PacketMI for dependence 674239310Sdim continue; 675239310Sdim 676239310Sdim for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { 677239310Sdim if (MI->getOperand(opNum).isReg() && 678239310Sdim TempSU->getInstr()->modifiesRegister(MI->getOperand(opNum).getReg(), 679239310Sdim QRI)) 680239310Sdim return false; 681239310Sdim } 682239310Sdim } 683239310Sdim 684239310Sdim // Make sure that for non POST_INC stores: 685239310Sdim // 1. The only use of reg is DepReg and no other registers. 686239310Sdim // This handles V4 base+index registers. 687239310Sdim // The following store can not be dot new. 688239310Sdim // Eg. r0 = add(r0, #3)a 689239310Sdim // memw(r1+r0<<#2) = r0 690239310Sdim if (!QII->isPostIncrement(MI) && 691239310Sdim GetStoreValueOperand(MI).isReg() && 692239310Sdim GetStoreValueOperand(MI).getReg() == DepReg) { 693239310Sdim for(unsigned opNum = 0; opNum < MI->getNumOperands()-1; opNum++) { 694239310Sdim if (MI->getOperand(opNum).isReg() && 695239310Sdim MI->getOperand(opNum).getReg() == DepReg) { 696239310Sdim return false; 697239310Sdim } 698239310Sdim } 699239310Sdim // 2. If data definition is because of implicit definition of the register, 700239310Sdim // do not newify the store. Eg. 701239310Sdim // %R9<def> = ZXTH %R12, %D6<imp-use>, %R12<imp-def> 702239310Sdim // STrih_indexed %R8, 2, %R12<kill>; mem:ST2[%scevgep343] 703239310Sdim for(unsigned opNum = 0; opNum < PacketMI->getNumOperands(); opNum++) { 704239310Sdim if (PacketMI->getOperand(opNum).isReg() && 705239310Sdim PacketMI->getOperand(opNum).getReg() == DepReg && 706239310Sdim PacketMI->getOperand(opNum).isDef() && 707239310Sdim PacketMI->getOperand(opNum).isImplicit()) { 708239310Sdim return false; 709239310Sdim } 710239310Sdim } 711239310Sdim } 712239310Sdim 713239310Sdim // Can be dot new store. 714239310Sdim return true; 715239310Sdim} 716239310Sdim 717239310Sdim// can this MI to promoted to either 718239310Sdim// new value store or new value jump 719239310Sdimbool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI, 720239310Sdim SUnit *PacketSU, unsigned DepReg, 721239310Sdim std::map <MachineInstr*, SUnit*> MIToSUnit, 722239310Sdim MachineBasicBlock::iterator &MII) 723239310Sdim{ 724239310Sdim 725263508Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 726239310Sdim const HexagonRegisterInfo* QRI = 727239310Sdim (const HexagonRegisterInfo *) TM.getRegisterInfo(); 728239310Sdim if (!QRI->Subtarget.hasV4TOps() || 729263508Sdim !QII->mayBeNewStore(MI)) 730239310Sdim return false; 731239310Sdim 732239310Sdim MachineInstr *PacketMI = PacketSU->getInstr(); 733239310Sdim 734239310Sdim // Check to see the store can be new value'ed. 735239310Sdim if (CanPromoteToNewValueStore(MI, PacketMI, DepReg, MIToSUnit)) 736239310Sdim return true; 737239310Sdim 738239310Sdim // Check to see the compare/jump can be new value'ed. 739239310Sdim // This is done as a pass on its own. Don't need to check it here. 740239310Sdim return false; 741239310Sdim} 742239310Sdim 743239310Sdim// Check to see if an instruction can be dot new 744239310Sdim// There are three kinds. 745239310Sdim// 1. dot new on predicate - V2/V3/V4 746239310Sdim// 2. dot new on stores NV/ST - V4 747239310Sdim// 3. dot new on jump NV/J - V4 -- This is generated in a pass. 748239310Sdimbool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI, 749239310Sdim SUnit *PacketSU, unsigned DepReg, 750239310Sdim std::map <MachineInstr*, SUnit*> MIToSUnit, 751239310Sdim MachineBasicBlock::iterator &MII, 752239310Sdim const TargetRegisterClass* RC ) 753239310Sdim{ 754249423Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 755249423Sdim // Already a dot new instruction. 756263508Sdim if (QII->isDotNewInst(MI) && !QII->mayBeNewStore(MI)) 757239310Sdim return false; 758239310Sdim 759239310Sdim if (!isNewifiable(MI)) 760239310Sdim return false; 761239310Sdim 762239310Sdim // predicate .new 763239310Sdim if (RC == &Hexagon::PredRegsRegClass && isCondInst(MI)) 764239310Sdim return true; 765239310Sdim else if (RC != &Hexagon::PredRegsRegClass && 766263508Sdim !QII->mayBeNewStore(MI)) // MI is not a new-value store 767239310Sdim return false; 768239310Sdim else { 769239310Sdim // Create a dot new machine instruction to see if resources can be 770239310Sdim // allocated. If not, bail out now. 771263508Sdim int NewOpcode = QII->GetDotNewOp(MI); 772239310Sdim const MCInstrDesc &desc = QII->get(NewOpcode); 773239310Sdim DebugLoc dl; 774239310Sdim MachineInstr *NewMI = 775239310Sdim MI->getParent()->getParent()->CreateMachineInstr(desc, dl); 776239310Sdim bool ResourcesAvailable = ResourceTracker->canReserveResources(NewMI); 777239310Sdim MI->getParent()->getParent()->DeleteMachineInstr(NewMI); 778239310Sdim 779239310Sdim if (!ResourcesAvailable) 780239310Sdim return false; 781239310Sdim 782239310Sdim // new value store only 783239310Sdim // new new value jump generated as a passes 784239310Sdim if (!CanPromoteToNewValue(MI, PacketSU, DepReg, MIToSUnit, MII)) { 785239310Sdim return false; 786239310Sdim } 787239310Sdim } 788239310Sdim return true; 789239310Sdim} 790239310Sdim 791239310Sdim// Go through the packet instructions and search for anti dependency 792239310Sdim// between them and DepReg from MI 793239310Sdim// Consider this case: 794239310Sdim// Trying to add 795239310Sdim// a) %R1<def> = TFRI_cdNotPt %P3, 2 796239310Sdim// to this packet: 797239310Sdim// { 798239310Sdim// b) %P0<def> = OR_pp %P3<kill>, %P0<kill> 799239310Sdim// c) %P3<def> = TFR_PdRs %R23 800239310Sdim// d) %R1<def> = TFRI_cdnPt %P3, 4 801239310Sdim// } 802239310Sdim// The P3 from a) and d) will be complements after 803239310Sdim// a)'s P3 is converted to .new form 804239310Sdim// Anti Dep between c) and b) is irrelevant for this case 805239310Sdimbool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI, 806239310Sdim unsigned DepReg, 807239310Sdim std::map <MachineInstr*, SUnit*> MIToSUnit) { 808239310Sdim 809239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 810239310Sdim SUnit* PacketSUDep = MIToSUnit[MI]; 811239310Sdim 812239310Sdim for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(), 813239310Sdim VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) { 814239310Sdim 815239310Sdim // We only care for dependencies to predicated instructions 816239310Sdim if(!QII->isPredicated(*VIN)) continue; 817239310Sdim 818239310Sdim // Scheduling Unit for current insn in the packet 819239310Sdim SUnit* PacketSU = MIToSUnit[*VIN]; 820239310Sdim 821239310Sdim // Look at dependencies between current members of the packet 822239310Sdim // and predicate defining instruction MI. 823239310Sdim // Make sure that dependency is on the exact register 824239310Sdim // we care about. 825239310Sdim if (PacketSU->isSucc(PacketSUDep)) { 826239310Sdim for (unsigned i = 0; i < PacketSU->Succs.size(); ++i) { 827239310Sdim if ((PacketSU->Succs[i].getSUnit() == PacketSUDep) && 828239310Sdim (PacketSU->Succs[i].getKind() == SDep::Anti) && 829239310Sdim (PacketSU->Succs[i].getReg() == DepReg)) { 830239310Sdim return true; 831239310Sdim } 832239310Sdim } 833239310Sdim } 834239310Sdim } 835239310Sdim 836239310Sdim return false; 837239310Sdim} 838239310Sdim 839239310Sdim 840263508Sdim/// Gets the predicate register of a predicated instruction. 841263508Sdimstatic unsigned getPredicatedRegister(MachineInstr *MI, 842263508Sdim const HexagonInstrInfo *QII) { 843263508Sdim /// We use the following rule: The first predicate register that is a use is 844263508Sdim /// the predicate register of a predicated instruction. 845263508Sdim 846263508Sdim assert(QII->isPredicated(MI) && "Must be predicated instruction"); 847263508Sdim 848263508Sdim for (MachineInstr::mop_iterator OI = MI->operands_begin(), 849263508Sdim OE = MI->operands_end(); OI != OE; ++OI) { 850263508Sdim MachineOperand &Op = *OI; 851263508Sdim if (Op.isReg() && Op.getReg() && Op.isUse() && 852263508Sdim Hexagon::PredRegsRegClass.contains(Op.getReg())) 853263508Sdim return Op.getReg(); 854263508Sdim } 855263508Sdim 856263508Sdim llvm_unreachable("Unknown instruction operand layout"); 857263508Sdim 858263508Sdim return 0; 859263508Sdim} 860263508Sdim 861239310Sdim// Given two predicated instructions, this function detects whether 862239310Sdim// the predicates are complements 863239310Sdimbool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1, 864239310Sdim MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) { 865239310Sdim 866239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 867263508Sdim 868263508Sdim // If we don't know the predicate sense of the instructions bail out early, we 869263508Sdim // need it later. 870263508Sdim if (getPredicateSense(MI1, QII) == PK_Unknown || 871263508Sdim getPredicateSense(MI2, QII) == PK_Unknown) 872239310Sdim return false; 873239310Sdim 874239310Sdim // Scheduling unit for candidate 875239310Sdim SUnit* SU = MIToSUnit[MI1]; 876239310Sdim 877239310Sdim // One corner case deals with the following scenario: 878239310Sdim // Trying to add 879239310Sdim // a) %R24<def> = TFR_cPt %P0, %R25 880239310Sdim // to this packet: 881239310Sdim // 882239310Sdim // { 883239310Sdim // b) %R25<def> = TFR_cNotPt %P0, %R24 884239310Sdim // c) %P0<def> = CMPEQri %R26, 1 885239310Sdim // } 886239310Sdim // 887239310Sdim // On general check a) and b) are complements, but 888239310Sdim // presence of c) will convert a) to .new form, and 889239310Sdim // then it is not a complement 890239310Sdim // We attempt to detect it by analyzing existing 891239310Sdim // dependencies in the packet 892239310Sdim 893239310Sdim // Analyze relationships between all existing members of the packet. 894239310Sdim // Look for Anti dependecy on the same predicate reg 895239310Sdim // as used in the candidate 896239310Sdim for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(), 897239310Sdim VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) { 898239310Sdim 899239310Sdim // Scheduling Unit for current insn in the packet 900239310Sdim SUnit* PacketSU = MIToSUnit[*VIN]; 901239310Sdim 902239310Sdim // If this instruction in the packet is succeeded by the candidate... 903239310Sdim if (PacketSU->isSucc(SU)) { 904239310Sdim for (unsigned i = 0; i < PacketSU->Succs.size(); ++i) { 905239310Sdim // The corner case exist when there is true data 906239310Sdim // dependency between candidate and one of current 907239310Sdim // packet members, this dep is on predicate reg, and 908239310Sdim // there already exist anti dep on the same pred in 909239310Sdim // the packet. 910239310Sdim if (PacketSU->Succs[i].getSUnit() == SU && 911263508Sdim PacketSU->Succs[i].getKind() == SDep::Data && 912239310Sdim Hexagon::PredRegsRegClass.contains( 913239310Sdim PacketSU->Succs[i].getReg()) && 914239310Sdim // Here I know that *VIN is predicate setting instruction 915239310Sdim // with true data dep to candidate on the register 916239310Sdim // we care about - c) in the above example. 917239310Sdim // Now I need to see if there is an anti dependency 918239310Sdim // from c) to any other instruction in the 919239310Sdim // same packet on the pred reg of interest 920239310Sdim RestrictingDepExistInPacket(*VIN,PacketSU->Succs[i].getReg(), 921239310Sdim MIToSUnit)) { 922239310Sdim return false; 923239310Sdim } 924239310Sdim } 925239310Sdim } 926239310Sdim } 927239310Sdim 928239310Sdim // If the above case does not apply, check regular 929239310Sdim // complement condition. 930239310Sdim // Check that the predicate register is the same and 931239310Sdim // that the predicate sense is different 932239310Sdim // We also need to differentiate .old vs. .new: 933239310Sdim // !p0 is not complimentary to p0.new 934263508Sdim unsigned PReg1 = getPredicatedRegister(MI1, QII); 935263508Sdim unsigned PReg2 = getPredicatedRegister(MI2, QII); 936263508Sdim return ((PReg1 == PReg2) && 937263508Sdim Hexagon::PredRegsRegClass.contains(PReg1) && 938263508Sdim Hexagon::PredRegsRegClass.contains(PReg2) && 939263508Sdim (getPredicateSense(MI1, QII) != getPredicateSense(MI2, QII)) && 940249423Sdim (QII->isDotNewInst(MI1) == QII->isDotNewInst(MI2))); 941239310Sdim} 942239310Sdim 943239310Sdim// initPacketizerState - Initialize packetizer flags 944239310Sdimvoid HexagonPacketizerList::initPacketizerState() { 945239310Sdim 946239310Sdim Dependence = false; 947239310Sdim PromotedToDotNew = false; 948239310Sdim GlueToNewValueJump = false; 949239310Sdim GlueAllocframeStore = false; 950239310Sdim FoundSequentialDependence = false; 951239310Sdim 952239310Sdim return; 953239310Sdim} 954239310Sdim 955239310Sdim// ignorePseudoInstruction - Ignore bundling of pseudo instructions. 956239310Sdimbool HexagonPacketizerList::ignorePseudoInstruction(MachineInstr *MI, 957239310Sdim MachineBasicBlock *MBB) { 958239310Sdim if (MI->isDebugValue()) 959239310Sdim return true; 960239310Sdim 961239310Sdim // We must print out inline assembly 962239310Sdim if (MI->isInlineAsm()) 963239310Sdim return false; 964239310Sdim 965239310Sdim // We check if MI has any functional units mapped to it. 966239310Sdim // If it doesn't, we ignore the instruction. 967239310Sdim const MCInstrDesc& TID = MI->getDesc(); 968239310Sdim unsigned SchedClass = TID.getSchedClass(); 969239310Sdim const InstrStage* IS = 970239310Sdim ResourceTracker->getInstrItins()->beginStage(SchedClass); 971239310Sdim unsigned FuncUnits = IS->getUnits(); 972239310Sdim return !FuncUnits; 973239310Sdim} 974239310Sdim 975239310Sdim// isSoloInstruction: - Returns true for instructions that must be 976239310Sdim// scheduled in their own packet. 977239310Sdimbool HexagonPacketizerList::isSoloInstruction(MachineInstr *MI) { 978239310Sdim 979239310Sdim if (MI->isInlineAsm()) 980239310Sdim return true; 981239310Sdim 982239310Sdim if (MI->isEHLabel()) 983239310Sdim return true; 984239310Sdim 985239310Sdim // From Hexagon V4 Programmer's Reference Manual 3.4.4 Grouping constraints: 986239310Sdim // trap, pause, barrier, icinva, isync, and syncht are solo instructions. 987239310Sdim // They must not be grouped with other instructions in a packet. 988239310Sdim if (IsSchedBarrier(MI)) 989239310Sdim return true; 990239310Sdim 991239310Sdim return false; 992239310Sdim} 993239310Sdim 994239310Sdim// isLegalToPacketizeTogether: 995239310Sdim// SUI is the current instruction that is out side of the current packet. 996239310Sdim// SUJ is the current instruction inside the current packet against which that 997239310Sdim// SUI will be packetized. 998239310Sdimbool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { 999239310Sdim MachineInstr *I = SUI->getInstr(); 1000239310Sdim MachineInstr *J = SUJ->getInstr(); 1001239310Sdim assert(I && J && "Unable to packetize null instruction!"); 1002239310Sdim 1003239310Sdim const MCInstrDesc &MCIDI = I->getDesc(); 1004239310Sdim const MCInstrDesc &MCIDJ = J->getDesc(); 1005239310Sdim 1006239310Sdim MachineBasicBlock::iterator II = I; 1007239310Sdim 1008239310Sdim const unsigned FrameSize = MF.getFrameInfo()->getStackSize(); 1009239310Sdim const HexagonRegisterInfo* QRI = 1010239310Sdim (const HexagonRegisterInfo *) TM.getRegisterInfo(); 1011239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 1012239310Sdim 1013239310Sdim // Inline asm cannot go in the packet. 1014239310Sdim if (I->getOpcode() == Hexagon::INLINEASM) 1015239310Sdim llvm_unreachable("Should not meet inline asm here!"); 1016239310Sdim 1017239310Sdim if (isSoloInstruction(I)) 1018239310Sdim llvm_unreachable("Should not meet solo instr here!"); 1019239310Sdim 1020239310Sdim // A save callee-save register function call can only be in a packet 1021239310Sdim // with instructions that don't write to the callee-save registers. 1022239310Sdim if ((QII->isSaveCalleeSavedRegsCall(I) && 1023239310Sdim DoesModifyCalleeSavedReg(J, QRI)) || 1024239310Sdim (QII->isSaveCalleeSavedRegsCall(J) && 1025239310Sdim DoesModifyCalleeSavedReg(I, QRI))) { 1026239310Sdim Dependence = true; 1027239310Sdim return false; 1028239310Sdim } 1029239310Sdim 1030239310Sdim // Two control flow instructions cannot go in the same packet. 1031239310Sdim if (IsControlFlow(I) && IsControlFlow(J)) { 1032239310Sdim Dependence = true; 1033239310Sdim return false; 1034239310Sdim } 1035239310Sdim 1036239310Sdim // A LoopN instruction cannot appear in the same packet as a jump or call. 1037263508Sdim if (IsLoopN(I) && 1038263508Sdim (IsDirectJump(J) || MCIDJ.isCall() || QII->isDeallocRet(J))) { 1039239310Sdim Dependence = true; 1040239310Sdim return false; 1041239310Sdim } 1042263508Sdim if (IsLoopN(J) && 1043263508Sdim (IsDirectJump(I) || MCIDI.isCall() || QII->isDeallocRet(I))) { 1044239310Sdim Dependence = true; 1045239310Sdim return false; 1046239310Sdim } 1047239310Sdim 1048239310Sdim // dealloc_return cannot appear in the same packet as a conditional or 1049239310Sdim // unconditional jump. 1050263508Sdim if (QII->isDeallocRet(I) && 1051263508Sdim (MCIDJ.isBranch() || MCIDJ.isCall() || MCIDJ.isBarrier())) { 1052239310Sdim Dependence = true; 1053239310Sdim return false; 1054239310Sdim } 1055239310Sdim 1056239310Sdim 1057239310Sdim // V4 allows dual store. But does not allow second store, if the 1058239310Sdim // first store is not in SLOT0. New value store, new value jump, 1059239310Sdim // dealloc_return and memop always take SLOT0. 1060239310Sdim // Arch spec 3.4.4.2 1061239310Sdim if (QRI->Subtarget.hasV4TOps()) { 1062249423Sdim if (MCIDI.mayStore() && MCIDJ.mayStore() && 1063249423Sdim (QII->isNewValueInst(J) || QII->isMemOp(J) || QII->isMemOp(I))) { 1064239310Sdim Dependence = true; 1065239310Sdim return false; 1066239310Sdim } 1067239310Sdim 1068249423Sdim if ((QII->isMemOp(J) && MCIDI.mayStore()) 1069239310Sdim || (MCIDJ.mayStore() && QII->isMemOp(I)) 1070239310Sdim || (QII->isMemOp(J) && QII->isMemOp(I))) { 1071239310Sdim Dependence = true; 1072239310Sdim return false; 1073239310Sdim } 1074239310Sdim 1075239310Sdim //if dealloc_return 1076263508Sdim if (MCIDJ.mayStore() && QII->isDeallocRet(I)) { 1077239310Sdim Dependence = true; 1078239310Sdim return false; 1079239310Sdim } 1080239310Sdim 1081239310Sdim // If an instruction feeds new value jump, glue it. 1082239310Sdim MachineBasicBlock::iterator NextMII = I; 1083239310Sdim ++NextMII; 1084251662Sdim if (NextMII != I->getParent()->end() && QII->isNewValueJump(NextMII)) { 1085251662Sdim MachineInstr *NextMI = NextMII; 1086239310Sdim 1087239310Sdim bool secondRegMatch = false; 1088239310Sdim bool maintainNewValueJump = false; 1089239310Sdim 1090239310Sdim if (NextMI->getOperand(1).isReg() && 1091239310Sdim I->getOperand(0).getReg() == NextMI->getOperand(1).getReg()) { 1092239310Sdim secondRegMatch = true; 1093239310Sdim maintainNewValueJump = true; 1094239310Sdim } 1095239310Sdim 1096239310Sdim if (!secondRegMatch && 1097239310Sdim I->getOperand(0).getReg() == NextMI->getOperand(0).getReg()) { 1098239310Sdim maintainNewValueJump = true; 1099239310Sdim } 1100239310Sdim 1101239310Sdim for (std::vector<MachineInstr*>::iterator 1102239310Sdim VI = CurrentPacketMIs.begin(), 1103239310Sdim VE = CurrentPacketMIs.end(); 1104239310Sdim (VI != VE && maintainNewValueJump); ++VI) { 1105239310Sdim SUnit* PacketSU = MIToSUnit[*VI]; 1106239310Sdim 1107239310Sdim // NVJ can not be part of the dual jump - Arch Spec: section 7.8 1108239310Sdim if (PacketSU->getInstr()->getDesc().isCall()) { 1109239310Sdim Dependence = true; 1110239310Sdim break; 1111239310Sdim } 1112239310Sdim // Validate 1113239310Sdim // 1. Packet does not have a store in it. 1114239310Sdim // 2. If the first operand of the nvj is newified, and the second 1115239310Sdim // operand is also a reg, it (second reg) is not defined in 1116239310Sdim // the same packet. 1117239310Sdim // 3. If the second operand of the nvj is newified, (which means 1118239310Sdim // first operand is also a reg), first reg is not defined in 1119239310Sdim // the same packet. 1120239310Sdim if (PacketSU->getInstr()->getDesc().mayStore() || 1121239310Sdim PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || 1122239310Sdim // Check #2. 1123239310Sdim (!secondRegMatch && NextMI->getOperand(1).isReg() && 1124239310Sdim PacketSU->getInstr()->modifiesRegister( 1125239310Sdim NextMI->getOperand(1).getReg(), QRI)) || 1126239310Sdim // Check #3. 1127239310Sdim (secondRegMatch && 1128239310Sdim PacketSU->getInstr()->modifiesRegister( 1129239310Sdim NextMI->getOperand(0).getReg(), QRI))) { 1130239310Sdim Dependence = true; 1131239310Sdim break; 1132239310Sdim } 1133239310Sdim } 1134239310Sdim if (!Dependence) 1135239310Sdim GlueToNewValueJump = true; 1136239310Sdim else 1137239310Sdim return false; 1138239310Sdim } 1139239310Sdim } 1140239310Sdim 1141239310Sdim if (SUJ->isSucc(SUI)) { 1142239310Sdim for (unsigned i = 0; 1143239310Sdim (i < SUJ->Succs.size()) && !FoundSequentialDependence; 1144239310Sdim ++i) { 1145239310Sdim 1146239310Sdim if (SUJ->Succs[i].getSUnit() != SUI) { 1147239310Sdim continue; 1148239310Sdim } 1149239310Sdim 1150239310Sdim SDep::Kind DepType = SUJ->Succs[i].getKind(); 1151239310Sdim 1152239310Sdim // For direct calls: 1153239310Sdim // Ignore register dependences for call instructions for 1154239310Sdim // packetization purposes except for those due to r31 and 1155239310Sdim // predicate registers. 1156239310Sdim // 1157239310Sdim // For indirect calls: 1158239310Sdim // Same as direct calls + check for true dependences to the register 1159239310Sdim // used in the indirect call. 1160239310Sdim // 1161239310Sdim // We completely ignore Order dependences for call instructions 1162239310Sdim // 1163239310Sdim // For returns: 1164239310Sdim // Ignore register dependences for return instructions like jumpr, 1165239310Sdim // dealloc return unless we have dependencies on the explicit uses 1166239310Sdim // of the registers used by jumpr (like r31) or dealloc return 1167239310Sdim // (like r29 or r30). 1168239310Sdim // 1169239310Sdim // TODO: Currently, jumpr is handling only return of r31. So, the 1170239310Sdim // following logic (specificaly IsCallDependent) is working fine. 1171239310Sdim // We need to enable jumpr for register other than r31 and then, 1172239310Sdim // we need to rework the last part, where it handles indirect call 1173239310Sdim // of that (IsCallDependent) function. Bug 6216 is opened for this. 1174239310Sdim // 1175239310Sdim unsigned DepReg = 0; 1176239310Sdim const TargetRegisterClass* RC = NULL; 1177239310Sdim if (DepType == SDep::Data) { 1178239310Sdim DepReg = SUJ->Succs[i].getReg(); 1179239310Sdim RC = QRI->getMinimalPhysRegClass(DepReg); 1180239310Sdim } 1181239310Sdim if ((MCIDI.isCall() || MCIDI.isReturn()) && 1182239310Sdim (!IsRegDependence(DepType) || 1183239310Sdim !IsCallDependent(I, DepType, SUJ->Succs[i].getReg()))) { 1184239310Sdim /* do nothing */ 1185239310Sdim } 1186239310Sdim 1187239310Sdim // For instructions that can be promoted to dot-new, try to promote. 1188239310Sdim else if ((DepType == SDep::Data) && 1189239310Sdim CanPromoteToDotNew(I, SUJ, DepReg, MIToSUnit, II, RC) && 1190239310Sdim PromoteToDotNew(I, DepType, II, RC)) { 1191239310Sdim PromotedToDotNew = true; 1192239310Sdim /* do nothing */ 1193239310Sdim } 1194239310Sdim 1195239310Sdim else if ((DepType == SDep::Data) && 1196239310Sdim (QII->isNewValueJump(I))) { 1197239310Sdim /* do nothing */ 1198239310Sdim } 1199239310Sdim 1200239310Sdim // For predicated instructions, if the predicates are complements 1201239310Sdim // then there can be no dependence. 1202239310Sdim else if (QII->isPredicated(I) && 1203239310Sdim QII->isPredicated(J) && 1204239310Sdim ArePredicatesComplements(I, J, MIToSUnit)) { 1205239310Sdim /* do nothing */ 1206239310Sdim 1207239310Sdim } 1208239310Sdim else if (IsDirectJump(I) && 1209239310Sdim !MCIDJ.isBranch() && 1210239310Sdim !MCIDJ.isCall() && 1211239310Sdim (DepType == SDep::Order)) { 1212239310Sdim // Ignore Order dependences between unconditional direct branches 1213239310Sdim // and non-control-flow instructions 1214239310Sdim /* do nothing */ 1215239310Sdim } 1216239310Sdim else if (MCIDI.isConditionalBranch() && (DepType != SDep::Data) && 1217239310Sdim (DepType != SDep::Output)) { 1218239310Sdim // Ignore all dependences for jumps except for true and output 1219239310Sdim // dependences 1220239310Sdim /* do nothing */ 1221239310Sdim } 1222239310Sdim 1223239310Sdim // Ignore output dependences due to superregs. We can 1224239310Sdim // write to two different subregisters of R1:0 for instance 1225239310Sdim // in the same cycle 1226239310Sdim // 1227239310Sdim 1228239310Sdim // 1229239310Sdim // Let the 1230239310Sdim // If neither I nor J defines DepReg, then this is a 1231239310Sdim // superfluous output dependence. The dependence must be of the 1232239310Sdim // form: 1233239310Sdim // R0 = ... 1234239310Sdim // R1 = ... 1235239310Sdim // and there is an output dependence between the two instructions 1236239310Sdim // with 1237239310Sdim // DepReg = D0 1238239310Sdim // We want to ignore these dependences. 1239239310Sdim // Ideally, the dependence constructor should annotate such 1240239310Sdim // dependences. We can then avoid this relatively expensive check. 1241239310Sdim // 1242239310Sdim else if (DepType == SDep::Output) { 1243239310Sdim // DepReg is the register that's responsible for the dependence. 1244239310Sdim unsigned DepReg = SUJ->Succs[i].getReg(); 1245239310Sdim 1246239310Sdim // Check if I and J really defines DepReg. 1247239310Sdim if (I->definesRegister(DepReg) || 1248239310Sdim J->definesRegister(DepReg)) { 1249239310Sdim FoundSequentialDependence = true; 1250239310Sdim break; 1251239310Sdim } 1252239310Sdim } 1253239310Sdim 1254239310Sdim // We ignore Order dependences for 1255239310Sdim // 1. Two loads unless they are volatile. 1256239310Sdim // 2. Two stores in V4 unless they are volatile. 1257239310Sdim else if ((DepType == SDep::Order) && 1258243830Sdim !I->hasOrderedMemoryRef() && 1259243830Sdim !J->hasOrderedMemoryRef()) { 1260239310Sdim if (QRI->Subtarget.hasV4TOps() && 1261239310Sdim // hexagonv4 allows dual store. 1262239310Sdim MCIDI.mayStore() && MCIDJ.mayStore()) { 1263239310Sdim /* do nothing */ 1264239310Sdim } 1265239310Sdim // store followed by store-- not OK on V2 1266239310Sdim // store followed by load -- not OK on all (OK if addresses 1267239310Sdim // are not aliased) 1268239310Sdim // load followed by store -- OK on all 1269239310Sdim // load followed by load -- OK on all 1270239310Sdim else if ( !MCIDJ.mayStore()) { 1271239310Sdim /* do nothing */ 1272239310Sdim } 1273239310Sdim else { 1274239310Sdim FoundSequentialDependence = true; 1275239310Sdim break; 1276239310Sdim } 1277239310Sdim } 1278239310Sdim 1279239310Sdim // For V4, special case ALLOCFRAME. Even though there is dependency 1280239310Sdim // between ALLOCAFRAME and subsequent store, allow it to be 1281239310Sdim // packetized in a same packet. This implies that the store is using 1282239310Sdim // caller's SP. Hense, offset needs to be updated accordingly. 1283239310Sdim else if (DepType == SDep::Data 1284239310Sdim && QRI->Subtarget.hasV4TOps() 1285239310Sdim && J->getOpcode() == Hexagon::ALLOCFRAME 1286239310Sdim && (I->getOpcode() == Hexagon::STrid 1287239310Sdim || I->getOpcode() == Hexagon::STriw 1288239310Sdim || I->getOpcode() == Hexagon::STrib) 1289239310Sdim && I->getOperand(0).getReg() == QRI->getStackRegister() 1290239310Sdim && QII->isValidOffset(I->getOpcode(), 1291239310Sdim I->getOperand(1).getImm() - 1292239310Sdim (FrameSize + HEXAGON_LRFP_SIZE))) 1293239310Sdim { 1294239310Sdim GlueAllocframeStore = true; 1295239310Sdim // Since this store is to be glued with allocframe in the same 1296239310Sdim // packet, it will use SP of the previous stack frame, i.e 1297239310Sdim // caller's SP. Therefore, we need to recalculate offset according 1298239310Sdim // to this change. 1299239310Sdim I->getOperand(1).setImm(I->getOperand(1).getImm() - 1300239310Sdim (FrameSize + HEXAGON_LRFP_SIZE)); 1301239310Sdim } 1302239310Sdim 1303239310Sdim // 1304239310Sdim // Skip over anti-dependences. Two instructions that are 1305239310Sdim // anti-dependent can share a packet 1306239310Sdim // 1307239310Sdim else if (DepType != SDep::Anti) { 1308239310Sdim FoundSequentialDependence = true; 1309239310Sdim break; 1310239310Sdim } 1311239310Sdim } 1312239310Sdim 1313239310Sdim if (FoundSequentialDependence) { 1314239310Sdim Dependence = true; 1315239310Sdim return false; 1316239310Sdim } 1317239310Sdim } 1318239310Sdim 1319239310Sdim return true; 1320239310Sdim} 1321239310Sdim 1322239310Sdim// isLegalToPruneDependencies 1323239310Sdimbool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { 1324239310Sdim MachineInstr *I = SUI->getInstr(); 1325239310Sdim assert(I && SUJ->getInstr() && "Unable to packetize null instruction!"); 1326239310Sdim 1327239310Sdim const unsigned FrameSize = MF.getFrameInfo()->getStackSize(); 1328239310Sdim 1329239310Sdim if (Dependence) { 1330239310Sdim 1331239310Sdim // Check if the instruction was promoted to a dot-new. If so, demote it 1332239310Sdim // back into a dot-old. 1333239310Sdim if (PromotedToDotNew) { 1334239310Sdim DemoteToDotOld(I); 1335239310Sdim } 1336239310Sdim 1337239310Sdim // Check if the instruction (must be a store) was glued with an Allocframe 1338239310Sdim // instruction. If so, restore its offset to its original value, i.e. use 1339239310Sdim // curent SP instead of caller's SP. 1340239310Sdim if (GlueAllocframeStore) { 1341239310Sdim I->getOperand(1).setImm(I->getOperand(1).getImm() + 1342239310Sdim FrameSize + HEXAGON_LRFP_SIZE); 1343239310Sdim } 1344239310Sdim 1345239310Sdim return false; 1346239310Sdim } 1347239310Sdim return true; 1348239310Sdim} 1349239310Sdim 1350239310SdimMachineBasicBlock::iterator 1351239310SdimHexagonPacketizerList::addToPacket(MachineInstr *MI) { 1352239310Sdim 1353239310Sdim MachineBasicBlock::iterator MII = MI; 1354239310Sdim MachineBasicBlock *MBB = MI->getParent(); 1355239310Sdim 1356239310Sdim const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 1357239310Sdim 1358239310Sdim if (GlueToNewValueJump) { 1359239310Sdim 1360239310Sdim ++MII; 1361239310Sdim MachineInstr *nvjMI = MII; 1362239310Sdim assert(ResourceTracker->canReserveResources(MI)); 1363239310Sdim ResourceTracker->reserveResources(MI); 1364249423Sdim if ((QII->isExtended(MI) || QII->isConstExtended(MI)) && 1365239310Sdim !tryAllocateResourcesForConstExt(MI)) { 1366239310Sdim endPacket(MBB, MI); 1367239310Sdim ResourceTracker->reserveResources(MI); 1368239310Sdim assert(canReserveResourcesForConstExt(MI) && 1369239310Sdim "Ensure that there is a slot"); 1370239310Sdim reserveResourcesForConstExt(MI); 1371239310Sdim // Reserve resources for new value jump constant extender. 1372239310Sdim assert(canReserveResourcesForConstExt(MI) && 1373239310Sdim "Ensure that there is a slot"); 1374239310Sdim reserveResourcesForConstExt(nvjMI); 1375239310Sdim assert(ResourceTracker->canReserveResources(nvjMI) && 1376239310Sdim "Ensure that there is a slot"); 1377239310Sdim 1378239310Sdim } else if ( // Extended instruction takes two slots in the packet. 1379239310Sdim // Try reserve and allocate 4-byte in the current packet first. 1380239310Sdim (QII->isExtended(nvjMI) 1381239310Sdim && (!tryAllocateResourcesForConstExt(nvjMI) 1382239310Sdim || !ResourceTracker->canReserveResources(nvjMI))) 1383239310Sdim || // For non-extended instruction, no need to allocate extra 4 bytes. 1384249423Sdim (!QII->isExtended(nvjMI) && 1385239310Sdim !ResourceTracker->canReserveResources(nvjMI))) 1386239310Sdim { 1387239310Sdim endPacket(MBB, MI); 1388239310Sdim // A new and empty packet starts. 1389239310Sdim // We are sure that the resources requirements can be satisfied. 1390239310Sdim // Therefore, do not need to call "canReserveResources" anymore. 1391239310Sdim ResourceTracker->reserveResources(MI); 1392239310Sdim if (QII->isExtended(nvjMI)) 1393239310Sdim reserveResourcesForConstExt(nvjMI); 1394239310Sdim } 1395239310Sdim // Here, we are sure that "reserveResources" would succeed. 1396239310Sdim ResourceTracker->reserveResources(nvjMI); 1397239310Sdim CurrentPacketMIs.push_back(MI); 1398239310Sdim CurrentPacketMIs.push_back(nvjMI); 1399239310Sdim } else { 1400249423Sdim if ( (QII->isExtended(MI) || QII->isConstExtended(MI)) 1401239310Sdim && ( !tryAllocateResourcesForConstExt(MI) 1402239310Sdim || !ResourceTracker->canReserveResources(MI))) 1403239310Sdim { 1404239310Sdim endPacket(MBB, MI); 1405239310Sdim // Check if the instruction was promoted to a dot-new. If so, demote it 1406239310Sdim // back into a dot-old 1407239310Sdim if (PromotedToDotNew) { 1408239310Sdim DemoteToDotOld(MI); 1409239310Sdim } 1410239310Sdim reserveResourcesForConstExt(MI); 1411239310Sdim } 1412239310Sdim // In case that "MI" is not an extended insn, 1413239310Sdim // the resource availability has already been checked. 1414239310Sdim ResourceTracker->reserveResources(MI); 1415239310Sdim CurrentPacketMIs.push_back(MI); 1416239310Sdim } 1417239310Sdim return MII; 1418239310Sdim} 1419239310Sdim 1420239310Sdim//===----------------------------------------------------------------------===// 1421239310Sdim// Public Constructor Functions 1422239310Sdim//===----------------------------------------------------------------------===// 1423239310Sdim 1424239310SdimFunctionPass *llvm::createHexagonPacketizer() { 1425239310Sdim return new HexagonPacketizer(); 1426239310Sdim} 1427239310Sdim 1428