xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonGenInsert.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- HexagonGenInsert.cpp ---------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "hexinsert"
11*9880d681SAndroid Build Coastguard Worker 
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/PostOrderIterator.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/PassRegistry.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Timer.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker #include "Hexagon.h"
31*9880d681SAndroid Build Coastguard Worker #include "HexagonRegisterInfo.h"
32*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetMachine.h"
33*9880d681SAndroid Build Coastguard Worker #include "HexagonBitTracker.h"
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker #include <vector>
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker using namespace llvm;
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned> VRegIndexCutoff("insert-vreg-cutoff", cl::init(~0U),
40*9880d681SAndroid Build Coastguard Worker   cl::Hidden, cl::ZeroOrMore, cl::desc("Vreg# cutoff for insert generation."));
41*9880d681SAndroid Build Coastguard Worker // The distance cutoff is selected based on the precheckin-perf results:
42*9880d681SAndroid Build Coastguard Worker // cutoffs 20, 25, 35, and 40 are worse than 30.
43*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned> VRegDistCutoff("insert-dist-cutoff", cl::init(30U),
44*9880d681SAndroid Build Coastguard Worker   cl::Hidden, cl::ZeroOrMore, cl::desc("Vreg distance cutoff for insert "
45*9880d681SAndroid Build Coastguard Worker   "generation."));
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> OptTiming("insert-timing", cl::init(false), cl::Hidden,
48*9880d681SAndroid Build Coastguard Worker   cl::ZeroOrMore, cl::desc("Enable timing of insert generation"));
49*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> OptTimingDetail("insert-timing-detail", cl::init(false),
50*9880d681SAndroid Build Coastguard Worker   cl::Hidden, cl::ZeroOrMore, cl::desc("Enable detailed timing of insert "
51*9880d681SAndroid Build Coastguard Worker   "generation"));
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> OptSelectAll0("insert-all0", cl::init(false), cl::Hidden,
54*9880d681SAndroid Build Coastguard Worker   cl::ZeroOrMore);
55*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> OptSelectHas0("insert-has0", cl::init(false), cl::Hidden,
56*9880d681SAndroid Build Coastguard Worker   cl::ZeroOrMore);
57*9880d681SAndroid Build Coastguard Worker // Whether to construct constant values via "insert". Could eliminate constant
58*9880d681SAndroid Build Coastguard Worker // extenders, but often not practical.
59*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> OptConst("insert-const", cl::init(false), cl::Hidden,
60*9880d681SAndroid Build Coastguard Worker   cl::ZeroOrMore);
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker namespace {
63*9880d681SAndroid Build Coastguard Worker   // The preprocessor gets confused when the DEBUG macro is passed larger
64*9880d681SAndroid Build Coastguard Worker   // chunks of code. Use this function to detect debugging.
isDebug()65*9880d681SAndroid Build Coastguard Worker   inline bool isDebug() {
66*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
67*9880d681SAndroid Build Coastguard Worker     return ::llvm::DebugFlag && ::llvm::isCurrentDebugType(DEBUG_TYPE);
68*9880d681SAndroid Build Coastguard Worker #else
69*9880d681SAndroid Build Coastguard Worker     return false;
70*9880d681SAndroid Build Coastguard Worker #endif
71*9880d681SAndroid Build Coastguard Worker   }
72*9880d681SAndroid Build Coastguard Worker }
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker namespace {
76*9880d681SAndroid Build Coastguard Worker   // Set of virtual registers, based on BitVector.
77*9880d681SAndroid Build Coastguard Worker   struct RegisterSet : private BitVector {
78*9880d681SAndroid Build Coastguard Worker     RegisterSet() = default;
RegisterSet__anon55633e700211::RegisterSet79*9880d681SAndroid Build Coastguard Worker     explicit RegisterSet(unsigned s, bool t = false) : BitVector(s, t) {}
80*9880d681SAndroid Build Coastguard Worker 
81*9880d681SAndroid Build Coastguard Worker     using BitVector::clear;
82*9880d681SAndroid Build Coastguard Worker 
find_first__anon55633e700211::RegisterSet83*9880d681SAndroid Build Coastguard Worker     unsigned find_first() const {
84*9880d681SAndroid Build Coastguard Worker       int First = BitVector::find_first();
85*9880d681SAndroid Build Coastguard Worker       if (First < 0)
86*9880d681SAndroid Build Coastguard Worker         return 0;
87*9880d681SAndroid Build Coastguard Worker       return x2v(First);
88*9880d681SAndroid Build Coastguard Worker     }
89*9880d681SAndroid Build Coastguard Worker 
find_next__anon55633e700211::RegisterSet90*9880d681SAndroid Build Coastguard Worker     unsigned find_next(unsigned Prev) const {
91*9880d681SAndroid Build Coastguard Worker       int Next = BitVector::find_next(v2x(Prev));
92*9880d681SAndroid Build Coastguard Worker       if (Next < 0)
93*9880d681SAndroid Build Coastguard Worker         return 0;
94*9880d681SAndroid Build Coastguard Worker       return x2v(Next);
95*9880d681SAndroid Build Coastguard Worker     }
96*9880d681SAndroid Build Coastguard Worker 
insert__anon55633e700211::RegisterSet97*9880d681SAndroid Build Coastguard Worker     RegisterSet &insert(unsigned R) {
98*9880d681SAndroid Build Coastguard Worker       unsigned Idx = v2x(R);
99*9880d681SAndroid Build Coastguard Worker       ensure(Idx);
100*9880d681SAndroid Build Coastguard Worker       return static_cast<RegisterSet&>(BitVector::set(Idx));
101*9880d681SAndroid Build Coastguard Worker     }
remove__anon55633e700211::RegisterSet102*9880d681SAndroid Build Coastguard Worker     RegisterSet &remove(unsigned R) {
103*9880d681SAndroid Build Coastguard Worker       unsigned Idx = v2x(R);
104*9880d681SAndroid Build Coastguard Worker       if (Idx >= size())
105*9880d681SAndroid Build Coastguard Worker         return *this;
106*9880d681SAndroid Build Coastguard Worker       return static_cast<RegisterSet&>(BitVector::reset(Idx));
107*9880d681SAndroid Build Coastguard Worker     }
108*9880d681SAndroid Build Coastguard Worker 
insert__anon55633e700211::RegisterSet109*9880d681SAndroid Build Coastguard Worker     RegisterSet &insert(const RegisterSet &Rs) {
110*9880d681SAndroid Build Coastguard Worker       return static_cast<RegisterSet&>(BitVector::operator|=(Rs));
111*9880d681SAndroid Build Coastguard Worker     }
remove__anon55633e700211::RegisterSet112*9880d681SAndroid Build Coastguard Worker     RegisterSet &remove(const RegisterSet &Rs) {
113*9880d681SAndroid Build Coastguard Worker       return static_cast<RegisterSet&>(BitVector::reset(Rs));
114*9880d681SAndroid Build Coastguard Worker     }
115*9880d681SAndroid Build Coastguard Worker 
operator []__anon55633e700211::RegisterSet116*9880d681SAndroid Build Coastguard Worker     reference operator[](unsigned R) {
117*9880d681SAndroid Build Coastguard Worker       unsigned Idx = v2x(R);
118*9880d681SAndroid Build Coastguard Worker       ensure(Idx);
119*9880d681SAndroid Build Coastguard Worker       return BitVector::operator[](Idx);
120*9880d681SAndroid Build Coastguard Worker     }
operator []__anon55633e700211::RegisterSet121*9880d681SAndroid Build Coastguard Worker     bool operator[](unsigned R) const {
122*9880d681SAndroid Build Coastguard Worker       unsigned Idx = v2x(R);
123*9880d681SAndroid Build Coastguard Worker       assert(Idx < size());
124*9880d681SAndroid Build Coastguard Worker       return BitVector::operator[](Idx);
125*9880d681SAndroid Build Coastguard Worker     }
has__anon55633e700211::RegisterSet126*9880d681SAndroid Build Coastguard Worker     bool has(unsigned R) const {
127*9880d681SAndroid Build Coastguard Worker       unsigned Idx = v2x(R);
128*9880d681SAndroid Build Coastguard Worker       if (Idx >= size())
129*9880d681SAndroid Build Coastguard Worker         return false;
130*9880d681SAndroid Build Coastguard Worker       return BitVector::test(Idx);
131*9880d681SAndroid Build Coastguard Worker     }
132*9880d681SAndroid Build Coastguard Worker 
empty__anon55633e700211::RegisterSet133*9880d681SAndroid Build Coastguard Worker     bool empty() const {
134*9880d681SAndroid Build Coastguard Worker       return !BitVector::any();
135*9880d681SAndroid Build Coastguard Worker     }
includes__anon55633e700211::RegisterSet136*9880d681SAndroid Build Coastguard Worker     bool includes(const RegisterSet &Rs) const {
137*9880d681SAndroid Build Coastguard Worker       // A.BitVector::test(B)  <=>  A-B != {}
138*9880d681SAndroid Build Coastguard Worker       return !Rs.BitVector::test(*this);
139*9880d681SAndroid Build Coastguard Worker     }
intersects__anon55633e700211::RegisterSet140*9880d681SAndroid Build Coastguard Worker     bool intersects(const RegisterSet &Rs) const {
141*9880d681SAndroid Build Coastguard Worker       return BitVector::anyCommon(Rs);
142*9880d681SAndroid Build Coastguard Worker     }
143*9880d681SAndroid Build Coastguard Worker 
144*9880d681SAndroid Build Coastguard Worker   private:
ensure__anon55633e700211::RegisterSet145*9880d681SAndroid Build Coastguard Worker     void ensure(unsigned Idx) {
146*9880d681SAndroid Build Coastguard Worker       if (size() <= Idx)
147*9880d681SAndroid Build Coastguard Worker         resize(std::max(Idx+1, 32U));
148*9880d681SAndroid Build Coastguard Worker     }
v2x__anon55633e700211::RegisterSet149*9880d681SAndroid Build Coastguard Worker     static inline unsigned v2x(unsigned v) {
150*9880d681SAndroid Build Coastguard Worker       return TargetRegisterInfo::virtReg2Index(v);
151*9880d681SAndroid Build Coastguard Worker     }
x2v__anon55633e700211::RegisterSet152*9880d681SAndroid Build Coastguard Worker     static inline unsigned x2v(unsigned x) {
153*9880d681SAndroid Build Coastguard Worker       return TargetRegisterInfo::index2VirtReg(x);
154*9880d681SAndroid Build Coastguard Worker     }
155*9880d681SAndroid Build Coastguard Worker   };
156*9880d681SAndroid Build Coastguard Worker 
157*9880d681SAndroid Build Coastguard Worker 
158*9880d681SAndroid Build Coastguard Worker   struct PrintRegSet {
PrintRegSet__anon55633e700211::PrintRegSet159*9880d681SAndroid Build Coastguard Worker     PrintRegSet(const RegisterSet &S, const TargetRegisterInfo *RI)
160*9880d681SAndroid Build Coastguard Worker       : RS(S), TRI(RI) {}
161*9880d681SAndroid Build Coastguard Worker     friend raw_ostream &operator<< (raw_ostream &OS,
162*9880d681SAndroid Build Coastguard Worker           const PrintRegSet &P);
163*9880d681SAndroid Build Coastguard Worker   private:
164*9880d681SAndroid Build Coastguard Worker     const RegisterSet &RS;
165*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI;
166*9880d681SAndroid Build Coastguard Worker   };
167*9880d681SAndroid Build Coastguard Worker 
operator <<(raw_ostream & OS,const PrintRegSet & P)168*9880d681SAndroid Build Coastguard Worker   raw_ostream &operator<< (raw_ostream &OS, const PrintRegSet &P) {
169*9880d681SAndroid Build Coastguard Worker     OS << '{';
170*9880d681SAndroid Build Coastguard Worker     for (unsigned R = P.RS.find_first(); R; R = P.RS.find_next(R))
171*9880d681SAndroid Build Coastguard Worker       OS << ' ' << PrintReg(R, P.TRI);
172*9880d681SAndroid Build Coastguard Worker     OS << " }";
173*9880d681SAndroid Build Coastguard Worker     return OS;
174*9880d681SAndroid Build Coastguard Worker   }
175*9880d681SAndroid Build Coastguard Worker }
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker 
178*9880d681SAndroid Build Coastguard Worker namespace {
179*9880d681SAndroid Build Coastguard Worker   // A convenience class to associate unsigned numbers (such as virtual
180*9880d681SAndroid Build Coastguard Worker   // registers) with unsigned numbers.
181*9880d681SAndroid Build Coastguard Worker   struct UnsignedMap : public DenseMap<unsigned,unsigned> {
UnsignedMap__anon55633e700311::UnsignedMap182*9880d681SAndroid Build Coastguard Worker     UnsignedMap() : BaseType() {}
183*9880d681SAndroid Build Coastguard Worker   private:
184*9880d681SAndroid Build Coastguard Worker     typedef DenseMap<unsigned,unsigned> BaseType;
185*9880d681SAndroid Build Coastguard Worker   };
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker   // A utility to establish an ordering between virtual registers:
188*9880d681SAndroid Build Coastguard Worker   // VRegA < VRegB  <=>  RegisterOrdering[VRegA] < RegisterOrdering[VRegB]
189*9880d681SAndroid Build Coastguard Worker   // This is meant as a cache for the ordering of virtual registers defined
190*9880d681SAndroid Build Coastguard Worker   // by a potentially expensive comparison function, or obtained by a proce-
191*9880d681SAndroid Build Coastguard Worker   // dure that should not be repeated each time two registers are compared.
192*9880d681SAndroid Build Coastguard Worker   struct RegisterOrdering : public UnsignedMap {
RegisterOrdering__anon55633e700311::RegisterOrdering193*9880d681SAndroid Build Coastguard Worker     RegisterOrdering() : UnsignedMap() {}
operator []__anon55633e700311::RegisterOrdering194*9880d681SAndroid Build Coastguard Worker     unsigned operator[](unsigned VR) const {
195*9880d681SAndroid Build Coastguard Worker       const_iterator F = find(VR);
196*9880d681SAndroid Build Coastguard Worker       assert(F != end());
197*9880d681SAndroid Build Coastguard Worker       return F->second;
198*9880d681SAndroid Build Coastguard Worker     }
199*9880d681SAndroid Build Coastguard Worker     // Add operator(), so that objects of this class can be used as
200*9880d681SAndroid Build Coastguard Worker     // comparators in std::sort et al.
operator ()__anon55633e700311::RegisterOrdering201*9880d681SAndroid Build Coastguard Worker     bool operator() (unsigned VR1, unsigned VR2) const {
202*9880d681SAndroid Build Coastguard Worker       return operator[](VR1) < operator[](VR2);
203*9880d681SAndroid Build Coastguard Worker     }
204*9880d681SAndroid Build Coastguard Worker   };
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker 
207*9880d681SAndroid Build Coastguard Worker 
208*9880d681SAndroid Build Coastguard Worker namespace {
209*9880d681SAndroid Build Coastguard Worker   // Ordering of bit values. This class does not have operator[], but
210*9880d681SAndroid Build Coastguard Worker   // is supplies a comparison operator() for use in std:: algorithms.
211*9880d681SAndroid Build Coastguard Worker   // The order is as follows:
212*9880d681SAndroid Build Coastguard Worker   // - 0 < 1 < ref
213*9880d681SAndroid Build Coastguard Worker   // - ref1 < ref2, if ord(ref1.Reg) < ord(ref2.Reg),
214*9880d681SAndroid Build Coastguard Worker   //   or ord(ref1.Reg) == ord(ref2.Reg), and ref1.Pos < ref2.Pos.
215*9880d681SAndroid Build Coastguard Worker   struct BitValueOrdering {
BitValueOrdering__anon55633e700411::BitValueOrdering216*9880d681SAndroid Build Coastguard Worker     BitValueOrdering(const RegisterOrdering &RB) : BaseOrd(RB) {}
217*9880d681SAndroid Build Coastguard Worker     bool operator() (const BitTracker::BitValue &V1,
218*9880d681SAndroid Build Coastguard Worker           const BitTracker::BitValue &V2) const;
219*9880d681SAndroid Build Coastguard Worker     const RegisterOrdering &BaseOrd;
220*9880d681SAndroid Build Coastguard Worker   };
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker 
operator ()(const BitTracker::BitValue & V1,const BitTracker::BitValue & V2) const224*9880d681SAndroid Build Coastguard Worker bool BitValueOrdering::operator() (const BitTracker::BitValue &V1,
225*9880d681SAndroid Build Coastguard Worker       const BitTracker::BitValue &V2) const {
226*9880d681SAndroid Build Coastguard Worker   if (V1 == V2)
227*9880d681SAndroid Build Coastguard Worker     return false;
228*9880d681SAndroid Build Coastguard Worker   // V1==0 => true, V2==0 => false
229*9880d681SAndroid Build Coastguard Worker   if (V1.is(0) || V2.is(0))
230*9880d681SAndroid Build Coastguard Worker     return V1.is(0);
231*9880d681SAndroid Build Coastguard Worker   // Neither of V1,V2 is 0, and V1!=V2.
232*9880d681SAndroid Build Coastguard Worker   // V2==1 => false, V1==1 => true
233*9880d681SAndroid Build Coastguard Worker   if (V2.is(1) || V1.is(1))
234*9880d681SAndroid Build Coastguard Worker     return !V2.is(1);
235*9880d681SAndroid Build Coastguard Worker   // Both V1,V2 are refs.
236*9880d681SAndroid Build Coastguard Worker   unsigned Ind1 = BaseOrd[V1.RefI.Reg], Ind2 = BaseOrd[V2.RefI.Reg];
237*9880d681SAndroid Build Coastguard Worker   if (Ind1 != Ind2)
238*9880d681SAndroid Build Coastguard Worker     return Ind1 < Ind2;
239*9880d681SAndroid Build Coastguard Worker   // If V1.Pos==V2.Pos
240*9880d681SAndroid Build Coastguard Worker   assert(V1.RefI.Pos != V2.RefI.Pos && "Bit values should be different");
241*9880d681SAndroid Build Coastguard Worker   return V1.RefI.Pos < V2.RefI.Pos;
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker 
244*9880d681SAndroid Build Coastguard Worker 
245*9880d681SAndroid Build Coastguard Worker namespace {
246*9880d681SAndroid Build Coastguard Worker   // Cache for the BitTracker's cell map. Map lookup has a logarithmic
247*9880d681SAndroid Build Coastguard Worker   // complexity, this class will memoize the lookup results to reduce
248*9880d681SAndroid Build Coastguard Worker   // the access time for repeated lookups of the same cell.
249*9880d681SAndroid Build Coastguard Worker   struct CellMapShadow {
CellMapShadow__anon55633e700511::CellMapShadow250*9880d681SAndroid Build Coastguard Worker     CellMapShadow(const BitTracker &T) : BT(T) {}
lookup__anon55633e700511::CellMapShadow251*9880d681SAndroid Build Coastguard Worker     const BitTracker::RegisterCell &lookup(unsigned VR) {
252*9880d681SAndroid Build Coastguard Worker       unsigned RInd = TargetRegisterInfo::virtReg2Index(VR);
253*9880d681SAndroid Build Coastguard Worker       // Grow the vector to at least 32 elements.
254*9880d681SAndroid Build Coastguard Worker       if (RInd >= CVect.size())
255*9880d681SAndroid Build Coastguard Worker         CVect.resize(std::max(RInd+16, 32U), 0);
256*9880d681SAndroid Build Coastguard Worker       const BitTracker::RegisterCell *CP = CVect[RInd];
257*9880d681SAndroid Build Coastguard Worker       if (CP == 0)
258*9880d681SAndroid Build Coastguard Worker         CP = CVect[RInd] = &BT.lookup(VR);
259*9880d681SAndroid Build Coastguard Worker       return *CP;
260*9880d681SAndroid Build Coastguard Worker     }
261*9880d681SAndroid Build Coastguard Worker 
262*9880d681SAndroid Build Coastguard Worker     const BitTracker &BT;
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker   private:
265*9880d681SAndroid Build Coastguard Worker     typedef std::vector<const BitTracker::RegisterCell*> CellVectType;
266*9880d681SAndroid Build Coastguard Worker     CellVectType CVect;
267*9880d681SAndroid Build Coastguard Worker   };
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker 
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker namespace {
272*9880d681SAndroid Build Coastguard Worker   // Comparator class for lexicographic ordering of virtual registers
273*9880d681SAndroid Build Coastguard Worker   // according to the corresponding BitTracker::RegisterCell objects.
274*9880d681SAndroid Build Coastguard Worker   struct RegisterCellLexCompare {
RegisterCellLexCompare__anon55633e700611::RegisterCellLexCompare275*9880d681SAndroid Build Coastguard Worker     RegisterCellLexCompare(const BitValueOrdering &BO, CellMapShadow &M)
276*9880d681SAndroid Build Coastguard Worker       : BitOrd(BO), CM(M) {}
277*9880d681SAndroid Build Coastguard Worker     bool operator() (unsigned VR1, unsigned VR2) const;
278*9880d681SAndroid Build Coastguard Worker   private:
279*9880d681SAndroid Build Coastguard Worker     const BitValueOrdering &BitOrd;
280*9880d681SAndroid Build Coastguard Worker     CellMapShadow &CM;
281*9880d681SAndroid Build Coastguard Worker   };
282*9880d681SAndroid Build Coastguard Worker 
283*9880d681SAndroid Build Coastguard Worker   // Comparator class for lexicographic ordering of virtual registers
284*9880d681SAndroid Build Coastguard Worker   // according to the specified bits of the corresponding BitTracker::
285*9880d681SAndroid Build Coastguard Worker   // RegisterCell objects.
286*9880d681SAndroid Build Coastguard Worker   // Specifically, this class will be used to compare bit B of a register
287*9880d681SAndroid Build Coastguard Worker   // cell for a selected virtual register R with bit N of any register
288*9880d681SAndroid Build Coastguard Worker   // other than R.
289*9880d681SAndroid Build Coastguard Worker   struct RegisterCellBitCompareSel {
RegisterCellBitCompareSel__anon55633e700611::RegisterCellBitCompareSel290*9880d681SAndroid Build Coastguard Worker     RegisterCellBitCompareSel(unsigned R, unsigned B, unsigned N,
291*9880d681SAndroid Build Coastguard Worker           const BitValueOrdering &BO, CellMapShadow &M)
292*9880d681SAndroid Build Coastguard Worker       : SelR(R), SelB(B), BitN(N), BitOrd(BO), CM(M) {}
293*9880d681SAndroid Build Coastguard Worker     bool operator() (unsigned VR1, unsigned VR2) const;
294*9880d681SAndroid Build Coastguard Worker   private:
295*9880d681SAndroid Build Coastguard Worker     const unsigned SelR, SelB;
296*9880d681SAndroid Build Coastguard Worker     const unsigned BitN;
297*9880d681SAndroid Build Coastguard Worker     const BitValueOrdering &BitOrd;
298*9880d681SAndroid Build Coastguard Worker     CellMapShadow &CM;
299*9880d681SAndroid Build Coastguard Worker   };
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker 
302*9880d681SAndroid Build Coastguard Worker 
operator ()(unsigned VR1,unsigned VR2) const303*9880d681SAndroid Build Coastguard Worker bool RegisterCellLexCompare::operator() (unsigned VR1, unsigned VR2) const {
304*9880d681SAndroid Build Coastguard Worker   // Ordering of registers, made up from two given orderings:
305*9880d681SAndroid Build Coastguard Worker   // - the ordering of the register numbers, and
306*9880d681SAndroid Build Coastguard Worker   // - the ordering of register cells.
307*9880d681SAndroid Build Coastguard Worker   // Def. R1 < R2 if:
308*9880d681SAndroid Build Coastguard Worker   // - cell(R1) < cell(R2), or
309*9880d681SAndroid Build Coastguard Worker   // - cell(R1) == cell(R2), and index(R1) < index(R2).
310*9880d681SAndroid Build Coastguard Worker   //
311*9880d681SAndroid Build Coastguard Worker   // For register cells, the ordering is lexicographic, with index 0 being
312*9880d681SAndroid Build Coastguard Worker   // the most significant.
313*9880d681SAndroid Build Coastguard Worker   if (VR1 == VR2)
314*9880d681SAndroid Build Coastguard Worker     return false;
315*9880d681SAndroid Build Coastguard Worker 
316*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC1 = CM.lookup(VR1), &RC2 = CM.lookup(VR2);
317*9880d681SAndroid Build Coastguard Worker   uint16_t W1 = RC1.width(), W2 = RC2.width();
318*9880d681SAndroid Build Coastguard Worker   for (uint16_t i = 0, w = std::min(W1, W2); i < w; ++i) {
319*9880d681SAndroid Build Coastguard Worker     const BitTracker::BitValue &V1 = RC1[i], &V2 = RC2[i];
320*9880d681SAndroid Build Coastguard Worker     if (V1 != V2)
321*9880d681SAndroid Build Coastguard Worker       return BitOrd(V1, V2);
322*9880d681SAndroid Build Coastguard Worker   }
323*9880d681SAndroid Build Coastguard Worker   // Cells are equal up until the common length.
324*9880d681SAndroid Build Coastguard Worker   if (W1 != W2)
325*9880d681SAndroid Build Coastguard Worker     return W1 < W2;
326*9880d681SAndroid Build Coastguard Worker 
327*9880d681SAndroid Build Coastguard Worker   return BitOrd.BaseOrd[VR1] < BitOrd.BaseOrd[VR2];
328*9880d681SAndroid Build Coastguard Worker }
329*9880d681SAndroid Build Coastguard Worker 
330*9880d681SAndroid Build Coastguard Worker 
operator ()(unsigned VR1,unsigned VR2) const331*9880d681SAndroid Build Coastguard Worker bool RegisterCellBitCompareSel::operator() (unsigned VR1, unsigned VR2) const {
332*9880d681SAndroid Build Coastguard Worker   if (VR1 == VR2)
333*9880d681SAndroid Build Coastguard Worker     return false;
334*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC1 = CM.lookup(VR1);
335*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC2 = CM.lookup(VR2);
336*9880d681SAndroid Build Coastguard Worker   uint16_t W1 = RC1.width(), W2 = RC2.width();
337*9880d681SAndroid Build Coastguard Worker   uint16_t Bit1 = (VR1 == SelR) ? SelB : BitN;
338*9880d681SAndroid Build Coastguard Worker   uint16_t Bit2 = (VR2 == SelR) ? SelB : BitN;
339*9880d681SAndroid Build Coastguard Worker   // If Bit1 exceeds the width of VR1, then:
340*9880d681SAndroid Build Coastguard Worker   // - return false, if at the same time Bit2 exceeds VR2, or
341*9880d681SAndroid Build Coastguard Worker   // - return true, otherwise.
342*9880d681SAndroid Build Coastguard Worker   // (I.e. "a bit value that does not exist is less than any bit value
343*9880d681SAndroid Build Coastguard Worker   // that does exist".)
344*9880d681SAndroid Build Coastguard Worker   if (W1 <= Bit1)
345*9880d681SAndroid Build Coastguard Worker     return Bit2 < W2;
346*9880d681SAndroid Build Coastguard Worker   // If Bit1 is within VR1, but Bit2 is not within VR2, return false.
347*9880d681SAndroid Build Coastguard Worker   if (W2 <= Bit2)
348*9880d681SAndroid Build Coastguard Worker     return false;
349*9880d681SAndroid Build Coastguard Worker 
350*9880d681SAndroid Build Coastguard Worker   const BitTracker::BitValue &V1 = RC1[Bit1], V2 = RC2[Bit2];
351*9880d681SAndroid Build Coastguard Worker   if (V1 != V2)
352*9880d681SAndroid Build Coastguard Worker     return BitOrd(V1, V2);
353*9880d681SAndroid Build Coastguard Worker   return false;
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker 
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker namespace {
358*9880d681SAndroid Build Coastguard Worker   class OrderedRegisterList {
359*9880d681SAndroid Build Coastguard Worker     typedef std::vector<unsigned> ListType;
360*9880d681SAndroid Build Coastguard Worker   public:
OrderedRegisterList(const RegisterOrdering & RO)361*9880d681SAndroid Build Coastguard Worker     OrderedRegisterList(const RegisterOrdering &RO) : Ord(RO) {}
362*9880d681SAndroid Build Coastguard Worker     void insert(unsigned VR);
363*9880d681SAndroid Build Coastguard Worker     void remove(unsigned VR);
operator [](unsigned Idx) const364*9880d681SAndroid Build Coastguard Worker     unsigned operator[](unsigned Idx) const {
365*9880d681SAndroid Build Coastguard Worker       assert(Idx < Seq.size());
366*9880d681SAndroid Build Coastguard Worker       return Seq[Idx];
367*9880d681SAndroid Build Coastguard Worker     }
size() const368*9880d681SAndroid Build Coastguard Worker     unsigned size() const {
369*9880d681SAndroid Build Coastguard Worker       return Seq.size();
370*9880d681SAndroid Build Coastguard Worker     }
371*9880d681SAndroid Build Coastguard Worker 
372*9880d681SAndroid Build Coastguard Worker     typedef ListType::iterator iterator;
373*9880d681SAndroid Build Coastguard Worker     typedef ListType::const_iterator const_iterator;
begin()374*9880d681SAndroid Build Coastguard Worker     iterator begin() { return Seq.begin(); }
end()375*9880d681SAndroid Build Coastguard Worker     iterator end() { return Seq.end(); }
begin() const376*9880d681SAndroid Build Coastguard Worker     const_iterator begin() const { return Seq.begin(); }
end() const377*9880d681SAndroid Build Coastguard Worker     const_iterator end() const { return Seq.end(); }
378*9880d681SAndroid Build Coastguard Worker 
379*9880d681SAndroid Build Coastguard Worker     // Convenience function to convert an iterator to the corresponding index.
idx(iterator It) const380*9880d681SAndroid Build Coastguard Worker     unsigned idx(iterator It) const { return It-begin(); }
381*9880d681SAndroid Build Coastguard Worker   private:
382*9880d681SAndroid Build Coastguard Worker     ListType Seq;
383*9880d681SAndroid Build Coastguard Worker     const RegisterOrdering &Ord;
384*9880d681SAndroid Build Coastguard Worker   };
385*9880d681SAndroid Build Coastguard Worker 
386*9880d681SAndroid Build Coastguard Worker 
387*9880d681SAndroid Build Coastguard Worker   struct PrintORL {
PrintORL__anon55633e700711::PrintORL388*9880d681SAndroid Build Coastguard Worker     PrintORL(const OrderedRegisterList &L, const TargetRegisterInfo *RI)
389*9880d681SAndroid Build Coastguard Worker       : RL(L), TRI(RI) {}
390*9880d681SAndroid Build Coastguard Worker     friend raw_ostream &operator<< (raw_ostream &OS, const PrintORL &P);
391*9880d681SAndroid Build Coastguard Worker   private:
392*9880d681SAndroid Build Coastguard Worker     const OrderedRegisterList &RL;
393*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI;
394*9880d681SAndroid Build Coastguard Worker   };
395*9880d681SAndroid Build Coastguard Worker 
operator <<(raw_ostream & OS,const PrintORL & P)396*9880d681SAndroid Build Coastguard Worker   raw_ostream &operator<< (raw_ostream &OS, const PrintORL &P) {
397*9880d681SAndroid Build Coastguard Worker     OS << '(';
398*9880d681SAndroid Build Coastguard Worker     OrderedRegisterList::const_iterator B = P.RL.begin(), E = P.RL.end();
399*9880d681SAndroid Build Coastguard Worker     for (OrderedRegisterList::const_iterator I = B; I != E; ++I) {
400*9880d681SAndroid Build Coastguard Worker       if (I != B)
401*9880d681SAndroid Build Coastguard Worker         OS << ", ";
402*9880d681SAndroid Build Coastguard Worker       OS << PrintReg(*I, P.TRI);
403*9880d681SAndroid Build Coastguard Worker     }
404*9880d681SAndroid Build Coastguard Worker     OS << ')';
405*9880d681SAndroid Build Coastguard Worker     return OS;
406*9880d681SAndroid Build Coastguard Worker   }
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker 
409*9880d681SAndroid Build Coastguard Worker 
insert(unsigned VR)410*9880d681SAndroid Build Coastguard Worker void OrderedRegisterList::insert(unsigned VR) {
411*9880d681SAndroid Build Coastguard Worker   iterator L = std::lower_bound(Seq.begin(), Seq.end(), VR, Ord);
412*9880d681SAndroid Build Coastguard Worker   if (L == Seq.end())
413*9880d681SAndroid Build Coastguard Worker     Seq.push_back(VR);
414*9880d681SAndroid Build Coastguard Worker   else
415*9880d681SAndroid Build Coastguard Worker     Seq.insert(L, VR);
416*9880d681SAndroid Build Coastguard Worker }
417*9880d681SAndroid Build Coastguard Worker 
418*9880d681SAndroid Build Coastguard Worker 
remove(unsigned VR)419*9880d681SAndroid Build Coastguard Worker void OrderedRegisterList::remove(unsigned VR) {
420*9880d681SAndroid Build Coastguard Worker   iterator L = std::lower_bound(Seq.begin(), Seq.end(), VR, Ord);
421*9880d681SAndroid Build Coastguard Worker   assert(L != Seq.end());
422*9880d681SAndroid Build Coastguard Worker   Seq.erase(L);
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker 
425*9880d681SAndroid Build Coastguard Worker 
426*9880d681SAndroid Build Coastguard Worker namespace {
427*9880d681SAndroid Build Coastguard Worker   // A record of the insert form. The fields correspond to the operands
428*9880d681SAndroid Build Coastguard Worker   // of the "insert" instruction:
429*9880d681SAndroid Build Coastguard Worker   // ... = insert(SrcR, InsR, #Wdh, #Off)
430*9880d681SAndroid Build Coastguard Worker   struct IFRecord {
IFRecord__anon55633e700811::IFRecord431*9880d681SAndroid Build Coastguard Worker     IFRecord(unsigned SR = 0, unsigned IR = 0, uint16_t W = 0, uint16_t O = 0)
432*9880d681SAndroid Build Coastguard Worker       : SrcR(SR), InsR(IR), Wdh(W), Off(O) {}
433*9880d681SAndroid Build Coastguard Worker     unsigned SrcR, InsR;
434*9880d681SAndroid Build Coastguard Worker     uint16_t Wdh, Off;
435*9880d681SAndroid Build Coastguard Worker   };
436*9880d681SAndroid Build Coastguard Worker 
437*9880d681SAndroid Build Coastguard Worker   struct PrintIFR {
PrintIFR__anon55633e700811::PrintIFR438*9880d681SAndroid Build Coastguard Worker     PrintIFR(const IFRecord &R, const TargetRegisterInfo *RI)
439*9880d681SAndroid Build Coastguard Worker       : IFR(R), TRI(RI) {}
440*9880d681SAndroid Build Coastguard Worker   private:
441*9880d681SAndroid Build Coastguard Worker     const IFRecord &IFR;
442*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI;
443*9880d681SAndroid Build Coastguard Worker     friend raw_ostream &operator<< (raw_ostream &OS, const PrintIFR &P);
444*9880d681SAndroid Build Coastguard Worker   };
445*9880d681SAndroid Build Coastguard Worker 
operator <<(raw_ostream & OS,const PrintIFR & P)446*9880d681SAndroid Build Coastguard Worker   raw_ostream &operator<< (raw_ostream &OS, const PrintIFR &P) {
447*9880d681SAndroid Build Coastguard Worker     unsigned SrcR = P.IFR.SrcR, InsR = P.IFR.InsR;
448*9880d681SAndroid Build Coastguard Worker     OS << '(' << PrintReg(SrcR, P.TRI) << ',' << PrintReg(InsR, P.TRI)
449*9880d681SAndroid Build Coastguard Worker        << ",#" << P.IFR.Wdh << ",#" << P.IFR.Off << ')';
450*9880d681SAndroid Build Coastguard Worker     return OS;
451*9880d681SAndroid Build Coastguard Worker   }
452*9880d681SAndroid Build Coastguard Worker 
453*9880d681SAndroid Build Coastguard Worker   typedef std::pair<IFRecord,RegisterSet> IFRecordWithRegSet;
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker 
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker namespace llvm {
458*9880d681SAndroid Build Coastguard Worker   void initializeHexagonGenInsertPass(PassRegistry&);
459*9880d681SAndroid Build Coastguard Worker   FunctionPass *createHexagonGenInsert();
460*9880d681SAndroid Build Coastguard Worker }
461*9880d681SAndroid Build Coastguard Worker 
462*9880d681SAndroid Build Coastguard Worker 
463*9880d681SAndroid Build Coastguard Worker namespace {
464*9880d681SAndroid Build Coastguard Worker   class HexagonGenInsert : public MachineFunctionPass {
465*9880d681SAndroid Build Coastguard Worker   public:
466*9880d681SAndroid Build Coastguard Worker     static char ID;
HexagonGenInsert()467*9880d681SAndroid Build Coastguard Worker     HexagonGenInsert() : MachineFunctionPass(ID), HII(0), HRI(0) {
468*9880d681SAndroid Build Coastguard Worker       initializeHexagonGenInsertPass(*PassRegistry::getPassRegistry());
469*9880d681SAndroid Build Coastguard Worker     }
getPassName() const470*9880d681SAndroid Build Coastguard Worker     virtual const char *getPassName() const {
471*9880d681SAndroid Build Coastguard Worker       return "Hexagon generate \"insert\" instructions";
472*9880d681SAndroid Build Coastguard Worker     }
getAnalysisUsage(AnalysisUsage & AU) const473*9880d681SAndroid Build Coastguard Worker     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
474*9880d681SAndroid Build Coastguard Worker       AU.addRequired<MachineDominatorTree>();
475*9880d681SAndroid Build Coastguard Worker       AU.addPreserved<MachineDominatorTree>();
476*9880d681SAndroid Build Coastguard Worker       MachineFunctionPass::getAnalysisUsage(AU);
477*9880d681SAndroid Build Coastguard Worker     }
478*9880d681SAndroid Build Coastguard Worker     virtual bool runOnMachineFunction(MachineFunction &MF);
479*9880d681SAndroid Build Coastguard Worker 
480*9880d681SAndroid Build Coastguard Worker   private:
481*9880d681SAndroid Build Coastguard Worker     typedef DenseMap<std::pair<unsigned,unsigned>,unsigned> PairMapType;
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker     void buildOrderingMF(RegisterOrdering &RO) const;
484*9880d681SAndroid Build Coastguard Worker     void buildOrderingBT(RegisterOrdering &RB, RegisterOrdering &RO) const;
485*9880d681SAndroid Build Coastguard Worker     bool isIntClass(const TargetRegisterClass *RC) const;
486*9880d681SAndroid Build Coastguard Worker     bool isConstant(unsigned VR) const;
487*9880d681SAndroid Build Coastguard Worker     bool isSmallConstant(unsigned VR) const;
488*9880d681SAndroid Build Coastguard Worker     bool isValidInsertForm(unsigned DstR, unsigned SrcR, unsigned InsR,
489*9880d681SAndroid Build Coastguard Worker           uint16_t L, uint16_t S) const;
490*9880d681SAndroid Build Coastguard Worker     bool findSelfReference(unsigned VR) const;
491*9880d681SAndroid Build Coastguard Worker     bool findNonSelfReference(unsigned VR) const;
492*9880d681SAndroid Build Coastguard Worker     void getInstrDefs(const MachineInstr *MI, RegisterSet &Defs) const;
493*9880d681SAndroid Build Coastguard Worker     void getInstrUses(const MachineInstr *MI, RegisterSet &Uses) const;
494*9880d681SAndroid Build Coastguard Worker     unsigned distance(const MachineBasicBlock *FromB,
495*9880d681SAndroid Build Coastguard Worker           const MachineBasicBlock *ToB, const UnsignedMap &RPO,
496*9880d681SAndroid Build Coastguard Worker           PairMapType &M) const;
497*9880d681SAndroid Build Coastguard Worker     unsigned distance(MachineBasicBlock::const_iterator FromI,
498*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock::const_iterator ToI, const UnsignedMap &RPO,
499*9880d681SAndroid Build Coastguard Worker           PairMapType &M) const;
500*9880d681SAndroid Build Coastguard Worker     bool findRecordInsertForms(unsigned VR, OrderedRegisterList &AVs);
501*9880d681SAndroid Build Coastguard Worker     void collectInBlock(MachineBasicBlock *B, OrderedRegisterList &AVs);
502*9880d681SAndroid Build Coastguard Worker     void findRemovableRegisters(unsigned VR, IFRecord IF,
503*9880d681SAndroid Build Coastguard Worker           RegisterSet &RMs) const;
504*9880d681SAndroid Build Coastguard Worker     void computeRemovableRegisters();
505*9880d681SAndroid Build Coastguard Worker 
506*9880d681SAndroid Build Coastguard Worker     void pruneEmptyLists();
507*9880d681SAndroid Build Coastguard Worker     void pruneCoveredSets(unsigned VR);
508*9880d681SAndroid Build Coastguard Worker     void pruneUsesTooFar(unsigned VR, const UnsignedMap &RPO, PairMapType &M);
509*9880d681SAndroid Build Coastguard Worker     void pruneRegCopies(unsigned VR);
510*9880d681SAndroid Build Coastguard Worker     void pruneCandidates();
511*9880d681SAndroid Build Coastguard Worker     void selectCandidates();
512*9880d681SAndroid Build Coastguard Worker     bool generateInserts();
513*9880d681SAndroid Build Coastguard Worker 
514*9880d681SAndroid Build Coastguard Worker     bool removeDeadCode(MachineDomTreeNode *N);
515*9880d681SAndroid Build Coastguard Worker 
516*9880d681SAndroid Build Coastguard Worker     // IFRecord coupled with a set of potentially removable registers:
517*9880d681SAndroid Build Coastguard Worker     typedef std::vector<IFRecordWithRegSet> IFListType;
518*9880d681SAndroid Build Coastguard Worker     typedef DenseMap<unsigned,IFListType> IFMapType;  // vreg -> IFListType
519*9880d681SAndroid Build Coastguard Worker 
520*9880d681SAndroid Build Coastguard Worker     void dump_map() const;
521*9880d681SAndroid Build Coastguard Worker 
522*9880d681SAndroid Build Coastguard Worker     const HexagonInstrInfo *HII;
523*9880d681SAndroid Build Coastguard Worker     const HexagonRegisterInfo *HRI;
524*9880d681SAndroid Build Coastguard Worker 
525*9880d681SAndroid Build Coastguard Worker     MachineFunction *MFN;
526*9880d681SAndroid Build Coastguard Worker     MachineRegisterInfo *MRI;
527*9880d681SAndroid Build Coastguard Worker     MachineDominatorTree *MDT;
528*9880d681SAndroid Build Coastguard Worker     CellMapShadow *CMS;
529*9880d681SAndroid Build Coastguard Worker 
530*9880d681SAndroid Build Coastguard Worker     RegisterOrdering BaseOrd;
531*9880d681SAndroid Build Coastguard Worker     RegisterOrdering CellOrd;
532*9880d681SAndroid Build Coastguard Worker     IFMapType IFMap;
533*9880d681SAndroid Build Coastguard Worker   };
534*9880d681SAndroid Build Coastguard Worker 
535*9880d681SAndroid Build Coastguard Worker   char HexagonGenInsert::ID = 0;
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker 
538*9880d681SAndroid Build Coastguard Worker 
dump_map() const539*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::dump_map() const {
540*9880d681SAndroid Build Coastguard Worker   typedef IFMapType::const_iterator iterator;
541*9880d681SAndroid Build Coastguard Worker   for (iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
542*9880d681SAndroid Build Coastguard Worker     dbgs() << "  " << PrintReg(I->first, HRI) << ":\n";
543*9880d681SAndroid Build Coastguard Worker     const IFListType &LL = I->second;
544*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, n = LL.size(); i < n; ++i)
545*9880d681SAndroid Build Coastguard Worker       dbgs() << "    " << PrintIFR(LL[i].first, HRI) << ", "
546*9880d681SAndroid Build Coastguard Worker              << PrintRegSet(LL[i].second, HRI) << '\n';
547*9880d681SAndroid Build Coastguard Worker   }
548*9880d681SAndroid Build Coastguard Worker }
549*9880d681SAndroid Build Coastguard Worker 
550*9880d681SAndroid Build Coastguard Worker 
buildOrderingMF(RegisterOrdering & RO) const551*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::buildOrderingMF(RegisterOrdering &RO) const {
552*9880d681SAndroid Build Coastguard Worker   unsigned Index = 0;
553*9880d681SAndroid Build Coastguard Worker   typedef MachineFunction::const_iterator mf_iterator;
554*9880d681SAndroid Build Coastguard Worker   for (mf_iterator A = MFN->begin(), Z = MFN->end(); A != Z; ++A) {
555*9880d681SAndroid Build Coastguard Worker     const MachineBasicBlock &B = *A;
556*9880d681SAndroid Build Coastguard Worker     if (!CMS->BT.reached(&B))
557*9880d681SAndroid Build Coastguard Worker       continue;
558*9880d681SAndroid Build Coastguard Worker     typedef MachineBasicBlock::const_iterator mb_iterator;
559*9880d681SAndroid Build Coastguard Worker     for (mb_iterator I = B.begin(), E = B.end(); I != E; ++I) {
560*9880d681SAndroid Build Coastguard Worker       const MachineInstr *MI = &*I;
561*9880d681SAndroid Build Coastguard Worker       for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) {
562*9880d681SAndroid Build Coastguard Worker         const MachineOperand &MO = MI->getOperand(i);
563*9880d681SAndroid Build Coastguard Worker         if (MO.isReg() && MO.isDef()) {
564*9880d681SAndroid Build Coastguard Worker           unsigned R = MO.getReg();
565*9880d681SAndroid Build Coastguard Worker           assert(MO.getSubReg() == 0 && "Unexpected subregister in definition");
566*9880d681SAndroid Build Coastguard Worker           if (TargetRegisterInfo::isVirtualRegister(R))
567*9880d681SAndroid Build Coastguard Worker             RO.insert(std::make_pair(R, Index++));
568*9880d681SAndroid Build Coastguard Worker         }
569*9880d681SAndroid Build Coastguard Worker       }
570*9880d681SAndroid Build Coastguard Worker     }
571*9880d681SAndroid Build Coastguard Worker   }
572*9880d681SAndroid Build Coastguard Worker   // Since some virtual registers may have had their def and uses eliminated,
573*9880d681SAndroid Build Coastguard Worker   // they are no longer referenced in the code, and so they will not appear
574*9880d681SAndroid Build Coastguard Worker   // in the map.
575*9880d681SAndroid Build Coastguard Worker }
576*9880d681SAndroid Build Coastguard Worker 
577*9880d681SAndroid Build Coastguard Worker 
buildOrderingBT(RegisterOrdering & RB,RegisterOrdering & RO) const578*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::buildOrderingBT(RegisterOrdering &RB,
579*9880d681SAndroid Build Coastguard Worker       RegisterOrdering &RO) const {
580*9880d681SAndroid Build Coastguard Worker   // Create a vector of all virtual registers (collect them from the base
581*9880d681SAndroid Build Coastguard Worker   // ordering RB), and then sort it using the RegisterCell comparator.
582*9880d681SAndroid Build Coastguard Worker   BitValueOrdering BVO(RB);
583*9880d681SAndroid Build Coastguard Worker   RegisterCellLexCompare LexCmp(BVO, *CMS);
584*9880d681SAndroid Build Coastguard Worker   typedef std::vector<unsigned> SortableVectorType;
585*9880d681SAndroid Build Coastguard Worker   SortableVectorType VRs;
586*9880d681SAndroid Build Coastguard Worker   for (RegisterOrdering::iterator I = RB.begin(), E = RB.end(); I != E; ++I)
587*9880d681SAndroid Build Coastguard Worker     VRs.push_back(I->first);
588*9880d681SAndroid Build Coastguard Worker   std::sort(VRs.begin(), VRs.end(), LexCmp);
589*9880d681SAndroid Build Coastguard Worker   // Transfer the results to the outgoing register ordering.
590*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = VRs.size(); i < n; ++i)
591*9880d681SAndroid Build Coastguard Worker     RO.insert(std::make_pair(VRs[i], i));
592*9880d681SAndroid Build Coastguard Worker }
593*9880d681SAndroid Build Coastguard Worker 
594*9880d681SAndroid Build Coastguard Worker 
isIntClass(const TargetRegisterClass * RC) const595*9880d681SAndroid Build Coastguard Worker inline bool HexagonGenInsert::isIntClass(const TargetRegisterClass *RC) const {
596*9880d681SAndroid Build Coastguard Worker   return RC == &Hexagon::IntRegsRegClass || RC == &Hexagon::DoubleRegsRegClass;
597*9880d681SAndroid Build Coastguard Worker }
598*9880d681SAndroid Build Coastguard Worker 
599*9880d681SAndroid Build Coastguard Worker 
isConstant(unsigned VR) const600*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::isConstant(unsigned VR) const {
601*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC = CMS->lookup(VR);
602*9880d681SAndroid Build Coastguard Worker   uint16_t W = RC.width();
603*9880d681SAndroid Build Coastguard Worker   for (uint16_t i = 0; i < W; ++i) {
604*9880d681SAndroid Build Coastguard Worker     const BitTracker::BitValue &BV = RC[i];
605*9880d681SAndroid Build Coastguard Worker     if (BV.is(0) || BV.is(1))
606*9880d681SAndroid Build Coastguard Worker       continue;
607*9880d681SAndroid Build Coastguard Worker     return false;
608*9880d681SAndroid Build Coastguard Worker   }
609*9880d681SAndroid Build Coastguard Worker   return true;
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker 
612*9880d681SAndroid Build Coastguard Worker 
isSmallConstant(unsigned VR) const613*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::isSmallConstant(unsigned VR) const {
614*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC = CMS->lookup(VR);
615*9880d681SAndroid Build Coastguard Worker   uint16_t W = RC.width();
616*9880d681SAndroid Build Coastguard Worker   if (W > 64)
617*9880d681SAndroid Build Coastguard Worker     return false;
618*9880d681SAndroid Build Coastguard Worker   uint64_t V = 0, B = 1;
619*9880d681SAndroid Build Coastguard Worker   for (uint16_t i = 0; i < W; ++i) {
620*9880d681SAndroid Build Coastguard Worker     const BitTracker::BitValue &BV = RC[i];
621*9880d681SAndroid Build Coastguard Worker     if (BV.is(1))
622*9880d681SAndroid Build Coastguard Worker       V |= B;
623*9880d681SAndroid Build Coastguard Worker     else if (!BV.is(0))
624*9880d681SAndroid Build Coastguard Worker       return false;
625*9880d681SAndroid Build Coastguard Worker     B <<= 1;
626*9880d681SAndroid Build Coastguard Worker   }
627*9880d681SAndroid Build Coastguard Worker 
628*9880d681SAndroid Build Coastguard Worker   // For 32-bit registers, consider: Rd = #s16.
629*9880d681SAndroid Build Coastguard Worker   if (W == 32)
630*9880d681SAndroid Build Coastguard Worker     return isInt<16>(V);
631*9880d681SAndroid Build Coastguard Worker 
632*9880d681SAndroid Build Coastguard Worker   // For 64-bit registers, it's Rdd = #s8 or Rdd = combine(#s8,#s8)
633*9880d681SAndroid Build Coastguard Worker   return isInt<8>(Lo_32(V)) && isInt<8>(Hi_32(V));
634*9880d681SAndroid Build Coastguard Worker }
635*9880d681SAndroid Build Coastguard Worker 
636*9880d681SAndroid Build Coastguard Worker 
isValidInsertForm(unsigned DstR,unsigned SrcR,unsigned InsR,uint16_t L,uint16_t S) const637*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::isValidInsertForm(unsigned DstR, unsigned SrcR,
638*9880d681SAndroid Build Coastguard Worker       unsigned InsR, uint16_t L, uint16_t S) const {
639*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *DstRC = MRI->getRegClass(DstR);
640*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *SrcRC = MRI->getRegClass(SrcR);
641*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *InsRC = MRI->getRegClass(InsR);
642*9880d681SAndroid Build Coastguard Worker   // Only integet (32-/64-bit) register classes.
643*9880d681SAndroid Build Coastguard Worker   if (!isIntClass(DstRC) || !isIntClass(SrcRC) || !isIntClass(InsRC))
644*9880d681SAndroid Build Coastguard Worker     return false;
645*9880d681SAndroid Build Coastguard Worker   // The "source" register must be of the same class as DstR.
646*9880d681SAndroid Build Coastguard Worker   if (DstRC != SrcRC)
647*9880d681SAndroid Build Coastguard Worker     return false;
648*9880d681SAndroid Build Coastguard Worker   if (DstRC == InsRC)
649*9880d681SAndroid Build Coastguard Worker     return true;
650*9880d681SAndroid Build Coastguard Worker   // A 64-bit register can only be generated from other 64-bit registers.
651*9880d681SAndroid Build Coastguard Worker   if (DstRC == &Hexagon::DoubleRegsRegClass)
652*9880d681SAndroid Build Coastguard Worker     return false;
653*9880d681SAndroid Build Coastguard Worker   // Otherwise, the L and S cannot span 32-bit word boundary.
654*9880d681SAndroid Build Coastguard Worker   if (S < 32 && S+L > 32)
655*9880d681SAndroid Build Coastguard Worker     return false;
656*9880d681SAndroid Build Coastguard Worker   return true;
657*9880d681SAndroid Build Coastguard Worker }
658*9880d681SAndroid Build Coastguard Worker 
659*9880d681SAndroid Build Coastguard Worker 
findSelfReference(unsigned VR) const660*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::findSelfReference(unsigned VR) const {
661*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC = CMS->lookup(VR);
662*9880d681SAndroid Build Coastguard Worker   for (uint16_t i = 0, w = RC.width(); i < w; ++i) {
663*9880d681SAndroid Build Coastguard Worker     const BitTracker::BitValue &V = RC[i];
664*9880d681SAndroid Build Coastguard Worker     if (V.Type == BitTracker::BitValue::Ref && V.RefI.Reg == VR)
665*9880d681SAndroid Build Coastguard Worker       return true;
666*9880d681SAndroid Build Coastguard Worker   }
667*9880d681SAndroid Build Coastguard Worker   return false;
668*9880d681SAndroid Build Coastguard Worker }
669*9880d681SAndroid Build Coastguard Worker 
670*9880d681SAndroid Build Coastguard Worker 
findNonSelfReference(unsigned VR) const671*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::findNonSelfReference(unsigned VR) const {
672*9880d681SAndroid Build Coastguard Worker   BitTracker::RegisterCell RC = CMS->lookup(VR);
673*9880d681SAndroid Build Coastguard Worker   for (uint16_t i = 0, w = RC.width(); i < w; ++i) {
674*9880d681SAndroid Build Coastguard Worker     const BitTracker::BitValue &V = RC[i];
675*9880d681SAndroid Build Coastguard Worker     if (V.Type == BitTracker::BitValue::Ref && V.RefI.Reg != VR)
676*9880d681SAndroid Build Coastguard Worker       return true;
677*9880d681SAndroid Build Coastguard Worker   }
678*9880d681SAndroid Build Coastguard Worker   return false;
679*9880d681SAndroid Build Coastguard Worker }
680*9880d681SAndroid Build Coastguard Worker 
681*9880d681SAndroid Build Coastguard Worker 
getInstrDefs(const MachineInstr * MI,RegisterSet & Defs) const682*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::getInstrDefs(const MachineInstr *MI,
683*9880d681SAndroid Build Coastguard Worker       RegisterSet &Defs) const {
684*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) {
685*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(i);
686*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg() || !MO.isDef())
687*9880d681SAndroid Build Coastguard Worker       continue;
688*9880d681SAndroid Build Coastguard Worker     unsigned R = MO.getReg();
689*9880d681SAndroid Build Coastguard Worker     if (!TargetRegisterInfo::isVirtualRegister(R))
690*9880d681SAndroid Build Coastguard Worker       continue;
691*9880d681SAndroid Build Coastguard Worker     Defs.insert(R);
692*9880d681SAndroid Build Coastguard Worker   }
693*9880d681SAndroid Build Coastguard Worker }
694*9880d681SAndroid Build Coastguard Worker 
695*9880d681SAndroid Build Coastguard Worker 
getInstrUses(const MachineInstr * MI,RegisterSet & Uses) const696*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::getInstrUses(const MachineInstr *MI,
697*9880d681SAndroid Build Coastguard Worker       RegisterSet &Uses) const {
698*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) {
699*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(i);
700*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg() || !MO.isUse())
701*9880d681SAndroid Build Coastguard Worker       continue;
702*9880d681SAndroid Build Coastguard Worker     unsigned R = MO.getReg();
703*9880d681SAndroid Build Coastguard Worker     if (!TargetRegisterInfo::isVirtualRegister(R))
704*9880d681SAndroid Build Coastguard Worker       continue;
705*9880d681SAndroid Build Coastguard Worker     Uses.insert(R);
706*9880d681SAndroid Build Coastguard Worker   }
707*9880d681SAndroid Build Coastguard Worker }
708*9880d681SAndroid Build Coastguard Worker 
709*9880d681SAndroid Build Coastguard Worker 
distance(const MachineBasicBlock * FromB,const MachineBasicBlock * ToB,const UnsignedMap & RPO,PairMapType & M) const710*9880d681SAndroid Build Coastguard Worker unsigned HexagonGenInsert::distance(const MachineBasicBlock *FromB,
711*9880d681SAndroid Build Coastguard Worker       const MachineBasicBlock *ToB, const UnsignedMap &RPO,
712*9880d681SAndroid Build Coastguard Worker       PairMapType &M) const {
713*9880d681SAndroid Build Coastguard Worker   // Forward distance from the end of a block to the beginning of it does
714*9880d681SAndroid Build Coastguard Worker   // not make sense. This function should not be called with FromB == ToB.
715*9880d681SAndroid Build Coastguard Worker   assert(FromB != ToB);
716*9880d681SAndroid Build Coastguard Worker 
717*9880d681SAndroid Build Coastguard Worker   unsigned FromN = FromB->getNumber(), ToN = ToB->getNumber();
718*9880d681SAndroid Build Coastguard Worker   // If we have already computed it, return the cached result.
719*9880d681SAndroid Build Coastguard Worker   PairMapType::iterator F = M.find(std::make_pair(FromN, ToN));
720*9880d681SAndroid Build Coastguard Worker   if (F != M.end())
721*9880d681SAndroid Build Coastguard Worker     return F->second;
722*9880d681SAndroid Build Coastguard Worker   unsigned ToRPO = RPO.lookup(ToN);
723*9880d681SAndroid Build Coastguard Worker 
724*9880d681SAndroid Build Coastguard Worker   unsigned MaxD = 0;
725*9880d681SAndroid Build Coastguard Worker   typedef MachineBasicBlock::const_pred_iterator pred_iterator;
726*9880d681SAndroid Build Coastguard Worker   for (pred_iterator I = ToB->pred_begin(), E = ToB->pred_end(); I != E; ++I) {
727*9880d681SAndroid Build Coastguard Worker     const MachineBasicBlock *PB = *I;
728*9880d681SAndroid Build Coastguard Worker     // Skip back edges. Also, if FromB is a predecessor of ToB, the distance
729*9880d681SAndroid Build Coastguard Worker     // along that path will be 0, and we don't need to do any calculations
730*9880d681SAndroid Build Coastguard Worker     // on it.
731*9880d681SAndroid Build Coastguard Worker     if (PB == FromB || RPO.lookup(PB->getNumber()) >= ToRPO)
732*9880d681SAndroid Build Coastguard Worker       continue;
733*9880d681SAndroid Build Coastguard Worker     unsigned D = PB->size() + distance(FromB, PB, RPO, M);
734*9880d681SAndroid Build Coastguard Worker     if (D > MaxD)
735*9880d681SAndroid Build Coastguard Worker       MaxD = D;
736*9880d681SAndroid Build Coastguard Worker   }
737*9880d681SAndroid Build Coastguard Worker 
738*9880d681SAndroid Build Coastguard Worker   // Memoize the result for later lookup.
739*9880d681SAndroid Build Coastguard Worker   M.insert(std::make_pair(std::make_pair(FromN, ToN), MaxD));
740*9880d681SAndroid Build Coastguard Worker   return MaxD;
741*9880d681SAndroid Build Coastguard Worker }
742*9880d681SAndroid Build Coastguard Worker 
743*9880d681SAndroid Build Coastguard Worker 
distance(MachineBasicBlock::const_iterator FromI,MachineBasicBlock::const_iterator ToI,const UnsignedMap & RPO,PairMapType & M) const744*9880d681SAndroid Build Coastguard Worker unsigned HexagonGenInsert::distance(MachineBasicBlock::const_iterator FromI,
745*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::const_iterator ToI, const UnsignedMap &RPO,
746*9880d681SAndroid Build Coastguard Worker       PairMapType &M) const {
747*9880d681SAndroid Build Coastguard Worker   const MachineBasicBlock *FB = FromI->getParent(), *TB = ToI->getParent();
748*9880d681SAndroid Build Coastguard Worker   if (FB == TB)
749*9880d681SAndroid Build Coastguard Worker     return std::distance(FromI, ToI);
750*9880d681SAndroid Build Coastguard Worker   unsigned D1 = std::distance(TB->begin(), ToI);
751*9880d681SAndroid Build Coastguard Worker   unsigned D2 = distance(FB, TB, RPO, M);
752*9880d681SAndroid Build Coastguard Worker   unsigned D3 = std::distance(FromI, FB->end());
753*9880d681SAndroid Build Coastguard Worker   return D1+D2+D3;
754*9880d681SAndroid Build Coastguard Worker }
755*9880d681SAndroid Build Coastguard Worker 
756*9880d681SAndroid Build Coastguard Worker 
findRecordInsertForms(unsigned VR,OrderedRegisterList & AVs)757*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::findRecordInsertForms(unsigned VR,
758*9880d681SAndroid Build Coastguard Worker       OrderedRegisterList &AVs) {
759*9880d681SAndroid Build Coastguard Worker   if (isDebug()) {
760*9880d681SAndroid Build Coastguard Worker     dbgs() << LLVM_FUNCTION_NAME << ": " << PrintReg(VR, HRI)
761*9880d681SAndroid Build Coastguard Worker            << "  AVs: " << PrintORL(AVs, HRI) << "\n";
762*9880d681SAndroid Build Coastguard Worker   }
763*9880d681SAndroid Build Coastguard Worker   if (AVs.size() == 0)
764*9880d681SAndroid Build Coastguard Worker     return false;
765*9880d681SAndroid Build Coastguard Worker 
766*9880d681SAndroid Build Coastguard Worker   typedef OrderedRegisterList::iterator iterator;
767*9880d681SAndroid Build Coastguard Worker   BitValueOrdering BVO(BaseOrd);
768*9880d681SAndroid Build Coastguard Worker   const BitTracker::RegisterCell &RC = CMS->lookup(VR);
769*9880d681SAndroid Build Coastguard Worker   uint16_t W = RC.width();
770*9880d681SAndroid Build Coastguard Worker 
771*9880d681SAndroid Build Coastguard Worker   typedef std::pair<unsigned,uint16_t> RSRecord;  // (reg,shift)
772*9880d681SAndroid Build Coastguard Worker   typedef std::vector<RSRecord> RSListType;
773*9880d681SAndroid Build Coastguard Worker   // Have a map, with key being the matching prefix length, and the value
774*9880d681SAndroid Build Coastguard Worker   // being the list of pairs (R,S), where R's prefix matches VR at S.
775*9880d681SAndroid Build Coastguard Worker   // (DenseMap<uint16_t,RSListType> fails to instantiate.)
776*9880d681SAndroid Build Coastguard Worker   typedef DenseMap<unsigned,RSListType> LRSMapType;
777*9880d681SAndroid Build Coastguard Worker   LRSMapType LM;
778*9880d681SAndroid Build Coastguard Worker 
779*9880d681SAndroid Build Coastguard Worker   // Conceptually, rotate the cell RC right (i.e. towards the LSB) by S,
780*9880d681SAndroid Build Coastguard Worker   // and find matching prefixes from AVs with the rotated RC. Such a prefix
781*9880d681SAndroid Build Coastguard Worker   // would match a string of bits (of length L) in RC starting at S.
782*9880d681SAndroid Build Coastguard Worker   for (uint16_t S = 0; S < W; ++S) {
783*9880d681SAndroid Build Coastguard Worker     iterator B = AVs.begin(), E = AVs.end();
784*9880d681SAndroid Build Coastguard Worker     // The registers in AVs are ordered according to the lexical order of
785*9880d681SAndroid Build Coastguard Worker     // the corresponding register cells. This means that the range of regis-
786*9880d681SAndroid Build Coastguard Worker     // ters in AVs that match a prefix of length L+1 will be contained in
787*9880d681SAndroid Build Coastguard Worker     // the range that matches a prefix of length L. This means that we can
788*9880d681SAndroid Build Coastguard Worker     // keep narrowing the search space as the prefix length goes up. This
789*9880d681SAndroid Build Coastguard Worker     // helps reduce the overall complexity of the search.
790*9880d681SAndroid Build Coastguard Worker     uint16_t L;
791*9880d681SAndroid Build Coastguard Worker     for (L = 0; L < W-S; ++L) {
792*9880d681SAndroid Build Coastguard Worker       // Compare against VR's bits starting at S, which emulates rotation
793*9880d681SAndroid Build Coastguard Worker       // of VR by S.
794*9880d681SAndroid Build Coastguard Worker       RegisterCellBitCompareSel RCB(VR, S+L, L, BVO, *CMS);
795*9880d681SAndroid Build Coastguard Worker       iterator NewB = std::lower_bound(B, E, VR, RCB);
796*9880d681SAndroid Build Coastguard Worker       iterator NewE = std::upper_bound(NewB, E, VR, RCB);
797*9880d681SAndroid Build Coastguard Worker       // For the registers that are eliminated from the next range, L is
798*9880d681SAndroid Build Coastguard Worker       // the longest prefix matching VR at position S (their prefixes
799*9880d681SAndroid Build Coastguard Worker       // differ from VR at S+L). If L>0, record this information for later
800*9880d681SAndroid Build Coastguard Worker       // use.
801*9880d681SAndroid Build Coastguard Worker       if (L > 0) {
802*9880d681SAndroid Build Coastguard Worker         for (iterator I = B; I != NewB; ++I)
803*9880d681SAndroid Build Coastguard Worker           LM[L].push_back(std::make_pair(*I, S));
804*9880d681SAndroid Build Coastguard Worker         for (iterator I = NewE; I != E; ++I)
805*9880d681SAndroid Build Coastguard Worker           LM[L].push_back(std::make_pair(*I, S));
806*9880d681SAndroid Build Coastguard Worker       }
807*9880d681SAndroid Build Coastguard Worker       B = NewB, E = NewE;
808*9880d681SAndroid Build Coastguard Worker       if (B == E)
809*9880d681SAndroid Build Coastguard Worker         break;
810*9880d681SAndroid Build Coastguard Worker     }
811*9880d681SAndroid Build Coastguard Worker     // Record the final register range. If this range is non-empty, then
812*9880d681SAndroid Build Coastguard Worker     // L=W-S.
813*9880d681SAndroid Build Coastguard Worker     assert(B == E || L == W-S);
814*9880d681SAndroid Build Coastguard Worker     if (B != E) {
815*9880d681SAndroid Build Coastguard Worker       for (iterator I = B; I != E; ++I)
816*9880d681SAndroid Build Coastguard Worker         LM[L].push_back(std::make_pair(*I, S));
817*9880d681SAndroid Build Coastguard Worker       // If B!=E, then we found a range of registers whose prefixes cover the
818*9880d681SAndroid Build Coastguard Worker       // rest of VR from position S. There is no need to further advance S.
819*9880d681SAndroid Build Coastguard Worker       break;
820*9880d681SAndroid Build Coastguard Worker     }
821*9880d681SAndroid Build Coastguard Worker   }
822*9880d681SAndroid Build Coastguard Worker 
823*9880d681SAndroid Build Coastguard Worker   if (isDebug()) {
824*9880d681SAndroid Build Coastguard Worker     dbgs() << "Prefixes matching register " << PrintReg(VR, HRI) << "\n";
825*9880d681SAndroid Build Coastguard Worker     for (LRSMapType::iterator I = LM.begin(), E = LM.end(); I != E; ++I) {
826*9880d681SAndroid Build Coastguard Worker       dbgs() << "  L=" << I->first << ':';
827*9880d681SAndroid Build Coastguard Worker       const RSListType &LL = I->second;
828*9880d681SAndroid Build Coastguard Worker       for (unsigned i = 0, n = LL.size(); i < n; ++i)
829*9880d681SAndroid Build Coastguard Worker         dbgs() << " (" << PrintReg(LL[i].first, HRI) << ",@"
830*9880d681SAndroid Build Coastguard Worker                << LL[i].second << ')';
831*9880d681SAndroid Build Coastguard Worker       dbgs() << '\n';
832*9880d681SAndroid Build Coastguard Worker     }
833*9880d681SAndroid Build Coastguard Worker   }
834*9880d681SAndroid Build Coastguard Worker 
835*9880d681SAndroid Build Coastguard Worker 
836*9880d681SAndroid Build Coastguard Worker   bool Recorded = false;
837*9880d681SAndroid Build Coastguard Worker 
838*9880d681SAndroid Build Coastguard Worker   for (iterator I = AVs.begin(), E = AVs.end(); I != E; ++I) {
839*9880d681SAndroid Build Coastguard Worker     unsigned SrcR = *I;
840*9880d681SAndroid Build Coastguard Worker     int FDi = -1, LDi = -1;   // First/last different bit.
841*9880d681SAndroid Build Coastguard Worker     const BitTracker::RegisterCell &AC = CMS->lookup(SrcR);
842*9880d681SAndroid Build Coastguard Worker     uint16_t AW = AC.width();
843*9880d681SAndroid Build Coastguard Worker     for (uint16_t i = 0, w = std::min(W, AW); i < w; ++i) {
844*9880d681SAndroid Build Coastguard Worker       if (RC[i] == AC[i])
845*9880d681SAndroid Build Coastguard Worker         continue;
846*9880d681SAndroid Build Coastguard Worker       if (FDi == -1)
847*9880d681SAndroid Build Coastguard Worker         FDi = i;
848*9880d681SAndroid Build Coastguard Worker       LDi = i;
849*9880d681SAndroid Build Coastguard Worker     }
850*9880d681SAndroid Build Coastguard Worker     if (FDi == -1)
851*9880d681SAndroid Build Coastguard Worker       continue;  // TODO (future): Record identical registers.
852*9880d681SAndroid Build Coastguard Worker     // Look for a register whose prefix could patch the range [FD..LD]
853*9880d681SAndroid Build Coastguard Worker     // where VR and SrcR differ.
854*9880d681SAndroid Build Coastguard Worker     uint16_t FD = FDi, LD = LDi;  // Switch to unsigned type.
855*9880d681SAndroid Build Coastguard Worker     uint16_t MinL = LD-FD+1;
856*9880d681SAndroid Build Coastguard Worker     for (uint16_t L = MinL; L < W; ++L) {
857*9880d681SAndroid Build Coastguard Worker       LRSMapType::iterator F = LM.find(L);
858*9880d681SAndroid Build Coastguard Worker       if (F == LM.end())
859*9880d681SAndroid Build Coastguard Worker         continue;
860*9880d681SAndroid Build Coastguard Worker       RSListType &LL = F->second;
861*9880d681SAndroid Build Coastguard Worker       for (unsigned i = 0, n = LL.size(); i < n; ++i) {
862*9880d681SAndroid Build Coastguard Worker         uint16_t S = LL[i].second;
863*9880d681SAndroid Build Coastguard Worker         // MinL is the minimum length of the prefix. Any length above MinL
864*9880d681SAndroid Build Coastguard Worker         // allows some flexibility as to where the prefix can start:
865*9880d681SAndroid Build Coastguard Worker         // given the extra length EL=L-MinL, the prefix must start between
866*9880d681SAndroid Build Coastguard Worker         // max(0,FD-EL) and FD.
867*9880d681SAndroid Build Coastguard Worker         if (S > FD)   // Starts too late.
868*9880d681SAndroid Build Coastguard Worker           continue;
869*9880d681SAndroid Build Coastguard Worker         uint16_t EL = L-MinL;
870*9880d681SAndroid Build Coastguard Worker         uint16_t LowS = (EL < FD) ? FD-EL : 0;
871*9880d681SAndroid Build Coastguard Worker         if (S < LowS) // Starts too early.
872*9880d681SAndroid Build Coastguard Worker           continue;
873*9880d681SAndroid Build Coastguard Worker         unsigned InsR = LL[i].first;
874*9880d681SAndroid Build Coastguard Worker         if (!isValidInsertForm(VR, SrcR, InsR, L, S))
875*9880d681SAndroid Build Coastguard Worker           continue;
876*9880d681SAndroid Build Coastguard Worker         if (isDebug()) {
877*9880d681SAndroid Build Coastguard Worker           dbgs() << PrintReg(VR, HRI) << " = insert(" << PrintReg(SrcR, HRI)
878*9880d681SAndroid Build Coastguard Worker                  << ',' << PrintReg(InsR, HRI) << ",#" << L << ",#"
879*9880d681SAndroid Build Coastguard Worker                  << S << ")\n";
880*9880d681SAndroid Build Coastguard Worker         }
881*9880d681SAndroid Build Coastguard Worker         IFRecordWithRegSet RR(IFRecord(SrcR, InsR, L, S), RegisterSet());
882*9880d681SAndroid Build Coastguard Worker         IFMap[VR].push_back(RR);
883*9880d681SAndroid Build Coastguard Worker         Recorded = true;
884*9880d681SAndroid Build Coastguard Worker       }
885*9880d681SAndroid Build Coastguard Worker     }
886*9880d681SAndroid Build Coastguard Worker   }
887*9880d681SAndroid Build Coastguard Worker 
888*9880d681SAndroid Build Coastguard Worker   return Recorded;
889*9880d681SAndroid Build Coastguard Worker }
890*9880d681SAndroid Build Coastguard Worker 
891*9880d681SAndroid Build Coastguard Worker 
collectInBlock(MachineBasicBlock * B,OrderedRegisterList & AVs)892*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::collectInBlock(MachineBasicBlock *B,
893*9880d681SAndroid Build Coastguard Worker       OrderedRegisterList &AVs) {
894*9880d681SAndroid Build Coastguard Worker   if (isDebug())
895*9880d681SAndroid Build Coastguard Worker     dbgs() << "visiting block BB#" << B->getNumber() << "\n";
896*9880d681SAndroid Build Coastguard Worker 
897*9880d681SAndroid Build Coastguard Worker   // First, check if this block is reachable at all. If not, the bit tracker
898*9880d681SAndroid Build Coastguard Worker   // will not have any information about registers in it.
899*9880d681SAndroid Build Coastguard Worker   if (!CMS->BT.reached(B))
900*9880d681SAndroid Build Coastguard Worker     return;
901*9880d681SAndroid Build Coastguard Worker 
902*9880d681SAndroid Build Coastguard Worker   bool DoConst = OptConst;
903*9880d681SAndroid Build Coastguard Worker   // Keep a separate set of registers defined in this block, so that we
904*9880d681SAndroid Build Coastguard Worker   // can remove them from the list of available registers once all DT
905*9880d681SAndroid Build Coastguard Worker   // successors have been processed.
906*9880d681SAndroid Build Coastguard Worker   RegisterSet BlockDefs, InsDefs;
907*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
908*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = &*I;
909*9880d681SAndroid Build Coastguard Worker     InsDefs.clear();
910*9880d681SAndroid Build Coastguard Worker     getInstrDefs(MI, InsDefs);
911*9880d681SAndroid Build Coastguard Worker     // Leave those alone. They are more transparent than "insert".
912*9880d681SAndroid Build Coastguard Worker     bool Skip = MI->isCopy() || MI->isRegSequence();
913*9880d681SAndroid Build Coastguard Worker 
914*9880d681SAndroid Build Coastguard Worker     if (!Skip) {
915*9880d681SAndroid Build Coastguard Worker       // Visit all defined registers, and attempt to find the corresponding
916*9880d681SAndroid Build Coastguard Worker       // "insert" representations.
917*9880d681SAndroid Build Coastguard Worker       for (unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR)) {
918*9880d681SAndroid Build Coastguard Worker         // Do not collect registers that are known to be compile-time cons-
919*9880d681SAndroid Build Coastguard Worker         // tants, unless requested.
920*9880d681SAndroid Build Coastguard Worker         if (!DoConst && isConstant(VR))
921*9880d681SAndroid Build Coastguard Worker           continue;
922*9880d681SAndroid Build Coastguard Worker         // If VR's cell contains a reference to VR, then VR cannot be defined
923*9880d681SAndroid Build Coastguard Worker         // via "insert". If VR is a constant that can be generated in a single
924*9880d681SAndroid Build Coastguard Worker         // instruction (without constant extenders), generating it via insert
925*9880d681SAndroid Build Coastguard Worker         // makes no sense.
926*9880d681SAndroid Build Coastguard Worker         if (findSelfReference(VR) || isSmallConstant(VR))
927*9880d681SAndroid Build Coastguard Worker           continue;
928*9880d681SAndroid Build Coastguard Worker 
929*9880d681SAndroid Build Coastguard Worker         findRecordInsertForms(VR, AVs);
930*9880d681SAndroid Build Coastguard Worker       }
931*9880d681SAndroid Build Coastguard Worker     }
932*9880d681SAndroid Build Coastguard Worker 
933*9880d681SAndroid Build Coastguard Worker     // Insert the defined registers into the list of available registers
934*9880d681SAndroid Build Coastguard Worker     // after they have been processed.
935*9880d681SAndroid Build Coastguard Worker     for (unsigned VR = InsDefs.find_first(); VR; VR = InsDefs.find_next(VR))
936*9880d681SAndroid Build Coastguard Worker       AVs.insert(VR);
937*9880d681SAndroid Build Coastguard Worker     BlockDefs.insert(InsDefs);
938*9880d681SAndroid Build Coastguard Worker   }
939*9880d681SAndroid Build Coastguard Worker 
940*9880d681SAndroid Build Coastguard Worker   MachineDomTreeNode *N = MDT->getNode(B);
941*9880d681SAndroid Build Coastguard Worker   typedef GraphTraits<MachineDomTreeNode*> GTN;
942*9880d681SAndroid Build Coastguard Worker   typedef GTN::ChildIteratorType ChildIter;
943*9880d681SAndroid Build Coastguard Worker   for (ChildIter I = GTN::child_begin(N), E = GTN::child_end(N); I != E; ++I) {
944*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *SB = (*I)->getBlock();
945*9880d681SAndroid Build Coastguard Worker     collectInBlock(SB, AVs);
946*9880d681SAndroid Build Coastguard Worker   }
947*9880d681SAndroid Build Coastguard Worker 
948*9880d681SAndroid Build Coastguard Worker   for (unsigned VR = BlockDefs.find_first(); VR; VR = BlockDefs.find_next(VR))
949*9880d681SAndroid Build Coastguard Worker     AVs.remove(VR);
950*9880d681SAndroid Build Coastguard Worker }
951*9880d681SAndroid Build Coastguard Worker 
952*9880d681SAndroid Build Coastguard Worker 
findRemovableRegisters(unsigned VR,IFRecord IF,RegisterSet & RMs) const953*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::findRemovableRegisters(unsigned VR, IFRecord IF,
954*9880d681SAndroid Build Coastguard Worker       RegisterSet &RMs) const {
955*9880d681SAndroid Build Coastguard Worker   // For a given register VR and a insert form, find the registers that are
956*9880d681SAndroid Build Coastguard Worker   // used by the current definition of VR, and which would no longer be
957*9880d681SAndroid Build Coastguard Worker   // needed for it after the definition of VR is replaced with the insert
958*9880d681SAndroid Build Coastguard Worker   // form. These are the registers that could potentially become dead.
959*9880d681SAndroid Build Coastguard Worker   RegisterSet Regs[2];
960*9880d681SAndroid Build Coastguard Worker 
961*9880d681SAndroid Build Coastguard Worker   unsigned S = 0;  // Register set selector.
962*9880d681SAndroid Build Coastguard Worker   Regs[S].insert(VR);
963*9880d681SAndroid Build Coastguard Worker 
964*9880d681SAndroid Build Coastguard Worker   while (!Regs[S].empty()) {
965*9880d681SAndroid Build Coastguard Worker     // Breadth-first search.
966*9880d681SAndroid Build Coastguard Worker     unsigned OtherS = 1-S;
967*9880d681SAndroid Build Coastguard Worker     Regs[OtherS].clear();
968*9880d681SAndroid Build Coastguard Worker     for (unsigned R = Regs[S].find_first(); R; R = Regs[S].find_next(R)) {
969*9880d681SAndroid Build Coastguard Worker       Regs[S].remove(R);
970*9880d681SAndroid Build Coastguard Worker       if (R == IF.SrcR || R == IF.InsR)
971*9880d681SAndroid Build Coastguard Worker         continue;
972*9880d681SAndroid Build Coastguard Worker       // Check if a given register has bits that are references to any other
973*9880d681SAndroid Build Coastguard Worker       // registers. This is to detect situations where the instruction that
974*9880d681SAndroid Build Coastguard Worker       // defines register R takes register Q as an operand, but R itself does
975*9880d681SAndroid Build Coastguard Worker       // not contain any bits from Q. Loads are examples of how this could
976*9880d681SAndroid Build Coastguard Worker       // happen:
977*9880d681SAndroid Build Coastguard Worker       //   R = load Q
978*9880d681SAndroid Build Coastguard Worker       // In this case (assuming we do not have any knowledge about the loaded
979*9880d681SAndroid Build Coastguard Worker       // value), we must not treat R as a "conveyance" of the bits from Q.
980*9880d681SAndroid Build Coastguard Worker       // (The information in BT about R's bits would have them as constants,
981*9880d681SAndroid Build Coastguard Worker       // in case of zero-extending loads, or refs to R.)
982*9880d681SAndroid Build Coastguard Worker       if (!findNonSelfReference(R))
983*9880d681SAndroid Build Coastguard Worker         continue;
984*9880d681SAndroid Build Coastguard Worker       RMs.insert(R);
985*9880d681SAndroid Build Coastguard Worker       const MachineInstr *DefI = MRI->getVRegDef(R);
986*9880d681SAndroid Build Coastguard Worker       assert(DefI);
987*9880d681SAndroid Build Coastguard Worker       // Do not iterate past PHI nodes to avoid infinite loops. This can
988*9880d681SAndroid Build Coastguard Worker       // make the final set a bit less accurate, but the removable register
989*9880d681SAndroid Build Coastguard Worker       // sets are an approximation anyway.
990*9880d681SAndroid Build Coastguard Worker       if (DefI->isPHI())
991*9880d681SAndroid Build Coastguard Worker         continue;
992*9880d681SAndroid Build Coastguard Worker       getInstrUses(DefI, Regs[OtherS]);
993*9880d681SAndroid Build Coastguard Worker     }
994*9880d681SAndroid Build Coastguard Worker     S = OtherS;
995*9880d681SAndroid Build Coastguard Worker   }
996*9880d681SAndroid Build Coastguard Worker   // The register VR is added to the list as a side-effect of the algorithm,
997*9880d681SAndroid Build Coastguard Worker   // but it is not "potentially removable". A potentially removable register
998*9880d681SAndroid Build Coastguard Worker   // is one that may become unused (dead) after conversion to the insert form
999*9880d681SAndroid Build Coastguard Worker   // IF, and obviously VR (or its replacement) will not become dead by apply-
1000*9880d681SAndroid Build Coastguard Worker   // ing IF.
1001*9880d681SAndroid Build Coastguard Worker   RMs.remove(VR);
1002*9880d681SAndroid Build Coastguard Worker }
1003*9880d681SAndroid Build Coastguard Worker 
1004*9880d681SAndroid Build Coastguard Worker 
computeRemovableRegisters()1005*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::computeRemovableRegisters() {
1006*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
1007*9880d681SAndroid Build Coastguard Worker     IFListType &LL = I->second;
1008*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, n = LL.size(); i < n; ++i)
1009*9880d681SAndroid Build Coastguard Worker       findRemovableRegisters(I->first, LL[i].first, LL[i].second);
1010*9880d681SAndroid Build Coastguard Worker   }
1011*9880d681SAndroid Build Coastguard Worker }
1012*9880d681SAndroid Build Coastguard Worker 
1013*9880d681SAndroid Build Coastguard Worker 
pruneEmptyLists()1014*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::pruneEmptyLists() {
1015*9880d681SAndroid Build Coastguard Worker   // Remove all entries from the map, where the register has no insert forms
1016*9880d681SAndroid Build Coastguard Worker   // associated with it.
1017*9880d681SAndroid Build Coastguard Worker   typedef SmallVector<IFMapType::iterator,16> IterListType;
1018*9880d681SAndroid Build Coastguard Worker   IterListType Prune;
1019*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
1020*9880d681SAndroid Build Coastguard Worker     if (I->second.size() == 0)
1021*9880d681SAndroid Build Coastguard Worker       Prune.push_back(I);
1022*9880d681SAndroid Build Coastguard Worker   }
1023*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = Prune.size(); i < n; ++i)
1024*9880d681SAndroid Build Coastguard Worker     IFMap.erase(Prune[i]);
1025*9880d681SAndroid Build Coastguard Worker }
1026*9880d681SAndroid Build Coastguard Worker 
1027*9880d681SAndroid Build Coastguard Worker 
pruneCoveredSets(unsigned VR)1028*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::pruneCoveredSets(unsigned VR) {
1029*9880d681SAndroid Build Coastguard Worker   IFMapType::iterator F = IFMap.find(VR);
1030*9880d681SAndroid Build Coastguard Worker   assert(F != IFMap.end());
1031*9880d681SAndroid Build Coastguard Worker   IFListType &LL = F->second;
1032*9880d681SAndroid Build Coastguard Worker 
1033*9880d681SAndroid Build Coastguard Worker   // First, examine the IF candidates for register VR whose removable-regis-
1034*9880d681SAndroid Build Coastguard Worker   // ter sets are empty. This means that a given candidate will not help eli-
1035*9880d681SAndroid Build Coastguard Worker   // minate any registers, but since "insert" is not a constant-extendable
1036*9880d681SAndroid Build Coastguard Worker   // instruction, using such a candidate may reduce code size if the defini-
1037*9880d681SAndroid Build Coastguard Worker   // tion of VR is constant-extended.
1038*9880d681SAndroid Build Coastguard Worker   // If there exists a candidate with a non-empty set, the ones with empty
1039*9880d681SAndroid Build Coastguard Worker   // sets will not be used and can be removed.
1040*9880d681SAndroid Build Coastguard Worker   MachineInstr *DefVR = MRI->getVRegDef(VR);
1041*9880d681SAndroid Build Coastguard Worker   bool DefEx = HII->isConstExtended(DefVR);
1042*9880d681SAndroid Build Coastguard Worker   bool HasNE = false;
1043*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = LL.size(); i < n; ++i) {
1044*9880d681SAndroid Build Coastguard Worker     if (LL[i].second.empty())
1045*9880d681SAndroid Build Coastguard Worker       continue;
1046*9880d681SAndroid Build Coastguard Worker     HasNE = true;
1047*9880d681SAndroid Build Coastguard Worker     break;
1048*9880d681SAndroid Build Coastguard Worker   }
1049*9880d681SAndroid Build Coastguard Worker   if (!DefEx || HasNE) {
1050*9880d681SAndroid Build Coastguard Worker     // The definition of VR is not constant-extended, or there is a candidate
1051*9880d681SAndroid Build Coastguard Worker     // with a non-empty set. Remove all candidates with empty sets.
1052*9880d681SAndroid Build Coastguard Worker     auto IsEmpty = [] (const IFRecordWithRegSet &IR) -> bool {
1053*9880d681SAndroid Build Coastguard Worker       return IR.second.empty();
1054*9880d681SAndroid Build Coastguard Worker     };
1055*9880d681SAndroid Build Coastguard Worker     auto End = std::remove_if(LL.begin(), LL.end(), IsEmpty);
1056*9880d681SAndroid Build Coastguard Worker     if (End != LL.end())
1057*9880d681SAndroid Build Coastguard Worker       LL.erase(End, LL.end());
1058*9880d681SAndroid Build Coastguard Worker   } else {
1059*9880d681SAndroid Build Coastguard Worker     // The definition of VR is constant-extended, and all candidates have
1060*9880d681SAndroid Build Coastguard Worker     // empty removable-register sets. Pick the maximum candidate, and remove
1061*9880d681SAndroid Build Coastguard Worker     // all others. The "maximum" does not have any special meaning here, it
1062*9880d681SAndroid Build Coastguard Worker     // is only so that the candidate that will remain on the list is selec-
1063*9880d681SAndroid Build Coastguard Worker     // ted deterministically.
1064*9880d681SAndroid Build Coastguard Worker     IFRecord MaxIF = LL[0].first;
1065*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 1, n = LL.size(); i < n; ++i) {
1066*9880d681SAndroid Build Coastguard Worker       // If LL[MaxI] < LL[i], then MaxI = i.
1067*9880d681SAndroid Build Coastguard Worker       const IFRecord &IF = LL[i].first;
1068*9880d681SAndroid Build Coastguard Worker       unsigned M0 = BaseOrd[MaxIF.SrcR], M1 = BaseOrd[MaxIF.InsR];
1069*9880d681SAndroid Build Coastguard Worker       unsigned R0 = BaseOrd[IF.SrcR], R1 = BaseOrd[IF.InsR];
1070*9880d681SAndroid Build Coastguard Worker       if (M0 > R0)
1071*9880d681SAndroid Build Coastguard Worker         continue;
1072*9880d681SAndroid Build Coastguard Worker       if (M0 == R0) {
1073*9880d681SAndroid Build Coastguard Worker         if (M1 > R1)
1074*9880d681SAndroid Build Coastguard Worker           continue;
1075*9880d681SAndroid Build Coastguard Worker         if (M1 == R1) {
1076*9880d681SAndroid Build Coastguard Worker           if (MaxIF.Wdh > IF.Wdh)
1077*9880d681SAndroid Build Coastguard Worker             continue;
1078*9880d681SAndroid Build Coastguard Worker           if (MaxIF.Wdh == IF.Wdh && MaxIF.Off >= IF.Off)
1079*9880d681SAndroid Build Coastguard Worker             continue;
1080*9880d681SAndroid Build Coastguard Worker         }
1081*9880d681SAndroid Build Coastguard Worker       }
1082*9880d681SAndroid Build Coastguard Worker       // MaxIF < IF.
1083*9880d681SAndroid Build Coastguard Worker       MaxIF = IF;
1084*9880d681SAndroid Build Coastguard Worker     }
1085*9880d681SAndroid Build Coastguard Worker     // Remove everything except the maximum candidate. All register sets
1086*9880d681SAndroid Build Coastguard Worker     // are empty, so no need to preserve anything.
1087*9880d681SAndroid Build Coastguard Worker     LL.clear();
1088*9880d681SAndroid Build Coastguard Worker     LL.push_back(std::make_pair(MaxIF, RegisterSet()));
1089*9880d681SAndroid Build Coastguard Worker   }
1090*9880d681SAndroid Build Coastguard Worker 
1091*9880d681SAndroid Build Coastguard Worker   // Now, remove those whose sets of potentially removable registers are
1092*9880d681SAndroid Build Coastguard Worker   // contained in another IF candidate for VR. For example, given these
1093*9880d681SAndroid Build Coastguard Worker   // candidates for vreg45,
1094*9880d681SAndroid Build Coastguard Worker   //   %vreg45:
1095*9880d681SAndroid Build Coastguard Worker   //     (%vreg44,%vreg41,#9,#8), { %vreg42 }
1096*9880d681SAndroid Build Coastguard Worker   //     (%vreg43,%vreg41,#9,#8), { %vreg42 %vreg44 }
1097*9880d681SAndroid Build Coastguard Worker   // remove the first one, since it is contained in the second one.
1098*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = LL.size(); i < n; ) {
1099*9880d681SAndroid Build Coastguard Worker     const RegisterSet &RMi = LL[i].second;
1100*9880d681SAndroid Build Coastguard Worker     unsigned j = 0;
1101*9880d681SAndroid Build Coastguard Worker     while (j < n) {
1102*9880d681SAndroid Build Coastguard Worker       if (j != i && LL[j].second.includes(RMi))
1103*9880d681SAndroid Build Coastguard Worker         break;
1104*9880d681SAndroid Build Coastguard Worker       j++;
1105*9880d681SAndroid Build Coastguard Worker     }
1106*9880d681SAndroid Build Coastguard Worker     if (j == n) {   // RMi not contained in anything else.
1107*9880d681SAndroid Build Coastguard Worker       i++;
1108*9880d681SAndroid Build Coastguard Worker       continue;
1109*9880d681SAndroid Build Coastguard Worker     }
1110*9880d681SAndroid Build Coastguard Worker     LL.erase(LL.begin()+i);
1111*9880d681SAndroid Build Coastguard Worker     n = LL.size();
1112*9880d681SAndroid Build Coastguard Worker   }
1113*9880d681SAndroid Build Coastguard Worker }
1114*9880d681SAndroid Build Coastguard Worker 
1115*9880d681SAndroid Build Coastguard Worker 
pruneUsesTooFar(unsigned VR,const UnsignedMap & RPO,PairMapType & M)1116*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::pruneUsesTooFar(unsigned VR, const UnsignedMap &RPO,
1117*9880d681SAndroid Build Coastguard Worker       PairMapType &M) {
1118*9880d681SAndroid Build Coastguard Worker   IFMapType::iterator F = IFMap.find(VR);
1119*9880d681SAndroid Build Coastguard Worker   assert(F != IFMap.end());
1120*9880d681SAndroid Build Coastguard Worker   IFListType &LL = F->second;
1121*9880d681SAndroid Build Coastguard Worker   unsigned Cutoff = VRegDistCutoff;
1122*9880d681SAndroid Build Coastguard Worker   const MachineInstr *DefV = MRI->getVRegDef(VR);
1123*9880d681SAndroid Build Coastguard Worker 
1124*9880d681SAndroid Build Coastguard Worker   for (unsigned i = LL.size(); i > 0; --i) {
1125*9880d681SAndroid Build Coastguard Worker     unsigned SR = LL[i-1].first.SrcR, IR = LL[i-1].first.InsR;
1126*9880d681SAndroid Build Coastguard Worker     const MachineInstr *DefS = MRI->getVRegDef(SR);
1127*9880d681SAndroid Build Coastguard Worker     const MachineInstr *DefI = MRI->getVRegDef(IR);
1128*9880d681SAndroid Build Coastguard Worker     unsigned DSV = distance(DefS, DefV, RPO, M);
1129*9880d681SAndroid Build Coastguard Worker     if (DSV < Cutoff) {
1130*9880d681SAndroid Build Coastguard Worker       unsigned DIV = distance(DefI, DefV, RPO, M);
1131*9880d681SAndroid Build Coastguard Worker       if (DIV < Cutoff)
1132*9880d681SAndroid Build Coastguard Worker         continue;
1133*9880d681SAndroid Build Coastguard Worker     }
1134*9880d681SAndroid Build Coastguard Worker     LL.erase(LL.begin()+(i-1));
1135*9880d681SAndroid Build Coastguard Worker   }
1136*9880d681SAndroid Build Coastguard Worker }
1137*9880d681SAndroid Build Coastguard Worker 
1138*9880d681SAndroid Build Coastguard Worker 
pruneRegCopies(unsigned VR)1139*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::pruneRegCopies(unsigned VR) {
1140*9880d681SAndroid Build Coastguard Worker   IFMapType::iterator F = IFMap.find(VR);
1141*9880d681SAndroid Build Coastguard Worker   assert(F != IFMap.end());
1142*9880d681SAndroid Build Coastguard Worker   IFListType &LL = F->second;
1143*9880d681SAndroid Build Coastguard Worker 
1144*9880d681SAndroid Build Coastguard Worker   auto IsCopy = [] (const IFRecordWithRegSet &IR) -> bool {
1145*9880d681SAndroid Build Coastguard Worker     return IR.first.Wdh == 32 && (IR.first.Off == 0 || IR.first.Off == 32);
1146*9880d681SAndroid Build Coastguard Worker   };
1147*9880d681SAndroid Build Coastguard Worker   auto End = std::remove_if(LL.begin(), LL.end(), IsCopy);
1148*9880d681SAndroid Build Coastguard Worker   if (End != LL.end())
1149*9880d681SAndroid Build Coastguard Worker     LL.erase(End, LL.end());
1150*9880d681SAndroid Build Coastguard Worker }
1151*9880d681SAndroid Build Coastguard Worker 
1152*9880d681SAndroid Build Coastguard Worker 
pruneCandidates()1153*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::pruneCandidates() {
1154*9880d681SAndroid Build Coastguard Worker   // Remove candidates that are not beneficial, regardless of the final
1155*9880d681SAndroid Build Coastguard Worker   // selection method.
1156*9880d681SAndroid Build Coastguard Worker   // First, remove candidates whose potentially removable set is a subset
1157*9880d681SAndroid Build Coastguard Worker   // of another candidate's set.
1158*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I)
1159*9880d681SAndroid Build Coastguard Worker     pruneCoveredSets(I->first);
1160*9880d681SAndroid Build Coastguard Worker 
1161*9880d681SAndroid Build Coastguard Worker   UnsignedMap RPO;
1162*9880d681SAndroid Build Coastguard Worker   typedef ReversePostOrderTraversal<const MachineFunction*> RPOTType;
1163*9880d681SAndroid Build Coastguard Worker   RPOTType RPOT(MFN);
1164*9880d681SAndroid Build Coastguard Worker   unsigned RPON = 0;
1165*9880d681SAndroid Build Coastguard Worker   for (RPOTType::rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I)
1166*9880d681SAndroid Build Coastguard Worker     RPO[(*I)->getNumber()] = RPON++;
1167*9880d681SAndroid Build Coastguard Worker 
1168*9880d681SAndroid Build Coastguard Worker   PairMapType Memo; // Memoization map for distance calculation.
1169*9880d681SAndroid Build Coastguard Worker   // Remove candidates that would use registers defined too far away.
1170*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I)
1171*9880d681SAndroid Build Coastguard Worker     pruneUsesTooFar(I->first, RPO, Memo);
1172*9880d681SAndroid Build Coastguard Worker 
1173*9880d681SAndroid Build Coastguard Worker   pruneEmptyLists();
1174*9880d681SAndroid Build Coastguard Worker 
1175*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I)
1176*9880d681SAndroid Build Coastguard Worker     pruneRegCopies(I->first);
1177*9880d681SAndroid Build Coastguard Worker }
1178*9880d681SAndroid Build Coastguard Worker 
1179*9880d681SAndroid Build Coastguard Worker 
1180*9880d681SAndroid Build Coastguard Worker namespace {
1181*9880d681SAndroid Build Coastguard Worker   // Class for comparing IF candidates for registers that have multiple of
1182*9880d681SAndroid Build Coastguard Worker   // them. The smaller the candidate, according to this ordering, the better.
1183*9880d681SAndroid Build Coastguard Worker   // First, compare the number of zeros in the associated potentially remova-
1184*9880d681SAndroid Build Coastguard Worker   // ble register sets. "Zero" indicates that the register is very likely to
1185*9880d681SAndroid Build Coastguard Worker   // become dead after this transformation.
1186*9880d681SAndroid Build Coastguard Worker   // Second, compare "averages", i.e. use-count per size. The lower wins.
1187*9880d681SAndroid Build Coastguard Worker   // After that, it does not really matter which one is smaller. Resolve
1188*9880d681SAndroid Build Coastguard Worker   // the tie in some deterministic way.
1189*9880d681SAndroid Build Coastguard Worker   struct IFOrdering {
IFOrdering__anon55633e700c11::IFOrdering1190*9880d681SAndroid Build Coastguard Worker     IFOrdering(const UnsignedMap &UC, const RegisterOrdering &BO)
1191*9880d681SAndroid Build Coastguard Worker       : UseC(UC), BaseOrd(BO) {}
1192*9880d681SAndroid Build Coastguard Worker     bool operator() (const IFRecordWithRegSet &A,
1193*9880d681SAndroid Build Coastguard Worker           const IFRecordWithRegSet &B) const;
1194*9880d681SAndroid Build Coastguard Worker   private:
1195*9880d681SAndroid Build Coastguard Worker     void stats(const RegisterSet &Rs, unsigned &Size, unsigned &Zero,
1196*9880d681SAndroid Build Coastguard Worker           unsigned &Sum) const;
1197*9880d681SAndroid Build Coastguard Worker     const UnsignedMap &UseC;
1198*9880d681SAndroid Build Coastguard Worker     const RegisterOrdering &BaseOrd;
1199*9880d681SAndroid Build Coastguard Worker   };
1200*9880d681SAndroid Build Coastguard Worker }
1201*9880d681SAndroid Build Coastguard Worker 
1202*9880d681SAndroid Build Coastguard Worker 
operator ()(const IFRecordWithRegSet & A,const IFRecordWithRegSet & B) const1203*9880d681SAndroid Build Coastguard Worker bool IFOrdering::operator() (const IFRecordWithRegSet &A,
1204*9880d681SAndroid Build Coastguard Worker       const IFRecordWithRegSet &B) const {
1205*9880d681SAndroid Build Coastguard Worker   unsigned SizeA = 0, ZeroA = 0, SumA = 0;
1206*9880d681SAndroid Build Coastguard Worker   unsigned SizeB = 0, ZeroB = 0, SumB = 0;
1207*9880d681SAndroid Build Coastguard Worker   stats(A.second, SizeA, ZeroA, SumA);
1208*9880d681SAndroid Build Coastguard Worker   stats(B.second, SizeB, ZeroB, SumB);
1209*9880d681SAndroid Build Coastguard Worker 
1210*9880d681SAndroid Build Coastguard Worker   // We will pick the minimum element. The more zeros, the better.
1211*9880d681SAndroid Build Coastguard Worker   if (ZeroA != ZeroB)
1212*9880d681SAndroid Build Coastguard Worker     return ZeroA > ZeroB;
1213*9880d681SAndroid Build Coastguard Worker   // Compare SumA/SizeA with SumB/SizeB, lower is better.
1214*9880d681SAndroid Build Coastguard Worker   uint64_t AvgA = SumA*SizeB, AvgB = SumB*SizeA;
1215*9880d681SAndroid Build Coastguard Worker   if (AvgA != AvgB)
1216*9880d681SAndroid Build Coastguard Worker     return AvgA < AvgB;
1217*9880d681SAndroid Build Coastguard Worker 
1218*9880d681SAndroid Build Coastguard Worker   // The sets compare identical so far. Resort to comparing the IF records.
1219*9880d681SAndroid Build Coastguard Worker   // The actual values don't matter, this is only for determinism.
1220*9880d681SAndroid Build Coastguard Worker   unsigned OSA = BaseOrd[A.first.SrcR], OSB = BaseOrd[B.first.SrcR];
1221*9880d681SAndroid Build Coastguard Worker   if (OSA != OSB)
1222*9880d681SAndroid Build Coastguard Worker     return OSA < OSB;
1223*9880d681SAndroid Build Coastguard Worker   unsigned OIA = BaseOrd[A.first.InsR], OIB = BaseOrd[B.first.InsR];
1224*9880d681SAndroid Build Coastguard Worker   if (OIA != OIB)
1225*9880d681SAndroid Build Coastguard Worker     return OIA < OIB;
1226*9880d681SAndroid Build Coastguard Worker   if (A.first.Wdh != B.first.Wdh)
1227*9880d681SAndroid Build Coastguard Worker     return A.first.Wdh < B.first.Wdh;
1228*9880d681SAndroid Build Coastguard Worker   return A.first.Off < B.first.Off;
1229*9880d681SAndroid Build Coastguard Worker }
1230*9880d681SAndroid Build Coastguard Worker 
1231*9880d681SAndroid Build Coastguard Worker 
stats(const RegisterSet & Rs,unsigned & Size,unsigned & Zero,unsigned & Sum) const1232*9880d681SAndroid Build Coastguard Worker void IFOrdering::stats(const RegisterSet &Rs, unsigned &Size, unsigned &Zero,
1233*9880d681SAndroid Build Coastguard Worker       unsigned &Sum) const {
1234*9880d681SAndroid Build Coastguard Worker   for (unsigned R = Rs.find_first(); R; R = Rs.find_next(R)) {
1235*9880d681SAndroid Build Coastguard Worker     UnsignedMap::const_iterator F = UseC.find(R);
1236*9880d681SAndroid Build Coastguard Worker     assert(F != UseC.end());
1237*9880d681SAndroid Build Coastguard Worker     unsigned UC = F->second;
1238*9880d681SAndroid Build Coastguard Worker     if (UC == 0)
1239*9880d681SAndroid Build Coastguard Worker       Zero++;
1240*9880d681SAndroid Build Coastguard Worker     Sum += UC;
1241*9880d681SAndroid Build Coastguard Worker     Size++;
1242*9880d681SAndroid Build Coastguard Worker   }
1243*9880d681SAndroid Build Coastguard Worker }
1244*9880d681SAndroid Build Coastguard Worker 
1245*9880d681SAndroid Build Coastguard Worker 
selectCandidates()1246*9880d681SAndroid Build Coastguard Worker void HexagonGenInsert::selectCandidates() {
1247*9880d681SAndroid Build Coastguard Worker   // Some registers may have multiple valid candidates. Pick the best one
1248*9880d681SAndroid Build Coastguard Worker   // (or decide not to use any).
1249*9880d681SAndroid Build Coastguard Worker 
1250*9880d681SAndroid Build Coastguard Worker   // Compute the "removability" measure of R:
1251*9880d681SAndroid Build Coastguard Worker   // For each potentially removable register R, record the number of regis-
1252*9880d681SAndroid Build Coastguard Worker   // ters with IF candidates, where R appears in at least one set.
1253*9880d681SAndroid Build Coastguard Worker   RegisterSet AllRMs;
1254*9880d681SAndroid Build Coastguard Worker   UnsignedMap UseC, RemC;
1255*9880d681SAndroid Build Coastguard Worker   IFMapType::iterator End = IFMap.end();
1256*9880d681SAndroid Build Coastguard Worker 
1257*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(); I != End; ++I) {
1258*9880d681SAndroid Build Coastguard Worker     const IFListType &LL = I->second;
1259*9880d681SAndroid Build Coastguard Worker     RegisterSet TT;
1260*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, n = LL.size(); i < n; ++i)
1261*9880d681SAndroid Build Coastguard Worker       TT.insert(LL[i].second);
1262*9880d681SAndroid Build Coastguard Worker     for (unsigned R = TT.find_first(); R; R = TT.find_next(R))
1263*9880d681SAndroid Build Coastguard Worker       RemC[R]++;
1264*9880d681SAndroid Build Coastguard Worker     AllRMs.insert(TT);
1265*9880d681SAndroid Build Coastguard Worker   }
1266*9880d681SAndroid Build Coastguard Worker 
1267*9880d681SAndroid Build Coastguard Worker   for (unsigned R = AllRMs.find_first(); R; R = AllRMs.find_next(R)) {
1268*9880d681SAndroid Build Coastguard Worker     typedef MachineRegisterInfo::use_nodbg_iterator use_iterator;
1269*9880d681SAndroid Build Coastguard Worker     typedef SmallSet<const MachineInstr*,16> InstrSet;
1270*9880d681SAndroid Build Coastguard Worker     InstrSet UIs;
1271*9880d681SAndroid Build Coastguard Worker     // Count as the number of instructions in which R is used, not the
1272*9880d681SAndroid Build Coastguard Worker     // number of operands.
1273*9880d681SAndroid Build Coastguard Worker     use_iterator E = MRI->use_nodbg_end();
1274*9880d681SAndroid Build Coastguard Worker     for (use_iterator I = MRI->use_nodbg_begin(R); I != E; ++I)
1275*9880d681SAndroid Build Coastguard Worker       UIs.insert(I->getParent());
1276*9880d681SAndroid Build Coastguard Worker     unsigned C = UIs.size();
1277*9880d681SAndroid Build Coastguard Worker     // Calculate a measure, which is the number of instructions using R,
1278*9880d681SAndroid Build Coastguard Worker     // minus the "removability" count computed earlier.
1279*9880d681SAndroid Build Coastguard Worker     unsigned D = RemC[R];
1280*9880d681SAndroid Build Coastguard Worker     UseC[R] = (C > D) ? C-D : 0;  // doz
1281*9880d681SAndroid Build Coastguard Worker   }
1282*9880d681SAndroid Build Coastguard Worker 
1283*9880d681SAndroid Build Coastguard Worker 
1284*9880d681SAndroid Build Coastguard Worker   bool SelectAll0 = OptSelectAll0, SelectHas0 = OptSelectHas0;
1285*9880d681SAndroid Build Coastguard Worker   if (!SelectAll0 && !SelectHas0)
1286*9880d681SAndroid Build Coastguard Worker     SelectAll0 = true;
1287*9880d681SAndroid Build Coastguard Worker 
1288*9880d681SAndroid Build Coastguard Worker   // The smaller the number UseC for a given register R, the "less used"
1289*9880d681SAndroid Build Coastguard Worker   // R is aside from the opportunities for removal offered by generating
1290*9880d681SAndroid Build Coastguard Worker   // "insert" instructions.
1291*9880d681SAndroid Build Coastguard Worker   // Iterate over the IF map, and for those registers that have multiple
1292*9880d681SAndroid Build Coastguard Worker   // candidates, pick the minimum one according to IFOrdering.
1293*9880d681SAndroid Build Coastguard Worker   IFOrdering IFO(UseC, BaseOrd);
1294*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(); I != End; ++I) {
1295*9880d681SAndroid Build Coastguard Worker     IFListType &LL = I->second;
1296*9880d681SAndroid Build Coastguard Worker     if (LL.empty())
1297*9880d681SAndroid Build Coastguard Worker       continue;
1298*9880d681SAndroid Build Coastguard Worker     // Get the minimum element, remember it and clear the list. If the
1299*9880d681SAndroid Build Coastguard Worker     // element found is adequate, we will put it back on the list, other-
1300*9880d681SAndroid Build Coastguard Worker     // wise the list will remain empty, and the entry for this register
1301*9880d681SAndroid Build Coastguard Worker     // will be removed (i.e. this register will not be replaced by insert).
1302*9880d681SAndroid Build Coastguard Worker     IFListType::iterator MinI = std::min_element(LL.begin(), LL.end(), IFO);
1303*9880d681SAndroid Build Coastguard Worker     assert(MinI != LL.end());
1304*9880d681SAndroid Build Coastguard Worker     IFRecordWithRegSet M = *MinI;
1305*9880d681SAndroid Build Coastguard Worker     LL.clear();
1306*9880d681SAndroid Build Coastguard Worker 
1307*9880d681SAndroid Build Coastguard Worker     // We want to make sure that this replacement will have a chance to be
1308*9880d681SAndroid Build Coastguard Worker     // beneficial, and that means that we want to have indication that some
1309*9880d681SAndroid Build Coastguard Worker     // register will be removed. The most likely registers to be eliminated
1310*9880d681SAndroid Build Coastguard Worker     // are the use operands in the definition of I->first. Accept/reject a
1311*9880d681SAndroid Build Coastguard Worker     // candidate based on how many of its uses it can potentially eliminate.
1312*9880d681SAndroid Build Coastguard Worker 
1313*9880d681SAndroid Build Coastguard Worker     RegisterSet Us;
1314*9880d681SAndroid Build Coastguard Worker     const MachineInstr *DefI = MRI->getVRegDef(I->first);
1315*9880d681SAndroid Build Coastguard Worker     getInstrUses(DefI, Us);
1316*9880d681SAndroid Build Coastguard Worker     bool Accept = false;
1317*9880d681SAndroid Build Coastguard Worker 
1318*9880d681SAndroid Build Coastguard Worker     if (SelectAll0) {
1319*9880d681SAndroid Build Coastguard Worker       bool All0 = true;
1320*9880d681SAndroid Build Coastguard Worker       for (unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1321*9880d681SAndroid Build Coastguard Worker         if (UseC[R] == 0)
1322*9880d681SAndroid Build Coastguard Worker           continue;
1323*9880d681SAndroid Build Coastguard Worker         All0 = false;
1324*9880d681SAndroid Build Coastguard Worker         break;
1325*9880d681SAndroid Build Coastguard Worker       }
1326*9880d681SAndroid Build Coastguard Worker       Accept = All0;
1327*9880d681SAndroid Build Coastguard Worker     } else if (SelectHas0) {
1328*9880d681SAndroid Build Coastguard Worker       bool Has0 = false;
1329*9880d681SAndroid Build Coastguard Worker       for (unsigned R = Us.find_first(); R; R = Us.find_next(R)) {
1330*9880d681SAndroid Build Coastguard Worker         if (UseC[R] != 0)
1331*9880d681SAndroid Build Coastguard Worker           continue;
1332*9880d681SAndroid Build Coastguard Worker         Has0 = true;
1333*9880d681SAndroid Build Coastguard Worker         break;
1334*9880d681SAndroid Build Coastguard Worker       }
1335*9880d681SAndroid Build Coastguard Worker       Accept = Has0;
1336*9880d681SAndroid Build Coastguard Worker     }
1337*9880d681SAndroid Build Coastguard Worker     if (Accept)
1338*9880d681SAndroid Build Coastguard Worker       LL.push_back(M);
1339*9880d681SAndroid Build Coastguard Worker   }
1340*9880d681SAndroid Build Coastguard Worker 
1341*9880d681SAndroid Build Coastguard Worker   // Remove candidates that add uses of removable registers, unless the
1342*9880d681SAndroid Build Coastguard Worker   // removable registers are among replacement candidates.
1343*9880d681SAndroid Build Coastguard Worker   // Recompute the removable registers, since some candidates may have
1344*9880d681SAndroid Build Coastguard Worker   // been eliminated.
1345*9880d681SAndroid Build Coastguard Worker   AllRMs.clear();
1346*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(); I != End; ++I) {
1347*9880d681SAndroid Build Coastguard Worker     const IFListType &LL = I->second;
1348*9880d681SAndroid Build Coastguard Worker     if (LL.size() > 0)
1349*9880d681SAndroid Build Coastguard Worker       AllRMs.insert(LL[0].second);
1350*9880d681SAndroid Build Coastguard Worker   }
1351*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(); I != End; ++I) {
1352*9880d681SAndroid Build Coastguard Worker     IFListType &LL = I->second;
1353*9880d681SAndroid Build Coastguard Worker     if (LL.size() == 0)
1354*9880d681SAndroid Build Coastguard Worker       continue;
1355*9880d681SAndroid Build Coastguard Worker     unsigned SR = LL[0].first.SrcR, IR = LL[0].first.InsR;
1356*9880d681SAndroid Build Coastguard Worker     if (AllRMs[SR] || AllRMs[IR])
1357*9880d681SAndroid Build Coastguard Worker       LL.clear();
1358*9880d681SAndroid Build Coastguard Worker   }
1359*9880d681SAndroid Build Coastguard Worker 
1360*9880d681SAndroid Build Coastguard Worker   pruneEmptyLists();
1361*9880d681SAndroid Build Coastguard Worker }
1362*9880d681SAndroid Build Coastguard Worker 
1363*9880d681SAndroid Build Coastguard Worker 
generateInserts()1364*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::generateInserts() {
1365*9880d681SAndroid Build Coastguard Worker   // Create a new register for each one from IFMap, and store them in the
1366*9880d681SAndroid Build Coastguard Worker   // map.
1367*9880d681SAndroid Build Coastguard Worker   UnsignedMap RegMap;
1368*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
1369*9880d681SAndroid Build Coastguard Worker     unsigned VR = I->first;
1370*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass *RC = MRI->getRegClass(VR);
1371*9880d681SAndroid Build Coastguard Worker     unsigned NewVR = MRI->createVirtualRegister(RC);
1372*9880d681SAndroid Build Coastguard Worker     RegMap[VR] = NewVR;
1373*9880d681SAndroid Build Coastguard Worker   }
1374*9880d681SAndroid Build Coastguard Worker 
1375*9880d681SAndroid Build Coastguard Worker   // We can generate the "insert" instructions using potentially stale re-
1376*9880d681SAndroid Build Coastguard Worker   // gisters: SrcR and InsR for a given VR may be among other registers that
1377*9880d681SAndroid Build Coastguard Worker   // are also replaced. This is fine, we will do the mass "rauw" a bit later.
1378*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
1379*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = MRI->getVRegDef(I->first);
1380*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &B = *MI->getParent();
1381*9880d681SAndroid Build Coastguard Worker     DebugLoc DL = MI->getDebugLoc();
1382*9880d681SAndroid Build Coastguard Worker     unsigned NewR = RegMap[I->first];
1383*9880d681SAndroid Build Coastguard Worker     bool R32 = MRI->getRegClass(NewR) == &Hexagon::IntRegsRegClass;
1384*9880d681SAndroid Build Coastguard Worker     const MCInstrDesc &D = R32 ? HII->get(Hexagon::S2_insert)
1385*9880d681SAndroid Build Coastguard Worker                                : HII->get(Hexagon::S2_insertp);
1386*9880d681SAndroid Build Coastguard Worker     IFRecord IF = I->second[0].first;
1387*9880d681SAndroid Build Coastguard Worker     unsigned Wdh = IF.Wdh, Off = IF.Off;
1388*9880d681SAndroid Build Coastguard Worker     unsigned InsS = 0;
1389*9880d681SAndroid Build Coastguard Worker     if (R32 && MRI->getRegClass(IF.InsR) == &Hexagon::DoubleRegsRegClass) {
1390*9880d681SAndroid Build Coastguard Worker       InsS = Hexagon::subreg_loreg;
1391*9880d681SAndroid Build Coastguard Worker       if (Off >= 32) {
1392*9880d681SAndroid Build Coastguard Worker         InsS = Hexagon::subreg_hireg;
1393*9880d681SAndroid Build Coastguard Worker         Off -= 32;
1394*9880d681SAndroid Build Coastguard Worker       }
1395*9880d681SAndroid Build Coastguard Worker     }
1396*9880d681SAndroid Build Coastguard Worker     // Advance to the proper location for inserting instructions. This could
1397*9880d681SAndroid Build Coastguard Worker     // be B.end().
1398*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator At = MI;
1399*9880d681SAndroid Build Coastguard Worker     if (MI->isPHI())
1400*9880d681SAndroid Build Coastguard Worker       At = B.getFirstNonPHI();
1401*9880d681SAndroid Build Coastguard Worker 
1402*9880d681SAndroid Build Coastguard Worker     BuildMI(B, At, DL, D, NewR)
1403*9880d681SAndroid Build Coastguard Worker       .addReg(IF.SrcR)
1404*9880d681SAndroid Build Coastguard Worker       .addReg(IF.InsR, 0, InsS)
1405*9880d681SAndroid Build Coastguard Worker       .addImm(Wdh)
1406*9880d681SAndroid Build Coastguard Worker       .addImm(Off);
1407*9880d681SAndroid Build Coastguard Worker 
1408*9880d681SAndroid Build Coastguard Worker     MRI->clearKillFlags(IF.SrcR);
1409*9880d681SAndroid Build Coastguard Worker     MRI->clearKillFlags(IF.InsR);
1410*9880d681SAndroid Build Coastguard Worker   }
1411*9880d681SAndroid Build Coastguard Worker 
1412*9880d681SAndroid Build Coastguard Worker   for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
1413*9880d681SAndroid Build Coastguard Worker     MachineInstr *DefI = MRI->getVRegDef(I->first);
1414*9880d681SAndroid Build Coastguard Worker     MRI->replaceRegWith(I->first, RegMap[I->first]);
1415*9880d681SAndroid Build Coastguard Worker     DefI->eraseFromParent();
1416*9880d681SAndroid Build Coastguard Worker   }
1417*9880d681SAndroid Build Coastguard Worker 
1418*9880d681SAndroid Build Coastguard Worker   return true;
1419*9880d681SAndroid Build Coastguard Worker }
1420*9880d681SAndroid Build Coastguard Worker 
1421*9880d681SAndroid Build Coastguard Worker 
removeDeadCode(MachineDomTreeNode * N)1422*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::removeDeadCode(MachineDomTreeNode *N) {
1423*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
1424*9880d681SAndroid Build Coastguard Worker   typedef GraphTraits<MachineDomTreeNode*> GTN;
1425*9880d681SAndroid Build Coastguard Worker   for (auto I = GTN::child_begin(N), E = GTN::child_end(N); I != E; ++I)
1426*9880d681SAndroid Build Coastguard Worker     Changed |= removeDeadCode(*I);
1427*9880d681SAndroid Build Coastguard Worker 
1428*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *B = N->getBlock();
1429*9880d681SAndroid Build Coastguard Worker   std::vector<MachineInstr*> Instrs;
1430*9880d681SAndroid Build Coastguard Worker   for (auto I = B->rbegin(), E = B->rend(); I != E; ++I)
1431*9880d681SAndroid Build Coastguard Worker     Instrs.push_back(&*I);
1432*9880d681SAndroid Build Coastguard Worker 
1433*9880d681SAndroid Build Coastguard Worker   for (auto I = Instrs.begin(), E = Instrs.end(); I != E; ++I) {
1434*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = *I;
1435*9880d681SAndroid Build Coastguard Worker     unsigned Opc = MI->getOpcode();
1436*9880d681SAndroid Build Coastguard Worker     // Do not touch lifetime markers. This is why the target-independent DCE
1437*9880d681SAndroid Build Coastguard Worker     // cannot be used.
1438*9880d681SAndroid Build Coastguard Worker     if (Opc == TargetOpcode::LIFETIME_START ||
1439*9880d681SAndroid Build Coastguard Worker         Opc == TargetOpcode::LIFETIME_END)
1440*9880d681SAndroid Build Coastguard Worker       continue;
1441*9880d681SAndroid Build Coastguard Worker     bool Store = false;
1442*9880d681SAndroid Build Coastguard Worker     if (MI->isInlineAsm() || !MI->isSafeToMove(nullptr, Store))
1443*9880d681SAndroid Build Coastguard Worker       continue;
1444*9880d681SAndroid Build Coastguard Worker 
1445*9880d681SAndroid Build Coastguard Worker     bool AllDead = true;
1446*9880d681SAndroid Build Coastguard Worker     SmallVector<unsigned,2> Regs;
1447*9880d681SAndroid Build Coastguard Worker     for (ConstMIOperands Op(*MI); Op.isValid(); ++Op) {
1448*9880d681SAndroid Build Coastguard Worker       if (!Op->isReg() || !Op->isDef())
1449*9880d681SAndroid Build Coastguard Worker         continue;
1450*9880d681SAndroid Build Coastguard Worker       unsigned R = Op->getReg();
1451*9880d681SAndroid Build Coastguard Worker       if (!TargetRegisterInfo::isVirtualRegister(R) ||
1452*9880d681SAndroid Build Coastguard Worker           !MRI->use_nodbg_empty(R)) {
1453*9880d681SAndroid Build Coastguard Worker         AllDead = false;
1454*9880d681SAndroid Build Coastguard Worker         break;
1455*9880d681SAndroid Build Coastguard Worker       }
1456*9880d681SAndroid Build Coastguard Worker       Regs.push_back(R);
1457*9880d681SAndroid Build Coastguard Worker     }
1458*9880d681SAndroid Build Coastguard Worker     if (!AllDead)
1459*9880d681SAndroid Build Coastguard Worker       continue;
1460*9880d681SAndroid Build Coastguard Worker 
1461*9880d681SAndroid Build Coastguard Worker     B->erase(MI);
1462*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0, N = Regs.size(); I != N; ++I)
1463*9880d681SAndroid Build Coastguard Worker       MRI->markUsesInDebugValueAsUndef(Regs[I]);
1464*9880d681SAndroid Build Coastguard Worker     Changed = true;
1465*9880d681SAndroid Build Coastguard Worker   }
1466*9880d681SAndroid Build Coastguard Worker 
1467*9880d681SAndroid Build Coastguard Worker   return Changed;
1468*9880d681SAndroid Build Coastguard Worker }
1469*9880d681SAndroid Build Coastguard Worker 
1470*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & MF)1471*9880d681SAndroid Build Coastguard Worker bool HexagonGenInsert::runOnMachineFunction(MachineFunction &MF) {
1472*9880d681SAndroid Build Coastguard Worker   if (skipFunction(*MF.getFunction()))
1473*9880d681SAndroid Build Coastguard Worker     return false;
1474*9880d681SAndroid Build Coastguard Worker 
1475*9880d681SAndroid Build Coastguard Worker   bool Timing = OptTiming, TimingDetail = Timing && OptTimingDetail;
1476*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
1477*9880d681SAndroid Build Coastguard Worker   TimerGroup __G("hexinsert");
1478*9880d681SAndroid Build Coastguard Worker   NamedRegionTimer __T("hexinsert", Timing && !TimingDetail);
1479*9880d681SAndroid Build Coastguard Worker 
1480*9880d681SAndroid Build Coastguard Worker   // Sanity check: one, but not both.
1481*9880d681SAndroid Build Coastguard Worker   assert(!OptSelectAll0 || !OptSelectHas0);
1482*9880d681SAndroid Build Coastguard Worker 
1483*9880d681SAndroid Build Coastguard Worker   IFMap.clear();
1484*9880d681SAndroid Build Coastguard Worker   BaseOrd.clear();
1485*9880d681SAndroid Build Coastguard Worker   CellOrd.clear();
1486*9880d681SAndroid Build Coastguard Worker 
1487*9880d681SAndroid Build Coastguard Worker   const auto &ST = MF.getSubtarget<HexagonSubtarget>();
1488*9880d681SAndroid Build Coastguard Worker   HII = ST.getInstrInfo();
1489*9880d681SAndroid Build Coastguard Worker   HRI = ST.getRegisterInfo();
1490*9880d681SAndroid Build Coastguard Worker   MFN = &MF;
1491*9880d681SAndroid Build Coastguard Worker   MRI = &MF.getRegInfo();
1492*9880d681SAndroid Build Coastguard Worker   MDT = &getAnalysis<MachineDominatorTree>();
1493*9880d681SAndroid Build Coastguard Worker 
1494*9880d681SAndroid Build Coastguard Worker   // Clean up before any further processing, so that dead code does not
1495*9880d681SAndroid Build Coastguard Worker   // get used in a newly generated "insert" instruction. Have a custom
1496*9880d681SAndroid Build Coastguard Worker   // version of DCE that preserves lifetime markers. Without it, merging
1497*9880d681SAndroid Build Coastguard Worker   // of stack objects can fail to recognize and merge disjoint objects
1498*9880d681SAndroid Build Coastguard Worker   // leading to unnecessary stack growth.
1499*9880d681SAndroid Build Coastguard Worker   Changed = removeDeadCode(MDT->getRootNode());
1500*9880d681SAndroid Build Coastguard Worker 
1501*9880d681SAndroid Build Coastguard Worker   const HexagonEvaluator HE(*HRI, *MRI, *HII, MF);
1502*9880d681SAndroid Build Coastguard Worker   BitTracker BTLoc(HE, MF);
1503*9880d681SAndroid Build Coastguard Worker   BTLoc.trace(isDebug());
1504*9880d681SAndroid Build Coastguard Worker   BTLoc.run();
1505*9880d681SAndroid Build Coastguard Worker   CellMapShadow MS(BTLoc);
1506*9880d681SAndroid Build Coastguard Worker   CMS = &MS;
1507*9880d681SAndroid Build Coastguard Worker 
1508*9880d681SAndroid Build Coastguard Worker   buildOrderingMF(BaseOrd);
1509*9880d681SAndroid Build Coastguard Worker   buildOrderingBT(BaseOrd, CellOrd);
1510*9880d681SAndroid Build Coastguard Worker 
1511*9880d681SAndroid Build Coastguard Worker   if (isDebug()) {
1512*9880d681SAndroid Build Coastguard Worker     dbgs() << "Cell ordering:\n";
1513*9880d681SAndroid Build Coastguard Worker     for (RegisterOrdering::iterator I = CellOrd.begin(), E = CellOrd.end();
1514*9880d681SAndroid Build Coastguard Worker         I != E; ++I) {
1515*9880d681SAndroid Build Coastguard Worker       unsigned VR = I->first, Pos = I->second;
1516*9880d681SAndroid Build Coastguard Worker       dbgs() << PrintReg(VR, HRI) << " -> " << Pos << "\n";
1517*9880d681SAndroid Build Coastguard Worker     }
1518*9880d681SAndroid Build Coastguard Worker   }
1519*9880d681SAndroid Build Coastguard Worker 
1520*9880d681SAndroid Build Coastguard Worker   // Collect candidates for conversion into the insert forms.
1521*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *RootB = MDT->getRoot();
1522*9880d681SAndroid Build Coastguard Worker   OrderedRegisterList AvailR(CellOrd);
1523*9880d681SAndroid Build Coastguard Worker 
1524*9880d681SAndroid Build Coastguard Worker   {
1525*9880d681SAndroid Build Coastguard Worker     NamedRegionTimer _T("collection", "hexinsert", TimingDetail);
1526*9880d681SAndroid Build Coastguard Worker     collectInBlock(RootB, AvailR);
1527*9880d681SAndroid Build Coastguard Worker     // Complete the information gathered in IFMap.
1528*9880d681SAndroid Build Coastguard Worker     computeRemovableRegisters();
1529*9880d681SAndroid Build Coastguard Worker   }
1530*9880d681SAndroid Build Coastguard Worker 
1531*9880d681SAndroid Build Coastguard Worker   if (isDebug()) {
1532*9880d681SAndroid Build Coastguard Worker     dbgs() << "Candidates after collection:\n";
1533*9880d681SAndroid Build Coastguard Worker     dump_map();
1534*9880d681SAndroid Build Coastguard Worker   }
1535*9880d681SAndroid Build Coastguard Worker 
1536*9880d681SAndroid Build Coastguard Worker   if (IFMap.empty())
1537*9880d681SAndroid Build Coastguard Worker     return Changed;
1538*9880d681SAndroid Build Coastguard Worker 
1539*9880d681SAndroid Build Coastguard Worker   {
1540*9880d681SAndroid Build Coastguard Worker     NamedRegionTimer _T("pruning", "hexinsert", TimingDetail);
1541*9880d681SAndroid Build Coastguard Worker     pruneCandidates();
1542*9880d681SAndroid Build Coastguard Worker   }
1543*9880d681SAndroid Build Coastguard Worker 
1544*9880d681SAndroid Build Coastguard Worker   if (isDebug()) {
1545*9880d681SAndroid Build Coastguard Worker     dbgs() << "Candidates after pruning:\n";
1546*9880d681SAndroid Build Coastguard Worker     dump_map();
1547*9880d681SAndroid Build Coastguard Worker   }
1548*9880d681SAndroid Build Coastguard Worker 
1549*9880d681SAndroid Build Coastguard Worker   if (IFMap.empty())
1550*9880d681SAndroid Build Coastguard Worker     return Changed;
1551*9880d681SAndroid Build Coastguard Worker 
1552*9880d681SAndroid Build Coastguard Worker   {
1553*9880d681SAndroid Build Coastguard Worker     NamedRegionTimer _T("selection", "hexinsert", TimingDetail);
1554*9880d681SAndroid Build Coastguard Worker     selectCandidates();
1555*9880d681SAndroid Build Coastguard Worker   }
1556*9880d681SAndroid Build Coastguard Worker 
1557*9880d681SAndroid Build Coastguard Worker   if (isDebug()) {
1558*9880d681SAndroid Build Coastguard Worker     dbgs() << "Candidates after selection:\n";
1559*9880d681SAndroid Build Coastguard Worker     dump_map();
1560*9880d681SAndroid Build Coastguard Worker   }
1561*9880d681SAndroid Build Coastguard Worker 
1562*9880d681SAndroid Build Coastguard Worker   // Filter out vregs beyond the cutoff.
1563*9880d681SAndroid Build Coastguard Worker   if (VRegIndexCutoff.getPosition()) {
1564*9880d681SAndroid Build Coastguard Worker     unsigned Cutoff = VRegIndexCutoff;
1565*9880d681SAndroid Build Coastguard Worker     typedef SmallVector<IFMapType::iterator,16> IterListType;
1566*9880d681SAndroid Build Coastguard Worker     IterListType Out;
1567*9880d681SAndroid Build Coastguard Worker     for (IFMapType::iterator I = IFMap.begin(), E = IFMap.end(); I != E; ++I) {
1568*9880d681SAndroid Build Coastguard Worker       unsigned Idx = TargetRegisterInfo::virtReg2Index(I->first);
1569*9880d681SAndroid Build Coastguard Worker       if (Idx >= Cutoff)
1570*9880d681SAndroid Build Coastguard Worker         Out.push_back(I);
1571*9880d681SAndroid Build Coastguard Worker     }
1572*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, n = Out.size(); i < n; ++i)
1573*9880d681SAndroid Build Coastguard Worker       IFMap.erase(Out[i]);
1574*9880d681SAndroid Build Coastguard Worker   }
1575*9880d681SAndroid Build Coastguard Worker   if (IFMap.empty())
1576*9880d681SAndroid Build Coastguard Worker     return Changed;
1577*9880d681SAndroid Build Coastguard Worker 
1578*9880d681SAndroid Build Coastguard Worker   {
1579*9880d681SAndroid Build Coastguard Worker     NamedRegionTimer _T("generation", "hexinsert", TimingDetail);
1580*9880d681SAndroid Build Coastguard Worker     generateInserts();
1581*9880d681SAndroid Build Coastguard Worker   }
1582*9880d681SAndroid Build Coastguard Worker 
1583*9880d681SAndroid Build Coastguard Worker   return true;
1584*9880d681SAndroid Build Coastguard Worker }
1585*9880d681SAndroid Build Coastguard Worker 
1586*9880d681SAndroid Build Coastguard Worker 
createHexagonGenInsert()1587*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createHexagonGenInsert() {
1588*9880d681SAndroid Build Coastguard Worker   return new HexagonGenInsert();
1589*9880d681SAndroid Build Coastguard Worker }
1590*9880d681SAndroid Build Coastguard Worker 
1591*9880d681SAndroid Build Coastguard Worker 
1592*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1593*9880d681SAndroid Build Coastguard Worker //                         Public Constructor Functions
1594*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1595*9880d681SAndroid Build Coastguard Worker 
1596*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(HexagonGenInsert, "hexinsert",
1597*9880d681SAndroid Build Coastguard Worker   "Hexagon generate \"insert\" instructions", false, false)
1598*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
1599*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(HexagonGenInsert, "hexinsert",
1600*9880d681SAndroid Build Coastguard Worker   "Hexagon generate \"insert\" instructions", false, false)
1601