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