LLVM 22.0.0git
ExecutionDomainFix.h
Go to the documentation of this file.
1//==-- llvm/CodeGen/ExecutionDomainFix.h - Execution Domain Fix -*- 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/// \file Execution Domain Fix pass.
10///
11/// Some X86 SSE instructions like mov, and, or, xor are available in different
12/// variants for different operand types. These variant instructions are
13/// equivalent, but on Nehalem and newer cpus there is extra latency
14/// transferring data between integer and floating point domains. ARM cores
15/// have similar issues when they are configured with both VFP and NEON
16/// pipelines.
17///
18/// This pass changes the variant instructions to minimize domain crossings.
19//
20//===----------------------------------------------------------------------===//
21
22#ifndef LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
23#define LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
24
30
31namespace llvm {
32
33class MachineInstr;
34class TargetInstrInfo;
35
36/// A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track
37/// of execution domains.
38///
39/// An open DomainValue represents a set of instructions that can still switch
40/// execution domain. Multiple registers may refer to the same open
41/// DomainValue - they will eventually be collapsed to the same execution
42/// domain.
43///
44/// A collapsed DomainValue represents a single register that has been forced
45/// into one of more execution domains. There is a separate collapsed
46/// DomainValue for each register, but it may contain multiple execution
47/// domains. A register value is initially created in a single execution
48/// domain, but if we were forced to pay the penalty of a domain crossing, we
49/// keep track of the fact that the register is now available in multiple
50/// domains.
52 /// Basic reference counting.
53 unsigned Refs = 0;
54
55 /// Bitmask of available domains. For an open DomainValue, it is the still
56 /// possible domains for collapsing. For a collapsed DomainValue it is the
57 /// domains where the register is available for free.
59
60 /// Pointer to the next DomainValue in a chain. When two DomainValues are
61 /// merged, Victim.Next is set to point to Victor, so old DomainValue
62 /// references can be updated by following the chain.
64
65 /// Twiddleable instructions using or defining these registers.
67
69
70 /// A collapsed DomainValue has no instructions to twiddle - it simply keeps
71 /// track of the domains where the registers are already available.
72 bool isCollapsed() const { return Instrs.empty(); }
73
74 /// Is domain available?
75 bool hasDomain(unsigned domain) const {
76 assert(domain <
77 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
78 "undefined behavior");
79 return AvailableDomains & (1u << domain);
80 }
81
82 /// Mark domain as available.
83 void addDomain(unsigned domain) {
84 assert(domain <
85 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
86 "undefined behavior");
87 AvailableDomains |= 1u << domain;
88 }
89
90 // Restrict to a single domain available.
91 void setSingleDomain(unsigned domain) {
92 assert(domain <
93 static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
94 "undefined behavior");
95 AvailableDomains = 1u << domain;
96 }
97
98 /// Return bitmask of domains that are available and in mask.
99 unsigned getCommonDomains(unsigned mask) const {
100 return AvailableDomains & mask;
101 }
102
103 /// First domain available.
104 unsigned getFirstDomain() const {
106 }
107
108 /// Clear this DomainValue and point to next which has all its data.
109 void clear() {
111 Next = nullptr;
112 Instrs.clear();
113 }
114};
115
119
120 const TargetRegisterClass *const RC;
121 MachineFunction *MF = nullptr;
122 const TargetInstrInfo *TII = nullptr;
123 const TargetRegisterInfo *TRI = nullptr;
124 std::vector<SmallVector<int, 1>> AliasMap;
125 const unsigned NumRegs;
126 /// Value currently in each register, or NULL when no value is being tracked.
127 /// This counts as a DomainValue reference.
128 using LiveRegsDVInfo = std::vector<DomainValue *>;
129 LiveRegsDVInfo LiveRegs;
130 /// Keeps domain information for all registers. Note that this
131 /// is different from the usual definition notion of liveness. The CPU
132 /// doesn't care whether or not we consider a register killed.
134 OutRegsInfoMap MBBOutRegsInfos;
135
136 ReachingDefAnalysis *RDA = nullptr;
137
138public:
140 : MachineFunctionPass(PassID), RC(&RC), NumRegs(RC.getNumRegs()) {}
141
142 void getAnalysisUsage(AnalysisUsage &AU) const override {
143 AU.setPreservesAll();
146 }
147
148 bool runOnMachineFunction(MachineFunction &MF) override;
149
151 return MachineFunctionProperties().setNoVRegs();
152 }
153
154private:
155 /// Translate TRI register number to a list of indices into our smaller tables
156 /// of interesting registers.
158 regIndices(MCRegister Reg) const;
159
160 /// DomainValue allocation.
161 DomainValue *alloc(int domain = -1);
162
163 /// Add reference to DV.
164 DomainValue *retain(DomainValue *DV) {
165 if (DV)
166 ++DV->Refs;
167 return DV;
168 }
169
170 /// Release a reference to DV. When the last reference is released,
171 /// collapse if needed.
172 void release(DomainValue *);
173
174 /// Follow the chain of dead DomainValues until a live DomainValue is reached.
175 /// Update the referenced pointer when necessary.
176 DomainValue *resolve(DomainValue *&);
177
178 /// Set LiveRegs[rx] = dv, updating reference counts.
179 void setLiveReg(int rx, DomainValue *DV);
180
181 /// Kill register rx, recycle or collapse any DomainValue.
182 void kill(int rx);
183
184 /// Force register rx into domain.
185 void force(int rx, unsigned domain);
186
187 /// Collapse open DomainValue into given domain. If there are multiple
188 /// registers using dv, they each get a unique collapsed DomainValue.
189 void collapse(DomainValue *dv, unsigned domain);
190
191 /// All instructions and registers in B are moved to A, and B is released.
192 bool merge(DomainValue *A, DomainValue *B);
193
194 /// Set up LiveRegs by merging predecessor live-out values.
195 void enterBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
196
197 /// Update live-out values.
198 void leaveBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
199
200 /// Process he given basic block.
201 void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
202
203 /// Visit given insturcion.
204 bool visitInstr(MachineInstr *);
205
206 /// Update def-ages for registers defined by MI.
207 /// If Kill is set, also kill off DomainValues clobbered by the defs.
208 void processDefs(MachineInstr *, bool Kill);
209
210 /// A soft instruction can be changed to work in other domains given by mask.
211 void visitSoftInstr(MachineInstr *, unsigned mask);
212
213 /// A hard instruction only works in one domain. All input registers will be
214 /// forced into that domain.
215 void visitHardInstr(MachineInstr *, unsigned domain);
216};
217
218} // namespace llvm
219
220#endif // LLVM_CODEGEN_EXECUTIONDOMAINFIX_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Register Reg
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
ExecutionDomainFix(char &PassID, const TargetRegisterClass &RC)
MachineFunctionProperties getRequiredProperties() const override
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Properties which a MachineFunction may have at a given point in time.
This class provides the reaching def analysis.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Definition: Allocator.h:390
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
A range adaptor for a pair of iterators.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: bit.h:157
A DomainValue is a bit like LiveIntervals' ValNo, but it also keeps track of execution domains.
unsigned getCommonDomains(unsigned mask) const
Return bitmask of domains that are available and in mask.
void clear()
Clear this DomainValue and point to next which has all its data.
SmallVector< MachineInstr *, 8 > Instrs
Twiddleable instructions using or defining these registers.
void setSingleDomain(unsigned domain)
bool isCollapsed() const
A collapsed DomainValue has no instructions to twiddle - it simply keeps track of the domains where t...
DomainValue * Next
Pointer to the next DomainValue in a chain.
void addDomain(unsigned domain)
Mark domain as available.
unsigned AvailableDomains
Bitmask of available domains.
unsigned Refs
Basic reference counting.
unsigned getFirstDomain() const
First domain available.
bool hasDomain(unsigned domain) const
Is domain available?