Path: blob/main/contrib/llvm-project/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
35266 views
//===- MipsDelaySlotFiller.cpp - Mips Delay Slot Filler -------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Simple pass to fill delay slots with useful instructions.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/MipsMCNaCl.h"13#include "Mips.h"14#include "MipsInstrInfo.h"15#include "MipsRegisterInfo.h"16#include "MipsSubtarget.h"17#include "llvm/ADT/BitVector.h"18#include "llvm/ADT/DenseMap.h"19#include "llvm/ADT/PointerUnion.h"20#include "llvm/ADT/SmallPtrSet.h"21#include "llvm/ADT/SmallVector.h"22#include "llvm/ADT/Statistic.h"23#include "llvm/ADT/StringRef.h"24#include "llvm/Analysis/AliasAnalysis.h"25#include "llvm/Analysis/ValueTracking.h"26#include "llvm/CodeGen/MachineBasicBlock.h"27#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"28#include "llvm/CodeGen/MachineFunction.h"29#include "llvm/CodeGen/MachineFunctionPass.h"30#include "llvm/CodeGen/MachineInstr.h"31#include "llvm/CodeGen/MachineInstrBuilder.h"32#include "llvm/CodeGen/MachineOperand.h"33#include "llvm/CodeGen/MachineRegisterInfo.h"34#include "llvm/CodeGen/PseudoSourceValue.h"35#include "llvm/CodeGen/TargetRegisterInfo.h"36#include "llvm/CodeGen/TargetSubtargetInfo.h"37#include "llvm/MC/MCInstrDesc.h"38#include "llvm/MC/MCRegisterInfo.h"39#include "llvm/Support/Casting.h"40#include "llvm/Support/CodeGen.h"41#include "llvm/Support/CommandLine.h"42#include "llvm/Support/ErrorHandling.h"43#include "llvm/Target/TargetMachine.h"44#include <algorithm>45#include <cassert>46#include <iterator>47#include <memory>48#include <utility>4950using namespace llvm;5152#define DEBUG_TYPE "mips-delay-slot-filler"5354STATISTIC(FilledSlots, "Number of delay slots filled");55STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"56" are not NOP.");5758static cl::opt<bool> DisableDelaySlotFiller(59"disable-mips-delay-filler",60cl::init(false),61cl::desc("Fill all delay slots with NOPs."),62cl::Hidden);6364static cl::opt<bool> DisableForwardSearch(65"disable-mips-df-forward-search",66cl::init(true),67cl::desc("Disallow MIPS delay filler to search forward."),68cl::Hidden);6970static cl::opt<bool> DisableSuccBBSearch(71"disable-mips-df-succbb-search",72cl::init(true),73cl::desc("Disallow MIPS delay filler to search successor basic blocks."),74cl::Hidden);7576static cl::opt<bool> DisableBackwardSearch(77"disable-mips-df-backward-search",78cl::init(false),79cl::desc("Disallow MIPS delay filler to search backward."),80cl::Hidden);8182enum CompactBranchPolicy {83CB_Never, ///< The policy 'never' may in some circumstances or for some84///< ISAs not be absolutely adhered to.85CB_Optimal, ///< Optimal is the default and will produce compact branches86///< when delay slots cannot be filled.87CB_Always ///< 'always' may in some circumstances may not be88///< absolutely adhered to there may not be a corresponding89///< compact form of a branch.90};9192static cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy(93"mips-compact-branches", cl::Optional, cl::init(CB_Optimal),94cl::desc("MIPS Specific: Compact branch policy."),95cl::values(clEnumValN(CB_Never, "never",96"Do not use compact branches if possible."),97clEnumValN(CB_Optimal, "optimal",98"Use compact branches where appropriate (default)."),99clEnumValN(CB_Always, "always",100"Always use compact branches if possible.")));101102namespace {103104using Iter = MachineBasicBlock::iterator;105using ReverseIter = MachineBasicBlock::reverse_iterator;106using BB2BrMap = SmallDenseMap<MachineBasicBlock *, MachineInstr *, 2>;107108class RegDefsUses {109public:110RegDefsUses(const TargetRegisterInfo &TRI);111112void init(const MachineInstr &MI);113114/// This function sets all caller-saved registers in Defs.115void setCallerSaved(const MachineInstr &MI);116117/// This function sets all unallocatable registers in Defs.118void setUnallocatableRegs(const MachineFunction &MF);119120/// Set bits in Uses corresponding to MBB's live-out registers except for121/// the registers that are live-in to SuccBB.122void addLiveOut(const MachineBasicBlock &MBB,123const MachineBasicBlock &SuccBB);124125bool update(const MachineInstr &MI, unsigned Begin, unsigned End);126127private:128bool checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses, unsigned Reg,129bool IsDef) const;130131/// Returns true if Reg or its alias is in RegSet.132bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;133134const TargetRegisterInfo &TRI;135BitVector Defs, Uses;136};137138/// Base class for inspecting loads and stores.139class InspectMemInstr {140public:141InspectMemInstr(bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {}142virtual ~InspectMemInstr() = default;143144/// Return true if MI cannot be moved to delay slot.145bool hasHazard(const MachineInstr &MI);146147protected:148/// Flags indicating whether loads or stores have been seen.149bool OrigSeenLoad = false;150bool OrigSeenStore = false;151bool SeenLoad = false;152bool SeenStore = false;153154/// Memory instructions are not allowed to move to delay slot if this flag155/// is true.156bool ForbidMemInstr;157158private:159virtual bool hasHazard_(const MachineInstr &MI) = 0;160};161162/// This subclass rejects any memory instructions.163class NoMemInstr : public InspectMemInstr {164public:165NoMemInstr() : InspectMemInstr(true) {}166167private:168bool hasHazard_(const MachineInstr &MI) override { return true; }169};170171/// This subclass accepts loads from stacks and constant loads.172class LoadFromStackOrConst : public InspectMemInstr {173public:174LoadFromStackOrConst() : InspectMemInstr(false) {}175176private:177bool hasHazard_(const MachineInstr &MI) override;178};179180/// This subclass uses memory dependence information to determine whether a181/// memory instruction can be moved to a delay slot.182class MemDefsUses : public InspectMemInstr {183public:184explicit MemDefsUses(const MachineFrameInfo *MFI);185186private:187using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;188189bool hasHazard_(const MachineInstr &MI) override;190191/// Update Defs and Uses. Return true if there exist dependences that192/// disqualify the delay slot candidate between V and values in Uses and193/// Defs.194bool updateDefsUses(ValueType V, bool MayStore);195196/// Get the list of underlying objects of MI's memory operand.197bool getUnderlyingObjects(const MachineInstr &MI,198SmallVectorImpl<ValueType> &Objects) const;199200const MachineFrameInfo *MFI;201SmallPtrSet<ValueType, 4> Uses, Defs;202203/// Flags indicating whether loads or stores with no underlying objects have204/// been seen.205bool SeenNoObjLoad = false;206bool SeenNoObjStore = false;207};208209class MipsDelaySlotFiller : public MachineFunctionPass {210public:211MipsDelaySlotFiller() : MachineFunctionPass(ID) {212initializeMipsDelaySlotFillerPass(*PassRegistry::getPassRegistry());213}214215StringRef getPassName() const override { return "Mips Delay Slot Filler"; }216217bool runOnMachineFunction(MachineFunction &F) override {218TM = &F.getTarget();219bool Changed = false;220for (MachineBasicBlock &MBB : F)221Changed |= runOnMachineBasicBlock(MBB);222223// This pass invalidates liveness information when it reorders224// instructions to fill delay slot. Without this, -verify-machineinstrs225// will fail.226if (Changed)227F.getRegInfo().invalidateLiveness();228229return Changed;230}231232MachineFunctionProperties getRequiredProperties() const override {233return MachineFunctionProperties().set(234MachineFunctionProperties::Property::NoVRegs);235}236237void getAnalysisUsage(AnalysisUsage &AU) const override {238AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();239MachineFunctionPass::getAnalysisUsage(AU);240}241242static char ID;243244private:245bool runOnMachineBasicBlock(MachineBasicBlock &MBB);246247Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch,248const DebugLoc &DL);249250/// This function checks if it is valid to move Candidate to the delay slot251/// and returns true if it isn't. It also updates memory and register252/// dependence information.253bool delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,254InspectMemInstr &IM) const;255256/// This function searches range [Begin, End) for an instruction that can be257/// moved to the delay slot. Returns true on success.258template<typename IterTy>259bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,260RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot,261IterTy &Filler) const;262263/// This function searches in the backward direction for an instruction that264/// can be moved to the delay slot. Returns true on success.265bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const;266267/// This function searches MBB in the forward direction for an instruction268/// that can be moved to the delay slot. Returns true on success.269bool searchForward(MachineBasicBlock &MBB, Iter Slot) const;270271/// This function searches one of MBB's successor blocks for an instruction272/// that can be moved to the delay slot and inserts clones of the273/// instruction into the successor's predecessor blocks.274bool searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const;275276/// Pick a successor block of MBB. Return NULL if MBB doesn't have a277/// successor block that is not a landing pad.278MachineBasicBlock *selectSuccBB(MachineBasicBlock &B) const;279280/// This function analyzes MBB and returns an instruction with an unoccupied281/// slot that branches to Dst.282std::pair<MipsInstrInfo::BranchType, MachineInstr *>283getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const;284285/// Examine Pred and see if it is possible to insert an instruction into286/// one of its branches delay slot or its end.287bool examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ,288RegDefsUses &RegDU, bool &HasMultipleSuccs,289BB2BrMap &BrMap) const;290291bool terminateSearch(const MachineInstr &Candidate) const;292293const TargetMachine *TM = nullptr;294};295296} // end anonymous namespace297298char MipsDelaySlotFiller::ID = 0;299300static bool hasUnoccupiedSlot(const MachineInstr *MI) {301return MI->hasDelaySlot() && !MI->isBundledWithSucc();302}303304INITIALIZE_PASS(MipsDelaySlotFiller, DEBUG_TYPE,305"Fill delay slot for MIPS", false, false)306307/// This function inserts clones of Filler into predecessor blocks.308static void insertDelayFiller(Iter Filler, const BB2BrMap &BrMap) {309MachineFunction *MF = Filler->getParent()->getParent();310311for (const auto &I : BrMap) {312if (I.second) {313MIBundleBuilder(I.second).append(MF->CloneMachineInstr(&*Filler));314++UsefulSlots;315} else {316I.first->push_back(MF->CloneMachineInstr(&*Filler));317}318}319}320321/// This function adds registers Filler defines to MBB's live-in register list.322static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB) {323for (const MachineOperand &MO : Filler->operands()) {324unsigned R;325326if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg()))327continue;328329#ifndef NDEBUG330const MachineFunction &MF = *MBB.getParent();331assert(MF.getSubtarget().getRegisterInfo()->getAllocatableSet(MF).test(R) &&332"Shouldn't move an instruction with unallocatable registers across "333"basic block boundaries.");334#endif335336if (!MBB.isLiveIn(R))337MBB.addLiveIn(R);338}339}340341RegDefsUses::RegDefsUses(const TargetRegisterInfo &TRI)342: TRI(TRI), Defs(TRI.getNumRegs(), false), Uses(TRI.getNumRegs(), false) {}343344void RegDefsUses::init(const MachineInstr &MI) {345// Add all register operands which are explicit and non-variadic.346update(MI, 0, MI.getDesc().getNumOperands());347348// If MI is a call, add RA to Defs to prevent users of RA from going into349// delay slot.350if (MI.isCall())351Defs.set(Mips::RA);352353// Add all implicit register operands of branch instructions except354// register AT.355if (MI.isBranch()) {356update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands());357Defs.reset(Mips::AT);358}359}360361void RegDefsUses::setCallerSaved(const MachineInstr &MI) {362assert(MI.isCall());363364// Add RA/RA_64 to Defs to prevent users of RA/RA_64 from going into365// the delay slot. The reason is that RA/RA_64 must not be changed366// in the delay slot so that the callee can return to the caller.367if (MI.definesRegister(Mips::RA, /*TRI=*/nullptr) ||368MI.definesRegister(Mips::RA_64, /*TRI=*/nullptr)) {369Defs.set(Mips::RA);370Defs.set(Mips::RA_64);371}372373// If MI is a call, add all caller-saved registers to Defs.374BitVector CallerSavedRegs(TRI.getNumRegs(), true);375376CallerSavedRegs.reset(Mips::ZERO);377CallerSavedRegs.reset(Mips::ZERO_64);378379for (const MCPhysReg *R = TRI.getCalleeSavedRegs(MI.getParent()->getParent());380*R; ++R)381for (MCRegAliasIterator AI(*R, &TRI, true); AI.isValid(); ++AI)382CallerSavedRegs.reset(*AI);383384Defs |= CallerSavedRegs;385}386387void RegDefsUses::setUnallocatableRegs(const MachineFunction &MF) {388BitVector AllocSet = TRI.getAllocatableSet(MF);389390for (unsigned R : AllocSet.set_bits())391for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI)392AllocSet.set(*AI);393394AllocSet.set(Mips::ZERO);395AllocSet.set(Mips::ZERO_64);396397Defs |= AllocSet.flip();398}399400void RegDefsUses::addLiveOut(const MachineBasicBlock &MBB,401const MachineBasicBlock &SuccBB) {402for (const MachineBasicBlock *S : MBB.successors())403if (S != &SuccBB)404for (const auto &LI : S->liveins())405Uses.set(LI.PhysReg);406}407408bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {409BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs());410bool HasHazard = false;411412for (unsigned I = Begin; I != End; ++I) {413const MachineOperand &MO = MI.getOperand(I);414415if (MO.isReg() && MO.getReg()) {416if (checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef())) {417LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found register hazard for operand "418<< I << ": ";419MO.dump());420HasHazard = true;421}422}423}424425Defs |= NewDefs;426Uses |= NewUses;427428return HasHazard;429}430431bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,432unsigned Reg, bool IsDef) const {433if (IsDef) {434NewDefs.set(Reg);435// check whether Reg has already been defined or used.436return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg));437}438439NewUses.set(Reg);440// check whether Reg has already been defined.441return isRegInSet(Defs, Reg);442}443444bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {445// Check Reg and all aliased Registers.446for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)447if (RegSet.test(*AI))448return true;449return false;450}451452bool InspectMemInstr::hasHazard(const MachineInstr &MI) {453if (!MI.mayStore() && !MI.mayLoad())454return false;455456if (ForbidMemInstr)457return true;458459OrigSeenLoad = SeenLoad;460OrigSeenStore = SeenStore;461SeenLoad |= MI.mayLoad();462SeenStore |= MI.mayStore();463464// If MI is an ordered or volatile memory reference, disallow moving465// subsequent loads and stores to delay slot.466if (MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {467ForbidMemInstr = true;468return true;469}470471return hasHazard_(MI);472}473474bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) {475if (MI.mayStore())476return true;477478if (!MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getPseudoValue())479return true;480481if (const PseudoSourceValue *PSV =482(*MI.memoperands_begin())->getPseudoValue()) {483if (isa<FixedStackPseudoSourceValue>(PSV))484return false;485return !PSV->isConstant(nullptr) && !PSV->isStack();486}487488return true;489}490491MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_)492: InspectMemInstr(false), MFI(MFI_) {}493494bool MemDefsUses::hasHazard_(const MachineInstr &MI) {495bool HasHazard = false;496497// Check underlying object list.498SmallVector<ValueType, 4> Objs;499if (getUnderlyingObjects(MI, Objs)) {500for (ValueType VT : Objs)501HasHazard |= updateDefsUses(VT, MI.mayStore());502return HasHazard;503}504505// No underlying objects found.506HasHazard = MI.mayStore() && (OrigSeenLoad || OrigSeenStore);507HasHazard |= MI.mayLoad() || OrigSeenStore;508509SeenNoObjLoad |= MI.mayLoad();510SeenNoObjStore |= MI.mayStore();511512return HasHazard;513}514515bool MemDefsUses::updateDefsUses(ValueType V, bool MayStore) {516if (MayStore)517return !Defs.insert(V).second || Uses.count(V) || SeenNoObjStore ||518SeenNoObjLoad;519520Uses.insert(V);521return Defs.count(V) || SeenNoObjStore;522}523524bool MemDefsUses::525getUnderlyingObjects(const MachineInstr &MI,526SmallVectorImpl<ValueType> &Objects) const {527if (!MI.hasOneMemOperand())528return false;529530auto & MMO = **MI.memoperands_begin();531532if (const PseudoSourceValue *PSV = MMO.getPseudoValue()) {533if (!PSV->isAliased(MFI))534return false;535Objects.push_back(PSV);536return true;537}538539if (const Value *V = MMO.getValue()) {540SmallVector<const Value *, 4> Objs;541::getUnderlyingObjects(V, Objs);542543for (const Value *UValue : Objs) {544if (!isIdentifiedObject(V))545return false;546547Objects.push_back(UValue);548}549return true;550}551552return false;553}554555// Replace Branch with the compact branch instruction.556Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &MBB,557Iter Branch,558const DebugLoc &DL) {559const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();560const MipsInstrInfo *TII = STI.getInstrInfo();561562unsigned NewOpcode = TII->getEquivalentCompactForm(Branch);563Branch = TII->genInstrWithNewOpc(NewOpcode, Branch);564565auto *ToErase = cast<MachineInstr>(&*std::next(Branch));566// Update call site info for the Branch.567if (ToErase->shouldUpdateCallSiteInfo())568ToErase->getMF()->moveCallSiteInfo(ToErase, cast<MachineInstr>(&*Branch));569ToErase->eraseFromParent();570return Branch;571}572573// For given opcode returns opcode of corresponding instruction with short574// delay slot.575// For the pseudo TAILCALL*_MM instructions return the short delay slot576// form. Unfortunately, TAILCALL<->b16 is denied as b16 has a limited range577// that is too short to make use of for tail calls.578static int getEquivalentCallShort(int Opcode) {579switch (Opcode) {580case Mips::BGEZAL:581return Mips::BGEZALS_MM;582case Mips::BLTZAL:583return Mips::BLTZALS_MM;584case Mips::JAL:585case Mips::JAL_MM:586return Mips::JALS_MM;587case Mips::JALR:588return Mips::JALRS_MM;589case Mips::JALR16_MM:590return Mips::JALRS16_MM;591case Mips::TAILCALL_MM:592llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!");593case Mips::TAILCALLREG:594return Mips::JR16_MM;595default:596llvm_unreachable("Unexpected call instruction for microMIPS.");597}598}599600/// runOnMachineBasicBlock - Fill in delay slots for the given basic block.601/// We assume there is only one delay slot per delayed instruction.602bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {603bool Changed = false;604const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();605bool InMicroMipsMode = STI.inMicroMipsMode();606const MipsInstrInfo *TII = STI.getInstrInfo();607608for (Iter I = MBB.begin(); I != MBB.end(); ++I) {609if (!hasUnoccupiedSlot(&*I))610continue;611612// Delay slot filling is disabled at -O0, or in microMIPS32R6.613if (!DisableDelaySlotFiller &&614(TM->getOptLevel() != CodeGenOptLevel::None) &&615!(InMicroMipsMode && STI.hasMips32r6())) {616617bool Filled = false;618619if (MipsCompactBranchPolicy.getValue() != CB_Always ||620!TII->getEquivalentCompactForm(I)) {621if (searchBackward(MBB, *I)) {622LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"623" in backwards search.\n");624Filled = true;625} else if (I->isTerminator()) {626if (searchSuccBBs(MBB, I)) {627Filled = true;628LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"629" in successor BB search.\n");630}631} else if (searchForward(MBB, I)) {632LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot"633" in forwards search.\n");634Filled = true;635}636}637638if (Filled) {639// Get instruction with delay slot.640MachineBasicBlock::instr_iterator DSI = I.getInstrIterator();641642if (InMicroMipsMode && TII->getInstSizeInBytes(*std::next(DSI)) == 2 &&643DSI->isCall()) {644// If instruction in delay slot is 16b change opcode to645// corresponding instruction with short delay slot.646647// TODO: Implement an instruction mapping table of 16bit opcodes to648// 32bit opcodes so that an instruction can be expanded. This would649// save 16 bits as a TAILCALL_MM pseudo requires a fullsized nop.650// TODO: Permit b16 when branching backwards to the same function651// if it is in range.652DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode())));653}654++FilledSlots;655Changed = true;656continue;657}658}659660// For microMIPS if instruction is BEQ or BNE with one ZERO register, then661// instead of adding NOP replace this instruction with the corresponding662// compact branch instruction, i.e. BEQZC or BNEZC. Additionally663// PseudoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can664// be replaced with JRC16_MM.665666// For MIPSR6 attempt to produce the corresponding compact (no delay slot)667// form of the CTI. For indirect jumps this will not require inserting a668// NOP and for branches will hopefully avoid requiring a NOP.669if ((InMicroMipsMode ||670(STI.hasMips32r6() && MipsCompactBranchPolicy != CB_Never)) &&671TII->getEquivalentCompactForm(I)) {672I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());673Changed = true;674continue;675}676677// Bundle the NOP to the instruction with the delay slot.678LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": could not fill delay slot for ";679I->dump());680TII->insertNop(MBB, std::next(I), I->getDebugLoc());681MIBundleBuilder(MBB, I, std::next(I, 2));682++FilledSlots;683Changed = true;684}685686return Changed;687}688689template <typename IterTy>690bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,691IterTy End, RegDefsUses &RegDU,692InspectMemInstr &IM, Iter Slot,693IterTy &Filler) const {694for (IterTy I = Begin; I != End;) {695IterTy CurrI = I;696++I;697LLVM_DEBUG(dbgs() << DEBUG_TYPE ": checking instruction: "; CurrI->dump());698// skip debug value699if (CurrI->isDebugInstr()) {700LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring debug instruction: ";701CurrI->dump());702continue;703}704705if (CurrI->isBundle()) {706LLVM_DEBUG(dbgs() << DEBUG_TYPE ": ignoring BUNDLE instruction: ";707CurrI->dump());708// However, we still need to update the register def-use information.709RegDU.update(*CurrI, 0, CurrI->getNumOperands());710continue;711}712713if (terminateSearch(*CurrI)) {714LLVM_DEBUG(dbgs() << DEBUG_TYPE ": should terminate search: ";715CurrI->dump());716break;717}718719assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&720"Cannot put calls, returns or branches in delay slot.");721722if (CurrI->isKill()) {723CurrI->eraseFromParent();724continue;725}726727if (delayHasHazard(*CurrI, RegDU, IM))728continue;729730const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>();731if (STI.isTargetNaCl()) {732// In NaCl, instructions that must be masked are forbidden in delay slots.733// We only check for loads, stores and SP changes. Calls, returns and734// branches are not checked because non-NaCl targets never put them in735// delay slots.736unsigned AddrIdx;737if ((isBasePlusOffsetMemoryAccess(CurrI->getOpcode(), &AddrIdx) &&738baseRegNeedsLoadStoreMask(CurrI->getOperand(AddrIdx).getReg())) ||739CurrI->modifiesRegister(Mips::SP, STI.getRegisterInfo()))740continue;741}742743bool InMicroMipsMode = STI.inMicroMipsMode();744const MipsInstrInfo *TII = STI.getInstrInfo();745unsigned Opcode = (*Slot).getOpcode();746// This is complicated by the tail call optimization. For non-PIC code747// there is only a 32bit sized unconditional branch which can be assumed748// to be able to reach the target. b16 only has a range of +/- 1 KB.749// It's entirely possible that the target function is reachable with b16750// but we don't have enough information to make that decision.751if (InMicroMipsMode && TII->getInstSizeInBytes(*CurrI) == 2 &&752(Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||753Opcode == Mips::PseudoIndirectBranch_MM ||754Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))755continue;756// Instructions LWP/SWP and MOVEP should not be in a delay slot as that757// results in unpredictable behaviour758if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||759Opcode == Mips::MOVEP_MM))760continue;761762Filler = CurrI;763LLVM_DEBUG(dbgs() << DEBUG_TYPE ": found instruction for delay slot: ";764CurrI->dump());765766return true;767}768769return false;770}771772bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,773MachineInstr &Slot) const {774if (DisableBackwardSearch)775return false;776777auto *Fn = MBB.getParent();778RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());779MemDefsUses MemDU(&Fn->getFrameInfo());780ReverseIter Filler;781782RegDU.init(Slot);783784MachineBasicBlock::iterator SlotI = Slot;785if (!searchRange(MBB, ++SlotI.getReverse(), MBB.rend(), RegDU, MemDU, Slot,786Filler)) {787LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "788"slot using backwards search.\n");789return false;790}791792MBB.splice(std::next(SlotI), &MBB, Filler.getReverse());793MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2));794++UsefulSlots;795return true;796}797798bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,799Iter Slot) const {800// Can handle only calls.801if (DisableForwardSearch || !Slot->isCall())802return false;803804RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo());805NoMemInstr NM;806Iter Filler;807808RegDU.setCallerSaved(*Slot);809810if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {811LLVM_DEBUG(dbgs() << DEBUG_TYPE ": could not find instruction for delay "812"slot using forwards search.\n");813return false;814}815816MBB.splice(std::next(Slot), &MBB, Filler);817MIBundleBuilder(MBB, Slot, std::next(Slot, 2));818++UsefulSlots;819return true;820}821822bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB,823Iter Slot) const {824if (DisableSuccBBSearch)825return false;826827MachineBasicBlock *SuccBB = selectSuccBB(MBB);828829if (!SuccBB)830return false;831832RegDefsUses RegDU(*MBB.getParent()->getSubtarget().getRegisterInfo());833bool HasMultipleSuccs = false;834BB2BrMap BrMap;835std::unique_ptr<InspectMemInstr> IM;836Iter Filler;837auto *Fn = MBB.getParent();838839// Iterate over SuccBB's predecessor list.840for (MachineBasicBlock *Pred : SuccBB->predecessors())841if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs, BrMap))842return false;843844// Do not allow moving instructions which have unallocatable register operands845// across basic block boundaries.846RegDU.setUnallocatableRegs(*Fn);847848// Only allow moving loads from stack or constants if any of the SuccBB's849// predecessors have multiple successors.850if (HasMultipleSuccs) {851IM.reset(new LoadFromStackOrConst());852} else {853const MachineFrameInfo &MFI = Fn->getFrameInfo();854IM.reset(new MemDefsUses(&MFI));855}856857if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,858Filler))859return false;860861insertDelayFiller(Filler, BrMap);862addLiveInRegs(Filler, *SuccBB);863Filler->eraseFromParent();864865return true;866}867868MachineBasicBlock *869MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &B) const {870if (B.succ_empty())871return nullptr;872873// Select the successor with the larget edge weight.874auto &Prob = getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();875MachineBasicBlock *S = *std::max_element(876B.succ_begin(), B.succ_end(),877[&](const MachineBasicBlock *Dst0, const MachineBasicBlock *Dst1) {878return Prob.getEdgeProbability(&B, Dst0) <879Prob.getEdgeProbability(&B, Dst1);880});881return S->isEHPad() ? nullptr : S;882}883884std::pair<MipsInstrInfo::BranchType, MachineInstr *>885MipsDelaySlotFiller::getBranch(MachineBasicBlock &MBB,886const MachineBasicBlock &Dst) const {887const MipsInstrInfo *TII =888MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo();889MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr;890SmallVector<MachineInstr*, 2> BranchInstrs;891SmallVector<MachineOperand, 2> Cond;892893MipsInstrInfo::BranchType R =894TII->analyzeBranch(MBB, TrueBB, FalseBB, Cond, false, BranchInstrs);895896if ((R == MipsInstrInfo::BT_None) || (R == MipsInstrInfo::BT_NoBranch))897return std::make_pair(R, nullptr);898899if (R != MipsInstrInfo::BT_CondUncond) {900if (!hasUnoccupiedSlot(BranchInstrs[0]))901return std::make_pair(MipsInstrInfo::BT_None, nullptr);902903assert(((R != MipsInstrInfo::BT_Uncond) || (TrueBB == &Dst)));904905return std::make_pair(R, BranchInstrs[0]);906}907908assert((TrueBB == &Dst) || (FalseBB == &Dst));909910// Examine the conditional branch. See if its slot is occupied.911if (hasUnoccupiedSlot(BranchInstrs[0]))912return std::make_pair(MipsInstrInfo::BT_Cond, BranchInstrs[0]);913914// If that fails, try the unconditional branch.915if (hasUnoccupiedSlot(BranchInstrs[1]) && (FalseBB == &Dst))916return std::make_pair(MipsInstrInfo::BT_Uncond, BranchInstrs[1]);917918return std::make_pair(MipsInstrInfo::BT_None, nullptr);919}920921bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,922const MachineBasicBlock &Succ,923RegDefsUses &RegDU,924bool &HasMultipleSuccs,925BB2BrMap &BrMap) const {926std::pair<MipsInstrInfo::BranchType, MachineInstr *> P =927getBranch(Pred, Succ);928929// Return if either getBranch wasn't able to analyze the branches or there930// were no branches with unoccupied slots.931if (P.first == MipsInstrInfo::BT_None)932return false;933934if ((P.first != MipsInstrInfo::BT_Uncond) &&935(P.first != MipsInstrInfo::BT_NoBranch)) {936HasMultipleSuccs = true;937RegDU.addLiveOut(Pred, Succ);938}939940BrMap[&Pred] = P.second;941return true;942}943944bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate,945RegDefsUses &RegDU,946InspectMemInstr &IM) const {947assert(!Candidate.isKill() &&948"KILL instructions should have been eliminated at this point.");949950bool HasHazard = Candidate.isImplicitDef();951952HasHazard |= IM.hasHazard(Candidate);953HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());954955return HasHazard;956}957958bool MipsDelaySlotFiller::terminateSearch(const MachineInstr &Candidate) const {959return (Candidate.isTerminator() || Candidate.isCall() ||960Candidate.isPosition() || Candidate.isInlineAsm() ||961Candidate.hasUnmodeledSideEffects());962}963964/// createMipsDelaySlotFillerPass - Returns a pass that fills in delay965/// slots in Mips MachineFunctions966FunctionPass *llvm::createMipsDelaySlotFillerPass() {967return new MipsDelaySlotFiller();968}969970971