1 | //===- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-===// |
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 | // This file implements the AntiDepBreaker class, which implements |
10 | // anti-dependence breaking heuristics for post-register-allocation scheduling. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_CODEGEN_ANTIDEPBREAKER_H |
15 | #define LLVM_CODEGEN_ANTIDEPBREAKER_H |
16 | |
17 | #include "llvm/ADT/iterator_range.h" |
18 | #include "llvm/CodeGen/MachineBasicBlock.h" |
19 | #include "llvm/CodeGen/MachineInstr.h" |
20 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
21 | #include "llvm/Support/Compiler.h" |
22 | #include <utility> |
23 | #include <vector> |
24 | |
25 | namespace llvm { |
26 | |
27 | class RegisterClassInfo; |
28 | |
29 | /// This class works in conjunction with the post-RA scheduler to rename |
30 | /// registers to break register anti-dependencies (WAR hazards). |
31 | class AntiDepBreaker { |
32 | public: |
33 | using DbgValueVector = |
34 | std::vector<std::pair<MachineInstr *, MachineInstr *>>; |
35 | |
36 | virtual ~AntiDepBreaker(); |
37 | |
38 | /// Initialize anti-dep breaking for a new basic block. |
39 | virtual void StartBlock(MachineBasicBlock *BB) = 0; |
40 | |
41 | /// Identifiy anti-dependencies within a basic-block region and break them by |
42 | /// renaming registers. Return the number of anti-dependencies broken. |
43 | virtual unsigned BreakAntiDependencies(const std::vector<SUnit> &SUnits, |
44 | MachineBasicBlock::iterator Begin, |
45 | MachineBasicBlock::iterator End, |
46 | unsigned InsertPosIndex, |
47 | DbgValueVector &DbgValues) = 0; |
48 | |
49 | /// Update liveness information to account for the current |
50 | /// instruction, which will not be scheduled. |
51 | virtual void Observe(MachineInstr &MI, unsigned Count, |
52 | unsigned InsertPosIndex) = 0; |
53 | |
54 | /// Finish anti-dep breaking for a basic block. |
55 | virtual void FinishBlock() = 0; |
56 | |
57 | /// Update DBG_VALUE or DBG_PHI if dependency breaker is updating |
58 | /// other machine instruction to use NewReg. |
59 | void UpdateDbgValue(MachineInstr &MI, unsigned OldReg, unsigned NewReg) { |
60 | if (MI.isDebugValue()) { |
61 | if (MI.getDebugOperand(Index: 0).isReg() && |
62 | MI.getDebugOperand(Index: 0).getReg() == OldReg) |
63 | MI.getDebugOperand(Index: 0).setReg(NewReg); |
64 | } else if (MI.isDebugPHI()) { |
65 | if (MI.getOperand(i: 0).isReg() && |
66 | MI.getOperand(i: 0).getReg() == OldReg) |
67 | MI.getOperand(i: 0).setReg(NewReg); |
68 | } else { |
69 | llvm_unreachable("MI is not DBG_VALUE / DBG_PHI!" ); |
70 | } |
71 | } |
72 | |
73 | /// Update all DBG_VALUE instructions that may be affected by the dependency |
74 | /// breaker's update of ParentMI to use NewReg. |
75 | void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI, |
76 | unsigned OldReg, unsigned NewReg) { |
77 | // The following code is dependent on the order in which the DbgValues are |
78 | // constructed in ScheduleDAGInstrs::buildSchedGraph. |
79 | MachineInstr *PrevDbgMI = nullptr; |
80 | for (const auto &DV : make_range(x: DbgValues.crbegin(), y: DbgValues.crend())) { |
81 | MachineInstr *PrevMI = DV.second; |
82 | if ((PrevMI == ParentMI) || (PrevMI == PrevDbgMI)) { |
83 | MachineInstr *DbgMI = DV.first; |
84 | UpdateDbgValue(MI&: *DbgMI, OldReg, NewReg); |
85 | PrevDbgMI = DbgMI; |
86 | } else if (PrevDbgMI) { |
87 | break; // If no match and already found a DBG_VALUE, we're done. |
88 | } |
89 | } |
90 | } |
91 | }; |
92 | |
93 | AntiDepBreaker *createAggressiveAntiDepBreaker( |
94 | MachineFunction &MFi, const RegisterClassInfo &RCI, |
95 | TargetSubtargetInfo::RegClassVector &CriticalPathRCs); |
96 | |
97 | AntiDepBreaker *createCriticalAntiDepBreaker(MachineFunction &MFi, |
98 | const RegisterClassInfo &RCI); |
99 | |
100 | } // end namespace llvm |
101 | |
102 | #endif // LLVM_CODEGEN_ANTIDEPBREAKER_H |
103 | |