brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.7 KiB · 3a21220 Raw
398 lines · cpp
1//===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/CodeGen/MachineInstrBundle.h"10#include "llvm/ADT/SetVector.h"11#include "llvm/ADT/SmallSet.h"12#include "llvm/ADT/SmallVector.h"13#include "llvm/CodeGen/MachineFunctionPass.h"14#include "llvm/CodeGen/MachineInstrBuilder.h"15#include "llvm/CodeGen/Passes.h"16#include "llvm/CodeGen/TargetInstrInfo.h"17#include "llvm/CodeGen/TargetRegisterInfo.h"18#include "llvm/CodeGen/TargetSubtargetInfo.h"19#include "llvm/InitializePasses.h"20#include "llvm/Pass.h"21#include "llvm/PassRegistry.h"22#include <utility>23using namespace llvm;24 25namespace {26  class UnpackMachineBundles : public MachineFunctionPass {27  public:28    static char ID; // Pass identification29    UnpackMachineBundles(30        std::function<bool(const MachineFunction &)> Ftor = nullptr)31        : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {32      initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());33    }34 35    bool runOnMachineFunction(MachineFunction &MF) override;36 37  private:38    std::function<bool(const MachineFunction &)> PredicateFtor;39  };40} // end anonymous namespace41 42char UnpackMachineBundles::ID = 0;43char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;44INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",45                "Unpack machine instruction bundles", false, false)46 47bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {48  if (PredicateFtor && !PredicateFtor(MF))49    return false;50 51  bool Changed = false;52  for (MachineBasicBlock &MBB : MF) {53    for (MachineBasicBlock::instr_iterator MII = MBB.instr_begin(),54           MIE = MBB.instr_end(); MII != MIE; ) {55      MachineInstr *MI = &*MII;56 57      // Remove BUNDLE instruction and the InsideBundle flags from bundled58      // instructions.59      if (MI->isBundle()) {60        while (++MII != MIE && MII->isBundledWithPred()) {61          MII->unbundleFromPred();62          for (MachineOperand &MO  : MII->operands()) {63            if (MO.isReg() && MO.isInternalRead())64              MO.setIsInternalRead(false);65          }66        }67        MI->eraseFromParent();68 69        Changed = true;70        continue;71      }72 73      ++MII;74    }75  }76 77  return Changed;78}79 80FunctionPass *81llvm::createUnpackMachineBundles(82    std::function<bool(const MachineFunction &)> Ftor) {83  return new UnpackMachineBundles(std::move(Ftor));84}85 86/// Return the first DebugLoc that has line number information, given a87/// range of instructions. The search range is from FirstMI to LastMI88/// (exclusive). Otherwise return the first DILocation or an empty location if89/// there are none.90static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,91                            MachineBasicBlock::instr_iterator LastMI) {92  DebugLoc DL;93  for (auto MII = FirstMI; MII != LastMI; ++MII) {94    if (DebugLoc MIIDL = MII->getDebugLoc()) {95      if (MIIDL.getLine() != 0)96        return MIIDL;97      DL = MIIDL.get();98    }99  }100  return DL;101}102 103/// Check if target reg is contained in given lists, which are:104/// LocalDefsV as given list for virtual regs105/// LocalDefsP as given list for physical regs, in BitVector[RegUnit] form106static bool containsReg(SmallSetVector<Register, 32> LocalDefsV,107                        const BitVector &LocalDefsP, Register Reg,108                        const TargetRegisterInfo *TRI) {109  if (Reg.isPhysical()) {110    for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))111      if (!LocalDefsP[static_cast<unsigned>(Unit)])112        return false;113 114    return true;115  }116  return LocalDefsV.contains(Reg);117}118 119/// finalizeBundle - Finalize a machine instruction bundle which includes120/// a sequence of instructions starting from FirstMI to LastMI (exclusive).121/// This routine adds a BUNDLE instruction to represent the bundle, it adds122/// IsInternalRead markers to MachineOperands which are defined inside the123/// bundle, and it copies externally visible defs and uses to the BUNDLE124/// instruction.125void llvm::finalizeBundle(MachineBasicBlock &MBB,126                          MachineBasicBlock::instr_iterator FirstMI,127                          MachineBasicBlock::instr_iterator LastMI) {128  assert(FirstMI != LastMI && "Empty bundle?");129  MIBundleBuilder Bundle(MBB, FirstMI, LastMI);130 131  MachineFunction &MF = *MBB.getParent();132  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();133  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();134 135  MachineInstrBuilder MIB =136      BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE));137  Bundle.prepend(MIB);138 139  SmallSetVector<Register, 32> LocalDefs;140  BitVector LocalDefsP(TRI->getNumRegUnits());141  SmallSet<Register, 8> DeadDefSet;142  SmallSetVector<Register, 8> ExternUses;143  SmallSet<Register, 8> KilledUseSet;144  SmallSet<Register, 8> UndefUseSet;145  SmallVector<std::pair<Register, Register>> TiedOperands;146  SmallVector<MachineInstr *> MemMIs;147  for (auto MII = FirstMI; MII != LastMI; ++MII) {148    // Debug instructions have no effects to track.149    if (MII->isDebugInstr())150      continue;151 152    for (MachineOperand &MO : MII->all_uses()) {153      Register Reg = MO.getReg();154      if (!Reg)155        continue;156 157      if (containsReg(LocalDefs, LocalDefsP, Reg, TRI)) {158        MO.setIsInternalRead();159        if (MO.isKill()) {160          // Internal def is now killed.161          DeadDefSet.insert(Reg);162        }163      } else {164        if (ExternUses.insert(Reg)) {165          if (MO.isUndef())166            UndefUseSet.insert(Reg);167        }168        if (MO.isKill()) {169          // External def is now killed.170          KilledUseSet.insert(Reg);171        }172        if (MO.isTied() && Reg.isVirtual()) {173          // Record tied operand constraints that involve virtual registers so174          // that bundles that are formed pre-register allocation reflect the175          // relevant constraints.176          unsigned TiedIdx = MII->findTiedOperandIdx(MO.getOperandNo());177          MachineOperand &TiedMO = MII->getOperand(TiedIdx);178          Register DefReg = TiedMO.getReg();179          TiedOperands.emplace_back(DefReg, Reg);180        }181      }182    }183 184    for (MachineOperand &MO : MII->all_defs()) {185      Register Reg = MO.getReg();186      if (!Reg)187        continue;188 189      if (LocalDefs.insert(Reg)) {190        if (!MO.isDead() && Reg.isPhysical()) {191          for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))192            LocalDefsP.set(static_cast<unsigned>(Unit));193        }194      } else {195        if (!MO.isDead()) {196          // Re-defined inside the bundle, it's no longer dead.197          DeadDefSet.erase(Reg);198        }199      }200      if (MO.isDead())201        DeadDefSet.insert(Reg);202    }203 204    // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions205    // got the property, then also set it on the bundle.206    if (MII->getFlag(MachineInstr::FrameSetup))207      MIB.setMIFlag(MachineInstr::FrameSetup);208    if (MII->getFlag(MachineInstr::FrameDestroy))209      MIB.setMIFlag(MachineInstr::FrameDestroy);210 211    if (MII->mayLoadOrStore())212      MemMIs.push_back(&*MII);213  }214 215  for (Register Reg : LocalDefs) {216    // If it's not live beyond end of the bundle, mark it dead.217    bool isDead = DeadDefSet.contains(Reg);218    MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |219                        getImplRegState(true));220  }221 222  for (Register Reg : ExternUses) {223    bool isKill = KilledUseSet.contains(Reg);224    bool isUndef = UndefUseSet.contains(Reg);225    MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |226                        getImplRegState(true));227  }228 229  for (auto [DefReg, UseReg] : TiedOperands) {230    unsigned DefIdx =231        std::distance(LocalDefs.begin(), llvm::find(LocalDefs, DefReg));232    unsigned UseIdx =233        std::distance(ExternUses.begin(), llvm::find(ExternUses, UseReg));234    assert(DefIdx < LocalDefs.size());235    assert(UseIdx < ExternUses.size());236    MIB->tieOperands(DefIdx, LocalDefs.size() + UseIdx);237  }238 239  MIB->cloneMergedMemRefs(MF, MemMIs);240}241 242/// finalizeBundle - Same functionality as the previous finalizeBundle except243/// the last instruction in the bundle is not provided as an input. This is244/// used in cases where bundles are pre-determined by marking instructions245/// with 'InsideBundle' marker. It returns the MBB instruction iterator that246/// points to the end of the bundle.247MachineBasicBlock::instr_iterator248llvm::finalizeBundle(MachineBasicBlock &MBB,249                     MachineBasicBlock::instr_iterator FirstMI) {250  MachineBasicBlock::instr_iterator E = MBB.instr_end();251  MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);252  while (LastMI != E && LastMI->isInsideBundle())253    ++LastMI;254  finalizeBundle(MBB, FirstMI, LastMI);255  return LastMI;256}257 258/// finalizeBundles - Finalize instruction bundles in the specified259/// MachineFunction. Return true if any bundles are finalized.260bool llvm::finalizeBundles(MachineFunction &MF) {261  bool Changed = false;262  for (MachineBasicBlock &MBB : MF) {263    MachineBasicBlock::instr_iterator MII = MBB.instr_begin();264    MachineBasicBlock::instr_iterator MIE = MBB.instr_end();265    if (MII == MIE)266      continue;267    assert(!MII->isInsideBundle() &&268           "First instr cannot be inside bundle before finalization!");269 270    for (++MII; MII != MIE; ) {271      if (!MII->isInsideBundle())272        ++MII;273      else {274        MII = finalizeBundle(MBB, std::prev(MII));275        Changed = true;276      }277    }278  }279 280  return Changed;281}282 283VirtRegInfo llvm::AnalyzeVirtRegInBundle(284    MachineInstr &MI, Register Reg,285    SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) {286  VirtRegInfo RI = {false, false, false};287  for (MIBundleOperands O(MI); O.isValid(); ++O) {288    MachineOperand &MO = *O;289    if (!MO.isReg() || MO.getReg() != Reg)290      continue;291 292    // Remember each (MI, OpNo) that refers to Reg.293    if (Ops)294      Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo()));295 296    // Both defs and uses can read virtual registers.297    if (MO.readsReg()) {298      RI.Reads = true;299      if (MO.isDef())300        RI.Tied = true;301    }302 303    // Only defs can write.304    if (MO.isDef())305      RI.Writes = true;306    else if (!RI.Tied &&307             MO.getParent()->isRegTiedToDefOperand(O.getOperandNo()))308      RI.Tied = true;309  }310  return RI;311}312 313std::pair<LaneBitmask, LaneBitmask>314llvm::AnalyzeVirtRegLanesInBundle(const MachineInstr &MI, Register Reg,315                                  const MachineRegisterInfo &MRI,316                                  const TargetRegisterInfo &TRI) {317 318  LaneBitmask UseMask, DefMask;319 320  for (const MachineOperand &MO : const_mi_bundle_ops(MI)) {321    if (!MO.isReg() || MO.getReg() != Reg)322      continue;323 324    unsigned SubReg = MO.getSubReg();325    if (SubReg == 0 && MO.isUse() && !MO.isUndef())326      UseMask |= MRI.getMaxLaneMaskForVReg(Reg);327 328    LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(SubReg);329    if (MO.isDef()) {330      if (!MO.isUndef())331        UseMask |= ~SubRegMask;332      DefMask |= SubRegMask;333    } else if (!MO.isUndef())334      UseMask |= SubRegMask;335  }336 337  return {UseMask, DefMask};338}339 340PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,341                                         const TargetRegisterInfo *TRI) {342  bool AllDefsDead = true;343  PhysRegInfo PRI = {false, false, false, false, false, false, false, false};344 345  assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!");346  for (const MachineOperand &MO : const_mi_bundle_ops(MI)) {347    if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {348      PRI.Clobbered = true;349      continue;350    }351 352    if (!MO.isReg())353      continue;354 355    Register MOReg = MO.getReg();356    if (!MOReg || !MOReg.isPhysical())357      continue;358 359    if (!TRI->regsOverlap(MOReg, Reg))360      continue;361 362    bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);363    if (MO.readsReg()) {364      PRI.Read = true;365      if (Covered) {366        PRI.FullyRead = true;367        if (MO.isKill())368          PRI.Killed = true;369      }370    } else if (MO.isDef()) {371      PRI.Defined = true;372      if (Covered)373        PRI.FullyDefined = true;374      if (!MO.isDead())375        AllDefsDead = false;376    }377  }378 379  if (AllDefsDead) {380    if (PRI.FullyDefined || PRI.Clobbered)381      PRI.DeadDef = true;382    else if (PRI.Defined)383      PRI.PartialDeadDef = true;384  }385 386  return PRI;387}388 389PreservedAnalyses390llvm::FinalizeBundleTestPass::run(MachineFunction &MF,391                                  MachineFunctionAnalysisManager &) {392  // For testing purposes, bundle the entire contents of each basic block393  // except for terminators.394  for (MachineBasicBlock &MBB : MF)395    finalizeBundle(MBB, MBB.instr_begin(), MBB.getFirstInstrTerminator());396  return PreservedAnalyses::none();397}398