126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande//===----- HexagonPacketizer.cpp - vliw packetizer ---------------------===// 226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// The LLVM Compiler Infrastructure 426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// This file is distributed under the University of Illinois Open Source 626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// License. See LICENSE.TXT for details. 726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande//===----------------------------------------------------------------------===// 926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 1026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// This implements a simple VLIW packetizer using DFA. The packetizer works on 1126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// machine basic blocks. For each instruction I in BB, the packetizer consults 1226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// the DFA to see if machine resources are available to execute I. If so, the 1326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// packetizer checks if I depends on any instruction J in the current packet. 1426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// If no dependency is found, I is added to current packet and machine resource 1526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// is marked as taken. If any dependency is found, a target API call is made to 1626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// prune the dependence. 1726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 1826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande//===----------------------------------------------------------------------===// 1926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/CodeGen/DFAPacketizer.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "Hexagon.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "HexagonMachineFunctionInfo.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "HexagonRegisterInfo.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "HexagonSubtarget.h" 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "HexagonTargetMachine.h" 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/DenseMap.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/Statistic.h" 2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/LatencyPriorityQueue.h" 2826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/CodeGen/MachineDominators.h" 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFrameInfo.h" 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFunctionAnalysis.h" 3126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/CodeGen/MachineFunctionPass.h" 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineInstrBuilder.h" 3326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/CodeGen/MachineLoopInfo.h" 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineRegisterInfo.h" 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/Passes.h" 3626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/CodeGen/ScheduleDAG.h" 3726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/CodeGen/ScheduleDAGInstrs.h" 38ef94c6c85eed42d16fde51ee4415d27bb281a2caJyotsna Verma#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/SchedulerRegistry.h" 4026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/MC/MCInstrItineraries.h" 41ef94c6c85eed42d16fde51ee4415d27bb281a2caJyotsna Verma#include "llvm/Support/CommandLine.h" 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Compiler.h" 4326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include "llvm/Support/Debug.h" 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MathExtras.h" 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetInstrInfo.h" 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetMachine.h" 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetRegisterInfo.h" 4826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#include <map> 49f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma#include <vector> 5026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 5126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandeusing namespace llvm; 5226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "packets" 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 55f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Vermastatic cl::opt<bool> PacketizeVolatiles("hexagon-packetize-volatiles", 56f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma cl::ZeroOrMore, cl::Hidden, cl::init(true), 57f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma cl::desc("Allow non-solo packetization of volatile memory references")); 58f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 59f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Vermanamespace llvm { 60f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma void initializeHexagonPacketizerPass(PassRegistry&); 61f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma} 62f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 63f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 6426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandenamespace { 6526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande class HexagonPacketizer : public MachineFunctionPass { 6626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 6726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande public: 6826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande static char ID; 69f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma HexagonPacketizer() : MachineFunctionPass(ID) { 70f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma initializeHexagonPacketizerPass(*PassRegistry::getPassRegistry()); 71f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma } 7226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override { 7426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande AU.setPreservesCFG(); 7526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande AU.addRequired<MachineDominatorTree>(); 76f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma AU.addRequired<MachineBranchProbabilityInfo>(); 7726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande AU.addPreserved<MachineDominatorTree>(); 7826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande AU.addRequired<MachineLoopInfo>(); 7926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande AU.addPreserved<MachineLoopInfo>(); 8026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineFunctionPass::getAnalysisUsage(AU); 8126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 8226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *getPassName() const override { 8426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return "Hexagon Packetizer"; 8526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 8626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool runOnMachineFunction(MachineFunction &Fn) override; 8826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande }; 8926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande char HexagonPacketizer::ID = 0; 9026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 9126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande class HexagonPacketizerList : public VLIWPacketizerList { 9226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 9326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande private: 9426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 9526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Has the instruction been promoted to a dot-new instruction. 9626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool PromotedToDotNew; 9726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 9826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Has the instruction been glued to allocframe. 9926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool GlueAllocframeStore; 10026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 10126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Has the feeder instruction been glued to new value jump. 10226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool GlueToNewValueJump; 10326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 10426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check if there is a dependence between some instruction already in this 10526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // packet and this instruction. 10626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool Dependence; 10726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 10826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Only check for dependence if there are resources available to 10926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // schedule this instruction. 11026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool FoundSequentialDependence; 11126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 112f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma /// \brief A handle to the branch probability pass. 113f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma const MachineBranchProbabilityInfo *MBPI; 114f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 115f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma // Track MIs with ignored dependece. 116f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma std::vector<MachineInstr*> IgnoreDepMIs; 117f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 11826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande public: 11926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ctor. 12026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, 121f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma MachineDominatorTree &MDT, 122f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma const MachineBranchProbabilityInfo *MBPI); 12326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 12426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // initPacketizerState - initialize some internal flags. 125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void initPacketizerState() override; 12626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 12726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // ignorePseudoInstruction - Ignore bundling of pseudo instructions. 128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool ignorePseudoInstruction(MachineInstr *MI, 129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineBasicBlock *MBB) override; 13026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 13126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // isSoloInstruction - return true if instruction MI can not be packetized 13226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // with any other instruction, which means that MI itself is a packet. 133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isSoloInstruction(MachineInstr *MI) override; 13426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 13526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ 13626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // together. 137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) override; 13826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 13926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // isLegalToPruneDependencies - Is it legal to prune dependece between SUI 14026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // and SUJ. 141dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) override; 14226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 143dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineBasicBlock::iterator addToPacket(MachineInstr *MI) override; 14426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande private: 14526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool IsCallDependent(MachineInstr* MI, SDep::Kind DepType, unsigned DepReg); 14626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType, 147f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma MachineBasicBlock::iterator &MII, 148f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma const TargetRegisterClass* RC); 14926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU, 150f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma unsigned DepReg, 151f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma std::map <MachineInstr*, SUnit*> MIToSUnit, 152f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma MachineBasicBlock::iterator &MII, 153f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma const TargetRegisterClass* RC); 15426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU, 155f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma unsigned DepReg, 156f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma std::map <MachineInstr*, SUnit*> MIToSUnit, 157f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma MachineBasicBlock::iterator &MII); 15826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI, 159f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma unsigned DepReg, 160f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma std::map <MachineInstr*, SUnit*> MIToSUnit); 16126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool DemoteToDotOld(MachineInstr* MI); 16226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2, 16326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande std::map <MachineInstr*, SUnit*> MIToSUnit); 16426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool RestrictingDepExistInPacket(MachineInstr*, 16526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned, std::map <MachineInstr*, SUnit*>); 16626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool isNewifiable(MachineInstr* MI); 16726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool isCondInst(MachineInstr* MI); 16826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool tryAllocateResourcesForConstExt(MachineInstr* MI); 16926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool canReserveResourcesForConstExt(MachineInstr *MI); 17026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande void reserveResourcesForConstExt(MachineInstr* MI); 17126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool isNewValueInst(MachineInstr* MI); 17226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande }; 17326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 17426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 175f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna VermaINITIALIZE_PASS_BEGIN(HexagonPacketizer, "packets", "Hexagon Packetizer", 176f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma false, false) 177f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna VermaINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 178f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna VermaINITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) 179f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna VermaINITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) 180942940a3262242ac55efea88f818959f28d18bbaKrzysztof ParzyszekINITIALIZE_AG_DEPENDENCY(AliasAnalysis) 181f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna VermaINITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer", 182f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma false, false) 183f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 184f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma 18526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// HexagonPacketizerList Ctor. 18626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish PandeHexagonPacketizerList::HexagonPacketizerList( 187f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT, 188f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma const MachineBranchProbabilityInfo *MBPI) 18926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande : VLIWPacketizerList(MF, MLI, MDT, true){ 190f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma this->MBPI = MBPI; 19126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 19226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 19326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) { 19426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); 19526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>(); 19626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>(); 197f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma const MachineBranchProbabilityInfo *MBPI = 198f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma &getAnalysis<MachineBranchProbabilityInfo>(); 19926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Instantiate the packetizer. 200f945d09d53a4f2f392b8b51191d37de2f8acd566Jyotsna Verma HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI); 20126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 20226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // DFA state table should not be empty. 20326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(Packetizer.getResourceTracker() && "Empty DFA table!"); 20426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 20526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 20626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Loop over all basic blocks and remove KILL pseudo-instructions 20726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // These instructions confuse the dependence analysis. Consider: 20826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // D0 = ... (Insn 0) 20926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // R0 = KILL R0, D0 (Insn 1) 21026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // R0 = ... (Insn 2) 21126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Here, Insn 1 will result in the dependence graph not emitting an output 21226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dependence between Insn 0 and Insn 2. This can lead to incorrect 21326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // packetization 21426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 21526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 21626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MBB != MBBe; ++MBB) { 21726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator End = MBB->end(); 21826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator MI = MBB->begin(); 21926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande while (MI != End) { 22026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->isKill()) { 22126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator DeleteMI = MI; 22226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ++MI; 22326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MBB->erase(DeleteMI); 22426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande End = MBB->end(); 22526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande continue; 22626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 22726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ++MI; 22826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 22926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 23026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 23126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Loop over all of the basic blocks. 23226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end(); 23326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MBB != MBBe; ++MBB) { 23426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Find scheduling regions and schedule / packetize each region. 23526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned RemainingCount = MBB->size(); 23626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(MachineBasicBlock::iterator RegionEnd = MBB->end(); 23726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande RegionEnd != MBB->begin();) { 23826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // The next region starts above the previous region. Look backward in the 23926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // instruction stream until we find the nearest boundary. 24026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator I = RegionEnd; 24126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(;I != MBB->begin(); --I, --RemainingCount) { 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TII->isSchedulingBoundary(std::prev(I), MBB, Fn)) 24326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 24426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 24526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande I = MBB->begin(); 24626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 24726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Skip empty scheduling regions. 24826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (I == RegionEnd) { 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegionEnd = std::prev(RegionEnd); 25026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande --RemainingCount; 25126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande continue; 25226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 25326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Skip regions with one instruction. 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I == std::prev(RegionEnd)) { 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RegionEnd = std::prev(RegionEnd); 25626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande continue; 25726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 25826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 25926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Packetizer.PacketizeMIs(MBB, I, RegionEnd); 26026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande RegionEnd = I; 26126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 26226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 26326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 26426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 26526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 26626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 26726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 26826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool IsIndirectCall(MachineInstr* MI) { 26926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return ((MI->getOpcode() == Hexagon::CALLR) || 27026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (MI->getOpcode() == Hexagon::CALLRv3)); 27126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 27226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 27326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Reserve resources for constant extender. Trigure an assertion if 27426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// reservation fail. 27526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandevoid HexagonPacketizerList::reserveResourcesForConstExt(MachineInstr* MI) { 27626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 27739498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MachineFunction *MF = MI->getParent()->getParent(); 27839498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i), 27939498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MI->getDebugLoc()); 28026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 28126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (ResourceTracker->canReserveResources(PseudoMI)) { 28226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(PseudoMI); 28326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 28426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } else { 28526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 28626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande llvm_unreachable("can not reserve resources for constant extender."); 28726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 28826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return; 28926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 29026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 29126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) { 29226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 293ef94c6c85eed42d16fde51ee4415d27bb281a2caJyotsna Verma assert((QII->isExtended(MI) || QII->isConstExtended(MI)) && 29426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande "Should only be called for constant extended instructions"); 29526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineFunction *MF = MI->getParent()->getParent(); 29639498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i), 29726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getDebugLoc()); 29826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool CanReserve = ResourceTracker->canReserveResources(PseudoMI); 29926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MF->DeleteMachineInstr(PseudoMI); 30026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return CanReserve; 30126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 30226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 30326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Allocate resources (i.e. 4 bytes) for constant extender. If succeed, return 30426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// true, otherwise, return false. 30526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::tryAllocateResourcesForConstExt(MachineInstr* MI) { 30626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 30739498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MachineFunction *MF = MI->getParent()->getParent(); 30839498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i), 30939498d1ff0dc5d1d4379c31a92596377d0d5d8a7Jyotsna Verma MI->getDebugLoc()); 31026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 31126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (ResourceTracker->canReserveResources(PseudoMI)) { 31226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(PseudoMI); 31326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 31426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 31526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } else { 31626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getParent()->getParent()->DeleteMachineInstr(PseudoMI); 31726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 31826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 31926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 32026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 32126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 32226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::IsCallDependent(MachineInstr* MI, 32326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SDep::Kind DepType, 32426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned DepReg) { 32526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 32626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 32726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonRegisterInfo* QRI = 32826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (const HexagonRegisterInfo *) TM.getRegisterInfo(); 32926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 33026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check for lr dependence 33126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (DepReg == QRI->getRARegister()) { 33226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 33326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 33426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 33526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QII->isDeallocRet(MI)) { 33626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (DepReg == QRI->getFrameRegister() || 33726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DepReg == QRI->getStackRegister()) 33826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 33926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 34026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 34126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check if this is a predicate dependence 34226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const TargetRegisterClass* RC = QRI->getMinimalPhysRegClass(DepReg); 34326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (RC == &Hexagon::PredRegsRegClass) { 34426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 34526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 34626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 34726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 34826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Lastly check for an operand used in an indirect call 34926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If we had an attribute for checking if an instruction is an indirect call, 35026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // then we could have avoided this relatively brittle implementation of 35126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // IsIndirectCall() 35226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 35326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Assumes that the first operand of the CALLr is the function address 35426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 35526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (IsIndirectCall(MI) && (DepType == SDep::Data)) { 35626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineOperand MO = MI->getOperand(0); 35726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MO.isReg() && MO.isUse() && (MO.getReg() == DepReg)) { 35826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 35926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 36026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 36126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 36226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 36326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 36426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 36526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool IsRegDependence(const SDep::Kind DepType) { 36626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (DepType == SDep::Data || DepType == SDep::Anti || 36726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DepType == SDep::Output); 36826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 36926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 37026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool IsDirectJump(MachineInstr* MI) { 37126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (MI->getOpcode() == Hexagon::JMP); 37226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 37326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 37426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool IsSchedBarrier(MachineInstr* MI) { 37526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande switch (MI->getOpcode()) { 37626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande case Hexagon::BARRIER: 37726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 37826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 37926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 38026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 38126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 38226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool IsControlFlow(MachineInstr* MI) { 38326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (MI->getDesc().isTerminator() || MI->getDesc().isCall()); 38426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 38526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 38626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool IsLoopN(MachineInstr *MI) { 38726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (MI->getOpcode() == Hexagon::LOOP0_i || 38826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getOpcode() == Hexagon::LOOP0_r); 38926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 39026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 39126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande/// DoesModifyCalleeSavedReg - Returns true if the instruction modifies a 39226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande/// callee-saved register. 39326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic bool DoesModifyCalleeSavedReg(MachineInstr *MI, 39426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const TargetRegisterInfo *TRI) { 395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const MCPhysReg *CSR = TRI->getCalleeSavedRegs(); *CSR; ++CSR) { 39626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned CalleeSavedReg = *CSR; 39726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->modifiesRegister(CalleeSavedReg, TRI)) 39826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 39926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 40026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 40126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 40226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 40326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Returns true if an instruction can be promoted to .new predicate 40426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// or new-value store. 40526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::isNewifiable(MachineInstr* MI) { 406cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 407cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if ( isCondInst(MI) || QII->mayBeNewStore(MI)) 40826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 40926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else 41026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 41126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 41226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 41326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::isCondInst (MachineInstr* MI) { 41426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 41526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const MCInstrDesc& TID = MI->getDesc(); 41626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // bug 5670: until that is fixed, 41726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // this portion is disabled. 41826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if ( TID.isConditionalBranch() // && !IsRegisterJump(MI)) || 41926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || QII->isConditionalTransfer(MI) 42026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || QII->isConditionalALU32(MI) 42126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || QII->isConditionalLoad(MI) 42226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || QII->isConditionalStore(MI)) { 42326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 42426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 42526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 42626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 42726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 4285262abb2682a4d09cda3563a55f27caffb57466cBrendon Cahoon 42926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Promote an instructiont to its .new form. 43026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// At this time, we have already made a call to CanPromoteToDotNew 43126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// and made sure that it can *indeed* be promoted. 43226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::PromoteToDotNew(MachineInstr* MI, 43326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SDep::Kind DepType, MachineBasicBlock::iterator &MII, 43426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const TargetRegisterClass* RC) { 43526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 43626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert (DepType == SDep::Data); 43726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 43826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 43926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande int NewOpcode; 44026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (RC == &Hexagon::PredRegsRegClass) 44180d81aa8ba923c9f9a953410677ac53c4c2b8318Jyotsna Verma NewOpcode = QII->GetDotNewPredOp(MI, MBPI); 44226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else 4431a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma NewOpcode = QII->GetDotNewOp(MI); 44426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->setDesc(QII->get(NewOpcode)); 44526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 44626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 44726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 44826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 44926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::DemoteToDotOld(MachineInstr* MI) { 45026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 451cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma int NewOpcode = QII->GetDotOldOp(MI->getOpcode()); 45226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->setDesc(QII->get(NewOpcode)); 45326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 45426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 45526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 4561a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Vermaenum PredicateKind { 4571a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma PK_False, 4581a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma PK_True, 4591a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma PK_Unknown 4601a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma}; 46126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 4621a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma/// Returns true if an instruction is predicated on p0 and false if it's 4631a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma/// predicated on !p0. 4641a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Vermastatic PredicateKind getPredicateSense(MachineInstr* MI, 4651a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma const HexagonInstrInfo *QII) { 4661a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma if (!QII->isPredicated(MI)) 4671a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma return PK_Unknown; 46826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 4691a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma if (QII->isPredicatedTrue(MI)) 4701a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma return PK_True; 47126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 4721a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma return PK_False; 47326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 47426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 47526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic MachineOperand& GetPostIncrementOperand(MachineInstr *MI, 47626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII) { 47726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(QII->isPostIncrement(MI) && "Not a post increment operation."); 47826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#ifndef NDEBUG 47926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Post Increment means duplicates. Use dense map to find duplicates in the 48026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // list. Caution: Densemap initializes with the minimum of 64 buckets, 48126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // whereas there are at most 5 operands in the post increment. 48226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DenseMap<unsigned, unsigned> DefRegsSet; 48326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) 48426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->getOperand(opNum).isReg() && 48526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getOperand(opNum).isDef()) { 48626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DefRegsSet[MI->getOperand(opNum).getReg()] = 1; 48726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 48826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 48926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) 49026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->getOperand(opNum).isReg() && 49126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getOperand(opNum).isUse()) { 49226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (DefRegsSet[MI->getOperand(opNum).getReg()]) { 49326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return MI->getOperand(opNum); 49426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 49526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 49626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#else 49726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->getDesc().mayLoad()) { 49826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // The 2nd operand is always the post increment operand in load. 49926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(MI->getOperand(1).isReg() && 50026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande "Post increment operand has be to a register."); 50126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (MI->getOperand(1)); 50226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 50326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->getDesc().mayStore()) { 50426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // The 1st operand is always the post increment operand in store. 50526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(MI->getOperand(0).isReg() && 50626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande "Post increment operand has be to a register."); 50726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (MI->getOperand(0)); 50826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 50926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande#endif 51026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // we should never come here. 51126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande llvm_unreachable("mayLoad or mayStore not set for Post Increment operation"); 51226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 51326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 51426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// get the value being stored 51526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandestatic MachineOperand& GetStoreValueOperand(MachineInstr *MI) { 51626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // value being stored is always the last operand. 51726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return (MI->getOperand(MI->getNumOperands()-1)); 51826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 51926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 52026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// can be new value store? 52126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Following restrictions are to be respected in convert a store into 52226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// a new value store. 52326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 1. If an instruction uses auto-increment, its address register cannot 52426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// be a new-value register. Arch Spec 5.4.2.1 52526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 2. If an instruction uses absolute-set addressing mode, 52626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// its address register cannot be a new-value register. 52726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Arch Spec 5.4.2.1.TODO: This is not enabled as 52826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// as absolute-set address mode patters are not implemented. 52926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 3. If an instruction produces a 64-bit result, its registers cannot be used 53026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// as new-value registers. Arch Spec 5.4.2.2. 53126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 4. If the instruction that sets a new-value register is conditional, then 53226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// the instruction that uses the new-value register must also be conditional, 53326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// and both must always have their predicates evaluate identically. 53426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Arch Spec 5.4.2.3. 53526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 5. There is an implied restriction of a packet can not have another store, 53626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// if there is a new value store in the packet. Corollary, if there is 53726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// already a store in a packet, there can not be a new value store. 53826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Arch Spec: 3.4.4.2 53926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI, 54026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *PacketMI, unsigned DepReg, 541cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma std::map <MachineInstr*, SUnit*> MIToSUnit) { 542cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 543cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma // Make sure we are looking at the store, that can be promoted. 544cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if (!QII->mayBeNewStore(MI)) 54526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 54626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 54726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Make sure there is dependency and can be new value'ed 54826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (GetStoreValueOperand(MI).isReg() && 54926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GetStoreValueOperand(MI).getReg() != DepReg) 55026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 55126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 552cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma const HexagonRegisterInfo* QRI = 55326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (const HexagonRegisterInfo *) TM.getRegisterInfo(); 55426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const MCInstrDesc& MCID = PacketMI->getDesc(); 55526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // first operand is always the result 55626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 557397fc4874efe9c17e737d4c5c50bd19dc3bf27f5Jakob Stoklund Olesen const TargetRegisterClass* PacketRC = QII->getRegClass(MCID, 0, QRI, MF); 55826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 55926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // if there is already an store in the packet, no can do new value store 56026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Arch Spec 3.4.4.2. 56126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(), 56226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande VE = CurrentPacketMIs.end(); 56326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (VI != VE); ++VI) { 56426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* PacketSU = MIToSUnit[*VI]; 56526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketSU->getInstr()->getDesc().mayStore() || 56626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // if we have mayStore = 1 set on ALLOCFRAME and DEALLOCFRAME, 56726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // then we don't need this 56826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || 56926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketSU->getInstr()->getOpcode() == Hexagon::DEALLOCFRAME) 57026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 57126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 57226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 57326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketRC == &Hexagon::DoubleRegsRegClass) { 57426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // new value store constraint: double regs can not feed into new value store 57526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // arch spec section: 5.4.2.2 57626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 57726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 57826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 57926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Make sure it's NOT the post increment register that we are going to 58026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // new value. 58126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QII->isPostIncrement(MI) && 58226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getDesc().mayStore() && 58326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GetPostIncrementOperand(MI, QII).getReg() == DepReg) { 58426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 58526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 58626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 58726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QII->isPostIncrement(PacketMI) && 58826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketMI->getDesc().mayLoad() && 58926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GetPostIncrementOperand(PacketMI, QII).getReg() == DepReg) { 59026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // if source is post_inc, or absolute-set addressing, 59126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // it can not feed into new value store 59226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // r3 = memw(r2++#4) 59326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // memw(r30 + #-1404) = r2.new -> can not be new value store 59426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // arch spec section: 5.4.2.1 59526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 59626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 59726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 59826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If the source that feeds the store is predicated, new value store must 599cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma // also be predicated. 60026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QII->isPredicated(PacketMI)) { 60126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!QII->isPredicated(MI)) 60226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 60326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 60426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check to make sure that they both will have their predicates 60526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // evaluate identically 60612a52525e8481d1884f1f37b20d67791c68ed1ceSirish Pande unsigned predRegNumSrc = 0; 60712a52525e8481d1884f1f37b20d67791c68ed1ceSirish Pande unsigned predRegNumDst = 0; 608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const TargetRegisterClass* predRegClass = nullptr; 60926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 61026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Get predicate register used in the source instruction 61126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < PacketMI->getNumOperands(); opNum++) { 61226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if ( PacketMI->getOperand(opNum).isReg()) 61326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande predRegNumSrc = PacketMI->getOperand(opNum).getReg(); 61426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande predRegClass = QRI->getMinimalPhysRegClass(predRegNumSrc); 61526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (predRegClass == &Hexagon::PredRegsRegClass) { 61626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 61726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 61826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 61926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert ((predRegClass == &Hexagon::PredRegsRegClass ) && 62026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ("predicate register not found in a predicated PacketMI instruction")); 62126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 62226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Get predicate register used in new-value store instruction 62326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { 62426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if ( MI->getOperand(opNum).isReg()) 62526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande predRegNumDst = MI->getOperand(opNum).getReg(); 62626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande predRegClass = QRI->getMinimalPhysRegClass(predRegNumDst); 62726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (predRegClass == &Hexagon::PredRegsRegClass) { 62826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 62926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 63026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 63126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert ((predRegClass == &Hexagon::PredRegsRegClass ) && 63226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ("predicate register not found in a predicated MI instruction")); 63326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 63426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // New-value register producer and user (store) need to satisfy these 63526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // constraints: 63626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 1) Both instructions should be predicated on the same register. 63726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 2) If producer of the new-value register is .new predicated then store 63826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // should also be .new predicated and if producer is not .new predicated 63926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // then store should not be .new predicated. 64026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 3) Both new-value register producer and user should have same predicate 64126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // sense, i.e, either both should be negated or both should be none negated. 64226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 64326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (( predRegNumDst != predRegNumSrc) || 644810848d5b3bc53747722db0d30a21dc168c5503eJyotsna Verma QII->isDotNewInst(PacketMI) != QII->isDotNewInst(MI) || 6451a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma getPredicateSense(MI, QII) != getPredicateSense(PacketMI, QII)) { 64626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 64726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 64826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 64926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 65026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Make sure that other than the new-value register no other store instruction 65126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // register has been modified in the same packet. Predicate registers can be 65226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // modified by they should not be modified between the producer and the store 65326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // instruction as it will make them both conditional on different values. 65426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We already know this to be true for all the instructions before and 65526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // including PacketMI. Howerver, we need to perform the check for the 65626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // remaining instructions in the packet. 65726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 65826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande std::vector<MachineInstr*>::iterator VI; 65926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande std::vector<MachineInstr*>::iterator VE; 66026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned StartCheck = 0; 66126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 66226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (VI=CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end(); 66326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (VI != VE); ++VI) { 66426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* TempSU = MIToSUnit[*VI]; 66526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr* TempMI = TempSU->getInstr(); 66626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 66726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Following condition is true for all the instructions until PacketMI is 66826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // reached (StartCheck is set to 0 before the for loop). 66926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // StartCheck flag is 1 for all the instructions after PacketMI. 67026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (TempMI != PacketMI && !StartCheck) // start processing only after 67126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande continue; // encountering PacketMI 67226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 67326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande StartCheck = 1; 67426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (TempMI == PacketMI) // We don't want to check PacketMI for dependence 67526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande continue; 67626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 67726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) { 67826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->getOperand(opNum).isReg() && 67926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande TempSU->getInstr()->modifiesRegister(MI->getOperand(opNum).getReg(), 68026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande QRI)) 68126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 68226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 68326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 68426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Make sure that for non-POST_INC stores: 68626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 1. The only use of reg is DepReg and no other registers. 68726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // This handles V4 base+index registers. 68826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // The following store can not be dot new. 68926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Eg. r0 = add(r0, #3)a 69026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // memw(r1+r0<<#2) = r0 69126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!QII->isPostIncrement(MI) && 69226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GetStoreValueOperand(MI).isReg() && 69326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GetStoreValueOperand(MI).getReg() == DepReg) { 69426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < MI->getNumOperands()-1; opNum++) { 69526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->getOperand(opNum).isReg() && 69626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getOperand(opNum).getReg() == DepReg) { 69726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 69826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 69926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 70026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 2. If data definition is because of implicit definition of the register, 70126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // do not newify the store. Eg. 70226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // %R9<def> = ZXTH %R12, %D6<imp-use>, %R12<imp-def> 70326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // STrih_indexed %R8, 2, %R12<kill>; mem:ST2[%scevgep343] 70426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for(unsigned opNum = 0; opNum < PacketMI->getNumOperands(); opNum++) { 70526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketMI->getOperand(opNum).isReg() && 70626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketMI->getOperand(opNum).getReg() == DepReg && 70726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketMI->getOperand(opNum).isDef() && 70826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketMI->getOperand(opNum).isImplicit()) { 70926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 71026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 71126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 71226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 71326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 71426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Can be dot new store. 71526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 71626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 71726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 71826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// can this MI to promoted to either 71926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// new value store or new value jump 72026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI, 72126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit *PacketSU, unsigned DepReg, 72226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande std::map <MachineInstr*, SUnit*> MIToSUnit, 72326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator &MII) 72426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande{ 72526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 726cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 72726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonRegisterInfo* QRI = 72826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (const HexagonRegisterInfo *) TM.getRegisterInfo(); 72926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!QRI->Subtarget.hasV4TOps() || 730cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma !QII->mayBeNewStore(MI)) 73126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 73226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 73326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *PacketMI = PacketSU->getInstr(); 73426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 73526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check to see the store can be new value'ed. 73626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (CanPromoteToNewValueStore(MI, PacketMI, DepReg, MIToSUnit)) 73726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 73826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 73926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check to see the compare/jump can be new value'ed. 74026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // This is done as a pass on its own. Don't need to check it here. 74126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 74226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 74326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 74426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Check to see if an instruction can be dot new 74526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// There are three kinds. 74626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 1. dot new on predicate - V2/V3/V4 74726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 2. dot new on stores NV/ST - V4 74826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// 3. dot new on jump NV/J - V4 -- This is generated in a pass. 74926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI, 75026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit *PacketSU, unsigned DepReg, 75126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande std::map <MachineInstr*, SUnit*> MIToSUnit, 75226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator &MII, 75326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const TargetRegisterClass* RC ) 75426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande{ 755810848d5b3bc53747722db0d30a21dc168c5503eJyotsna Verma const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 756810848d5b3bc53747722db0d30a21dc168c5503eJyotsna Verma // Already a dot new instruction. 757cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if (QII->isDotNewInst(MI) && !QII->mayBeNewStore(MI)) 75826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 75926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 76026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!isNewifiable(MI)) 76126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 76226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 76326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // predicate .new 76426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (RC == &Hexagon::PredRegsRegClass && isCondInst(MI)) 76526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 76626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (RC != &Hexagon::PredRegsRegClass && 767cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma !QII->mayBeNewStore(MI)) // MI is not a new-value store 76826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 76926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else { 77026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Create a dot new machine instruction to see if resources can be 77126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // allocated. If not, bail out now. 7721a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma int NewOpcode = QII->GetDotNewOp(MI); 77326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const MCInstrDesc &desc = QII->get(NewOpcode); 77426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DebugLoc dl; 77526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *NewMI = 77626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getParent()->getParent()->CreateMachineInstr(desc, dl); 77726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool ResourcesAvailable = ResourceTracker->canReserveResources(NewMI); 77826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MI->getParent()->getParent()->DeleteMachineInstr(NewMI); 77926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 78026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!ResourcesAvailable) 78126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 78226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 78326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // new value store only 78426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // new new value jump generated as a passes 78526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!CanPromoteToNewValue(MI, PacketSU, DepReg, MIToSUnit, MII)) { 78626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 78726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 78826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 78926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 79026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 79126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 79226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Go through the packet instructions and search for anti dependency 79326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// between them and DepReg from MI 79426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Consider this case: 79526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Trying to add 79626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// a) %R1<def> = TFRI_cdNotPt %P3, 2 79726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// to this packet: 79826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// { 79926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// b) %P0<def> = OR_pp %P3<kill>, %P0<kill> 80026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// c) %P3<def> = TFR_PdRs %R23 80126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// d) %R1<def> = TFRI_cdnPt %P3, 4 80226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// } 80326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// The P3 from a) and d) will be complements after 80426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// a)'s P3 is converted to .new form 80526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Anti Dep between c) and b) is irrelevant for this case 80626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI, 80726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned DepReg, 80826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande std::map <MachineInstr*, SUnit*> MIToSUnit) { 80926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 81026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 81126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* PacketSUDep = MIToSUnit[MI]; 81226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 81326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(), 81426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) { 81526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 81626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We only care for dependencies to predicated instructions 81726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if(!QII->isPredicated(*VIN)) continue; 81826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 81926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Scheduling Unit for current insn in the packet 82026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* PacketSU = MIToSUnit[*VIN]; 82126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 82226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Look at dependencies between current members of the packet 82326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // and predicate defining instruction MI. 82426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Make sure that dependency is on the exact register 82526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // we care about. 82626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketSU->isSucc(PacketSUDep)) { 82726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (unsigned i = 0; i < PacketSU->Succs.size(); ++i) { 82826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if ((PacketSU->Succs[i].getSUnit() == PacketSUDep) && 82926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (PacketSU->Succs[i].getKind() == SDep::Anti) && 83026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (PacketSU->Succs[i].getReg() == DepReg)) { 83126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 83226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 83326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 83426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 83526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 83626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 83726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 83826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 83926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 84026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 84191eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma/// Gets the predicate register of a predicated instruction. 842a32218a7eca458e55217f5a0674c23351a9472acBenjamin Kramerstatic unsigned getPredicatedRegister(MachineInstr *MI, 843a32218a7eca458e55217f5a0674c23351a9472acBenjamin Kramer const HexagonInstrInfo *QII) { 84491eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma /// We use the following rule: The first predicate register that is a use is 84591eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma /// the predicate register of a predicated instruction. 84691eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma 84791eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma assert(QII->isPredicated(MI) && "Must be predicated instruction"); 84891eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma 84991eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma for (MachineInstr::mop_iterator OI = MI->operands_begin(), 85091eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma OE = MI->operands_end(); OI != OE; ++OI) { 85191eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma MachineOperand &Op = *OI; 85291eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma if (Op.isReg() && Op.getReg() && Op.isUse() && 85391eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma Hexagon::PredRegsRegClass.contains(Op.getReg())) 85491eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma return Op.getReg(); 85591eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma } 85691eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma 85791eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma llvm_unreachable("Unknown instruction operand layout"); 85891eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma 85991eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma return 0; 86091eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma} 86191eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma 86226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Given two predicated instructions, this function detects whether 86326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// the predicates are complements 86426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1, 86526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) { 86626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 86726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 86891eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma 86991eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma // If we don't know the predicate sense of the instructions bail out early, we 87091eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma // need it later. 87191eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma if (getPredicateSense(MI1, QII) == PK_Unknown || 87291eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma getPredicateSense(MI2, QII) == PK_Unknown) 87326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 87426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 87526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Scheduling unit for candidate 87626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* SU = MIToSUnit[MI1]; 87726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 87826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // One corner case deals with the following scenario: 87926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Trying to add 88026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // a) %R24<def> = TFR_cPt %P0, %R25 88126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // to this packet: 88226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 88326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // { 88426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // b) %R25<def> = TFR_cNotPt %P0, %R24 88526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // c) %P0<def> = CMPEQri %R26, 1 88626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // } 88726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 88826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // On general check a) and b) are complements, but 88926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // presence of c) will convert a) to .new form, and 89026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // then it is not a complement 89126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We attempt to detect it by analyzing existing 89226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dependencies in the packet 89326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 89426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Analyze relationships between all existing members of the packet. 89526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Look for Anti dependecy on the same predicate reg 89626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // as used in the candidate 89726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(), 89826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) { 89926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 90026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Scheduling Unit for current insn in the packet 90126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* PacketSU = MIToSUnit[*VIN]; 90226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 90326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If this instruction in the packet is succeeded by the candidate... 90426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketSU->isSucc(SU)) { 90526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (unsigned i = 0; i < PacketSU->Succs.size(); ++i) { 90626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // The corner case exist when there is true data 90726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dependency between candidate and one of current 90826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // packet members, this dep is on predicate reg, and 90926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // there already exist anti dep on the same pred in 91026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // the packet. 91126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketSU->Succs[i].getSUnit() == SU && 91291eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma PacketSU->Succs[i].getKind() == SDep::Data && 91326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Hexagon::PredRegsRegClass.contains( 91426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketSU->Succs[i].getReg()) && 91526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Here I know that *VIN is predicate setting instruction 91626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // with true data dep to candidate on the register 91726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // we care about - c) in the above example. 91826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Now I need to see if there is an anti dependency 91926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // from c) to any other instruction in the 92026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // same packet on the pred reg of interest 92126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande RestrictingDepExistInPacket(*VIN,PacketSU->Succs[i].getReg(), 92226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MIToSUnit)) { 92326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 92426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 92526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 92626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 92726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 92826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 92926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If the above case does not apply, check regular 93026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // complement condition. 93126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check that the predicate register is the same and 93226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // that the predicate sense is different 93326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We also need to differentiate .old vs. .new: 93426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // !p0 is not complimentary to p0.new 93591eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma unsigned PReg1 = getPredicatedRegister(MI1, QII); 93691eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma unsigned PReg2 = getPredicatedRegister(MI2, QII); 93791eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma return ((PReg1 == PReg2) && 93891eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma Hexagon::PredRegsRegClass.contains(PReg1) && 93991eadc6d697647f426d05cab66aae2a19112343eJyotsna Verma Hexagon::PredRegsRegClass.contains(PReg2) && 9401a35b8e2eb165624013d5a2eaf8b673f026999fcJyotsna Verma (getPredicateSense(MI1, QII) != getPredicateSense(MI2, QII)) && 941810848d5b3bc53747722db0d30a21dc168c5503eJyotsna Verma (QII->isDotNewInst(MI1) == QII->isDotNewInst(MI2))); 94226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 94326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 94426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// initPacketizerState - Initialize packetizer flags 94526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandevoid HexagonPacketizerList::initPacketizerState() { 94626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 94726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = false; 94826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PromotedToDotNew = false; 94926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GlueToNewValueJump = false; 95026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GlueAllocframeStore = false; 95126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande FoundSequentialDependence = false; 95226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 95326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return; 95426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 95526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 95626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// ignorePseudoInstruction - Ignore bundling of pseudo instructions. 95726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::ignorePseudoInstruction(MachineInstr *MI, 95826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock *MBB) { 95926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->isDebugValue()) 96026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 96126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 96226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We must print out inline assembly 96326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->isInlineAsm()) 96426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 96526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 96626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We check if MI has any functional units mapped to it. 96726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If it doesn't, we ignore the instruction. 96826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const MCInstrDesc& TID = MI->getDesc(); 96926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned SchedClass = TID.getSchedClass(); 97026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const InstrStage* IS = 97126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->getInstrItins()->beginStage(SchedClass); 972b460a3382961c5be9952a75d46228f624edbd39fHal Finkel unsigned FuncUnits = IS->getUnits(); 97326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return !FuncUnits; 97426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 97526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 97626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// isSoloInstruction: - Returns true for instructions that must be 97726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// scheduled in their own packet. 97826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::isSoloInstruction(MachineInstr *MI) { 97926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 98026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->isInlineAsm()) 98126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 98226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 98326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (MI->isEHLabel()) 98426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 98526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 98626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // From Hexagon V4 Programmer's Reference Manual 3.4.4 Grouping constraints: 98726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // trap, pause, barrier, icinva, isync, and syncht are solo instructions. 98826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // They must not be grouped with other instructions in a packet. 98926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (IsSchedBarrier(MI)) 99026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 99126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 99226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 99326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 99426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 99526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// isLegalToPacketizeTogether: 99626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// SUI is the current instruction that is out side of the current packet. 99726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// SUJ is the current instruction inside the current packet against which that 99826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// SUI will be packetized. 99926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) { 100026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *I = SUI->getInstr(); 100126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *J = SUJ->getInstr(); 100226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(I && J && "Unable to packetize null instruction!"); 100326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 100426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const MCInstrDesc &MCIDI = I->getDesc(); 100526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const MCInstrDesc &MCIDJ = J->getDesc(); 100626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 100726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator II = I; 100826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 100926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const unsigned FrameSize = MF.getFrameInfo()->getStackSize(); 101026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonRegisterInfo* QRI = 101126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (const HexagonRegisterInfo *) TM.getRegisterInfo(); 101226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 101326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 101426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Inline asm cannot go in the packet. 101526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (I->getOpcode() == Hexagon::INLINEASM) 101626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande llvm_unreachable("Should not meet inline asm here!"); 101726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 101826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (isSoloInstruction(I)) 101926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande llvm_unreachable("Should not meet solo instr here!"); 102026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 102126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // A save callee-save register function call can only be in a packet 102226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // with instructions that don't write to the callee-save registers. 102326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if ((QII->isSaveCalleeSavedRegsCall(I) && 102426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DoesModifyCalleeSavedReg(J, QRI)) || 102526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (QII->isSaveCalleeSavedRegsCall(J) && 102626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DoesModifyCalleeSavedReg(I, QRI))) { 102726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 102826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 102926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 103026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 103126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Two control flow instructions cannot go in the same packet. 103226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (IsControlFlow(I) && IsControlFlow(J)) { 103326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 103426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 103526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 103626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 103726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // A LoopN instruction cannot appear in the same packet as a jump or call. 1038cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if (IsLoopN(I) && 1039cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma (IsDirectJump(J) || MCIDJ.isCall() || QII->isDeallocRet(J))) { 104026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 104126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 104226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 1043cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if (IsLoopN(J) && 1044cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma (IsDirectJump(I) || MCIDI.isCall() || QII->isDeallocRet(I))) { 104526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 104626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 104726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 104826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 104926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dealloc_return cannot appear in the same packet as a conditional or 105026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // unconditional jump. 1051cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if (QII->isDeallocRet(I) && 1052cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma (MCIDJ.isBranch() || MCIDJ.isCall() || MCIDJ.isBarrier())) { 105326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 105426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 105526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 105626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 105726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 105826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // V4 allows dual store. But does not allow second store, if the 105926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // first store is not in SLOT0. New value store, new value jump, 106026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dealloc_return and memop always take SLOT0. 106126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Arch spec 3.4.4.2 106226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QRI->Subtarget.hasV4TOps()) { 10639feabc23b39d90f8bf9ab5ac23f5a7f8af71480aJyotsna Verma if (MCIDI.mayStore() && MCIDJ.mayStore() && 10649feabc23b39d90f8bf9ab5ac23f5a7f8af71480aJyotsna Verma (QII->isNewValueInst(J) || QII->isMemOp(J) || QII->isMemOp(I))) { 106526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 106626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 106726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 106826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 10699feabc23b39d90f8bf9ab5ac23f5a7f8af71480aJyotsna Verma if ((QII->isMemOp(J) && MCIDI.mayStore()) 107026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || (MCIDJ.mayStore() && QII->isMemOp(I)) 107126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || (QII->isMemOp(J) && QII->isMemOp(I))) { 107226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 107326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 107426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 107526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 107626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande //if dealloc_return 1077cdfb55d15bbcdf1533ca26ffcb9c94fa5d225bd0Jyotsna Verma if (MCIDJ.mayStore() && QII->isDeallocRet(I)) { 107826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 107926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 108026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 108126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 108226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If an instruction feeds new value jump, glue it. 108326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator NextMII = I; 108426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ++NextMII; 10851a7eab387849feaa3e9c35f145d5b07be54686e3Jyotsna Verma if (NextMII != I->getParent()->end() && QII->isNewValueJump(NextMII)) { 10861a7eab387849feaa3e9c35f145d5b07be54686e3Jyotsna Verma MachineInstr *NextMI = NextMII; 108726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 108826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool secondRegMatch = false; 108926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande bool maintainNewValueJump = false; 109026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 109126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (NextMI->getOperand(1).isReg() && 109226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande I->getOperand(0).getReg() == NextMI->getOperand(1).getReg()) { 109326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande secondRegMatch = true; 109426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande maintainNewValueJump = true; 109526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 109626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 109726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!secondRegMatch && 109826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande I->getOperand(0).getReg() == NextMI->getOperand(0).getReg()) { 109926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande maintainNewValueJump = true; 110026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 110126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 110226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (std::vector<MachineInstr*>::iterator 110326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande VI = CurrentPacketMIs.begin(), 110426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande VE = CurrentPacketMIs.end(); 110526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (VI != VE && maintainNewValueJump); ++VI) { 110626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SUnit* PacketSU = MIToSUnit[*VI]; 110726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 110826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // NVJ can not be part of the dual jump - Arch Spec: section 7.8 110926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketSU->getInstr()->getDesc().isCall()) { 111026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 111126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 111226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 111326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Validate 111426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 1. Packet does not have a store in it. 111526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 2. If the first operand of the nvj is newified, and the second 111626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // operand is also a reg, it (second reg) is not defined in 111726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // the same packet. 111826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 3. If the second operand of the nvj is newified, (which means 111926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // first operand is also a reg), first reg is not defined in 112026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // the same packet. 112126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PacketSU->getInstr()->getDesc().mayStore() || 112226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME || 112326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check #2. 112426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (!secondRegMatch && NextMI->getOperand(1).isReg() && 112526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketSU->getInstr()->modifiesRegister( 112626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande NextMI->getOperand(1).getReg(), QRI)) || 112726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check #3. 112826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (secondRegMatch && 112926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PacketSU->getInstr()->modifiesRegister( 113026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande NextMI->getOperand(0).getReg(), QRI))) { 113126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 113226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 113326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 113426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 113526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (!Dependence) 113626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GlueToNewValueJump = true; 113726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else 113826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 113926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 114026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 114126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 114226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (SUJ->isSucc(SUI)) { 114326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande for (unsigned i = 0; 114426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (i < SUJ->Succs.size()) && !FoundSequentialDependence; 114526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ++i) { 114626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 114726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (SUJ->Succs[i].getSUnit() != SUI) { 114826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande continue; 114926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 115026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 115126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande SDep::Kind DepType = SUJ->Succs[i].getKind(); 115226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 115326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // For direct calls: 115426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ignore register dependences for call instructions for 115526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // packetization purposes except for those due to r31 and 115626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // predicate registers. 115726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 115826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // For indirect calls: 115926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Same as direct calls + check for true dependences to the register 116026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // used in the indirect call. 116126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 116226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We completely ignore Order dependences for call instructions 116326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 116426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // For returns: 116526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ignore register dependences for return instructions like jumpr, 116626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dealloc return unless we have dependencies on the explicit uses 116726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // of the registers used by jumpr (like r31) or dealloc return 116826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // (like r29 or r30). 116926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 117026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // TODO: Currently, jumpr is handling only return of r31. So, the 117126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // following logic (specificaly IsCallDependent) is working fine. 117226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We need to enable jumpr for register other than r31 and then, 117326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // we need to rework the last part, where it handles indirect call 117426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // of that (IsCallDependent) function. Bug 6216 is opened for this. 117526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 117626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned DepReg = 0; 1177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const TargetRegisterClass* RC = nullptr; 117826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (DepType == SDep::Data) { 117926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DepReg = SUJ->Succs[i].getReg(); 118026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande RC = QRI->getMinimalPhysRegClass(DepReg); 118126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 118226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if ((MCIDI.isCall() || MCIDI.isReturn()) && 118326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (!IsRegDependence(DepType) || 118426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande !IsCallDependent(I, DepType, SUJ->Succs[i].getReg()))) { 118526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 118626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 118726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 118826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // For instructions that can be promoted to dot-new, try to promote. 118926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if ((DepType == SDep::Data) && 119026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande CanPromoteToDotNew(I, SUJ, DepReg, MIToSUnit, II, RC) && 119126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PromoteToDotNew(I, DepType, II, RC)) { 119226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande PromotedToDotNew = true; 119326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 119426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 119526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 119626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if ((DepType == SDep::Data) && 119726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (QII->isNewValueJump(I))) { 119826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 119926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 120026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 120126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // For predicated instructions, if the predicates are complements 120226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // then there can be no dependence. 120326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (QII->isPredicated(I) && 120426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande QII->isPredicated(J) && 120526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ArePredicatesComplements(I, J, MIToSUnit)) { 120626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 120726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 120826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 120926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (IsDirectJump(I) && 121026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande !MCIDJ.isBranch() && 121126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande !MCIDJ.isCall() && 121226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (DepType == SDep::Order)) { 121326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ignore Order dependences between unconditional direct branches 121426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // and non-control-flow instructions 121526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 121626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 121726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (MCIDI.isConditionalBranch() && (DepType != SDep::Data) && 121826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (DepType != SDep::Output)) { 121926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ignore all dependences for jumps except for true and output 122026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dependences 122126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 122226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 122326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 122426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ignore output dependences due to superregs. We can 122526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // write to two different subregisters of R1:0 for instance 122626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // in the same cycle 122726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 122826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 122926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 123026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Let the 123126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // If neither I nor J defines DepReg, then this is a 123226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // superfluous output dependence. The dependence must be of the 123326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // form: 123426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // R0 = ... 123526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // R1 = ... 123626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // and there is an output dependence between the two instructions 123726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // with 123826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // DepReg = D0 123926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We want to ignore these dependences. 124026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Ideally, the dependence constructor should annotate such 124126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // dependences. We can then avoid this relatively expensive check. 124226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 124326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (DepType == SDep::Output) { 124426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // DepReg is the register that's responsible for the dependence. 124526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande unsigned DepReg = SUJ->Succs[i].getReg(); 124626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 124726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check if I and J really defines DepReg. 124826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (I->definesRegister(DepReg) || 124926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande J->definesRegister(DepReg)) { 125026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande FoundSequentialDependence = true; 125126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 125226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 125326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 125426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 125526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We ignore Order dependences for 125626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 1. Two loads unless they are volatile. 125726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 2. Two stores in V4 unless they are volatile. 125826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if ((DepType == SDep::Order) && 1259f036f7a1e79910bf5b5b6f37d2e512b4f01155a0Jakob Stoklund Olesen !I->hasOrderedMemoryRef() && 1260f036f7a1e79910bf5b5b6f37d2e512b4f01155a0Jakob Stoklund Olesen !J->hasOrderedMemoryRef()) { 126126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QRI->Subtarget.hasV4TOps() && 126226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // hexagonv4 allows dual store. 126326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MCIDI.mayStore() && MCIDJ.mayStore()) { 126426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 126526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 126626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // store followed by store-- not OK on V2 126726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // store followed by load -- not OK on all (OK if addresses 126826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // are not aliased) 126926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // load followed by store -- OK on all 127026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // load followed by load -- OK on all 127126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if ( !MCIDJ.mayStore()) { 127226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande /* do nothing */ 127326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 127426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else { 127526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande FoundSequentialDependence = true; 127626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 127726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 127826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 127926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 128026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // For V4, special case ALLOCFRAME. Even though there is dependency 128126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // between ALLOCAFRAME and subsequent store, allow it to be 128226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // packetized in a same packet. This implies that the store is using 128326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // caller's SP. Hense, offset needs to be updated accordingly. 128426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (DepType == SDep::Data 128526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && QRI->Subtarget.hasV4TOps() 128626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && J->getOpcode() == Hexagon::ALLOCFRAME 128726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && (I->getOpcode() == Hexagon::STrid 128826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || I->getOpcode() == Hexagon::STriw 128926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || I->getOpcode() == Hexagon::STrib) 129026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && I->getOperand(0).getReg() == QRI->getStackRegister() 129126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && QII->isValidOffset(I->getOpcode(), 129226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande I->getOperand(1).getImm() - 129326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (FrameSize + HEXAGON_LRFP_SIZE))) 129426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande { 129526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande GlueAllocframeStore = true; 129626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Since this store is to be glued with allocframe in the same 129726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // packet, it will use SP of the previous stack frame, i.e 129826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // caller's SP. Therefore, we need to recalculate offset according 129926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // to this change. 130026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande I->getOperand(1).setImm(I->getOperand(1).getImm() - 130126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (FrameSize + HEXAGON_LRFP_SIZE)); 130226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 130326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 130426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 130526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Skip over anti-dependences. Two instructions that are 130626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // anti-dependent can share a packet 130726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // 130826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande else if (DepType != SDep::Anti) { 130926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande FoundSequentialDependence = true; 131026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande break; 131126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 131226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 131326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 131426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (FoundSequentialDependence) { 131526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande Dependence = true; 131626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 131726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 131826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 131926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 132026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 132126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 132226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 132326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// isLegalToPruneDependencies 132426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pandebool HexagonPacketizerList::isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) { 132526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *I = SUI->getInstr(); 132626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(I && SUJ->getInstr() && "Unable to packetize null instruction!"); 132726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 132826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const unsigned FrameSize = MF.getFrameInfo()->getStackSize(); 132926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 133026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (Dependence) { 133126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 133226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check if the instruction was promoted to a dot-new. If so, demote it 133326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // back into a dot-old. 133426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PromotedToDotNew) { 133526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DemoteToDotOld(I); 133626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 133726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 133826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check if the instruction (must be a store) was glued with an Allocframe 133926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // instruction. If so, restore its offset to its original value, i.e. use 134026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // curent SP instead of caller's SP. 134126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (GlueAllocframeStore) { 134226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande I->getOperand(1).setImm(I->getOperand(1).getImm() + 134326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande FrameSize + HEXAGON_LRFP_SIZE); 134426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 134526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 134626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return false; 134726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 134826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return true; 134926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 135026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 135126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish PandeMachineBasicBlock::iterator 135226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish PandeHexagonPacketizerList::addToPacket(MachineInstr *MI) { 135326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 135426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock::iterator MII = MI; 135526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineBasicBlock *MBB = MI->getParent(); 135626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 135726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII; 135826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 135926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (GlueToNewValueJump) { 136026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 136126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ++MII; 136226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande MachineInstr *nvjMI = MII; 136326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(ResourceTracker->canReserveResources(MI)); 136426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(MI); 1365ef94c6c85eed42d16fde51ee4415d27bb281a2caJyotsna Verma if ((QII->isExtended(MI) || QII->isConstExtended(MI)) && 136626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande !tryAllocateResourcesForConstExt(MI)) { 136726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande endPacket(MBB, MI); 136826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(MI); 136926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(canReserveResourcesForConstExt(MI) && 137026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande "Ensure that there is a slot"); 137126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande reserveResourcesForConstExt(MI); 137226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Reserve resources for new value jump constant extender. 137326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(canReserveResourcesForConstExt(MI) && 137426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande "Ensure that there is a slot"); 137526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande reserveResourcesForConstExt(nvjMI); 137626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande assert(ResourceTracker->canReserveResources(nvjMI) && 137726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande "Ensure that there is a slot"); 137826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 137926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } else if ( // Extended instruction takes two slots in the packet. 138026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Try reserve and allocate 4-byte in the current packet first. 138126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande (QII->isExtended(nvjMI) 138226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && (!tryAllocateResourcesForConstExt(nvjMI) 138326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || !ResourceTracker->canReserveResources(nvjMI))) 138426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || // For non-extended instruction, no need to allocate extra 4 bytes. 1385ef94c6c85eed42d16fde51ee4415d27bb281a2caJyotsna Verma (!QII->isExtended(nvjMI) && 138626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande !ResourceTracker->canReserveResources(nvjMI))) 138726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande { 138826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande endPacket(MBB, MI); 138926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // A new and empty packet starts. 139026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // We are sure that the resources requirements can be satisfied. 139126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Therefore, do not need to call "canReserveResources" anymore. 139226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(MI); 139326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (QII->isExtended(nvjMI)) 139426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande reserveResourcesForConstExt(nvjMI); 139526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 139626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Here, we are sure that "reserveResources" would succeed. 139726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(nvjMI); 139826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande CurrentPacketMIs.push_back(MI); 139926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande CurrentPacketMIs.push_back(nvjMI); 140026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } else { 1401ef94c6c85eed42d16fde51ee4415d27bb281a2caJyotsna Verma if ( (QII->isExtended(MI) || QII->isConstExtended(MI)) 140226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande && ( !tryAllocateResourcesForConstExt(MI) 140326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande || !ResourceTracker->canReserveResources(MI))) 140426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande { 140526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande endPacket(MBB, MI); 140626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // Check if the instruction was promoted to a dot-new. If so, demote it 140726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // back into a dot-old 140826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande if (PromotedToDotNew) { 140926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande DemoteToDotOld(MI); 141026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 141126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande reserveResourcesForConstExt(MI); 141226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 141326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // In case that "MI" is not an extended insn, 141426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande // the resource availability has already been checked. 141526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande ResourceTracker->reserveResources(MI); 141626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande CurrentPacketMIs.push_back(MI); 141726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande } 141826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return MII; 141926f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 142026f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 142126f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande//===----------------------------------------------------------------------===// 142226f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande// Public Constructor Functions 142326f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande//===----------------------------------------------------------------------===// 142426f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 142526f61a158b3cce69252c05cc0e79f500d6c3d92eSirish PandeFunctionPass *llvm::createHexagonPacketizer() { 142626f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande return new HexagonPacketizer(); 142726f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande} 142826f61a158b3cce69252c05cc0e79f500d6c3d92eSirish Pande 1429