LLVM  12.0.0git
SILowerSGPRSpills.cpp
Go to the documentation of this file.
1 //===-- SILowerSGPRSPills.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Handle SGPR spills. This pass takes the place of PrologEpilogInserter for all
10 // SGPR spills, so must insert CSR SGPR spills as well as expand them.
11 //
12 // This pass must never create new SGPR virtual registers.
13 //
14 // FIXME: Must stop RegScavenger spills in later passes.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #include "AMDGPU.h"
19 #include "AMDGPUSubtarget.h"
20 #include "SIMachineFunctionInfo.h"
23 #include "llvm/InitializePasses.h"
24 
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "si-lower-sgpr-spills"
28 
30 
31 namespace {
32 
33 static cl::opt<bool> EnableSpillVGPRToAGPR(
34  "amdgpu-spill-vgpr-to-agpr",
35  cl::desc("Enable spilling VGPRs to AGPRs"),
37  cl::init(true));
38 
39 class SILowerSGPRSpills : public MachineFunctionPass {
40 private:
41  const SIRegisterInfo *TRI = nullptr;
42  const SIInstrInfo *TII = nullptr;
43  VirtRegMap *VRM = nullptr;
44  LiveIntervals *LIS = nullptr;
45 
46  // Save and Restore blocks of the current function. Typically there is a
47  // single save block, unless Windows EH funclets are involved.
48  MBBVector SaveBlocks;
49  MBBVector RestoreBlocks;
50 
51 public:
52  static char ID;
53 
54  SILowerSGPRSpills() : MachineFunctionPass(ID) {}
55 
56  void calculateSaveRestoreBlocks(MachineFunction &MF);
57  bool spillCalleeSavedRegs(MachineFunction &MF);
58 
59  bool runOnMachineFunction(MachineFunction &MF) override;
60 
61  void getAnalysisUsage(AnalysisUsage &AU) const override {
62  AU.setPreservesAll();
64  }
65 };
66 
67 } // end anonymous namespace
68 
69 char SILowerSGPRSpills::ID = 0;
70 
71 INITIALIZE_PASS_BEGIN(SILowerSGPRSpills, DEBUG_TYPE,
72  "SI lower SGPR spill instructions", false, false)
74 INITIALIZE_PASS_END(SILowerSGPRSpills, DEBUG_TYPE,
75  "SI lower SGPR spill instructions", false, false)
76 
77 char &llvm::SILowerSGPRSpillsID = SILowerSGPRSpills::ID;
78 
79 /// Insert restore code for the callee-saved registers used in the function.
80 static void insertCSRSaves(MachineBasicBlock &SaveBlock,
82  LiveIntervals *LIS) {
83  MachineFunction &MF = *SaveBlock.getParent();
87 
88  MachineBasicBlock::iterator I = SaveBlock.begin();
89  if (!TFI->spillCalleeSavedRegisters(SaveBlock, I, CSI, TRI)) {
90  for (const CalleeSavedInfo &CS : CSI) {
91  // Insert the spill to the stack frame.
92  MCRegister Reg = CS.getReg();
93 
94  MachineInstrSpan MIS(I, &SaveBlock);
95  const TargetRegisterClass *RC =
96  TRI->getMinimalPhysRegClass(Reg, MVT::i32);
97 
98  TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC,
99  TRI);
100 
101  if (LIS) {
102  assert(std::distance(MIS.begin(), I) == 1);
103  MachineInstr &Inst = *std::prev(I);
104 
105  LIS->InsertMachineInstrInMaps(Inst);
106  LIS->removeAllRegUnitsForPhysReg(Reg);
107  }
108  }
109  }
110 }
111 
112 /// Insert restore code for the callee-saved registers used in the function.
113 static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
115  LiveIntervals *LIS) {
116  MachineFunction &MF = *RestoreBlock.getParent();
117  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
120 
121  // Restore all registers immediately before the return and any
122  // terminators that precede it.
124 
125  // FIXME: Just emit the readlane/writelane directly
126  if (!TFI->restoreCalleeSavedRegisters(RestoreBlock, I, CSI, TRI)) {
127  for (const CalleeSavedInfo &CI : reverse(CSI)) {
128  unsigned Reg = CI.getReg();
129  const TargetRegisterClass *RC =
130  TRI->getMinimalPhysRegClass(Reg, MVT::i32);
131 
132  TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI);
133  assert(I != RestoreBlock.begin() &&
134  "loadRegFromStackSlot didn't insert any code!");
135  // Insert in reverse order. loadRegFromStackSlot can insert
136  // multiple instructions.
137 
138  if (LIS) {
139  MachineInstr &Inst = *std::prev(I);
140  LIS->InsertMachineInstrInMaps(Inst);
142  }
143  }
144  }
145 }
146 
147 /// Compute the sets of entry and return blocks for saving and restoring
148 /// callee-saved registers, and placing prolog and epilog code.
149 void SILowerSGPRSpills::calculateSaveRestoreBlocks(MachineFunction &MF) {
150  const MachineFrameInfo &MFI = MF.getFrameInfo();
151 
152  // Even when we do not change any CSR, we still want to insert the
153  // prologue and epilogue of the function.
154  // So set the save points for those.
155 
156  // Use the points found by shrink-wrapping, if any.
157  if (MFI.getSavePoint()) {
158  SaveBlocks.push_back(MFI.getSavePoint());
159  assert(MFI.getRestorePoint() && "Both restore and save must be set");
160  MachineBasicBlock *RestoreBlock = MFI.getRestorePoint();
161  // If RestoreBlock does not have any successor and is not a return block
162  // then the end point is unreachable and we do not need to insert any
163  // epilogue.
164  if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
165  RestoreBlocks.push_back(RestoreBlock);
166  return;
167  }
168 
169  // Save refs to entry and return blocks.
170  SaveBlocks.push_back(&MF.front());
171  for (MachineBasicBlock &MBB : MF) {
172  if (MBB.isEHFuncletEntry())
173  SaveBlocks.push_back(&MBB);
174  if (MBB.isReturnBlock())
175  RestoreBlocks.push_back(&MBB);
176  }
177 }
178 
179 // TODO: To support shrink wrapping, this would need to copy
180 // PrologEpilogInserter's updateLiveness.
182  MachineBasicBlock &EntryBB = MF.front();
183 
184  for (const CalleeSavedInfo &CSIReg : CSI)
185  EntryBB.addLiveIn(CSIReg.getReg());
186  EntryBB.sortUniqueLiveIns();
187 }
188 
189 bool SILowerSGPRSpills::spillCalleeSavedRegs(MachineFunction &MF) {
191  const Function &F = MF.getFunction();
192  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
193  const SIFrameLowering *TFI = ST.getFrameLowering();
194  MachineFrameInfo &MFI = MF.getFrameInfo();
195  RegScavenger *RS = nullptr;
196 
197  // Determine which of the registers in the callee save list should be saved.
198  BitVector SavedRegs;
199  TFI->determineCalleeSavesSGPR(MF, SavedRegs, RS);
200 
201  // Add the code to save and restore the callee saved registers.
202  if (!F.hasFnAttribute(Attribute::Naked)) {
203  // FIXME: This is a lie. The CalleeSavedInfo is incomplete, but this is
204  // necessary for verifier liveness checks.
205  MFI.setCalleeSavedInfoValid(true);
206 
207  std::vector<CalleeSavedInfo> CSI;
208  const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
209 
210  for (unsigned I = 0; CSRegs[I]; ++I) {
211  MCRegister Reg = CSRegs[I];
212 
213  if (SavedRegs.test(Reg)) {
214  const TargetRegisterClass *RC =
215  TRI->getMinimalPhysRegClass(Reg, MVT::i32);
216  int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
217  TRI->getSpillAlign(*RC), true);
218 
219  CSI.push_back(CalleeSavedInfo(Reg, JunkFI));
220  }
221  }
222 
223  if (!CSI.empty()) {
224  for (MachineBasicBlock *SaveBlock : SaveBlocks)
225  insertCSRSaves(*SaveBlock, CSI, LIS);
226 
227  // Add live ins to save blocks.
228  assert(SaveBlocks.size() == 1 && "shrink wrapping not fully implemented");
229  updateLiveness(MF, CSI);
230 
231  for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
232  insertCSRRestores(*RestoreBlock, CSI, LIS);
233  return true;
234  }
235  }
236 
237  return false;
238 }
239 
240 // Find lowest available VGPR and use it as VGPR reserved for SGPR spills.
242  const GCNSubtarget &ST) {
244  const Register PreReservedVGPR = FuncInfo->VGPRReservedForSGPRSpill;
245  // Early out if pre-reservation of a VGPR for SGPR spilling is disabled.
246  if (!PreReservedVGPR)
247  return false;
248 
249  // If there are no free lower VGPRs available, default to using the
250  // pre-reserved register instead.
251  const SIRegisterInfo *TRI = ST.getRegisterInfo();
252  Register LowestAvailableVGPR =
253  TRI->findUnusedRegister(MF.getRegInfo(), &AMDGPU::VGPR_32RegClass, MF);
254  if (!LowestAvailableVGPR)
255  LowestAvailableVGPR = PreReservedVGPR;
256 
257  const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
258  MachineFrameInfo &FrameInfo = MF.getFrameInfo();
259  Optional<int> FI;
260  // Check if we are reserving a CSR. Create a stack object for a possible spill
261  // in the function prologue.
262  if (FuncInfo->isCalleeSavedReg(CSRegs, LowestAvailableVGPR))
263  FI = FrameInfo.CreateSpillStackObject(4, Align(4));
264 
265  // Find saved info about the pre-reserved register.
266  const auto *ReservedVGPRInfoItr =
267  llvm::find_if(FuncInfo->getSGPRSpillVGPRs(),
268  [PreReservedVGPR](const auto &SpillRegInfo) {
269  return SpillRegInfo.VGPR == PreReservedVGPR;
270  });
271 
272  assert(ReservedVGPRInfoItr != FuncInfo->getSGPRSpillVGPRs().end());
273  auto Index =
274  std::distance(FuncInfo->getSGPRSpillVGPRs().begin(), ReservedVGPRInfoItr);
275 
276  FuncInfo->setSGPRSpillVGPRs(LowestAvailableVGPR, FI, Index);
277 
278  for (MachineBasicBlock &MBB : MF) {
279  assert(LowestAvailableVGPR.isValid() && "Did not find an available VGPR");
280  MBB.addLiveIn(LowestAvailableVGPR);
282  }
283 
284  return true;
285 }
286 
287 bool SILowerSGPRSpills::runOnMachineFunction(MachineFunction &MF) {
288  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
289  TII = ST.getInstrInfo();
290  TRI = &TII->getRegisterInfo();
291 
292  VRM = getAnalysisIfAvailable<VirtRegMap>();
293 
294  assert(SaveBlocks.empty() && RestoreBlocks.empty());
295 
296  // First, expose any CSR SGPR spills. This is mostly the same as what PEI
297  // does, but somewhat simpler.
298  calculateSaveRestoreBlocks(MF);
299  bool HasCSRs = spillCalleeSavedRegs(MF);
300 
301  MachineFrameInfo &MFI = MF.getFrameInfo();
302  if (!MFI.hasStackObjects() && !HasCSRs) {
303  SaveBlocks.clear();
304  RestoreBlocks.clear();
305  return false;
306  }
307 
310  const bool SpillVGPRToAGPR = ST.hasMAIInsts() && FuncInfo->hasSpilledVGPRs()
311  && EnableSpillVGPRToAGPR;
312 
313  bool MadeChange = false;
314 
315  const bool SpillToAGPR = EnableSpillVGPRToAGPR && ST.hasMAIInsts();
316  std::unique_ptr<RegScavenger> RS;
317 
318  bool NewReservedRegs = false;
319 
320  // TODO: CSR VGPRs will never be spilled to AGPRs. These can probably be
321  // handled as SpilledToReg in regular PrologEpilogInserter.
322  const bool HasSGPRSpillToVGPR = TRI->spillSGPRToVGPR() &&
323  (HasCSRs || FuncInfo->hasSpilledSGPRs());
324  if (HasSGPRSpillToVGPR || SpillVGPRToAGPR) {
325  // Process all SGPR spills before frame offsets are finalized. Ideally SGPRs
326  // are spilled to VGPRs, in which case we can eliminate the stack usage.
327  //
328  // This operates under the assumption that only other SGPR spills are users
329  // of the frame index.
330 
332 
333  for (MachineBasicBlock &MBB : MF) {
335  for (auto I = MBB.begin(), E = MBB.end(); I != E; I = Next) {
336  MachineInstr &MI = *I;
337  Next = std::next(I);
338 
339  if (SpillToAGPR && TII->isVGPRSpill(MI)) {
340  // Try to eliminate stack used by VGPR spills before frame
341  // finalization.
342  unsigned FIOp = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
343  AMDGPU::OpName::vaddr);
344  int FI = MI.getOperand(FIOp).getIndex();
345  Register VReg =
346  TII->getNamedOperand(MI, AMDGPU::OpName::vdata)->getReg();
347  if (FuncInfo->allocateVGPRSpillToAGPR(MF, FI,
348  TRI->isAGPR(MRI, VReg))) {
349  NewReservedRegs = true;
350  if (!RS)
351  RS.reset(new RegScavenger());
352 
353  // FIXME: change to enterBasicBlockEnd()
354  RS->enterBasicBlock(MBB);
355  TRI->eliminateFrameIndex(MI, 0, FIOp, RS.get());
356  continue;
357  }
358  }
359 
360  if (!TII->isSGPRSpill(MI))
361  continue;
362 
363  int FI = TII->getNamedOperand(MI, AMDGPU::OpName::addr)->getIndex();
365  if (FuncInfo->allocateSGPRSpillToVGPR(MF, FI)) {
366  NewReservedRegs = true;
367  bool Spilled = TRI->eliminateSGPRToVGPRSpillFrameIndex(MI, FI, nullptr);
368  (void)Spilled;
369  assert(Spilled && "failed to spill SGPR to VGPR when allocated");
370  }
371  }
372  }
373 
374  for (MachineBasicBlock &MBB : MF) {
375  for (auto SSpill : FuncInfo->getSGPRSpillVGPRs())
376  MBB.addLiveIn(SSpill.VGPR);
377 
378  for (MCPhysReg Reg : FuncInfo->getVGPRSpillAGPRs())
379  MBB.addLiveIn(Reg);
380 
381  for (MCPhysReg Reg : FuncInfo->getAGPRSpillVGPRs())
382  MBB.addLiveIn(Reg);
383 
385  }
386 
387  MadeChange = true;
388  } else if (FuncInfo->VGPRReservedForSGPRSpill) {
389  FuncInfo->removeVGPRForSGPRSpill(FuncInfo->VGPRReservedForSGPRSpill, MF);
390  }
391 
392  SaveBlocks.clear();
393  RestoreBlocks.clear();
394 
395  // Updated the reserved registers with any VGPRs added for SGPR spills.
396  if (NewReservedRegs)
397  MRI.freezeReservedRegs(MF);
398 
399  return MadeChange;
400 }
bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR)
Reserve AGPRs or VGPRs to support spilling for FrameIndex FI.
AMDGPU specific subclass of TargetSubtarget.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:22
void setCalleeSavedInfoValid(bool v)
This class represents lattice values for constants.
Definition: AllocatorList.h:23
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool hasStackObjects() const
Return true if there are any stack objects in this function.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned Reg
bool test(unsigned Idx) const
Definition: BitVector.h:484
unsigned const TargetRegisterInfo * TRI
F(f)
static void updateLiveness(MachineFunction &MF, ArrayRef< CalleeSavedInfo > CSI)
bool removeVGPRForSGPRSpill(Register ReservedVGPR, MachineFunction &MF)
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineBasicBlock & MBB
MachineInstrSpan provides an interface to get an iteration range containing the instruction it was in...
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
ArrayRef< MCPhysReg > getAGPRSpillVGPRs() const
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
MachineBasicBlock * getRestorePoint() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool isCalleeSavedReg(const MCPhysReg *CSRegs, MCPhysReg Reg)
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
virtual const TargetInstrInfo * getInstrInfo() const
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI)
Reserve a slice of a VGPR to support spilling for FrameIndex FI.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition: MCRegister.h:19
TargetInstrInfo - Interface to description of machine instruction set.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:427
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:298
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static void insertCSRRestores(MachineBasicBlock &RestoreBlock, MutableArrayRef< CalleeSavedInfo > CSI, LiveIntervals *LIS)
Insert restore code for the callee-saved registers used in the function.
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static void insertCSRSaves(MachineBasicBlock &SaveBlock, ArrayRef< CalleeSavedInfo > CSI, LiveIntervals *LIS)
Insert restore code for the callee-saved registers used in the function.
#define DEBUG_TYPE
void setSGPRSpillVGPRs(Register NewVGPR, Optional< int > newFI, int Index)
ArrayRef< SGPRSpillVGPRCSR > getSGPRSpillVGPRs() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1116
uint32_t Index
Information about stack frame layout on the target.
void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
void setPreservesAll()
Set by analyses that do not transform their input at all.
char & SILowerSGPRSpillsID
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isValid() const
Definition: Register.h:126
Representation of each machine instruction.
Definition: MachineInstr.h:62
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Load the specified register of the given register class from the specified stack frame index.
void push_back(MachineInstr *MI)
#define I(x, y, z)
Definition: MD5.cpp:59
virtual const TargetFrameLowering * getFrameLowering() const
static bool lowerShiftReservedVGPR(MachineFunction &MF, const GCNSubtarget &ST)
uint8_t getStackID(int ObjectIdx) const
MachineBasicBlock * getSavePoint() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
INITIALIZE_PASS_BEGIN(SILowerSGPRSpills, DEBUG_TYPE, "SI lower SGPR spill instructions", false, false) INITIALIZE_PASS_END(SILowerSGPRSpills
IRTranslator LLVM IR MI
inst_range instructions(Function *F)
Definition: InstIterator.h:133
ArrayRef< MCPhysReg > getVGPRSpillAGPRs() const
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:338
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1525
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Store the specified register of the given register class to the specified stack frame index.
MachineBasicBlock::iterator begin()
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)