summaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp
diff options
context:
space:
mode:
authororivej <[email protected]>2022-02-10 16:45:01 +0300
committerDaniil Cherednik <[email protected]>2022-02-10 16:45:01 +0300
commit2d37894b1b037cf24231090eda8589bbb44fb6fc (patch)
treebe835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp
parent718c552901d703c502ccbefdfc3c9028d608b947 (diff)
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp')
-rw-r--r--contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp720
1 files changed, 360 insertions, 360 deletions
diff --git a/contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp b/contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp
index 6417cc81800..50456e489ea 100644
--- a/contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp
+++ b/contrib/libs/llvm12/lib/CodeGen/MachineInstrBundle.cpp
@@ -1,360 +1,360 @@
-//===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/MachineInstrBundle.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/CodeGen/TargetSubtargetInfo.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Target/TargetMachine.h"
-#include <utility>
-using namespace llvm;
-
-namespace {
- class UnpackMachineBundles : public MachineFunctionPass {
- public:
- static char ID; // Pass identification
- UnpackMachineBundles(
- std::function<bool(const MachineFunction &)> Ftor = nullptr)
- : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
- initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- private:
- std::function<bool(const MachineFunction &)> PredicateFtor;
- };
-} // end anonymous namespace
-
-char UnpackMachineBundles::ID = 0;
-char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
-INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
- "Unpack machine instruction bundles", false, false)
-
-bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
- if (PredicateFtor && !PredicateFtor(MF))
- return false;
-
- bool Changed = false;
- for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
- MachineBasicBlock *MBB = &*I;
-
- for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
- MIE = MBB->instr_end(); MII != MIE; ) {
- MachineInstr *MI = &*MII;
-
- // Remove BUNDLE instruction and the InsideBundle flags from bundled
- // instructions.
- if (MI->isBundle()) {
- while (++MII != MIE && MII->isBundledWithPred()) {
- MII->unbundleFromPred();
- for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MII->getOperand(i);
- if (MO.isReg() && MO.isInternalRead())
- MO.setIsInternalRead(false);
- }
- }
- MI->eraseFromParent();
-
- Changed = true;
- continue;
- }
-
- ++MII;
- }
- }
-
- return Changed;
-}
-
-FunctionPass *
-llvm::createUnpackMachineBundles(
- std::function<bool(const MachineFunction &)> Ftor) {
- return new UnpackMachineBundles(std::move(Ftor));
-}
-
-namespace {
- class FinalizeMachineBundles : public MachineFunctionPass {
- public:
- static char ID; // Pass identification
- FinalizeMachineBundles() : MachineFunctionPass(ID) {
- initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
- };
-} // end anonymous namespace
-
-char FinalizeMachineBundles::ID = 0;
-char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID;
-INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles",
- "Finalize machine instruction bundles", false, false)
-
-bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) {
- return llvm::finalizeBundles(MF);
-}
-
-/// Return the first found DebugLoc that has a DILocation, given a range of
-/// instructions. The search range is from FirstMI to LastMI (exclusive). If no
-/// DILocation is found, then an empty location is returned.
-static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,
- MachineBasicBlock::instr_iterator LastMI) {
- for (auto MII = FirstMI; MII != LastMI; ++MII)
- if (MII->getDebugLoc().get())
- return MII->getDebugLoc();
- return DebugLoc();
-}
-
-/// finalizeBundle - Finalize a machine instruction bundle which includes
-/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
-/// This routine adds a BUNDLE instruction to represent the bundle, it adds
-/// IsInternalRead markers to MachineOperands which are defined inside the
-/// bundle, and it copies externally visible defs and uses to the BUNDLE
-/// instruction.
-void llvm::finalizeBundle(MachineBasicBlock &MBB,
- MachineBasicBlock::instr_iterator FirstMI,
- MachineBasicBlock::instr_iterator LastMI) {
- assert(FirstMI != LastMI && "Empty bundle?");
- MIBundleBuilder Bundle(MBB, FirstMI, LastMI);
-
- MachineFunction &MF = *MBB.getParent();
- const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
- const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
-
- MachineInstrBuilder MIB =
- BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE));
- Bundle.prepend(MIB);
-
- SmallVector<Register, 32> LocalDefs;
- SmallSet<Register, 32> LocalDefSet;
- SmallSet<Register, 8> DeadDefSet;
- SmallSet<Register, 16> KilledDefSet;
- SmallVector<Register, 8> ExternUses;
- SmallSet<Register, 8> ExternUseSet;
- SmallSet<Register, 8> KilledUseSet;
- SmallSet<Register, 8> UndefUseSet;
- SmallVector<MachineOperand*, 4> Defs;
- for (auto MII = FirstMI; MII != LastMI; ++MII) {
- for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
- MachineOperand &MO = MII->getOperand(i);
- if (!MO.isReg())
- continue;
- if (MO.isDef()) {
- Defs.push_back(&MO);
- continue;
- }
-
- Register Reg = MO.getReg();
- if (!Reg)
- continue;
-
- if (LocalDefSet.count(Reg)) {
- MO.setIsInternalRead();
- if (MO.isKill())
- // Internal def is now killed.
- KilledDefSet.insert(Reg);
- } else {
- if (ExternUseSet.insert(Reg).second) {
- ExternUses.push_back(Reg);
- if (MO.isUndef())
- UndefUseSet.insert(Reg);
- }
- if (MO.isKill())
- // External def is now killed.
- KilledUseSet.insert(Reg);
- }
- }
-
- for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
- MachineOperand &MO = *Defs[i];
- Register Reg = MO.getReg();
- if (!Reg)
- continue;
-
- if (LocalDefSet.insert(Reg).second) {
- LocalDefs.push_back(Reg);
- if (MO.isDead()) {
- DeadDefSet.insert(Reg);
- }
- } else {
- // Re-defined inside the bundle, it's no longer killed.
- KilledDefSet.erase(Reg);
- if (!MO.isDead())
- // Previously defined but dead.
- DeadDefSet.erase(Reg);
- }
-
- if (!MO.isDead() && Register::isPhysicalRegister(Reg)) {
- for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
- unsigned SubReg = *SubRegs;
- if (LocalDefSet.insert(SubReg).second)
- LocalDefs.push_back(SubReg);
- }
- }
- }
-
- Defs.clear();
- }
-
- SmallSet<Register, 32> Added;
- for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
- Register Reg = LocalDefs[i];
- if (Added.insert(Reg).second) {
- // If it's not live beyond end of the bundle, mark it dead.
- bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg);
- MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |
- getImplRegState(true));
- }
- }
-
- for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) {
- Register Reg = ExternUses[i];
- bool isKill = KilledUseSet.count(Reg);
- bool isUndef = UndefUseSet.count(Reg);
- MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
- getImplRegState(true));
- }
-
- // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got
- // the property, then also set it on the bundle.
- for (auto MII = FirstMI; MII != LastMI; ++MII) {
- if (MII->getFlag(MachineInstr::FrameSetup))
- MIB.setMIFlag(MachineInstr::FrameSetup);
- if (MII->getFlag(MachineInstr::FrameDestroy))
- MIB.setMIFlag(MachineInstr::FrameDestroy);
- }
-}
-
-/// finalizeBundle - Same functionality as the previous finalizeBundle except
-/// the last instruction in the bundle is not provided as an input. This is
-/// used in cases where bundles are pre-determined by marking instructions
-/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
-/// points to the end of the bundle.
-MachineBasicBlock::instr_iterator
-llvm::finalizeBundle(MachineBasicBlock &MBB,
- MachineBasicBlock::instr_iterator FirstMI) {
- MachineBasicBlock::instr_iterator E = MBB.instr_end();
- MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
- while (LastMI != E && LastMI->isInsideBundle())
- ++LastMI;
- finalizeBundle(MBB, FirstMI, LastMI);
- return LastMI;
-}
-
-/// finalizeBundles - Finalize instruction bundles in the specified
-/// MachineFunction. Return true if any bundles are finalized.
-bool llvm::finalizeBundles(MachineFunction &MF) {
- bool Changed = false;
- for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
- MachineBasicBlock &MBB = *I;
- MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
- MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
- if (MII == MIE)
- continue;
- assert(!MII->isInsideBundle() &&
- "First instr cannot be inside bundle before finalization!");
-
- for (++MII; MII != MIE; ) {
- if (!MII->isInsideBundle())
- ++MII;
- else {
- MII = finalizeBundle(MBB, std::prev(MII));
- Changed = true;
- }
- }
- }
-
- return Changed;
-}
-
-VirtRegInfo llvm::AnalyzeVirtRegInBundle(
- MachineInstr &MI, Register Reg,
- SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) {
- VirtRegInfo RI = {false, false, false};
- for (MIBundleOperands O(MI); O.isValid(); ++O) {
- MachineOperand &MO = *O;
- if (!MO.isReg() || MO.getReg() != Reg)
- continue;
-
- // Remember each (MI, OpNo) that refers to Reg.
- if (Ops)
- Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo()));
-
- // Both defs and uses can read virtual registers.
- if (MO.readsReg()) {
- RI.Reads = true;
- if (MO.isDef())
- RI.Tied = true;
- }
-
- // Only defs can write.
- if (MO.isDef())
- RI.Writes = true;
- else if (!RI.Tied &&
- MO.getParent()->isRegTiedToDefOperand(O.getOperandNo()))
- RI.Tied = true;
- }
- return RI;
-}
-
-PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
- const TargetRegisterInfo *TRI) {
- bool AllDefsDead = true;
- PhysRegInfo PRI = {false, false, false, false, false, false, false, false};
-
- assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!");
- for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
- const MachineOperand &MO = *O;
-
- if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {
- PRI.Clobbered = true;
- continue;
- }
-
- if (!MO.isReg())
- continue;
-
- Register MOReg = MO.getReg();
- if (!MOReg || !Register::isPhysicalRegister(MOReg))
- continue;
-
- if (!TRI->regsOverlap(MOReg, Reg))
- continue;
-
- bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
- if (MO.readsReg()) {
- PRI.Read = true;
- if (Covered) {
- PRI.FullyRead = true;
- if (MO.isKill())
- PRI.Killed = true;
- }
- } else if (MO.isDef()) {
- PRI.Defined = true;
- if (Covered)
- PRI.FullyDefined = true;
- if (!MO.isDead())
- AllDefsDead = false;
- }
- }
-
- if (AllDefsDead) {
- if (PRI.FullyDefined || PRI.Clobbered)
- PRI.DeadDef = true;
- else if (PRI.Defined)
- PRI.PartialDeadDef = true;
- }
-
- return PRI;
-}
+//===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineInstrBundle.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Target/TargetMachine.h"
+#include <utility>
+using namespace llvm;
+
+namespace {
+ class UnpackMachineBundles : public MachineFunctionPass {
+ public:
+ static char ID; // Pass identification
+ UnpackMachineBundles(
+ std::function<bool(const MachineFunction &)> Ftor = nullptr)
+ : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
+ initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ private:
+ std::function<bool(const MachineFunction &)> PredicateFtor;
+ };
+} // end anonymous namespace
+
+char UnpackMachineBundles::ID = 0;
+char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
+INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
+ "Unpack machine instruction bundles", false, false)
+
+bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
+ if (PredicateFtor && !PredicateFtor(MF))
+ return false;
+
+ bool Changed = false;
+ for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
+ MachineBasicBlock *MBB = &*I;
+
+ for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
+ MIE = MBB->instr_end(); MII != MIE; ) {
+ MachineInstr *MI = &*MII;
+
+ // Remove BUNDLE instruction and the InsideBundle flags from bundled
+ // instructions.
+ if (MI->isBundle()) {
+ while (++MII != MIE && MII->isBundledWithPred()) {
+ MII->unbundleFromPred();
+ for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MII->getOperand(i);
+ if (MO.isReg() && MO.isInternalRead())
+ MO.setIsInternalRead(false);
+ }
+ }
+ MI->eraseFromParent();
+
+ Changed = true;
+ continue;
+ }
+
+ ++MII;
+ }
+ }
+
+ return Changed;
+}
+
+FunctionPass *
+llvm::createUnpackMachineBundles(
+ std::function<bool(const MachineFunction &)> Ftor) {
+ return new UnpackMachineBundles(std::move(Ftor));
+}
+
+namespace {
+ class FinalizeMachineBundles : public MachineFunctionPass {
+ public:
+ static char ID; // Pass identification
+ FinalizeMachineBundles() : MachineFunctionPass(ID) {
+ initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+ };
+} // end anonymous namespace
+
+char FinalizeMachineBundles::ID = 0;
+char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID;
+INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles",
+ "Finalize machine instruction bundles", false, false)
+
+bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) {
+ return llvm::finalizeBundles(MF);
+}
+
+/// Return the first found DebugLoc that has a DILocation, given a range of
+/// instructions. The search range is from FirstMI to LastMI (exclusive). If no
+/// DILocation is found, then an empty location is returned.
+static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,
+ MachineBasicBlock::instr_iterator LastMI) {
+ for (auto MII = FirstMI; MII != LastMI; ++MII)
+ if (MII->getDebugLoc().get())
+ return MII->getDebugLoc();
+ return DebugLoc();
+}
+
+/// finalizeBundle - Finalize a machine instruction bundle which includes
+/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
+/// This routine adds a BUNDLE instruction to represent the bundle, it adds
+/// IsInternalRead markers to MachineOperands which are defined inside the
+/// bundle, and it copies externally visible defs and uses to the BUNDLE
+/// instruction.
+void llvm::finalizeBundle(MachineBasicBlock &MBB,
+ MachineBasicBlock::instr_iterator FirstMI,
+ MachineBasicBlock::instr_iterator LastMI) {
+ assert(FirstMI != LastMI && "Empty bundle?");
+ MIBundleBuilder Bundle(MBB, FirstMI, LastMI);
+
+ MachineFunction &MF = *MBB.getParent();
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+
+ MachineInstrBuilder MIB =
+ BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE));
+ Bundle.prepend(MIB);
+
+ SmallVector<Register, 32> LocalDefs;
+ SmallSet<Register, 32> LocalDefSet;
+ SmallSet<Register, 8> DeadDefSet;
+ SmallSet<Register, 16> KilledDefSet;
+ SmallVector<Register, 8> ExternUses;
+ SmallSet<Register, 8> ExternUseSet;
+ SmallSet<Register, 8> KilledUseSet;
+ SmallSet<Register, 8> UndefUseSet;
+ SmallVector<MachineOperand*, 4> Defs;
+ for (auto MII = FirstMI; MII != LastMI; ++MII) {
+ for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MII->getOperand(i);
+ if (!MO.isReg())
+ continue;
+ if (MO.isDef()) {
+ Defs.push_back(&MO);
+ continue;
+ }
+
+ Register Reg = MO.getReg();
+ if (!Reg)
+ continue;
+
+ if (LocalDefSet.count(Reg)) {
+ MO.setIsInternalRead();
+ if (MO.isKill())
+ // Internal def is now killed.
+ KilledDefSet.insert(Reg);
+ } else {
+ if (ExternUseSet.insert(Reg).second) {
+ ExternUses.push_back(Reg);
+ if (MO.isUndef())
+ UndefUseSet.insert(Reg);
+ }
+ if (MO.isKill())
+ // External def is now killed.
+ KilledUseSet.insert(Reg);
+ }
+ }
+
+ for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
+ MachineOperand &MO = *Defs[i];
+ Register Reg = MO.getReg();
+ if (!Reg)
+ continue;
+
+ if (LocalDefSet.insert(Reg).second) {
+ LocalDefs.push_back(Reg);
+ if (MO.isDead()) {
+ DeadDefSet.insert(Reg);
+ }
+ } else {
+ // Re-defined inside the bundle, it's no longer killed.
+ KilledDefSet.erase(Reg);
+ if (!MO.isDead())
+ // Previously defined but dead.
+ DeadDefSet.erase(Reg);
+ }
+
+ if (!MO.isDead() && Register::isPhysicalRegister(Reg)) {
+ for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
+ unsigned SubReg = *SubRegs;
+ if (LocalDefSet.insert(SubReg).second)
+ LocalDefs.push_back(SubReg);
+ }
+ }
+ }
+
+ Defs.clear();
+ }
+
+ SmallSet<Register, 32> Added;
+ for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
+ Register Reg = LocalDefs[i];
+ if (Added.insert(Reg).second) {
+ // If it's not live beyond end of the bundle, mark it dead.
+ bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg);
+ MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |
+ getImplRegState(true));
+ }
+ }
+
+ for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) {
+ Register Reg = ExternUses[i];
+ bool isKill = KilledUseSet.count(Reg);
+ bool isUndef = UndefUseSet.count(Reg);
+ MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
+ getImplRegState(true));
+ }
+
+ // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got
+ // the property, then also set it on the bundle.
+ for (auto MII = FirstMI; MII != LastMI; ++MII) {
+ if (MII->getFlag(MachineInstr::FrameSetup))
+ MIB.setMIFlag(MachineInstr::FrameSetup);
+ if (MII->getFlag(MachineInstr::FrameDestroy))
+ MIB.setMIFlag(MachineInstr::FrameDestroy);
+ }
+}
+
+/// finalizeBundle - Same functionality as the previous finalizeBundle except
+/// the last instruction in the bundle is not provided as an input. This is
+/// used in cases where bundles are pre-determined by marking instructions
+/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
+/// points to the end of the bundle.
+MachineBasicBlock::instr_iterator
+llvm::finalizeBundle(MachineBasicBlock &MBB,
+ MachineBasicBlock::instr_iterator FirstMI) {
+ MachineBasicBlock::instr_iterator E = MBB.instr_end();
+ MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
+ while (LastMI != E && LastMI->isInsideBundle())
+ ++LastMI;
+ finalizeBundle(MBB, FirstMI, LastMI);
+ return LastMI;
+}
+
+/// finalizeBundles - Finalize instruction bundles in the specified
+/// MachineFunction. Return true if any bundles are finalized.
+bool llvm::finalizeBundles(MachineFunction &MF) {
+ bool Changed = false;
+ for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
+ MachineBasicBlock &MBB = *I;
+ MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
+ MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
+ if (MII == MIE)
+ continue;
+ assert(!MII->isInsideBundle() &&
+ "First instr cannot be inside bundle before finalization!");
+
+ for (++MII; MII != MIE; ) {
+ if (!MII->isInsideBundle())
+ ++MII;
+ else {
+ MII = finalizeBundle(MBB, std::prev(MII));
+ Changed = true;
+ }
+ }
+ }
+
+ return Changed;
+}
+
+VirtRegInfo llvm::AnalyzeVirtRegInBundle(
+ MachineInstr &MI, Register Reg,
+ SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops) {
+ VirtRegInfo RI = {false, false, false};
+ for (MIBundleOperands O(MI); O.isValid(); ++O) {
+ MachineOperand &MO = *O;
+ if (!MO.isReg() || MO.getReg() != Reg)
+ continue;
+
+ // Remember each (MI, OpNo) that refers to Reg.
+ if (Ops)
+ Ops->push_back(std::make_pair(MO.getParent(), O.getOperandNo()));
+
+ // Both defs and uses can read virtual registers.
+ if (MO.readsReg()) {
+ RI.Reads = true;
+ if (MO.isDef())
+ RI.Tied = true;
+ }
+
+ // Only defs can write.
+ if (MO.isDef())
+ RI.Writes = true;
+ else if (!RI.Tied &&
+ MO.getParent()->isRegTiedToDefOperand(O.getOperandNo()))
+ RI.Tied = true;
+ }
+ return RI;
+}
+
+PhysRegInfo llvm::AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
+ const TargetRegisterInfo *TRI) {
+ bool AllDefsDead = true;
+ PhysRegInfo PRI = {false, false, false, false, false, false, false, false};
+
+ assert(Reg.isPhysical() && "analyzePhysReg not given a physical register!");
+ for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
+ const MachineOperand &MO = *O;
+
+ if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {
+ PRI.Clobbered = true;
+ continue;
+ }
+
+ if (!MO.isReg())
+ continue;
+
+ Register MOReg = MO.getReg();
+ if (!MOReg || !Register::isPhysicalRegister(MOReg))
+ continue;
+
+ if (!TRI->regsOverlap(MOReg, Reg))
+ continue;
+
+ bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
+ if (MO.readsReg()) {
+ PRI.Read = true;
+ if (Covered) {
+ PRI.FullyRead = true;
+ if (MO.isKill())
+ PRI.Killed = true;
+ }
+ } else if (MO.isDef()) {
+ PRI.Defined = true;
+ if (Covered)
+ PRI.FullyDefined = true;
+ if (!MO.isDead())
+ AllDefsDead = false;
+ }
+ }
+
+ if (AllDefsDead) {
+ if (PRI.FullyDefined || PRI.Clobbered)
+ PRI.DeadDef = true;
+ else if (PRI.Defined)
+ PRI.PartialDeadDef = true;
+ }
+
+ return PRI;
+}