MipsDelaySlotFiller.cpp revision 327952
1327952Sdim//===- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler -------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10249423Sdim// Simple pass to fill delay slots with useful instructions. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14276479Sdim#include "MCTargetDesc/MipsMCNaCl.h" 15193323Sed#include "Mips.h" 16249423Sdim#include "MipsInstrInfo.h" 17327952Sdim#include "MipsRegisterInfo.h" 18321369Sdim#include "MipsSubtarget.h" 19249423Sdim#include "llvm/ADT/BitVector.h" 20321369Sdim#include "llvm/ADT/DenseMap.h" 21321369Sdim#include "llvm/ADT/PointerUnion.h" 22249423Sdim#include "llvm/ADT/SmallPtrSet.h" 23321369Sdim#include "llvm/ADT/SmallVector.h" 24249423Sdim#include "llvm/ADT/Statistic.h" 25321369Sdim#include "llvm/ADT/StringRef.h" 26249423Sdim#include "llvm/Analysis/AliasAnalysis.h" 27249423Sdim#include "llvm/Analysis/ValueTracking.h" 28321369Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 29249423Sdim#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 30321369Sdim#include "llvm/CodeGen/MachineFunction.h" 31193323Sed#include "llvm/CodeGen/MachineFunctionPass.h" 32321369Sdim#include "llvm/CodeGen/MachineInstr.h" 33193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 34321369Sdim#include "llvm/CodeGen/MachineOperand.h" 35276479Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 36249423Sdim#include "llvm/CodeGen/PseudoSourceValue.h" 37327952Sdim#include "llvm/CodeGen/TargetRegisterInfo.h" 38327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h" 39321369Sdim#include "llvm/MC/MCInstrDesc.h" 40321369Sdim#include "llvm/MC/MCRegisterInfo.h" 41321369Sdim#include "llvm/Support/Casting.h" 42321369Sdim#include "llvm/Support/CodeGen.h" 43226633Sdim#include "llvm/Support/CommandLine.h" 44321369Sdim#include "llvm/Support/ErrorHandling.h" 45226633Sdim#include "llvm/Target/TargetMachine.h" 46321369Sdim#include <algorithm> 47321369Sdim#include <cassert> 48321369Sdim#include <iterator> 49321369Sdim#include <memory> 50321369Sdim#include <utility> 51193323Sed 52193323Sedusing namespace llvm; 53193323Sed 54276479Sdim#define DEBUG_TYPE "delay-slot-filler" 55276479Sdim 56193323SedSTATISTIC(FilledSlots, "Number of delay slots filled"); 57226633SdimSTATISTIC(UsefulSlots, "Number of delay slots filled with instructions that" 58226633Sdim " are not NOP."); 59193323Sed 60243830Sdimstatic cl::opt<bool> DisableDelaySlotFiller( 61243830Sdim "disable-mips-delay-filler", 62226633Sdim cl::init(false), 63249423Sdim cl::desc("Fill all delay slots with NOPs."), 64226633Sdim cl::Hidden); 65226633Sdim 66249423Sdimstatic cl::opt<bool> DisableForwardSearch( 67249423Sdim "disable-mips-df-forward-search", 68249423Sdim cl::init(true), 69249423Sdim cl::desc("Disallow MIPS delay filler to search forward."), 70249423Sdim cl::Hidden); 71249423Sdim 72249423Sdimstatic cl::opt<bool> DisableSuccBBSearch( 73249423Sdim "disable-mips-df-succbb-search", 74249423Sdim cl::init(true), 75249423Sdim cl::desc("Disallow MIPS delay filler to search successor basic blocks."), 76249423Sdim cl::Hidden); 77249423Sdim 78249423Sdimstatic cl::opt<bool> DisableBackwardSearch( 79249423Sdim "disable-mips-df-backward-search", 80239462Sdim cl::init(false), 81249423Sdim cl::desc("Disallow MIPS delay filler to search backward."), 82239462Sdim cl::Hidden); 83239462Sdim 84309124Sdimenum CompactBranchPolicy { 85309124Sdim CB_Never, ///< The policy 'never' may in some circumstances or for some 86309124Sdim ///< ISAs not be absolutely adhered to. 87309124Sdim CB_Optimal, ///< Optimal is the default and will produce compact branches 88309124Sdim ///< when delay slots cannot be filled. 89309124Sdim CB_Always ///< 'always' may in some circumstances may not be 90309124Sdim ///< absolutely adhered to there may not be a corresponding 91309124Sdim ///< compact form of a branch. 92309124Sdim}; 93309124Sdim 94309124Sdimstatic cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy( 95309124Sdim "mips-compact-branches",cl::Optional, 96309124Sdim cl::init(CB_Optimal), 97309124Sdim cl::desc("MIPS Specific: Compact branch policy."), 98309124Sdim cl::values( 99309124Sdim clEnumValN(CB_Never, "never", "Do not use compact branches if possible."), 100309124Sdim clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropiate (default)."), 101314564Sdim clEnumValN(CB_Always, "always", "Always use compact branches if possible.") 102309124Sdim ) 103309124Sdim); 104309124Sdim 105193323Sednamespace { 106321369Sdim 107327952Sdim using Iter = MachineBasicBlock::iterator; 108327952Sdim using ReverseIter = MachineBasicBlock::reverse_iterator; 109327952Sdim using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>; 110193323Sed 111249423Sdim class RegDefsUses { 112249423Sdim public: 113288943Sdim RegDefsUses(const TargetRegisterInfo &TRI); 114321369Sdim 115249423Sdim void init(const MachineInstr &MI); 116249423Sdim 117249423Sdim /// This function sets all caller-saved registers in Defs. 118249423Sdim void setCallerSaved(const MachineInstr &MI); 119249423Sdim 120249423Sdim /// This function sets all unallocatable registers in Defs. 121249423Sdim void setUnallocatableRegs(const MachineFunction &MF); 122249423Sdim 123249423Sdim /// Set bits in Uses corresponding to MBB's live-out registers except for 124249423Sdim /// the registers that are live-in to SuccBB. 125249423Sdim void addLiveOut(const MachineBasicBlock &MBB, 126249423Sdim const MachineBasicBlock &SuccBB); 127249423Sdim 128249423Sdim bool update(const MachineInstr &MI, unsigned Begin, unsigned End); 129249423Sdim 130249423Sdim private: 131249423Sdim bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses, unsigned Reg, 132249423Sdim bool IsDef) const; 133249423Sdim 134249423Sdim /// Returns true if Reg or its alias is in RegSet. 135249423Sdim bool isRegInSet(const BitVector &RegSet, unsigned Reg) const; 136249423Sdim 137249423Sdim const TargetRegisterInfo &TRI; 138249423Sdim BitVector Defs, Uses; 139249423Sdim }; 140249423Sdim 141249423Sdim /// Base class for inspecting loads and stores. 142249423Sdim class InspectMemInstr { 143249423Sdim public: 144321369Sdim InspectMemInstr(bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {} 145321369Sdim virtual ~InspectMemInstr() = default; 146249423Sdim 147249423Sdim /// Return true if MI cannot be moved to delay slot. 148249423Sdim bool hasHazard(const MachineInstr &MI); 149249423Sdim 150249423Sdim protected: 151249423Sdim /// Flags indicating whether loads or stores have been seen. 152321369Sdim bool OrigSeenLoad = false; 153321369Sdim bool OrigSeenStore = false; 154321369Sdim bool SeenLoad = false; 155321369Sdim bool SeenStore = false; 156249423Sdim 157249423Sdim /// Memory instructions are not allowed to move to delay slot if this flag 158249423Sdim /// is true. 159249423Sdim bool ForbidMemInstr; 160249423Sdim 161249423Sdim private: 162249423Sdim virtual bool hasHazard_(const MachineInstr &MI) = 0; 163249423Sdim }; 164249423Sdim 165249423Sdim /// This subclass rejects any memory instructions. 166249423Sdim class NoMemInstr : public InspectMemInstr { 167249423Sdim public: 168249423Sdim NoMemInstr() : InspectMemInstr(true) {} 169321369Sdim 170249423Sdim private: 171276479Sdim bool hasHazard_(const MachineInstr &MI) override { return true; } 172249423Sdim }; 173249423Sdim 174249423Sdim /// This subclass accepts loads from stacks and constant loads. 175249423Sdim class LoadFromStackOrConst : public InspectMemInstr { 176249423Sdim public: 177249423Sdim LoadFromStackOrConst() : InspectMemInstr(false) {} 178321369Sdim 179249423Sdim private: 180276479Sdim bool hasHazard_(const MachineInstr &MI) override; 181249423Sdim }; 182249423Sdim 183249423Sdim /// This subclass uses memory dependence information to determine whether a 184249423Sdim /// memory instruction can be moved to a delay slot. 185249423Sdim class MemDefsUses : public InspectMemInstr { 186249423Sdim public: 187288943Sdim MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI); 188249423Sdim 189249423Sdim private: 190327952Sdim using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>; 191249423Sdim 192276479Sdim bool hasHazard_(const MachineInstr &MI) override; 193276479Sdim 194249423Sdim /// Update Defs and Uses. Return true if there exist dependences that 195249423Sdim /// disqualify the delay slot candidate between V and values in Uses and 196249423Sdim /// Defs. 197276479Sdim bool updateDefsUses(ValueType V, bool MayStore); 198249423Sdim 199249423Sdim /// Get the list of underlying objects of MI's memory operand. 200249423Sdim bool getUnderlyingObjects(const MachineInstr &MI, 201276479Sdim SmallVectorImpl<ValueType> &Objects) const; 202249423Sdim 203249423Sdim const MachineFrameInfo *MFI; 204276479Sdim SmallPtrSet<ValueType, 4> Uses, Defs; 205288943Sdim const DataLayout &DL; 206249423Sdim 207249423Sdim /// Flags indicating whether loads or stores with no underlying objects have 208249423Sdim /// been seen. 209321369Sdim bool SeenNoObjLoad = false; 210321369Sdim bool SeenNoObjStore = false; 211249423Sdim }; 212249423Sdim 213249423Sdim class Filler : public MachineFunctionPass { 214249423Sdim public: 215327952Sdim Filler() : MachineFunctionPass(ID) {} 216193323Sed 217314564Sdim StringRef getPassName() const override { return "Mips Delay Slot Filler"; } 218193323Sed 219276479Sdim bool runOnMachineFunction(MachineFunction &F) override { 220321369Sdim TM = &F.getTarget(); 221193323Sed bool Changed = false; 222193323Sed for (MachineFunction::iterator FI = F.begin(), FE = F.end(); 223193323Sed FI != FE; ++FI) 224193323Sed Changed |= runOnMachineBasicBlock(*FI); 225276479Sdim 226276479Sdim // This pass invalidates liveness information when it reorders 227276479Sdim // instructions to fill delay slot. Without this, -verify-machineinstrs 228276479Sdim // will fail. 229276479Sdim if (Changed) 230276479Sdim F.getRegInfo().invalidateLiveness(); 231276479Sdim 232193323Sed return Changed; 233193323Sed } 234193323Sed 235309124Sdim MachineFunctionProperties getRequiredProperties() const override { 236309124Sdim return MachineFunctionProperties().set( 237314564Sdim MachineFunctionProperties::Property::NoVRegs); 238309124Sdim } 239309124Sdim 240276479Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 241249423Sdim AU.addRequired<MachineBranchProbabilityInfo>(); 242249423Sdim MachineFunctionPass::getAnalysisUsage(AU); 243249423Sdim } 244226633Sdim 245249423Sdim private: 246249423Sdim bool runOnMachineBasicBlock(MachineBasicBlock &MBB); 247226633Sdim 248309124Sdim Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, 249309124Sdim const DebugLoc &DL); 250280031Sdim 251249423Sdim /// This function checks if it is valid to move Candidate to the delay slot 252249423Sdim /// and returns true if it isn't. It also updates memory and register 253249423Sdim /// dependence information. 254249423Sdim bool delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU, 255249423Sdim InspectMemInstr &IM) const; 256226633Sdim 257249423Sdim /// This function searches range [Begin, End) for an instruction that can be 258249423Sdim /// moved to the delay slot. Returns true on success. 259249423Sdim template<typename IterTy> 260249423Sdim bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, 261288943Sdim RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot, 262288943Sdim IterTy &Filler) const; 263226633Sdim 264249423Sdim /// This function searches in the backward direction for an instruction that 265249423Sdim /// can be moved to the delay slot. Returns true on success. 266314564Sdim bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const; 267226633Sdim 268249423Sdim /// This function searches MBB in the forward direction for an instruction 269249423Sdim /// that can be moved to the delay slot. Returns true on success. 270249423Sdim bool searchForward(MachineBasicBlock &MBB, Iter Slot) const; 271226633Sdim 272249423Sdim /// This function searches one of MBB's successor blocks for an instruction 273249423Sdim /// that can be moved to the delay slot and inserts clones of the 274249423Sdim /// instruction into the successor's predecessor blocks. 275249423Sdim bool searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const; 276226633Sdim 277249423Sdim /// Pick a successor block of MBB. Return NULL if MBB doesn't have a 278249423Sdim /// successor block that is not a landing pad. 279249423Sdim MachineBasicBlock *selectSuccBB(MachineBasicBlock &B) const; 280249423Sdim 281249423Sdim /// This function analyzes MBB and returns an instruction with an unoccupied 282249423Sdim /// slot that branches to Dst. 283249423Sdim std::pair<MipsInstrInfo::BranchType, MachineInstr *> 284249423Sdim getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const; 285249423Sdim 286249423Sdim /// Examine Pred and see if it is possible to insert an instruction into 287249423Sdim /// one of its branches delay slot or its end. 288249423Sdim bool examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ, 289249423Sdim RegDefsUses &RegDU, bool &HasMultipleSuccs, 290249423Sdim BB2BrMap &BrMap) const; 291249423Sdim 292249423Sdim bool terminateSearch(const MachineInstr &Candidate) const; 293249423Sdim 294327952Sdim const TargetMachine *TM = nullptr; 295249423Sdim 296249423Sdim static char ID; 297193323Sed }; 298321369Sdim 299321369Sdim} // end anonymous namespace 300321369Sdim 301327952Sdimchar Filler::ID = 0; 302327952Sdim 303249423Sdimstatic bool hasUnoccupiedSlot(const MachineInstr *MI) { 304249423Sdim return MI->hasDelaySlot() && !MI->isBundledWithSucc(); 305249423Sdim} 306249423Sdim 307249423Sdim/// This function inserts clones of Filler into predecessor blocks. 308249423Sdimstatic void insertDelayFiller(Iter Filler, const BB2BrMap &BrMap) { 309249423Sdim MachineFunction *MF = Filler->getParent()->getParent(); 310249423Sdim 311249423Sdim for (BB2BrMap::const_iterator I = BrMap.begin(); I != BrMap.end(); ++I) { 312249423Sdim if (I->second) { 313249423Sdim MIBundleBuilder(I->second).append(MF->CloneMachineInstr(&*Filler)); 314249423Sdim ++UsefulSlots; 315249423Sdim } else { 316249423Sdim I->first->insert(I->first->end(), MF->CloneMachineInstr(&*Filler)); 317249423Sdim } 318249423Sdim } 319249423Sdim} 320249423Sdim 321249423Sdim/// This function adds registers Filler defines to MBB's live-in register list. 322249423Sdimstatic void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB) { 323249423Sdim for (unsigned I = 0, E = Filler->getNumOperands(); I != E; ++I) { 324249423Sdim const MachineOperand &MO = Filler->getOperand(I); 325249423Sdim unsigned R; 326249423Sdim 327249423Sdim if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg())) 328249423Sdim continue; 329249423Sdim 330249423Sdim#ifndef NDEBUG 331249423Sdim const MachineFunction &MF = *MBB.getParent(); 332288943Sdim assert(MF.getSubtarget().getRegisterInfo()->getAllocatableSet(MF).test(R) && 333249423Sdim "Shouldn't move an instruction with unallocatable registers across " 334249423Sdim "basic block boundaries."); 335249423Sdim#endif 336249423Sdim 337249423Sdim if (!MBB.isLiveIn(R)) 338249423Sdim MBB.addLiveIn(R); 339249423Sdim } 340249423Sdim} 341249423Sdim 342288943SdimRegDefsUses::RegDefsUses(const TargetRegisterInfo &TRI) 343288943Sdim : TRI(TRI), Defs(TRI.getNumRegs(), false), Uses(TRI.getNumRegs(), false) {} 344249423Sdim 345249423Sdimvoid RegDefsUses::init(const MachineInstr &MI) { 346249423Sdim // Add all register operands which are explicit and non-variadic. 347249423Sdim update(MI, 0, MI.getDesc().getNumOperands()); 348249423Sdim 349249423Sdim // If MI is a call, add RA to Defs to prevent users of RA from going into 350249423Sdim // delay slot. 351249423Sdim if (MI.isCall()) 352249423Sdim Defs.set(Mips::RA); 353249423Sdim 354249423Sdim // Add all implicit register operands of branch instructions except 355249423Sdim // register AT. 356249423Sdim if (MI.isBranch()) { 357249423Sdim update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands()); 358249423Sdim Defs.reset(Mips::AT); 359249423Sdim } 360249423Sdim} 361249423Sdim 362249423Sdimvoid RegDefsUses::setCallerSaved(const MachineInstr &MI) { 363249423Sdim assert(MI.isCall()); 364249423Sdim 365288943Sdim // Add RA/RA_64 to Defs to prevent users of RA/RA_64 from going into 366288943Sdim // the delay slot. The reason is that RA/RA_64 must not be changed 367288943Sdim // in the delay slot so that the callee can return to the caller. 368288943Sdim if (MI.definesRegister(Mips::RA) || MI.definesRegister(Mips::RA_64)) { 369288943Sdim Defs.set(Mips::RA); 370288943Sdim Defs.set(Mips::RA_64); 371288943Sdim } 372288943Sdim 373249423Sdim // If MI is a call, add all caller-saved registers to Defs. 374249423Sdim BitVector CallerSavedRegs(TRI.getNumRegs(), true); 375249423Sdim 376249423Sdim CallerSavedRegs.reset(Mips::ZERO); 377249423Sdim CallerSavedRegs.reset(Mips::ZERO_64); 378249423Sdim 379288943Sdim for (const MCPhysReg *R = TRI.getCalleeSavedRegs(MI.getParent()->getParent()); 380288943Sdim *R; ++R) 381249423Sdim for (MCRegAliasIterator AI(*R, &TRI, true); AI.isValid(); ++AI) 382249423Sdim CallerSavedRegs.reset(*AI); 383249423Sdim 384249423Sdim Defs |= CallerSavedRegs; 385249423Sdim} 386249423Sdim 387249423Sdimvoid RegDefsUses::setUnallocatableRegs(const MachineFunction &MF) { 388249423Sdim BitVector AllocSet = TRI.getAllocatableSet(MF); 389249423Sdim 390321369Sdim for (unsigned R : AllocSet.set_bits()) 391249423Sdim for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI) 392249423Sdim AllocSet.set(*AI); 393249423Sdim 394249423Sdim AllocSet.set(Mips::ZERO); 395249423Sdim AllocSet.set(Mips::ZERO_64); 396249423Sdim 397249423Sdim Defs |= AllocSet.flip(); 398249423Sdim} 399249423Sdim 400249423Sdimvoid RegDefsUses::addLiveOut(const MachineBasicBlock &MBB, 401249423Sdim const MachineBasicBlock &SuccBB) { 402249423Sdim for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), 403249423Sdim SE = MBB.succ_end(); SI != SE; ++SI) 404249423Sdim if (*SI != &SuccBB) 405296417Sdim for (const auto &LI : (*SI)->liveins()) 406296417Sdim Uses.set(LI.PhysReg); 407249423Sdim} 408249423Sdim 409249423Sdimbool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) { 410249423Sdim BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs()); 411249423Sdim bool HasHazard = false; 412249423Sdim 413249423Sdim for (unsigned I = Begin; I != End; ++I) { 414249423Sdim const MachineOperand &MO = MI.getOperand(I); 415249423Sdim 416249423Sdim if (MO.isReg() && MO.getReg()) 417249423Sdim HasHazard |= checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef()); 418249423Sdim } 419249423Sdim 420249423Sdim Defs |= NewDefs; 421249423Sdim Uses |= NewUses; 422249423Sdim 423249423Sdim return HasHazard; 424249423Sdim} 425249423Sdim 426249423Sdimbool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses, 427249423Sdim unsigned Reg, bool IsDef) const { 428249423Sdim if (IsDef) { 429249423Sdim NewDefs.set(Reg); 430249423Sdim // check whether Reg has already been defined or used. 431249423Sdim return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg)); 432249423Sdim } 433249423Sdim 434249423Sdim NewUses.set(Reg); 435249423Sdim // check whether Reg has already been defined. 436249423Sdim return isRegInSet(Defs, Reg); 437249423Sdim} 438249423Sdim 439249423Sdimbool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const { 440249423Sdim // Check Reg and all aliased Registers. 441249423Sdim for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) 442249423Sdim if (RegSet.test(*AI)) 443249423Sdim return true; 444249423Sdim return false; 445249423Sdim} 446249423Sdim 447249423Sdimbool InspectMemInstr::hasHazard(const MachineInstr &MI) { 448249423Sdim if (!MI.mayStore() && !MI.mayLoad()) 449249423Sdim return false; 450249423Sdim 451249423Sdim if (ForbidMemInstr) 452249423Sdim return true; 453249423Sdim 454249423Sdim OrigSeenLoad = SeenLoad; 455249423Sdim OrigSeenStore = SeenStore; 456249423Sdim SeenLoad |= MI.mayLoad(); 457249423Sdim SeenStore |= MI.mayStore(); 458249423Sdim 459249423Sdim // If MI is an ordered or volatile memory reference, disallow moving 460249423Sdim // subsequent loads and stores to delay slot. 461249423Sdim if (MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) { 462249423Sdim ForbidMemInstr = true; 463249423Sdim return true; 464249423Sdim } 465249423Sdim 466249423Sdim return hasHazard_(MI); 467249423Sdim} 468249423Sdim 469249423Sdimbool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) { 470249423Sdim if (MI.mayStore()) 471249423Sdim return true; 472249423Sdim 473276479Sdim if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getPseudoValue()) 474249423Sdim return true; 475249423Sdim 476276479Sdim if (const PseudoSourceValue *PSV = 477276479Sdim (*MI.memoperands_begin())->getPseudoValue()) { 478276479Sdim if (isa<FixedStackPseudoSourceValue>(PSV)) 479276479Sdim return false; 480296417Sdim return !PSV->isConstant(nullptr) && !PSV->isStack(); 481276479Sdim } 482249423Sdim 483249423Sdim return true; 484249423Sdim} 485249423Sdim 486288943SdimMemDefsUses::MemDefsUses(const DataLayout &DL, const MachineFrameInfo *MFI_) 487321369Sdim : InspectMemInstr(false), MFI(MFI_), DL(DL) {} 488249423Sdim 489249423Sdimbool MemDefsUses::hasHazard_(const MachineInstr &MI) { 490249423Sdim bool HasHazard = false; 491276479Sdim SmallVector<ValueType, 4> Objs; 492249423Sdim 493249423Sdim // Check underlying object list. 494249423Sdim if (getUnderlyingObjects(MI, Objs)) { 495276479Sdim for (SmallVectorImpl<ValueType>::const_iterator I = Objs.begin(); 496249423Sdim I != Objs.end(); ++I) 497249423Sdim HasHazard |= updateDefsUses(*I, MI.mayStore()); 498249423Sdim 499249423Sdim return HasHazard; 500249423Sdim } 501249423Sdim 502249423Sdim // No underlying objects found. 503249423Sdim HasHazard = MI.mayStore() && (OrigSeenLoad || OrigSeenStore); 504249423Sdim HasHazard |= MI.mayLoad() || OrigSeenStore; 505249423Sdim 506249423Sdim SeenNoObjLoad |= MI.mayLoad(); 507249423Sdim SeenNoObjStore |= MI.mayStore(); 508249423Sdim 509249423Sdim return HasHazard; 510249423Sdim} 511249423Sdim 512276479Sdimbool MemDefsUses::updateDefsUses(ValueType V, bool MayStore) { 513249423Sdim if (MayStore) 514280031Sdim return !Defs.insert(V).second || Uses.count(V) || SeenNoObjStore || 515280031Sdim SeenNoObjLoad; 516249423Sdim 517249423Sdim Uses.insert(V); 518249423Sdim return Defs.count(V) || SeenNoObjStore; 519249423Sdim} 520249423Sdim 521249423Sdimbool MemDefsUses:: 522249423SdimgetUnderlyingObjects(const MachineInstr &MI, 523276479Sdim SmallVectorImpl<ValueType> &Objects) const { 524276479Sdim if (!MI.hasOneMemOperand() || 525276479Sdim (!(*MI.memoperands_begin())->getValue() && 526276479Sdim !(*MI.memoperands_begin())->getPseudoValue())) 527249423Sdim return false; 528249423Sdim 529276479Sdim if (const PseudoSourceValue *PSV = 530276479Sdim (*MI.memoperands_begin())->getPseudoValue()) { 531276479Sdim if (!PSV->isAliased(MFI)) 532276479Sdim return false; 533276479Sdim Objects.push_back(PSV); 534276479Sdim return true; 535276479Sdim } 536276479Sdim 537249423Sdim const Value *V = (*MI.memoperands_begin())->getValue(); 538249423Sdim 539249423Sdim SmallVector<Value *, 4> Objs; 540288943Sdim GetUnderlyingObjects(const_cast<Value *>(V), Objs, DL); 541249423Sdim 542261991Sdim for (SmallVectorImpl<Value *>::iterator I = Objs.begin(), E = Objs.end(); 543249423Sdim I != E; ++I) { 544276479Sdim if (!isIdentifiedObject(V)) 545249423Sdim return false; 546249423Sdim 547249423Sdim Objects.push_back(*I); 548249423Sdim } 549249423Sdim 550249423Sdim return true; 551249423Sdim} 552249423Sdim 553280031Sdim// Replace Branch with the compact branch instruction. 554309124SdimIter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, 555309124Sdim const DebugLoc &DL) { 556309124Sdim const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); 557309124Sdim const MipsInstrInfo *TII = STI.getInstrInfo(); 558280031Sdim 559309124Sdim unsigned NewOpcode = TII->getEquivalentCompactForm(Branch); 560309124Sdim Branch = TII->genInstrWithNewOpc(NewOpcode, Branch); 561280031Sdim 562309124Sdim std::next(Branch)->eraseFromParent(); 563280031Sdim return Branch; 564280031Sdim} 565280031Sdim 566280031Sdim// For given opcode returns opcode of corresponding instruction with short 567280031Sdim// delay slot. 568321369Sdim// For the pseudo TAILCALL*_MM instructions return the short delay slot 569314564Sdim// form. Unfortunately, TAILCALL<->b16 is denied as b16 has a limited range 570314564Sdim// that is too short to make use of for tail calls. 571280031Sdimstatic int getEquivalentCallShort(int Opcode) { 572280031Sdim switch (Opcode) { 573280031Sdim case Mips::BGEZAL: 574280031Sdim return Mips::BGEZALS_MM; 575280031Sdim case Mips::BLTZAL: 576280031Sdim return Mips::BLTZALS_MM; 577280031Sdim case Mips::JAL: 578280031Sdim return Mips::JALS_MM; 579280031Sdim case Mips::JALR: 580280031Sdim return Mips::JALRS_MM; 581280031Sdim case Mips::JALR16_MM: 582280031Sdim return Mips::JALRS16_MM; 583314564Sdim case Mips::TAILCALL_MM: 584314564Sdim llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!"); 585314564Sdim case Mips::TAILCALLREG: 586314564Sdim return Mips::JR16_MM; 587280031Sdim default: 588280031Sdim llvm_unreachable("Unexpected call instruction for microMIPS."); 589280031Sdim } 590280031Sdim} 591280031Sdim 592193323Sed/// runOnMachineBasicBlock - Fill in delay slots for the given basic block. 593226633Sdim/// We assume there is only one delay slot per delayed instruction. 594249423Sdimbool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { 595193323Sed bool Changed = false; 596288943Sdim const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); 597288943Sdim bool InMicroMipsMode = STI.inMicroMipsMode(); 598288943Sdim const MipsInstrInfo *TII = STI.getInstrInfo(); 599226633Sdim 600249423Sdim for (Iter I = MBB.begin(); I != MBB.end(); ++I) { 601249423Sdim if (!hasUnoccupiedSlot(&*I)) 602249423Sdim continue; 603218893Sdim 604327952Sdim // Delay slot filling is disabled at -O0, or in microMIPS32R6. 605327952Sdim if (!DisableDelaySlotFiller && (TM->getOptLevel() != CodeGenOpt::None) && 606327952Sdim !(InMicroMipsMode && STI.hasMips32r6())) { 607226633Sdim 608280031Sdim bool Filled = false; 609226633Sdim 610309124Sdim if (MipsCompactBranchPolicy.getValue() != CB_Always || 611309124Sdim !TII->getEquivalentCompactForm(I)) { 612314564Sdim if (searchBackward(MBB, *I)) { 613280031Sdim Filled = true; 614309124Sdim } else if (I->isTerminator()) { 615309124Sdim if (searchSuccBBs(MBB, I)) { 616309124Sdim Filled = true; 617309124Sdim } 618309124Sdim } else if (searchForward(MBB, I)) { 619309124Sdim Filled = true; 620280031Sdim } 621280031Sdim } 622280031Sdim 623280031Sdim if (Filled) { 624280031Sdim // Get instruction with delay slot. 625309124Sdim MachineBasicBlock::instr_iterator DSI = I.getInstrIterator(); 626280031Sdim 627314564Sdim if (InMicroMipsMode && TII->getInstSizeInBytes(*std::next(DSI)) == 2 && 628280031Sdim DSI->isCall()) { 629280031Sdim // If instruction in delay slot is 16b change opcode to 630280031Sdim // corresponding instruction with short delay slot. 631314564Sdim 632314564Sdim // TODO: Implement an instruction mapping table of 16bit opcodes to 633314564Sdim // 32bit opcodes so that an instruction can be expanded. This would 634314564Sdim // save 16 bits as a TAILCALL_MM pseudo requires a fullsized nop. 635314564Sdim // TODO: Permit b16 when branching backwards to the the same function 636314564Sdim // if it is in range. 637280031Sdim DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode()))); 638280031Sdim } 639327952Sdim ++FilledSlots; 640327952Sdim Changed = true; 641249423Sdim continue; 642249423Sdim } 643249423Sdim } 644239462Sdim 645309124Sdim // For microMIPS if instruction is BEQ or BNE with one ZERO register, then 646309124Sdim // instead of adding NOP replace this instruction with the corresponding 647309124Sdim // compact branch instruction, i.e. BEQZC or BNEZC. Additionally 648309124Sdim // PseudoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can 649309124Sdim // be replaced with JRC16_MM. 650309124Sdim 651309124Sdim // For MIPSR6 attempt to produce the corresponding compact (no delay slot) 652309124Sdim // form of the CTI. For indirect jumps this will not require inserting a 653309124Sdim // NOP and for branches will hopefully avoid requiring a NOP. 654309124Sdim if ((InMicroMipsMode || 655309124Sdim (STI.hasMips32r6() && MipsCompactBranchPolicy != CB_Never)) && 656309124Sdim TII->getEquivalentCompactForm(I)) { 657309124Sdim I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); 658327952Sdim Changed = true; 659309124Sdim continue; 660280031Sdim } 661309124Sdim 662288943Sdim // Bundle the NOP to the instruction with the delay slot. 663288943Sdim BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); 664288943Sdim MIBundleBuilder(MBB, I, std::next(I, 2)); 665327952Sdim ++FilledSlots; 666327952Sdim Changed = true; 667249423Sdim } 668249423Sdim 669193323Sed return Changed; 670193323Sed} 671193323Sed 672249423Sdimtemplate<typename IterTy> 673249423Sdimbool Filler::searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End, 674288943Sdim RegDefsUses &RegDU, InspectMemInstr& IM, Iter Slot, 675288943Sdim IterTy &Filler) const { 676288943Sdim for (IterTy I = Begin; I != End;) { 677288943Sdim IterTy CurrI = I; 678288943Sdim ++I; 679288943Sdim 680226633Sdim // skip debug value 681288943Sdim if (CurrI->isDebugValue()) 682226633Sdim continue; 683226633Sdim 684288943Sdim if (terminateSearch(*CurrI)) 685226633Sdim break; 686226633Sdim 687288943Sdim assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) && 688249423Sdim "Cannot put calls, returns or branches in delay slot."); 689249423Sdim 690288943Sdim if (CurrI->isKill()) { 691288943Sdim CurrI->eraseFromParent(); 692226633Sdim continue; 693288943Sdim } 694226633Sdim 695288943Sdim if (delayHasHazard(*CurrI, RegDU, IM)) 696288943Sdim continue; 697288943Sdim 698288943Sdim const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); 699288943Sdim if (STI.isTargetNaCl()) { 700276479Sdim // In NaCl, instructions that must be masked are forbidden in delay slots. 701276479Sdim // We only check for loads, stores and SP changes. Calls, returns and 702276479Sdim // branches are not checked because non-NaCl targets never put them in 703276479Sdim // delay slots. 704276479Sdim unsigned AddrIdx; 705288943Sdim if ((isBasePlusOffsetMemoryAccess(CurrI->getOpcode(), &AddrIdx) && 706288943Sdim baseRegNeedsLoadStoreMask(CurrI->getOperand(AddrIdx).getReg())) || 707288943Sdim CurrI->modifiesRegister(Mips::SP, STI.getRegisterInfo())) 708276479Sdim continue; 709276479Sdim } 710276479Sdim 711288943Sdim bool InMicroMipsMode = STI.inMicroMipsMode(); 712288943Sdim const MipsInstrInfo *TII = STI.getInstrInfo(); 713280031Sdim unsigned Opcode = (*Slot).getOpcode(); 714314564Sdim // This is complicated by the tail call optimization. For non-PIC code 715314564Sdim // there is only a 32bit sized unconditional branch which can be assumed 716314564Sdim // to be able to reach the target. b16 only has a range of +/- 1 KB. 717314564Sdim // It's entirely possible that the target function is reachable with b16 718314564Sdim // but we don't have enough information to make that decision. 719314564Sdim if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 && 720280031Sdim (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch || 721314564Sdim Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL)) 722280031Sdim continue; 723280031Sdim 724288943Sdim Filler = CurrI; 725226633Sdim return true; 726226633Sdim } 727226633Sdim 728226633Sdim return false; 729226633Sdim} 730226633Sdim 731314564Sdimbool Filler::searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const { 732249423Sdim if (DisableBackwardSearch) 733249423Sdim return false; 734226633Sdim 735296417Sdim auto *Fn = MBB.getParent(); 736296417Sdim RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo()); 737314564Sdim MemDefsUses MemDU(Fn->getDataLayout(), &Fn->getFrameInfo()); 738249423Sdim ReverseIter Filler; 739226633Sdim 740314564Sdim RegDU.init(Slot); 741249423Sdim 742314564Sdim MachineBasicBlock::iterator SlotI = Slot; 743314564Sdim if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot, 744288943Sdim Filler)) 745261991Sdim return false; 746226633Sdim 747314564Sdim MBB.splice(std::next(SlotI), &MBB, Filler.getReverse()); 748314564Sdim MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2)); 749261991Sdim ++UsefulSlots; 750261991Sdim return true; 751249423Sdim} 752226633Sdim 753249423Sdimbool Filler::searchForward(MachineBasicBlock &MBB, Iter Slot) const { 754249423Sdim // Can handle only calls. 755249423Sdim if (DisableForwardSearch || !Slot->isCall()) 756249423Sdim return false; 757226633Sdim 758288943Sdim RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo()); 759249423Sdim NoMemInstr NM; 760249423Sdim Iter Filler; 761226633Sdim 762249423Sdim RegDU.setCallerSaved(*Slot); 763249423Sdim 764288943Sdim if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) 765261991Sdim return false; 766249423Sdim 767276479Sdim MBB.splice(std::next(Slot), &MBB, Filler); 768276479Sdim MIBundleBuilder(MBB, Slot, std::next(Slot, 2)); 769261991Sdim ++UsefulSlots; 770261991Sdim return true; 771226633Sdim} 772226633Sdim 773249423Sdimbool Filler::searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const { 774249423Sdim if (DisableSuccBBSearch) 775249423Sdim return false; 776234353Sdim 777249423Sdim MachineBasicBlock *SuccBB = selectSuccBB(MBB); 778226633Sdim 779249423Sdim if (!SuccBB) 780249423Sdim return false; 781226633Sdim 782288943Sdim RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo()); 783249423Sdim bool HasMultipleSuccs = false; 784249423Sdim BB2BrMap BrMap; 785276479Sdim std::unique_ptr<InspectMemInstr> IM; 786249423Sdim Iter Filler; 787296417Sdim auto *Fn = MBB.getParent(); 788226633Sdim 789249423Sdim // Iterate over SuccBB's predecessor list. 790249423Sdim for (MachineBasicBlock::pred_iterator PI = SuccBB->pred_begin(), 791249423Sdim PE = SuccBB->pred_end(); PI != PE; ++PI) 792249423Sdim if (!examinePred(**PI, *SuccBB, RegDU, HasMultipleSuccs, BrMap)) 793249423Sdim return false; 794249423Sdim 795249423Sdim // Do not allow moving instructions which have unallocatable register operands 796249423Sdim // across basic block boundaries. 797296417Sdim RegDU.setUnallocatableRegs(*Fn); 798249423Sdim 799249423Sdim // Only allow moving loads from stack or constants if any of the SuccBB's 800249423Sdim // predecessors have multiple successors. 801249423Sdim if (HasMultipleSuccs) { 802249423Sdim IM.reset(new LoadFromStackOrConst()); 803249423Sdim } else { 804314564Sdim const MachineFrameInfo &MFI = Fn->getFrameInfo(); 805314564Sdim IM.reset(new MemDefsUses(Fn->getDataLayout(), &MFI)); 806226633Sdim } 807249423Sdim 808288943Sdim if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot, 809288943Sdim Filler)) 810249423Sdim return false; 811249423Sdim 812249423Sdim insertDelayFiller(Filler, BrMap); 813249423Sdim addLiveInRegs(Filler, *SuccBB); 814249423Sdim Filler->eraseFromParent(); 815249423Sdim 816249423Sdim return true; 817226633Sdim} 818226633Sdim 819249423SdimMachineBasicBlock *Filler::selectSuccBB(MachineBasicBlock &B) const { 820249423Sdim if (B.succ_empty()) 821276479Sdim return nullptr; 822249423Sdim 823249423Sdim // Select the successor with the larget edge weight. 824276479Sdim auto &Prob = getAnalysis<MachineBranchProbabilityInfo>(); 825296417Sdim MachineBasicBlock *S = *std::max_element( 826296417Sdim B.succ_begin(), B.succ_end(), 827296417Sdim [&](const MachineBasicBlock *Dst0, const MachineBasicBlock *Dst1) { 828296417Sdim return Prob.getEdgeProbability(&B, Dst0) < 829296417Sdim Prob.getEdgeProbability(&B, Dst1); 830296417Sdim }); 831296417Sdim return S->isEHPad() ? nullptr : S; 832226633Sdim} 833249423Sdim 834249423Sdimstd::pair<MipsInstrInfo::BranchType, MachineInstr *> 835249423SdimFiller::getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const { 836249423Sdim const MipsInstrInfo *TII = 837288943Sdim MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo(); 838276479Sdim MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr; 839249423Sdim SmallVector<MachineInstr*, 2> BranchInstrs; 840249423Sdim SmallVector<MachineOperand, 2> Cond; 841249423Sdim 842249423Sdim MipsInstrInfo::BranchType R = 843309124Sdim TII->analyzeBranch(MBB, TrueBB, FalseBB, Cond, false, BranchInstrs); 844249423Sdim 845249423Sdim if ((R == MipsInstrInfo::BT_None) || (R == MipsInstrInfo::BT_NoBranch)) 846276479Sdim return std::make_pair(R, nullptr); 847249423Sdim 848249423Sdim if (R != MipsInstrInfo::BT_CondUncond) { 849249423Sdim if (!hasUnoccupiedSlot(BranchInstrs[0])) 850276479Sdim return std::make_pair(MipsInstrInfo::BT_None, nullptr); 851249423Sdim 852249423Sdim assert(((R != MipsInstrInfo::BT_Uncond) || (TrueBB == &Dst))); 853249423Sdim 854249423Sdim return std::make_pair(R, BranchInstrs[0]); 855249423Sdim } 856249423Sdim 857249423Sdim assert((TrueBB == &Dst) || (FalseBB == &Dst)); 858249423Sdim 859249423Sdim // Examine the conditional branch. See if its slot is occupied. 860249423Sdim if (hasUnoccupiedSlot(BranchInstrs[0])) 861249423Sdim return std::make_pair(MipsInstrInfo::BT_Cond, BranchInstrs[0]); 862249423Sdim 863249423Sdim // If that fails, try the unconditional branch. 864249423Sdim if (hasUnoccupiedSlot(BranchInstrs[1]) && (FalseBB == &Dst)) 865249423Sdim return std::make_pair(MipsInstrInfo::BT_Uncond, BranchInstrs[1]); 866249423Sdim 867276479Sdim return std::make_pair(MipsInstrInfo::BT_None, nullptr); 868249423Sdim} 869249423Sdim 870249423Sdimbool Filler::examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ, 871249423Sdim RegDefsUses &RegDU, bool &HasMultipleSuccs, 872249423Sdim BB2BrMap &BrMap) const { 873249423Sdim std::pair<MipsInstrInfo::BranchType, MachineInstr *> P = 874249423Sdim getBranch(Pred, Succ); 875249423Sdim 876249423Sdim // Return if either getBranch wasn't able to analyze the branches or there 877249423Sdim // were no branches with unoccupied slots. 878249423Sdim if (P.first == MipsInstrInfo::BT_None) 879249423Sdim return false; 880249423Sdim 881249423Sdim if ((P.first != MipsInstrInfo::BT_Uncond) && 882249423Sdim (P.first != MipsInstrInfo::BT_NoBranch)) { 883249423Sdim HasMultipleSuccs = true; 884249423Sdim RegDU.addLiveOut(Pred, Succ); 885249423Sdim } 886249423Sdim 887249423Sdim BrMap[&Pred] = P.second; 888249423Sdim return true; 889249423Sdim} 890249423Sdim 891249423Sdimbool Filler::delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU, 892249423Sdim InspectMemInstr &IM) const { 893288943Sdim assert(!Candidate.isKill() && 894288943Sdim "KILL instructions should have been eliminated at this point."); 895249423Sdim 896288943Sdim bool HasHazard = Candidate.isImplicitDef(); 897288943Sdim 898249423Sdim HasHazard |= IM.hasHazard(Candidate); 899249423Sdim HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands()); 900249423Sdim 901249423Sdim return HasHazard; 902249423Sdim} 903249423Sdim 904249423Sdimbool Filler::terminateSearch(const MachineInstr &Candidate) const { 905249423Sdim return (Candidate.isTerminator() || Candidate.isCall() || 906276479Sdim Candidate.isPosition() || Candidate.isInlineAsm() || 907249423Sdim Candidate.hasUnmodeledSideEffects()); 908249423Sdim} 909321369Sdim 910321369Sdim/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay 911321369Sdim/// slots in Mips MachineFunctions 912321369SdimFunctionPass *llvm::createMipsDelaySlotFillerPass() { return new Filler(); } 913