1f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===--- HexagonBitSimplify.cpp -------------------------------------------===//
2f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
3f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
5f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// License. See LICENSE.TXT for details.
7f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
8f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
9f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
10f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#define DEBUG_TYPE "hexbit"
11f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
12de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "HexagonBitTracker.h"
13de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "HexagonTargetMachine.h"
14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineDominators.h"
15f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineFunctionPass.h"
16f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineInstrBuilder.h"
17f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/CodeGen/MachineRegisterInfo.h"
18de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/CodeGen/Passes.h"
19f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/Debug.h"
20f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h"
21f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "llvm/Target/TargetInstrInfo.h"
22de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Target/TargetMachine.h"
23f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
24f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarusing namespace llvm;
25f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
26f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace llvm {
27f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void initializeHexagonBitSimplifyPass(PassRegistry& Registry);
28f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  FunctionPass *createHexagonBitSimplify();
29f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
30f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
31f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Set of virtual registers, based on BitVector.
33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  struct RegisterSet : private BitVector {
34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet() : BitVector() {}
35f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    explicit RegisterSet(unsigned s, bool t = false) : BitVector(s, t) {}
36f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet(const RegisterSet &RS) : BitVector(RS) {}
37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
38f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    using BitVector::clear;
39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    using BitVector::count;
40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned find_first() const {
42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      int First = BitVector::find_first();
43f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (First < 0)
44f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return 0;
45f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return x2v(First);
46f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
47f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned find_next(unsigned Prev) const {
49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      int Next = BitVector::find_next(v2x(Prev));
50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Next < 0)
51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return 0;
52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return x2v(Next);
53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet &insert(unsigned R) {
56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Idx = v2x(R);
57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ensure(Idx);
58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return static_cast<RegisterSet&>(BitVector::set(Idx));
59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet &remove(unsigned R) {
61f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Idx = v2x(R);
62f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Idx >= size())
63f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return *this;
64f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return static_cast<RegisterSet&>(BitVector::reset(Idx));
65f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
67f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet &insert(const RegisterSet &Rs) {
68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return static_cast<RegisterSet&>(BitVector::operator|=(Rs));
69f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
70f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet &remove(const RegisterSet &Rs) {
71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return static_cast<RegisterSet&>(BitVector::reset(Rs));
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reference operator[](unsigned R) {
75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Idx = v2x(R);
76f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ensure(Idx);
77f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return BitVector::operator[](Idx);
78f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
79f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool operator[](unsigned R) const {
80f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Idx = v2x(R);
81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      assert(Idx < size());
82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return BitVector::operator[](Idx);
83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool has(unsigned R) const {
85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Idx = v2x(R);
86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Idx >= size())
87f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
88f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return BitVector::test(Idx);
89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool empty() const {
92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return !BitVector::any();
93f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
94f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool includes(const RegisterSet &Rs) const {
95f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // A.BitVector::test(B)  <=>  A-B != {}
96f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return !Rs.BitVector::test(*this);
97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool intersects(const RegisterSet &Rs) const {
99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return BitVector::anyCommon(Rs);
100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    void ensure(unsigned Idx) {
104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (size() <= Idx)
105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        resize(std::max(Idx+1, 32U));
106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static inline unsigned v2x(unsigned v) {
108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return TargetRegisterInfo::virtReg2Index(v);
109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static inline unsigned x2v(unsigned x) {
111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return TargetRegisterInfo::index2VirtReg(x);
112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  struct PrintRegSet {
117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    PrintRegSet(const RegisterSet &S, const TargetRegisterInfo *RI)
118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : RS(S), TRI(RI) {}
119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    friend raw_ostream &operator<< (raw_ostream &OS,
120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          const PrintRegSet &P);
121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const RegisterSet &RS;
123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const TargetRegisterInfo *TRI;
124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  raw_ostream &operator<< (raw_ostream &OS, const PrintRegSet &P)
127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LLVM_ATTRIBUTE_UNUSED;
128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  raw_ostream &operator<< (raw_ostream &OS, const PrintRegSet &P) {
129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    OS << '{';
130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned R = P.RS.find_first(); R; R = P.RS.find_next(R))
131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      OS << ' ' << PrintReg(R, P.TRI);
132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    OS << " }";
133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return OS;
134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class Transformation;
140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class HexagonBitSimplify : public MachineFunctionPass {
142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static char ID;
144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HexagonBitSimplify() : MachineFunctionPass(ID), MDT(0) {
145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      initializeHexagonBitSimplifyPass(*PassRegistry::getPassRegistry());
146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    virtual const char *getPassName() const {
148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return "Hexagon bit simplification";
149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      AU.addRequired<MachineDominatorTree>();
152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      AU.addPreserved<MachineDominatorTree>();
153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineFunctionPass::getAnalysisUsage(AU);
154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    virtual bool runOnMachineFunction(MachineFunction &MF);
156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static void getInstrDefs(const MachineInstr &MI, RegisterSet &Defs);
158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static void getInstrUses(const MachineInstr &MI, RegisterSet &Uses);
159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool isEqual(const BitTracker::RegisterCell &RC1, uint16_t B1,
160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        const BitTracker::RegisterCell &RC2, uint16_t B2, uint16_t W);
161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool isZero(const BitTracker::RegisterCell &RC, uint16_t B,
162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint16_t W);
163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool getConst(const BitTracker::RegisterCell &RC, uint16_t B,
164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint16_t W, uint64_t &U);
165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool replaceReg(unsigned OldR, unsigned NewR,
166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MachineRegisterInfo &MRI);
167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool getSubregMask(const BitTracker::RegisterRef &RR,
168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned &Begin, unsigned &Width, MachineRegisterInfo &MRI);
169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool replaceRegWithSub(unsigned OldR, unsigned NewR,
170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned NewSR, MachineRegisterInfo &MRI);
171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool replaceSubWithSub(unsigned OldR, unsigned OldSR,
172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned NewR, unsigned NewSR, MachineRegisterInfo &MRI);
173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool parseRegSequence(const MachineInstr &I,
174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        BitTracker::RegisterRef &SL, BitTracker::RegisterRef &SH);
175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool getUsedBitsInStore(unsigned Opc, BitVector &Bits,
177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint16_t Begin);
178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool getUsedBits(unsigned Opc, unsigned OpN, BitVector &Bits,
179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint16_t Begin, const HexagonInstrInfo &HII);
180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static const TargetRegisterClass *getFinalVRegClass(
182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        const BitTracker::RegisterRef &RR, MachineRegisterInfo &MRI);
183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool isTransparentCopy(const BitTracker::RegisterRef &RD,
184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        const BitTracker::RegisterRef &RS, MachineRegisterInfo &MRI);
185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineDominatorTree *MDT;
188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool visitBlock(MachineBasicBlock &B, Transformation &T, RegisterSet &AVs);
190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  char HexagonBitSimplify::ID = 0;
193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  typedef HexagonBitSimplify HBS;
194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The purpose of this class is to provide a common facility to traverse
197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // the function top-down or bottom-up via the dominator tree, and keep
198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // track of the available registers.
199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class Transformation {
200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool TopDown;
202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Transformation(bool TD) : TopDown(TD) {}
203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    virtual bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) = 0;
204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    virtual ~Transformation() {}
205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS_BEGIN(HexagonBitSimplify, "hexbit",
209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      "Hexagon bit simplification", false, false)
210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS_END(HexagonBitSimplify, "hexbit",
212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      "Hexagon bit simplification", false, false)
213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::visitBlock(MachineBasicBlock &B, Transformation &T,
216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegisterSet &AVs) {
217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineDomTreeNode *N = MDT->getNode(&B);
218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  typedef GraphTraits<MachineDomTreeNode*> GTN;
219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (T.TopDown)
222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed = T.processBlock(B, AVs);
223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet Defs;
225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &I : B)
226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getInstrDefs(I, Defs);
227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet NewAVs = AVs;
228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  NewAVs.insert(Defs);
229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = GTN::child_begin(N), E = GTN::child_end(N); I != E; ++I) {
231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineBasicBlock *SB = (*I)->getBlock();
232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed |= visitBlock(*SB, T, NewAVs);
233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!T.TopDown)
235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed |= T.processBlock(B, AVs);
236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
239f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Utility functions:
242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonBitSimplify::getInstrDefs(const MachineInstr &MI,
244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegisterSet &Defs) {
245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &Op : MI.operands()) {
246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Op.isReg() || !Op.isDef())
247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned R = Op.getReg();
249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!TargetRegisterInfo::isVirtualRegister(R))
250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Defs.insert(R);
252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonBitSimplify::getInstrUses(const MachineInstr &MI,
256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegisterSet &Uses) {
257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &Op : MI.operands()) {
258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Op.isReg() || !Op.isUse())
259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned R = Op.getReg();
261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!TargetRegisterInfo::isVirtualRegister(R))
262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Uses.insert(R);
264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check if all the bits in range [B, E) in both cells are equal.
268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::isEqual(const BitTracker::RegisterCell &RC1,
269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint16_t B1, const BitTracker::RegisterCell &RC2, uint16_t B2,
270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint16_t W) {
271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (uint16_t i = 0; i < W; ++i) {
272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If RC1[i] is "bottom", it cannot be proven equal to RC2[i].
273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RC1[B1+i].Type == BitTracker::BitValue::Ref && RC1[B1+i].RefI.Reg == 0)
274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Same for RC2[i].
276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RC2[B2+i].Type == BitTracker::BitValue::Ref && RC2[B2+i].RefI.Reg == 0)
277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RC1[B1+i] != RC2[B2+i])
279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::isZero(const BitTracker::RegisterCell &RC,
285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint16_t B, uint16_t W) {
286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(B < RC.width() && B+W <= RC.width());
287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (uint16_t i = B; i < B+W; ++i)
288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!RC[i].is(0))
289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::getConst(const BitTracker::RegisterCell &RC,
295f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        uint16_t B, uint16_t W, uint64_t &U) {
296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(B < RC.width() && B+W <= RC.width());
297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t T = 0;
298f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (uint16_t i = B+W; i > B; --i) {
299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::BitValue &BV = RC[i-1];
300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    T <<= 1;
301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (BV.is(1))
302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      T |= 1;
303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if (!BV.is(0))
304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  U = T;
307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::replaceReg(unsigned OldR, unsigned NewR,
312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineRegisterInfo &MRI) {
313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TargetRegisterInfo::isVirtualRegister(OldR) ||
314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      !TargetRegisterInfo::isVirtualRegister(NewR))
315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto Begin = MRI.use_begin(OldR), End = MRI.use_end();
317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  decltype(End) NextI;
318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = Begin; I != End; I = NextI) {
319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NextI = std::next(I);
320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    I->setReg(NewR);
321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Begin != End;
323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::replaceRegWithSub(unsigned OldR, unsigned NewR,
327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned NewSR, MachineRegisterInfo &MRI) {
328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TargetRegisterInfo::isVirtualRegister(OldR) ||
329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      !TargetRegisterInfo::isVirtualRegister(NewR))
330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto Begin = MRI.use_begin(OldR), End = MRI.use_end();
332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  decltype(End) NextI;
333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = Begin; I != End; I = NextI) {
334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NextI = std::next(I);
335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    I->setReg(NewR);
336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    I->setSubReg(NewSR);
337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Begin != End;
339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::replaceSubWithSub(unsigned OldR, unsigned OldSR,
343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned NewR, unsigned NewSR, MachineRegisterInfo &MRI) {
344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TargetRegisterInfo::isVirtualRegister(OldR) ||
345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      !TargetRegisterInfo::isVirtualRegister(NewR))
346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto Begin = MRI.use_begin(OldR), End = MRI.use_end();
348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  decltype(End) NextI;
349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = Begin; I != End; I = NextI) {
350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NextI = std::next(I);
351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (I->getSubReg() != OldSR)
352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    I->setReg(NewR);
354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    I->setSubReg(NewSR);
355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Begin != End;
357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// For a register ref (pair Reg:Sub), set Begin to the position of the LSB
361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of Sub in Reg, and set Width to the size of Sub in bits. Return true,
362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// if this succeeded, otherwise return false.
363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::getSubregMask(const BitTracker::RegisterRef &RR,
364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned &Begin, unsigned &Width, MachineRegisterInfo &MRI) {
365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const TargetRegisterClass *RC = MRI.getRegClass(RR.Reg);
366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RC == &Hexagon::IntRegsRegClass) {
367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(RR.Sub == 0);
368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Begin = 0;
369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Width = 32;
370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RC == &Hexagon::DoubleRegsRegClass) {
373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RR.Sub == 0) {
374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Begin = 0;
375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Width = 64;
376f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
377f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
378f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(RR.Sub == Hexagon::subreg_loreg || RR.Sub == Hexagon::subreg_hireg);
379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Width = 32;
380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Begin = (RR.Sub == Hexagon::subreg_loreg ? 0 : 32);
381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// For a REG_SEQUENCE, set SL to the low subregister and SH to the high
388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// subregister.
389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::parseRegSequence(const MachineInstr &I,
390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef &SL, BitTracker::RegisterRef &SH) {
391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(I.getOpcode() == TargetOpcode::REG_SEQUENCE);
392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Sub1 = I.getOperand(2).getImm(), Sub2 = I.getOperand(4).getImm();
393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(Sub1 != Sub2);
394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Sub1 == Hexagon::subreg_loreg && Sub2 == Hexagon::subreg_hireg) {
395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SL = I.getOperand(1);
396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SH = I.getOperand(3);
397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Sub1 == Hexagon::subreg_hireg && Sub2 == Hexagon::subreg_loreg) {
400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SH = I.getOperand(1);
401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SL = I.getOperand(3);
402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
408f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// All stores (except 64-bit stores) take a 32-bit register as the source
409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of the value to be stored. If the instruction stores into a location
410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// that is shorter than 32 bits, some bits of the source register are not
411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// used. For each store instruction, calculate the set of used bits in
412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// the source register, and set appropriate bits in Bits. Return true if
413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// the bits are calculated, false otherwise.
414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::getUsedBitsInStore(unsigned Opc, BitVector &Bits,
415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint16_t Begin) {
416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  using namespace Hexagon;
417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
419f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Store byte
420f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerb_io:           // memb(Rs32+#s11:0)=Rt32
421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnew_io:        // memb(Rs32+#s11:0)=Nt8.new
422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbt_io:         // if (Pv4) memb(Rs32+#u6:0)=Rt32
423f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbf_io:         // if (!Pv4) memb(Rs32+#u6:0)=Rt32
424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbtnew_io:      // if (Pv4.new) memb(Rs32+#u6:0)=Rt32
425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbfnew_io:      // if (!Pv4.new) memb(Rs32+#u6:0)=Rt32
426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbnewt_io:      // if (Pv4) memb(Rs32+#u6:0)=Nt8.new
427f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbnewf_io:      // if (!Pv4) memb(Rs32+#u6:0)=Nt8.new
428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewtnew_io:   // if (Pv4.new) memb(Rs32+#u6:0)=Nt8.new
429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewfnew_io:   // if (!Pv4.new) memb(Rs32+#u6:0)=Nt8.new
430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerb_pi:           // memb(Rx32++#s4:0)=Rt32
431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnew_pi:        // memb(Rx32++#s4:0)=Nt8.new
432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbt_pi:         // if (Pv4) memb(Rx32++#s4:0)=Rt32
433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbf_pi:         // if (!Pv4) memb(Rx32++#s4:0)=Rt32
434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbtnew_pi:      // if (Pv4.new) memb(Rx32++#s4:0)=Rt32
435f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbfnew_pi:      // if (!Pv4.new) memb(Rx32++#s4:0)=Rt32
436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbnewt_pi:      // if (Pv4) memb(Rx32++#s4:0)=Nt8.new
437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbnewf_pi:      // if (!Pv4) memb(Rx32++#s4:0)=Nt8.new
438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbnewtnew_pi:   // if (Pv4.new) memb(Rx32++#s4:0)=Nt8.new
439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerbnewfnew_pi:   // if (!Pv4.new) memb(Rx32++#s4:0)=Nt8.new
440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerb_ap:           // memb(Re32=#U6)=Rt32
441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerbnew_ap:        // memb(Re32=#U6)=Nt8.new
442f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerb_pr:           // memb(Rx32++Mu2)=Rt32
443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnew_pr:        // memb(Rx32++Mu2)=Nt8.new
444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerb_ur:           // memb(Ru32<<#u2+#U6)=Rt32
445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerbnew_ur:        // memb(Ru32<<#u2+#U6)=Nt8.new
446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerb_pbr:          // memb(Rx32++Mu2:brev)=Rt32
447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnew_pbr:       // memb(Rx32++Mu2:brev)=Nt8.new
448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerb_pci:          // memb(Rx32++#s4:0:circ(Mu2))=Rt32
449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnew_pci:       // memb(Rx32++#s4:0:circ(Mu2))=Nt8.new
450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerb_pcr:          // memb(Rx32++I:circ(Mu2))=Rt32
451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnew_pcr:       // memb(Rx32++I:circ(Mu2))=Nt8.new
452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerb_rr:           // memb(Rs32+Ru32<<#u2)=Rt32
453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerbnew_rr:        // memb(Rs32+Ru32<<#u2)=Nt8.new
454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbt_rr:         // if (Pv4) memb(Rs32+Ru32<<#u2)=Rt32
455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbf_rr:         // if (!Pv4) memb(Rs32+Ru32<<#u2)=Rt32
456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbtnew_rr:      // if (Pv4.new) memb(Rs32+Ru32<<#u2)=Rt32
457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbfnew_rr:      // if (!Pv4.new) memb(Rs32+Ru32<<#u2)=Rt32
458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewt_rr:      // if (Pv4) memb(Rs32+Ru32<<#u2)=Nt8.new
459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewf_rr:      // if (!Pv4) memb(Rs32+Ru32<<#u2)=Nt8.new
460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewtnew_rr:   // if (Pv4.new) memb(Rs32+Ru32<<#u2)=Nt8.new
461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewfnew_rr:   // if (!Pv4.new) memb(Rs32+Ru32<<#u2)=Nt8.new
462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbgp:            // memb(gp+#u16:0)=Rt32
463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerbnewgp:         // memb(gp+#u16:0)=Nt8.new
464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbt_abs:        // if (Pv4) memb(#u6)=Rt32
465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbf_abs:        // if (!Pv4) memb(#u6)=Rt32
466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbtnew_abs:     // if (Pv4.new) memb(#u6)=Rt32
467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbfnew_abs:     // if (!Pv4.new) memb(#u6)=Rt32
468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewt_abs:     // if (Pv4) memb(#u6)=Nt8.new
469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewf_abs:     // if (!Pv4) memb(#u6)=Nt8.new
470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewtnew_abs:  // if (Pv4.new) memb(#u6)=Nt8.new
471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerbnewfnew_abs:  // if (!Pv4.new) memb(#u6)=Nt8.new
472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Bits.set(Begin, Begin+8);
473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Store low half
476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerh_io:           // memh(Rs32+#s11:1)=Rt32
477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnew_io:        // memh(Rs32+#s11:1)=Nt8.new
478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerht_io:         // if (Pv4) memh(Rs32+#u6:1)=Rt32
479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhf_io:         // if (!Pv4) memh(Rs32+#u6:1)=Rt32
480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhtnew_io:      // if (Pv4.new) memh(Rs32+#u6:1)=Rt32
481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhfnew_io:      // if (!Pv4.new) memh(Rs32+#u6:1)=Rt32
482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhnewt_io:      // if (Pv4) memh(Rs32+#u6:1)=Nt8.new
483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhnewf_io:      // if (!Pv4) memh(Rs32+#u6:1)=Nt8.new
484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewtnew_io:   // if (Pv4.new) memh(Rs32+#u6:1)=Nt8.new
485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewfnew_io:   // if (!Pv4.new) memh(Rs32+#u6:1)=Nt8.new
486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerh_pi:           // memh(Rx32++#s4:1)=Rt32
487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnew_pi:        // memh(Rx32++#s4:1)=Nt8.new
488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerht_pi:         // if (Pv4) memh(Rx32++#s4:1)=Rt32
489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhf_pi:         // if (!Pv4) memh(Rx32++#s4:1)=Rt32
490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhtnew_pi:      // if (Pv4.new) memh(Rx32++#s4:1)=Rt32
491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhfnew_pi:      // if (!Pv4.new) memh(Rx32++#s4:1)=Rt32
492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhnewt_pi:      // if (Pv4) memh(Rx32++#s4:1)=Nt8.new
493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhnewf_pi:      // if (!Pv4) memh(Rx32++#s4:1)=Nt8.new
494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhnewtnew_pi:   // if (Pv4.new) memh(Rx32++#s4:1)=Nt8.new
495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerhnewfnew_pi:   // if (!Pv4.new) memh(Rx32++#s4:1)=Nt8.new
496f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerh_ap:           // memh(Re32=#U6)=Rt32
497f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerhnew_ap:        // memh(Re32=#U6)=Nt8.new
498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerh_pr:           // memh(Rx32++Mu2)=Rt32
499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnew_pr:        // memh(Rx32++Mu2)=Nt8.new
500f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerh_ur:           // memh(Ru32<<#u2+#U6)=Rt32
501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerhnew_ur:        // memh(Ru32<<#u2+#U6)=Nt8.new
502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerh_pbr:          // memh(Rx32++Mu2:brev)=Rt32
503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnew_pbr:       // memh(Rx32++Mu2:brev)=Nt8.new
504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerh_pci:          // memh(Rx32++#s4:1:circ(Mu2))=Rt32
505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnew_pci:       // memh(Rx32++#s4:1:circ(Mu2))=Nt8.new
506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerh_pcr:          // memh(Rx32++I:circ(Mu2))=Rt32
507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnew_pcr:       // memh(Rx32++I:circ(Mu2))=Nt8.new
508f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerh_rr:           // memh(Rs32+Ru32<<#u2)=Rt32
509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerht_rr:         // if (Pv4) memh(Rs32+Ru32<<#u2)=Rt32
510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhf_rr:         // if (!Pv4) memh(Rs32+Ru32<<#u2)=Rt32
511f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhtnew_rr:      // if (Pv4.new) memh(Rs32+Ru32<<#u2)=Rt32
512f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhfnew_rr:      // if (!Pv4.new) memh(Rs32+Ru32<<#u2)=Rt32
513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerhnew_rr:        // memh(Rs32+Ru32<<#u2)=Nt8.new
514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewt_rr:      // if (Pv4) memh(Rs32+Ru32<<#u2)=Nt8.new
515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewf_rr:      // if (!Pv4) memh(Rs32+Ru32<<#u2)=Nt8.new
516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewtnew_rr:   // if (Pv4.new) memh(Rs32+Ru32<<#u2)=Nt8.new
517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewfnew_rr:   // if (!Pv4.new) memh(Rs32+Ru32<<#u2)=Nt8.new
518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhgp:            // memh(gp+#u16:1)=Rt32
519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerhnewgp:         // memh(gp+#u16:1)=Nt8.new
520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerht_abs:        // if (Pv4) memh(#u6)=Rt32
521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhf_abs:        // if (!Pv4) memh(#u6)=Rt32
522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhtnew_abs:     // if (Pv4.new) memh(#u6)=Rt32
523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhfnew_abs:     // if (!Pv4.new) memh(#u6)=Rt32
524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewt_abs:     // if (Pv4) memh(#u6)=Nt8.new
525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewf_abs:     // if (!Pv4) memh(#u6)=Nt8.new
526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewtnew_abs:  // if (Pv4.new) memh(#u6)=Nt8.new
527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerhnewfnew_abs:  // if (!Pv4.new) memh(#u6)=Nt8.new
528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Bits.set(Begin, Begin+16);
529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Store high half
532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerf_io:           // memh(Rs32+#s11:1)=Rt.H32
533f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerft_io:         // if (Pv4) memh(Rs32+#u6:1)=Rt.H32
534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerff_io:         // if (!Pv4) memh(Rs32+#u6:1)=Rt.H32
535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerftnew_io:      // if (Pv4.new) memh(Rs32+#u6:1)=Rt.H32
536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerffnew_io:      // if (!Pv4.new) memh(Rs32+#u6:1)=Rt.H32
537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerf_pi:           // memh(Rx32++#s4:1)=Rt.H32
538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerft_pi:         // if (Pv4) memh(Rx32++#s4:1)=Rt.H32
539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerff_pi:         // if (!Pv4) memh(Rx32++#s4:1)=Rt.H32
540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerftnew_pi:      // if (Pv4.new) memh(Rx32++#s4:1)=Rt.H32
541f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_pstorerffnew_pi:      // if (!Pv4.new) memh(Rx32++#s4:1)=Rt.H32
542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerf_ap:           // memh(Re32=#U6)=Rt.H32
543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerf_pr:           // memh(Rx32++Mu2)=Rt.H32
544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerf_ur:           // memh(Ru32<<#u2+#U6)=Rt.H32
545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerf_pbr:          // memh(Rx32++Mu2:brev)=Rt.H32
546f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerf_pci:          // memh(Rx32++#s4:1:circ(Mu2))=Rt.H32
547f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerf_pcr:          // memh(Rx32++I:circ(Mu2))=Rt.H32
548f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_storerf_rr:           // memh(Rs32+Ru32<<#u2)=Rt.H32
549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerft_rr:         // if (Pv4) memh(Rs32+Ru32<<#u2)=Rt.H32
550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerff_rr:         // if (!Pv4) memh(Rs32+Ru32<<#u2)=Rt.H32
551f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerftnew_rr:      // if (Pv4.new) memh(Rs32+Ru32<<#u2)=Rt.H32
552f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerffnew_rr:      // if (!Pv4.new) memh(Rs32+Ru32<<#u2)=Rt.H32
553f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_storerfgp:            // memh(gp+#u16:1)=Rt.H32
554f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerft_abs:        // if (Pv4) memh(#u6)=Rt.H32
555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerff_abs:        // if (!Pv4) memh(#u6)=Rt.H32
556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerftnew_abs:     // if (Pv4.new) memh(#u6)=Rt.H32
557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_pstorerffnew_abs:     // if (!Pv4.new) memh(#u6)=Rt.H32
558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Bits.set(Begin+16, Begin+32);
559f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
563f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
564f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
565f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
566f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// For an instruction with opcode Opc, calculate the set of bits that it
567f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// uses in a register in operand OpN. This only calculates the set of used
568f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// bits for cases where it does not depend on any operands (as is the case
569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// in shifts, for example). For concrete instructions from a program, the
570f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// operand may be a subregister of a larger register, while Bits would
571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// correspond to the larger register in its entirety. Because of that,
572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// the parameter Begin can be used to indicate which bit of Bits should be
573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// considered the LSB of of the operand.
574f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::getUsedBits(unsigned Opc, unsigned OpN,
575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitVector &Bits, uint16_t Begin, const HexagonInstrInfo &HII) {
576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  using namespace Hexagon;
577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCInstrDesc &D = HII.get(Opc);
579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (D.mayStore()) {
580f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (OpN == D.getNumOperands()-1)
581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return getUsedBitsInStore(Opc, Bits, Begin);
582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
584f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // One register source. Used bits: R1[0-7].
587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_sxtb:
588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_zxtb:
589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpbeqi:
590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpbgti:
591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpbgtui:
592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1) {
593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin, Begin+8);
594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // One register source. Used bits: R1[0-15].
599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_aslh:
600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_sxth:
601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_zxth:
602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpheqi:
603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmphgti:
604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmphgtui:
605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1) {
606f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin, Begin+16);
607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // One register source. Used bits: R1[16-31].
612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_asrh:
613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1) {
614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin+16, Begin+32);
615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Two register sources. Used bits: R1[0-7], R2[0-7].
620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpbeq:
621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpbgt:
622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpbgtu:
623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1) {
624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin, Begin+8);
625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Two register sources. Used bits: R1[0-15], R2[0-15].
630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmpheq:
631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmphgt:
632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A4_cmphgtu:
633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_ll:
634f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_sat_ll:
635f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_l16_ll:
636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_l16_sat_ll:
637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_combine_ll:
638f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_ll:
639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_sat_ll:
640f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_l16_ll:
641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_l16_sat_ll:
642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_ll_s0:
643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_ll_s1:
644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_ll_s0:
645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_ll_s1:
646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_ll_s0:
647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_ll_s1:
648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_ll_s0:
649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_ll_s1:
650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_ll_s0:
651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_ll_s1:
652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_ll_s0:
653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_ll_s1:
654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_ll_s0:
655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_ll_s1:
656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_ll_s0:
657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_ll_s1:
658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_ll_s0:
659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_ll_s1:
660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_ll_s0:
661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_ll_s1:
662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_ll_s0:
663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_ll_s1:
664f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_ll_s0:
665f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_ll_s1:
666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_ll_s0:
667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_ll_s1:
668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_ll_s0:
669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_ll_s1:
670f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_ll_s0:
671f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_ll_s1:
672f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_ll_s0:
673f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_ll_s1:
674f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_ll_s0:
675f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_ll_s1:
676f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_ll_s0:
677f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_ll_s1:
678f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1 || OpN == 2) {
679f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin, Begin+16);
680f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Two register sources. Used bits: R1[0-15], R2[16-31].
685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_lh:
686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_sat_lh:
687f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_combine_lh:
688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_lh:
689f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_sat_lh:
690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_lh_s0:
691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_lh_s1:
692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_lh_s0:
693f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_lh_s1:
694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_lh_s0:
695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_lh_s1:
696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_lh_s0:
697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_lh_s1:
698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_lh_s0:
699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_lh_s1:
700f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_lh_s0:
701f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_lh_s1:
702f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_lh_s0:
703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_lh_s1:
704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_lh_s0:
705f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_lh_s1:
706f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_lh_s0:
707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_lh_s1:
708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_lh_s0:
709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_lh_s1:
710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_lh_s0:
711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_lh_s1:
712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_lh_s0:
713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_lh_s1:
714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_lh_s0:
715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_lh_s1:
716f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_lh_s0:
717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_lh_s1:
718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_lh_s0:
719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_lh_s1:
720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_lh_s0:
721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_lh_s1:
722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_lh_s0:
723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_lh_s1:
724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_lh_s0:
725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_lh_s1:
726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // These four are actually LH.
727f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_l16_hl:
728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_l16_sat_hl:
729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_l16_hl:
730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_l16_sat_hl:
731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1) {
732f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin, Begin+16);
733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
734f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 2) {
736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin+16, Begin+32);
737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Two register sources, used bits: R1[16-31], R2[0-15].
742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_hl:
743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_sat_hl:
744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_combine_hl:
745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_hl:
746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_sat_hl:
747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_hl_s0:
748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_hl_s1:
749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_hl_s0:
750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_hl_s1:
751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_hl_s0:
752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_hl_s1:
753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_hl_s0:
754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_hl_s1:
755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_hl_s0:
756f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_hl_s1:
757f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_hl_s0:
758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_hl_s1:
759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_hl_s0:
760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_hl_s1:
761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_hl_s0:
762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_hl_s1:
763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_hl_s0:
764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_hl_s1:
765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_hl_s0:
766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_hl_s1:
767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_hl_s0:
768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_hl_s1:
769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_hl_s0:
770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_hl_s1:
771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_hl_s0:
772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_hl_s1:
773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_hl_s0:
774f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_hl_s1:
775f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_hl_s0:
776f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_hl_s1:
777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_hl_s0:
778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_hl_s1:
779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_hl_s0:
780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_hl_s1:
781f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_hl_s0:
782f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_hl_s1:
783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1) {
784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin+16, Begin+32);
785f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
787f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 2) {
788f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin, Begin+16);
789f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
790f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
791f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
792f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
793f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Two register sources, used bits: R1[16-31], R2[16-31].
794f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_hh:
795f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_addh_h16_sat_hh:
796f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_combine_hh:
797f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_hh:
798f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case A2_subh_h16_sat_hh:
799f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_hh_s0:
800f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_hh_s1:
801f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_hh_s0:
802f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_acc_sat_hh_s1:
803f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_hh_s0:
804f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_hh_s1:
805f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_hh_s0:
806f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_hh_s1:
807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_hh_s0:
808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_nac_sat_hh_s1:
809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_hh_s0:
810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_rnd_hh_s1:
811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_hh_s0:
812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_hh_s1:
813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_hh_s0:
814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpy_sat_rnd_hh_s1:
815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_hh_s0:
816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_acc_hh_s1:
817f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_hh_s0:
818f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_hh_s1:
819f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_hh_s0:
820f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_nac_hh_s1:
821f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_hh_s0:
822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyd_rnd_hh_s1:
823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_hh_s0:
824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_acc_hh_s1:
825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_hh_s0:
826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_hh_s1:
827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_hh_s0:
828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyu_nac_hh_s1:
829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_hh_s0:
830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_acc_hh_s1:
831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_hh_s0:
832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_hh_s1:
833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_hh_s0:
834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case M2_mpyud_nac_hh_s1:
835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (OpN == 1 || OpN == 2) {
836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Bits.set(Begin+16, Begin+32);
837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
845f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
846f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Calculate the register class that matches Reg:Sub. For example, if
847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// vreg1 is a double register, then vreg1:subreg_hireg would match "int"
848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// register class.
849f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarconst TargetRegisterClass *HexagonBitSimplify::getFinalVRegClass(
850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const BitTracker::RegisterRef &RR, MachineRegisterInfo &MRI) {
851f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TargetRegisterInfo::isVirtualRegister(RR.Reg))
852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
853f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto *RC = MRI.getRegClass(RR.Reg);
854f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RR.Sub == 0)
855f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return RC;
856f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
857f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto VerifySR = [] (unsigned Sub) -> void {
858f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(Sub == Hexagon::subreg_hireg || Sub == Hexagon::subreg_loreg);
859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (RC->getID()) {
862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::DoubleRegsRegClassID:
863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      VerifySR(RR.Sub);
864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return &Hexagon::IntRegsRegClass;
865de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case Hexagon::VecDblRegsRegClassID:
866de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      VerifySR(RR.Sub);
867de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return &Hexagon::VectorRegsRegClass;
868de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case Hexagon::VecDblRegs128BRegClassID:
869de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      VerifySR(RR.Sub);
870de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return &Hexagon::VectorRegs128BRegClass;
871f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
872f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return nullptr;
873f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
874f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
875f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
876f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check if RD could be replaced with RS at any possible use of RD.
877f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// For example a predicate register cannot be replaced with a integer
878f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// register, but a 64-bit register with a subregister can be replaced
879f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// with a 32-bit register.
880f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::isTransparentCopy(const BitTracker::RegisterRef &RD,
881f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const BitTracker::RegisterRef &RS, MachineRegisterInfo &MRI) {
882f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TargetRegisterInfo::isVirtualRegister(RD.Reg) ||
883f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      !TargetRegisterInfo::isVirtualRegister(RS.Reg))
884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Return false if one (or both) classes are nullptr.
886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto *DRC = getFinalVRegClass(RD, MRI);
887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!DRC)
888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
890f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return DRC == getFinalVRegClass(RS, MRI);
891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
893f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
894f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Dead code elimination
896f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
897f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
898f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class DeadCodeElimination {
899f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
900f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DeadCodeElimination(MachineFunction &mf, MachineDominatorTree &mdt)
901f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : MF(mf), HII(*MF.getSubtarget<HexagonSubtarget>().getInstrInfo()),
902f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MDT(mdt), MRI(mf.getRegInfo()) {}
903f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
904f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool run() {
905f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return runOnNode(MDT.getRootNode());
906f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
907f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
908f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
909f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isDead(unsigned R) const;
910f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool runOnNode(MachineDomTreeNode *N);
911f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineFunction &MF;
913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonInstrInfo &HII;
914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineDominatorTree &MDT;
915f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo &MRI;
916f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
917f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
918f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool DeadCodeElimination::isDead(unsigned R) const {
921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = MRI.use_begin(R), E = MRI.use_end(); I != E; ++I) {
922f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineInstr *UseI = I->getParent();
923f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (UseI->isDebugValue())
924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (UseI->isPHI()) {
926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      assert(!UseI->getOperand(0).getSubReg());
927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned DR = UseI->getOperand(0).getReg();
928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (DR == R)
929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool DeadCodeElimination::runOnNode(MachineDomTreeNode *N) {
938f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
939f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  typedef GraphTraits<MachineDomTreeNode*> GTN;
940f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = GTN::child_begin(N), E = GTN::child_end(N); I != E; ++I)
941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed |= runOnNode(*I);
942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock *B = N->getBlock();
944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::vector<MachineInstr*> Instrs;
945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = B->rbegin(), E = B->rend(); I != E; ++I)
946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Instrs.push_back(&*I);
947f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
948f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto MI : Instrs) {
949f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned Opc = MI->getOpcode();
950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Do not touch lifetime markers. This is why the target-independent DCE
951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // cannot be used.
952f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Opc == TargetOpcode::LIFETIME_START ||
953f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Opc == TargetOpcode::LIFETIME_END)
954f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
955f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool Store = false;
956f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (MI->isInlineAsm())
957f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Delete PHIs if possible.
959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!MI->isPHI() && !MI->isSafeToMove(nullptr, Store))
960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
962f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool AllDead = true;
963f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SmallVector<unsigned,2> Regs;
964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto &Op : MI->operands()) {
965f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Op.isReg() || !Op.isDef())
966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
967f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned R = Op.getReg();
968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!TargetRegisterInfo::isVirtualRegister(R) || !isDead(R)) {
969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        AllDead = false;
970f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        break;
971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Regs.push_back(R);
973f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
974f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!AllDead)
975f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
976f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
977f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    B->erase(MI);
978f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned i = 0, n = Regs.size(); i != n; ++i)
979f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MRI.markUsesInDebugValueAsUndef(Regs[i]);
980f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed = true;
981f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
982f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
984f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
985f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
987f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
988f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Eliminate redundant instructions
989f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
990f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This transformation will identify instructions where the output register
991f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// is the same as one of its input registers. This only works on instructions
992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// that define a single register (unlike post-increment loads, for example).
993f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The equality check is actually more detailed: the code calculates which
994f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// bits of the output are used, and only compares these bits with the input
995f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// registers.
996f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If the output matches an input, the instruction is replaced with COPY.
997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The copies will be removed by another transformation.
998f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
999f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class RedundantInstrElimination : public Transformation {
1000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
1001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RedundantInstrElimination(BitTracker &bt, const HexagonInstrInfo &hii,
1002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          MachineRegisterInfo &mri)
1003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        : Transformation(true), HII(hii), MRI(mri), BT(bt) {}
1004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
1006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isLossyShiftLeft(const MachineInstr &MI, unsigned OpN,
1007f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          unsigned &LostB, unsigned &LostE);
1008f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isLossyShiftRight(const MachineInstr &MI, unsigned OpN,
1009f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          unsigned &LostB, unsigned &LostE);
1010f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool computeUsedBits(unsigned Reg, BitVector &Bits);
1011f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool computeUsedBits(const MachineInstr &MI, unsigned OpN, BitVector &Bits,
1012f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          uint16_t Begin);
1013f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool usedBitsEqual(BitTracker::RegisterRef RD, BitTracker::RegisterRef RS);
1014f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1015f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonInstrInfo &HII;
1016f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo &MRI;
1017f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker &BT;
1018f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
1019f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1020f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1022f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check if the instruction is a lossy shift left, where the input being
1023f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// shifted is the operand OpN of MI. If true, [LostB, LostE) is the range
1024f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of bit indices that are lost.
1025f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RedundantInstrElimination::isLossyShiftLeft(const MachineInstr &MI,
1026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned OpN, unsigned &LostB, unsigned &LostE) {
1027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  using namespace Hexagon;
1028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI.getOpcode();
1029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ImN, RegN, Width;
1030f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_p:
1032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 2;
1033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 1;
1034f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Width = 64;
1035f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1036f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_p_acc:
1037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_p_and:
1038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_p_nac:
1039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_p_or:
1040f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_p_xacc:
1041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 3;
1042f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 2;
1043f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Width = 64;
1044f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1045f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r:
1046f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 2;
1047f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 1;
1048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Width = 32;
1049f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1050f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_addasl_rrri:
1051f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_andi_asl_ri:
1052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_ori_asl_ri:
1053f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_addi_asl_ri:
1054f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_subi_asl_ri:
1055f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r_acc:
1056f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r_and:
1057f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r_nac:
1058f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r_or:
1059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r_sat:
1060f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asl_i_r_xacc:
1061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 3;
1062f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 2;
1063f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Width = 32;
1064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1065f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
1066f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1067f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1068f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1069f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RegN != OpN)
1070f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1071f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1072f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(MI.getOperand(ImN).isImm());
1073f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned S = MI.getOperand(ImN).getImm();
1074f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (S == 0)
1075f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1076f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LostB = Width-S;
1077f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LostE = Width;
1078f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1079f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1080f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1081f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1082f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check if the instruction is a lossy shift right, where the input being
1083f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// shifted is the operand OpN of MI. If true, [LostB, LostE) is the range
1084f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of bit indices that are lost.
1085f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RedundantInstrElimination::isLossyShiftRight(const MachineInstr &MI,
1086f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned OpN, unsigned &LostB, unsigned &LostE) {
1087f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  using namespace Hexagon;
1088f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI.getOpcode();
1089f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ImN, RegN;
1090f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1091f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_p:
1092f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_p:
1093f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 2;
1094f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 1;
1095f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1096f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_p_acc:
1097f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_p_and:
1098f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_p_nac:
1099f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_p_or:
1100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_p_acc:
1101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_p_and:
1102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_p_nac:
1103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_p_or:
1104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_p_xacc:
1105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 3;
1106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 2;
1107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_r:
1109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_r:
1110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 2;
1111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 1;
1112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_andi_lsr_ri:
1114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_ori_lsr_ri:
1115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_addi_lsr_ri:
1116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S4_subi_lsr_ri:
1117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_r_acc:
1118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_r_and:
1119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_r_nac:
1120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_asr_i_r_or:
1121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_r_acc:
1122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_r_and:
1123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_r_nac:
1124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_r_or:
1125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case S2_lsr_i_r_xacc:
1126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImN = 3;
1127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegN = 2;
1128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
1131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RegN != OpN)
1135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(MI.getOperand(ImN).isImm());
1138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned S = MI.getOperand(ImN).getImm();
1139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LostB = 0;
1140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LostE = S;
1141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Calculate the bit vector that corresponds to the used bits of register Reg.
1146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The vector Bits has the same size, as the size of Reg in bits. If the cal-
1147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// culation fails (i.e. the used bits are unknown), it returns false. Other-
1148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// wise, it returns true and sets the corresponding bits in Bits.
1149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RedundantInstrElimination::computeUsedBits(unsigned Reg, BitVector &Bits) {
1150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitVector Used(Bits.size());
1151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet Visited;
1152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::vector<unsigned> Pending;
1153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Pending.push_back(Reg);
1154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i < Pending.size(); ++i) {
1156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned R = Pending[i];
1157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Visited.has(R))
1158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Visited.insert(R);
1160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto I = MRI.use_begin(R), E = MRI.use_end(); I != E; ++I) {
1161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef UR = *I;
1162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned B, W;
1163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!HBS::getSubregMask(UR, B, W, MRI))
1164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
1165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineInstr &UseI = *I->getParent();
1166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (UseI.isPHI() || UseI.isCopy()) {
1167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned DefR = UseI.getOperand(0).getReg();
1168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (!TargetRegisterInfo::isVirtualRegister(DefR))
1169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          return false;
1170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Pending.push_back(DefR);
1171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
1172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (!computeUsedBits(UseI, I.getOperandNo(), Used, B))
1173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          return false;
1174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
1175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Bits |= Used;
1178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Calculate the bits used by instruction MI in a register in operand OpN.
1183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Return true/false if the calculation succeeds/fails. If is succeeds, set
1184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// used bits in Bits. This function does not reset any bits in Bits, so
1185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// subsequent calls over different instructions will result in the union
1186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of the used bits in all these instructions.
1187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The register in question may be used with a sub-register, whereas Bits
1188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// holds the bits for the entire register. To keep track of that, the
1189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// argument Begin indicates where in Bits is the lowest-significant bit
1190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of the register used in operand OpN. For example, in instruction:
1191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   vreg1 = S2_lsr_i_r vreg2:subreg_hireg, 10
1192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// the operand 1 is a 32-bit register, which happens to be a subregister
1193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of the 64-bit register vreg2, and that subregister starts at position 32.
1194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// In this case Begin=32, since Bits[32] would be the lowest-significant bit
1195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// of vreg2:subreg_hireg.
1196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RedundantInstrElimination::computeUsedBits(const MachineInstr &MI,
1197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned OpN, BitVector &Bits, uint16_t Begin) {
1198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI.getOpcode();
1199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitVector T(Bits.size());
1200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool GotBits = HBS::getUsedBits(Opc, OpN, T, Begin, HII);
1201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Even if we don't have bits yet, we could still provide some information
1202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // if the instruction is a lossy shift: the lost bits will be marked as
1203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // not used.
1204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned LB, LE;
1205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isLossyShiftLeft(MI, OpN, LB, LE) || isLossyShiftRight(MI, OpN, LB, LE)) {
1206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(MI.getOperand(OpN).isReg());
1207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker::RegisterRef RR = MI.getOperand(OpN);
1208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const TargetRegisterClass *RC = HBS::getFinalVRegClass(RR, MRI);
1209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint16_t Width = RC->getSize()*8;
1210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!GotBits)
1212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      T.set(Begin, Begin+Width);
1213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(LB <= LE && LB < Width && LE <= Width);
1214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    T.reset(Begin+LB, Begin+LE);
1215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    GotBits = true;
1216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (GotBits)
1218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Bits |= T;
1219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return GotBits;
1220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Calculates the used bits in RD ("defined register"), and checks if these
1224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// bits in RS ("used register") and RD are identical.
1225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RedundantInstrElimination::usedBitsEqual(BitTracker::RegisterRef RD,
1226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RS) {
1227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &DC = BT.lookup(RD.Reg);
1228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
1229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DB, DW;
1231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!HBS::getSubregMask(RD, DB, DW, MRI))
1232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SB, SW;
1234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!HBS::getSubregMask(RS, SB, SW, MRI))
1235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (SW != DW)
1237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1239f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitVector Used(DC.width());
1240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!computeUsedBits(RD.Reg, Used))
1241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i != DW; ++i)
1244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Used[i+DB] && DC[DB+i] != SC[SB+i])
1245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool RedundantInstrElimination::processBlock(MachineBasicBlock &B,
1251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const RegisterSet&) {
1252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
1253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = B.begin(), E = B.end(), NextI = I; I != E; ++I) {
1255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NextI = std::next(I);
1256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineInstr *MI = &*I;
1257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (MI->getOpcode() == TargetOpcode::COPY)
1259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (MI->hasUnmodeledSideEffects() || MI->isInlineAsm())
1261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned NumD = MI->getDesc().getNumDefs();
1263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (NumD != 1)
1264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker::RegisterRef RD = MI->getOperand(0);
1267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!BT.has(RD.Reg))
1268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::RegisterCell &DC = BT.lookup(RD.Reg);
1270de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    auto At = MI->isPHI() ? B.getFirstNonPHI()
1271de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                          : MachineBasicBlock::iterator(MI);
1272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Find a source operand that is equal to the result.
1274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto &Op : MI->uses()) {
1275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Op.isReg())
1276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RS = Op;
1278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!BT.has(RS.Reg))
1279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!HBS::isTransparentCopy(RD, RS, MRI))
1281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned BN, BW;
1284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!HBS::getSubregMask(RS, BN, BW, MRI))
1285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
1288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!usedBitsEqual(RD, RS) && !HBS::isEqual(DC, 0, SC, BN, BW))
1289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If found, replace the instruction with a COPY.
1292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      const DebugLoc &DL = MI->getDebugLoc();
1293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const TargetRegisterClass *FRC = HBS::getFinalVRegClass(RD, MRI);
1294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned NewR = MRI.createVirtualRegister(FRC);
1295de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
1296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addReg(RS.Reg, 0, RS.Sub);
1297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
1298f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BT.put(BitTracker::RegisterRef(NewR), SC);
1299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed = true;
1300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
1305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Const generation
1310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Recognize instructions that produce constant values known at compile-time.
1312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Replace them with register definitions that load these constants directly.
1313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
1314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class ConstGeneration : public Transformation {
1315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
1316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ConstGeneration(BitTracker &bt, const HexagonInstrInfo &hii,
1317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MachineRegisterInfo &mri)
1318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : Transformation(true), HII(hii), MRI(mri), BT(bt) {}
1319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
1321de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool isTfrConst(const MachineInstr &MI) const;
1322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isConst(unsigned R, int64_t &V) const;
1323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned genTfrConst(const TargetRegisterClass *RC, int64_t C,
1324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MachineBasicBlock &B, MachineBasicBlock::iterator At, DebugLoc &DL);
1325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonInstrInfo &HII;
1327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo &MRI;
1328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker &BT;
1329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
1330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool ConstGeneration::isConst(unsigned R, int64_t &C) const {
1333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BT.has(R))
1334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &RC = BT.lookup(R);
1336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t T = 0;
1337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = RC.width(); i > 0; --i) {
1338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::BitValue &V = RC[i-1];
1339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    T <<= 1;
1340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V.is(1))
1341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      T |= 1;
1342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if (!V.is(0))
1343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  C = T;
1346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool ConstGeneration::isTfrConst(const MachineInstr &MI) const {
1350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned Opc = MI.getOpcode();
1351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combineii:
1353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineii:
1354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_tfrsi:
1355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_tfrpi:
1356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::TFR_PdTrue:
1357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::TFR_PdFalse:
1358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::CONST32_Int_Real:
1359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::CONST64_Int_Real:
1360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
1361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
1363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Generate a transfer-immediate instruction that is appropriate for the
1367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// register class and the actual value being transferred.
1368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned ConstGeneration::genTfrConst(const TargetRegisterClass *RC, int64_t C,
1369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineBasicBlock &B, MachineBasicBlock::iterator At, DebugLoc &DL) {
1370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Reg = MRI.createVirtualRegister(RC);
1371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RC == &Hexagon::IntRegsRegClass) {
1372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrsi), Reg)
1373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        .addImm(int32_t(C));
1374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Reg;
1375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1376f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1377f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RC == &Hexagon::DoubleRegsRegClass) {
1378f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isInt<8>(C)) {
1379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BuildMI(B, At, DL, HII.get(Hexagon::A2_tfrpi), Reg)
1380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addImm(C);
1381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return Reg;
1382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned Lo = Lo_32(C), Hi = Hi_32(C);
1385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isInt<8>(Lo) || isInt<8>(Hi)) {
1386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Opc = isInt<8>(Lo) ? Hexagon::A2_combineii
1387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                  : Hexagon::A4_combineii;
1388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BuildMI(B, At, DL, HII.get(Opc), Reg)
1389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addImm(int32_t(Hi))
1390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addImm(int32_t(Lo));
1391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return Reg;
1392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BuildMI(B, At, DL, HII.get(Hexagon::CONST64_Int_Real), Reg)
1395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        .addImm(C);
1396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Reg;
1397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RC == &Hexagon::PredRegsRegClass) {
1400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned Opc;
1401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (C == 0)
1402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Opc = Hexagon::TFR_PdFalse;
1403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if ((C & 0xFF) == 0xFF)
1404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Opc = Hexagon::TFR_PdTrue;
1405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
1406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return 0;
1407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BuildMI(B, At, DL, HII.get(Opc), Reg);
1408f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Reg;
1409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return 0;
1412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool ConstGeneration::processBlock(MachineBasicBlock &B, const RegisterSet&) {
1416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
1417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet Defs;
1418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1419f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = B.begin(), E = B.end(); I != E; ++I) {
1420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (isTfrConst(*I))
1421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Defs.clear();
1423f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::getInstrDefs(*I, Defs);
1424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Defs.count() != 1)
1425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned DR = Defs.find_first();
1427f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!TargetRegisterInfo::isVirtualRegister(DR))
1428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int64_t C;
1430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isConst(DR, C)) {
1431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      DebugLoc DL = I->getDebugLoc();
1432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto At = I->isPHI() ? B.getFirstNonPHI() : I;
1433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned ImmReg = genTfrConst(MRI.getRegClass(DR), C, B, At, DL);
1434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ImmReg) {
1435f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        HBS::replaceReg(DR, ImmReg, MRI);
1436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        BT.put(ImmReg, BT.lookup(DR));
1437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Changed = true;
1438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
1439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
1442f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Copy generation
1447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Identify pairs of available registers which hold identical values.
1449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// In such cases, only one of them needs to be calculated, the other one
1450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// will be defined as a copy of the first.
1451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Copy propagation
1453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Eliminate register copies RD = RS, by replacing the uses of RD with
1455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// with uses of RS.
1456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
1457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class CopyGeneration : public Transformation {
1458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
1459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CopyGeneration(BitTracker &bt, const HexagonInstrInfo &hii,
1460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MachineRegisterInfo &mri)
1461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : Transformation(true), HII(hii), MRI(mri), BT(bt) {}
1462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
1464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool findMatch(const BitTracker::RegisterRef &Inp,
1465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        BitTracker::RegisterRef &Out, const RegisterSet &AVs);
1466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonInstrInfo &HII;
1468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo &MRI;
1469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker &BT;
1470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
1471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class CopyPropagation : public Transformation {
1473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
1474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CopyPropagation(const HexagonRegisterInfo &hri, MachineRegisterInfo &mri)
1475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        : Transformation(false), MRI(mri) {}
1476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static bool isCopyReg(unsigned Opc);
1478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
1479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool propagateRegCopy(MachineInstr &MI);
1480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo &MRI;
1482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
1483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Check if there is a register in AVs that is identical to Inp. If so,
1488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// set Out to the found register. The output may be a pair Reg:Sub.
1489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool CopyGeneration::findMatch(const BitTracker::RegisterRef &Inp,
1490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef &Out, const RegisterSet &AVs) {
1491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BT.has(Inp.Reg))
1492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &InpRC = BT.lookup(Inp.Reg);
1494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned B, W;
1495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!HBS::getSubregMask(Inp, B, W, MRI))
1496f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1497f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned R = AVs.find_first(); R; R = AVs.find_next(R)) {
1499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!BT.has(R) || !HBS::isTransparentCopy(R, Inp, MRI))
1500f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::RegisterCell &RC = BT.lookup(R);
1502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned RW = RC.width();
1503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (W == RW) {
1504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (MRI.getRegClass(Inp.Reg) != MRI.getRegClass(R))
1505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!HBS::isEqual(InpRC, B, RC, 0, W))
1507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1508f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Out.Reg = R;
1509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Out.Sub = 0;
1510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
1511f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1512f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Check if there is a super-register, whose part (with a subregister)
1513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // is equal to the input.
1514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Only do double registers for now.
1515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (W*2 != RW)
1516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (MRI.getRegClass(R) != &Hexagon::DoubleRegsRegClass)
1518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (HBS::isEqual(InpRC, B, RC, 0, W))
1521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Out.Sub = Hexagon::subreg_loreg;
1522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if (HBS::isEqual(InpRC, B, RC, W, W))
1523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Out.Sub = Hexagon::subreg_hireg;
1524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
1525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Out.Reg = R;
1527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
1528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
1530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1533f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool CopyGeneration::processBlock(MachineBasicBlock &B,
1534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const RegisterSet &AVs) {
1535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet AVB(AVs);
1536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
1537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet Defs;
1538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = B.begin(), E = B.end(), NextI = I; I != E;
1540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar       ++I, AVB.insert(Defs)) {
1541f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NextI = std::next(I);
1542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Defs.clear();
1543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::getInstrDefs(*I, Defs);
1544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned Opc = I->getOpcode();
1546f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (CopyPropagation::isCopyReg(Opc))
1547f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1548f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned R = Defs.find_first(); R; R = Defs.find_next(R)) {
1550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef MR;
1551f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!findMatch(R, MR, AVB))
1552f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
1553f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      DebugLoc DL = I->getDebugLoc();
1554f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto *FRC = HBS::getFinalVRegClass(MR, MRI);
1555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned NewR = MRI.createVirtualRegister(FRC);
1556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      auto At = I->isPHI() ? B.getFirstNonPHI() : I;
1557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
1558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        .addReg(MR.Reg, 0, MR.Sub);
1559f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BT.put(BitTracker::RegisterRef(NewR), BT.get(MR));
1560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1563f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
1564f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1565f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1566f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1567f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool CopyPropagation::isCopyReg(unsigned Opc) {
1568f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetOpcode::COPY:
1570f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetOpcode::REG_SEQUENCE:
1571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_tfr:
1572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_tfrp:
1573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combinew:
1574f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineir:
1575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineri:
1576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
1577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
1578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1580f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
1581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1584f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool CopyPropagation::propagateRegCopy(MachineInstr &MI) {
1585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
1586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI.getOpcode();
1587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker::RegisterRef RD = MI.getOperand(0);
1588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(MI.getOperand(0).getSubReg() == 0);
1589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetOpcode::COPY:
1592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_tfr:
1593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_tfrp: {
1594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RS = MI.getOperand(1);
1595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!HBS::isTransparentCopy(RD, RS, MRI))
1596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        break;
1597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (RS.Sub != 0)
1598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Changed = HBS::replaceRegWithSub(RD.Reg, RS.Reg, RS.Sub, MRI);
1599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else
1600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Changed = HBS::replaceReg(RD.Reg, RS.Reg, MRI);
1601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetOpcode::REG_SEQUENCE: {
1604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef SL, SH;
1605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (HBS::parseRegSequence(MI, SL, SH)) {
1606f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Changed = HBS::replaceSubWithSub(RD.Reg, Hexagon::subreg_loreg,
1607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                         SL.Reg, SL.Sub, MRI);
1608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Changed |= HBS::replaceSubWithSub(RD.Reg, Hexagon::subreg_hireg,
1609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                          SH.Reg, SH.Sub, MRI);
1610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
1611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combinew: {
1614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RH = MI.getOperand(1), RL = MI.getOperand(2);
1615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed = HBS::replaceSubWithSub(RD.Reg, Hexagon::subreg_loreg,
1616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                       RL.Reg, RL.Sub, MRI);
1617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed |= HBS::replaceSubWithSub(RD.Reg, Hexagon::subreg_hireg,
1618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                        RH.Reg, RH.Sub, MRI);
1619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineir:
1622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineri: {
1623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned SrcX = (Opc == Hexagon::A4_combineir) ? 2 : 1;
1624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Sub = (Opc == Hexagon::A4_combineir) ? Hexagon::subreg_loreg
1625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                    : Hexagon::subreg_hireg;
1626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RS = MI.getOperand(SrcX);
1627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed = HBS::replaceSubWithSub(RD.Reg, Sub, RS.Reg, RS.Sub, MRI);
1628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
1632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1634f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1635f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool CopyPropagation::processBlock(MachineBasicBlock &B, const RegisterSet&) {
1636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::vector<MachineInstr*> Instrs;
1637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = B.rbegin(), E = B.rend(); I != E; ++I)
1638f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Instrs.push_back(&*I);
1639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1640f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
1641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I : Instrs) {
1642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned Opc = I->getOpcode();
1643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!CopyPropagation::isCopyReg(Opc))
1644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed |= propagateRegCopy(*I);
1646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
1649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Bit simplification
1654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
1655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Recognize patterns that can be simplified and replace them with the
1656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// simpler forms.
1657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This is by no means complete
1658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
1659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class BitSimplification : public Transformation {
1660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
1661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitSimplification(BitTracker &bt, const HexagonInstrInfo &hii,
1662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MachineRegisterInfo &mri)
1663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      : Transformation(true), HII(hii), MRI(mri), BT(bt) {}
1664f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
1665f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
1666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    struct RegHalf : public BitTracker::RegisterRef {
1667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      bool Low;  // Low/High halfword.
1668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    };
1669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1670f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool matchHalf(unsigned SelfR, const BitTracker::RegisterCell &RC,
1671f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          unsigned B, RegHalf &RH);
1672f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1673f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool matchPackhl(unsigned SelfR, const BitTracker::RegisterCell &RC,
1674f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          BitTracker::RegisterRef &Rs, BitTracker::RegisterRef &Rt);
1675f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned getCombineOpcode(bool HLow, bool LLow);
1676f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1677f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool genStoreUpperHalf(MachineInstr *MI);
1678f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool genStoreImmediate(MachineInstr *MI);
1679f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool genPackhl(MachineInstr *MI, BitTracker::RegisterRef RD,
1680f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          const BitTracker::RegisterCell &RC);
1681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool genExtractHalf(MachineInstr *MI, BitTracker::RegisterRef RD,
1682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          const BitTracker::RegisterCell &RC);
1683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool genCombineHalf(MachineInstr *MI, BitTracker::RegisterRef RD,
1684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          const BitTracker::RegisterCell &RC);
1685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool genExtractLow(MachineInstr *MI, BitTracker::RegisterRef RD,
1686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          const BitTracker::RegisterCell &RC);
1687f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool simplifyTstbit(MachineInstr *MI, BitTracker::RegisterRef RD,
1688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          const BitTracker::RegisterCell &RC);
1689f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonInstrInfo &HII;
1691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo &MRI;
1692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker &BT;
1693f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
1694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check if the bits [B..B+16) in register cell RC form a valid halfword,
1698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// i.e. [0..16), [16..32), etc. of some register. If so, return true and
1699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// set the information about the found register in RH.
1700f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::matchHalf(unsigned SelfR,
1701f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const BitTracker::RegisterCell &RC, unsigned B, RegHalf &RH) {
1702f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // XXX This could be searching in the set of available registers, in case
1703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // the match is not exact.
1704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1705f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Match 16-bit chunks, where the RC[B..B+15] references exactly one
1706f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // register and all the bits B..B+15 match between RC and the register.
1707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // This is meant to match "v1[0-15]", where v1 = { [0]:0 [1-15]:v1... },
1708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // and RC = { [0]:0 [1-15]:v1[1-15]... }.
1709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Low = false;
1710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned I = B;
1711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  while (I < B+16 && RC[I].num())
1712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    I++;
1713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (I == B+16)
1714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1716f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Reg = RC[I].RefI.Reg;
1717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned P = RC[I].RefI.Pos;    // The RefI.Pos will be advanced by I-B.
1718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (P < I-B)
1719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Pos = P - (I-B);
1721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Reg == 0 || Reg == SelfR)    // Don't match "self".
1723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!TargetRegisterInfo::isVirtualRegister(Reg))
1725f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1726f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BT.has(Reg))
1727f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &SC = BT.lookup(Reg);
1730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Pos+16 > SC.width())
1731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1732f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i < 16; ++i) {
1734f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::BitValue &RV = RC[i+B];
1735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RV.Type == BitTracker::BitValue::Ref) {
1736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (RV.RefI.Reg != Reg)
1737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
1738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (RV.RefI.Pos != i+Pos)
1739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
1740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
1741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RC[i+B] != SC[i+Pos])
1743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Sub = 0;
1747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Pos) {
1748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case 0:
1749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Sub = Hexagon::subreg_loreg;
1750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Low = true;
1751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case 16:
1753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Sub = Hexagon::subreg_loreg;
1754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Low = false;
1755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1756f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case 32:
1757f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Sub = Hexagon::subreg_hireg;
1758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Low = true;
1759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case 48:
1761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Sub = Hexagon::subreg_hireg;
1762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Low = false;
1763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
1765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RH.Reg = Reg;
1769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RH.Sub = Sub;
1770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RH.Low = Low;
1771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If the subregister is not valid with the register, set it to 0.
1772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!HBS::getFinalVRegClass(RH, MRI))
1773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RH.Sub = 0;
1774f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1775f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1776f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check if RC matches the pattern of a S2_packhl. If so, return true and
1780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// set the inputs Rs and Rt.
1781f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::matchPackhl(unsigned SelfR,
1782f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const BitTracker::RegisterCell &RC, BitTracker::RegisterRef &Rs,
1783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef &Rt) {
1784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegHalf L1, H1, L2, H2;
1785f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!matchHalf(SelfR, RC, 0, L2)  || !matchHalf(SelfR, RC, 16, L1))
1787f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1788f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!matchHalf(SelfR, RC, 32, H2) || !matchHalf(SelfR, RC, 48, H1))
1789f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1790f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1791f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Rs = H1.L1, Rt = H2.L2
1792f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (H1.Reg != L1.Reg || H1.Sub != L1.Sub || H1.Low || !L1.Low)
1793f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1794f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (H2.Reg != L2.Reg || H2.Sub != L2.Sub || H2.Low || !L2.Low)
1795f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1796f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1797f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Rs = H1;
1798f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Rt = H2;
1799f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1800f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1801f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1802f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1803f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned BitSimplification::getCombineOpcode(bool HLow, bool LLow) {
1804f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return HLow ? LLow ? Hexagon::A2_combine_ll
1805f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     : Hexagon::A2_combine_lh
1806f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              : LLow ? Hexagon::A2_combine_hl
1807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     : Hexagon::A2_combine_hh;
1808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If MI stores the upper halfword of a register (potentially obtained via
1812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// shifts or extracts), replace it with a storerf instruction. This could
1813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// cause the "extraction" code to become dead.
1814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::genStoreUpperHalf(MachineInstr *MI) {
1815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
1816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Opc != Hexagon::S2_storerh_io)
1817f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1818f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1819f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineOperand &ValOp = MI->getOperand(2);
1820f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker::RegisterRef RS = ValOp;
1821f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BT.has(RS.Reg))
1822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &RC = BT.lookup(RS.Reg);
1824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegHalf H;
1825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!matchHalf(0, RC, 0, H))
1826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (H.Low)
1828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MI->setDesc(HII.get(Hexagon::S2_storerf_io));
1830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ValOp.setReg(H.Reg);
1831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ValOp.setSubReg(H.Sub);
1832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If MI stores a value known at compile-time, and the value is within a range
1837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// that avoids using constant-extenders, replace it with a store-immediate.
1838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::genStoreImmediate(MachineInstr *MI) {
1839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
1840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Align = 0;
1841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storeri_io:
1843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Align++;
1844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storerh_io:
1845f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Align++;
1846f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storerb_io:
1847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
1849f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1851f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Avoid stores to frame-indices (due to an unknown offset).
1853f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!MI->getOperand(0).isReg())
1854f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1855f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineOperand &OffOp = MI->getOperand(1);
1856f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!OffOp.isImm())
1857f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1858f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t Off = OffOp.getImm();
1860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Offset is u6:a. Sadly, there is no isShiftedUInt(n,x).
1861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!isUIntN(6+Align, Off) || (Off & ((1<<Align)-1)))
1862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Source register:
1864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker::RegisterRef RS = MI->getOperand(2);
1865f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BT.has(RS.Reg))
1866f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1867f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &RC = BT.lookup(RS.Reg);
1868f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  uint64_t U;
1869f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!HBS::getConst(RC, 0, RC.width(), U))
1870f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1871f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1872f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Only consider 8-bit values to avoid constant-extenders.
1873f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int V;
1874f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1875f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storerb_io:
1876f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      V = int8_t(U);
1877f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1878f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storerh_io:
1879f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      V = int16_t(U);
1880f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1881f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storeri_io:
1882f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      V = int32_t(U);
1883f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!isInt<8>(V))
1886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MI->RemoveOperand(2);
1889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
1890f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storerb_io:
1891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MI->setDesc(HII.get(Hexagon::S4_storeirb_io));
1892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1893f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storerh_io:
1894f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MI->setDesc(HII.get(Hexagon::S4_storeirh_io));
1895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1896f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_storeri_io:
1897f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MI->setDesc(HII.get(Hexagon::S4_storeiri_io));
1898f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
1899f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1900f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MI->addOperand(MachineOperand::CreateImm(V));
1901f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1902f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1903f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1904f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1905f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If MI is equivalent o S2_packhl, generate the S2_packhl. MI could be the
1906f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// last instruction in a sequence that results in something equivalent to
1907f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// the pack-halfwords. The intent is to cause the entire sequence to become
1908f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// dead.
1909f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::genPackhl(MachineInstr *MI,
1910f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
1911f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
1912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Opc == Hexagon::S2_packhl)
1913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker::RegisterRef Rs, Rt;
1915f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!matchPackhl(RD.Reg, RC, Rs, Rt))
1916f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1917f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1918f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock &B = *MI->getParent();
1919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned NewR = MRI.createVirtualRegister(&Hexagon::DoubleRegsRegClass);
1920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DebugLoc DL = MI->getDebugLoc();
1921de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  auto At = MI->isPHI() ? B.getFirstNonPHI()
1922de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                        : MachineBasicBlock::iterator(MI);
1923de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BuildMI(B, At, DL, HII.get(Hexagon::S2_packhl), NewR)
1924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      .addReg(Rs.Reg, 0, Rs.Sub)
1925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      .addReg(Rt.Reg, 0, Rt.Sub);
1926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
1927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BT.put(BitTracker::RegisterRef(NewR), RC);
1928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If MI produces halfword of the input in the low half of the output,
1933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// replace it with zero-extend or extractu.
1934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::genExtractHalf(MachineInstr *MI,
1935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
1936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegHalf L;
1937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Check for halfword in low 16 bits, zeros elsewhere.
1938f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!matchHalf(RD.Reg, RC, 0, L) || !HBS::isZero(RC, 16, 16))
1939f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1940f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
1942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock &B = *MI->getParent();
1943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DebugLoc DL = MI->getDebugLoc();
1944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Prefer zxth, since zxth can go in any slot, while extractu only in
1946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // slots 2 and 3.
1947f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned NewR = 0;
1948de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  auto At = MI->isPHI() ? B.getFirstNonPHI()
1949de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                        : MachineBasicBlock::iterator(MI);
1950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (L.Low && Opc != Hexagon::A2_zxth) {
1951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1952de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    BuildMI(B, At, DL, HII.get(Hexagon::A2_zxth), NewR)
1953f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        .addReg(L.Reg, 0, L.Sub);
1954de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  } else if (!L.Low && Opc != Hexagon::S2_lsr_i_r) {
1955f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1956de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    BuildMI(B, MI, DL, HII.get(Hexagon::S2_lsr_i_r), NewR)
1957f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        .addReg(L.Reg, 0, L.Sub)
1958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        .addImm(16);
1959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (NewR == 0)
1961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1962f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
1963f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BT.put(BitTracker::RegisterRef(NewR), RC);
1964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1965f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1967f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If MI is equivalent to a combine(.L/.H, .L/.H) replace with with the
1969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// combine.
1970f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::genCombineHalf(MachineInstr *MI,
1971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
1972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegHalf L, H;
1973f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Check for combine h/l
1974f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!matchHalf(RD.Reg, RC, 0, L) || !matchHalf(RD.Reg, RC, 16, H))
1975f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1976f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Do nothing if this is just a reg copy.
1977f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (L.Reg == H.Reg && L.Sub == H.Sub && !H.Low && L.Low)
1978f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1979f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1980f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
1981f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned COpc = getCombineOpcode(H.Low, L.Low);
1982f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (COpc == Opc)
1983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
1984f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1985f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock &B = *MI->getParent();
1986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DebugLoc DL = MI->getDebugLoc();
1987f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
1988de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  auto At = MI->isPHI() ? B.getFirstNonPHI()
1989de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                        : MachineBasicBlock::iterator(MI);
1990de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  BuildMI(B, At, DL, HII.get(COpc), NewR)
1991f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      .addReg(H.Reg, 0, H.Sub)
1992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      .addReg(L.Reg, 0, L.Sub);
1993f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
1994f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BT.put(BitTracker::RegisterRef(NewR), RC);
1995f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
1996f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1998f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1999f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// If MI resets high bits of a register and keeps the lower ones, replace it
2000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// with zero-extend byte/half, and-immediate, or extractu, as appropriate.
2001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::genExtractLow(MachineInstr *MI,
2002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
2004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
2005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_zxtb:
2006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_zxth:
2007f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_extractu:
2008f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2009f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2010f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Opc == Hexagon::A2_andir && MI->getOperand(2).isImm()) {
2011f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int32_t Imm = MI->getOperand(2).getImm();
2012f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isInt<10>(Imm))
2013f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2014f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2015f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2016f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (MI->hasUnmodeledSideEffects() || MI->isInlineAsm())
2017f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2018f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned W = RC.width();
2019f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  while (W > 0 && RC[W-1].is(0))
2020f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    W--;
2021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (W == 0 || W == RC.width())
2022f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2023f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned NewOpc = (W == 8)  ? Hexagon::A2_zxtb
2024f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  : (W == 16) ? Hexagon::A2_zxth
2025f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  : (W < 10)  ? Hexagon::A2_andir
2026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  : Hexagon::S2_extractu;
2027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock &B = *MI->getParent();
2028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DebugLoc DL = MI->getDebugLoc();
2029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2030f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &Op : MI->uses()) {
2031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Op.isReg())
2032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker::RegisterRef RS = Op;
2034f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!BT.has(RS.Reg))
2035f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2036f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
2037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned BN, BW;
2038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!HBS::getSubregMask(RS, BN, BW, MRI))
2039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2040f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (BW < W || !HBS::isEqual(RC, 0, SC, BN, W))
2041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2042f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2043f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned NewR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    auto At = MI->isPHI() ? B.getFirstNonPHI()
2045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                          : MachineBasicBlock::iterator(MI);
2046de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    auto MIB = BuildMI(B, At, DL, HII.get(NewOpc), NewR)
2047f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  .addReg(RS.Reg, 0, RS.Sub);
2048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (NewOpc == Hexagon::A2_andir)
2049f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MIB.addImm((1 << W) - 1);
2050f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if (NewOpc == Hexagon::S2_extractu)
2051f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MIB.addImm(W).addImm(0);
2052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::replaceSubWithSub(RD.Reg, RD.Sub, NewR, 0, MRI);
2053f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BT.put(BitTracker::RegisterRef(NewR), RC);
2054f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
2055f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2056f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
2057f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2058f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2060f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Check for tstbit simplification opportunity, where the bit being checked
2061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// can be tracked back to another register. For example:
2062f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   vreg2 = S2_lsr_i_r  vreg1, 5
2063f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   vreg3 = S2_tstbit_i vreg2, 0
2064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// =>
2065f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   vreg3 = S2_tstbit_i vreg1, 5
2066f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::simplifyTstbit(MachineInstr *MI,
2067f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef RD, const BitTracker::RegisterCell &RC) {
2068f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
2069f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Opc != Hexagon::S2_tstbit_i)
2070f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2071f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2072f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned BN = MI->getOperand(2).getImm();
2073f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker::RegisterRef RS = MI->getOperand(1);
2074f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned F, W;
2075f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DebugLoc DL = MI->getDebugLoc();
2076f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BT.has(RS.Reg) || !HBS::getSubregMask(RS, F, W, MRI))
2077f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2078f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock &B = *MI->getParent();
2079de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  auto At = MI->isPHI() ? B.getFirstNonPHI()
2080de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                        : MachineBasicBlock::iterator(MI);
2081f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2082f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &SC = BT.lookup(RS.Reg);
2083f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::BitValue &V = SC[F+BN];
2084f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (V.Type == BitTracker::BitValue::Ref && V.RefI.Reg != RS.Reg) {
2085f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const TargetRegisterClass *TC = MRI.getRegClass(V.RefI.Reg);
2086f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Need to map V.RefI.Reg to a 32-bit register, i.e. if it is
2087f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // a double register, need to use a subregister and adjust bit
2088f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // number.
2089f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned P = UINT_MAX;
2090f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker::RegisterRef RR(V.RefI.Reg, 0);
2091f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (TC == &Hexagon::DoubleRegsRegClass) {
2092f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      P = V.RefI.Pos;
2093f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RR.Sub = Hexagon::subreg_loreg;
2094f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (P >= 32) {
2095f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        P -= 32;
2096f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        RR.Sub = Hexagon::subreg_hireg;
2097f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
2098f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else if (TC == &Hexagon::IntRegsRegClass) {
2099f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      P = V.RefI.Pos;
2100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (P != UINT_MAX) {
2102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned NewR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
2103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      BuildMI(B, At, DL, HII.get(Hexagon::S2_tstbit_i), NewR)
2104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addReg(RR.Reg, 0, RR.Sub)
2105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addImm(P);
2106f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      HBS::replaceReg(RD.Reg, NewR, MRI);
2107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BT.put(NewR, RC);
2108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else if (V.is(0) || V.is(1)) {
2111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned NewR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
2112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned NewOpc = V.is(0) ? Hexagon::TFR_PdFalse : Hexagon::TFR_PdTrue;
2113de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    BuildMI(B, At, DL, HII.get(NewOpc), NewR);
2114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::replaceReg(RD.Reg, NewR, MRI);
2115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
2116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
2119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool BitSimplification::processBlock(MachineBasicBlock &B,
2123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const RegisterSet &AVs) {
2124f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
2125f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet AVB = AVs;
2126f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet Defs;
2127f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2128f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = B.begin(), E = B.end(); I != E; ++I, AVB.insert(Defs)) {
2129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineInstr *MI = &*I;
2130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Defs.clear();
2131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::getInstrDefs(*MI, Defs);
2132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned Opc = MI->getOpcode();
2134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Opc == TargetOpcode::COPY || Opc == TargetOpcode::REG_SEQUENCE)
2135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (MI->mayStore()) {
2138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      bool T = genStoreUpperHalf(MI);
2139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      T = T || genStoreImmediate(MI);
2140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed |= T;
2141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Defs.count() != 1)
2145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MachineOperand &Op0 = MI->getOperand(0);
2147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Op0.isReg() || !Op0.isDef())
2148f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker::RegisterRef RD = Op0;
2150f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!BT.has(RD.Reg))
2151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const TargetRegisterClass *FRC = HBS::getFinalVRegClass(RD, MRI);
2153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::RegisterCell &RC = BT.lookup(RD.Reg);
2154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (FRC->getID() == Hexagon::DoubleRegsRegClassID) {
2156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      bool T = genPackhl(MI, RD, RC);
2157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed |= T;
2158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (FRC->getID() == Hexagon::IntRegsRegClassID) {
2162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      bool T = genExtractHalf(MI, RD, RC);
2163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      T = T || genCombineHalf(MI, RD, RC);
2164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      T = T || genExtractLow(MI, RD, RC);
2165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed |= T;
2166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (FRC->getID() == Hexagon::PredRegsRegClassID) {
2170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      bool T = simplifyTstbit(MI, RD, RC);
2171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Changed |= T;
2172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
2176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonBitSimplify::runOnMachineFunction(MachineFunction &MF) {
2180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (skipFunction(*MF.getFunction()))
2181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
2182de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto &HST = MF.getSubtarget<HexagonSubtarget>();
2184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto &HRI = *HST.getRegisterInfo();
2185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto &HII = *HST.getInstrInfo();
2186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MDT = &getAnalysis<MachineDominatorTree>();
2188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineRegisterInfo &MRI = MF.getRegInfo();
2189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed;
2190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed = DeadCodeElimination(MF, *MDT).run();
2192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const HexagonEvaluator HE(HRI, MRI, HII, MF);
2194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker BT(HE, MF);
2195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DEBUG(BT.trace(true));
2196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BT.run();
2197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MachineBasicBlock &Entry = MF.front();
2199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet AIG;  // Available registers for IG.
2201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ConstGeneration ImmG(BT, HII, MRI);
2202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed |= visitBlock(Entry, ImmG, AIG);
2203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet ARE;  // Available registers for RIE.
2205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RedundantInstrElimination RIE(BT, HII, MRI);
2206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed |= visitBlock(Entry, RIE, ARE);
2207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet ACG;  // Available registers for CG.
2209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  CopyGeneration CopyG(BT, HII, MRI);
2210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed |= visitBlock(Entry, CopyG, ACG);
2211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet ACP;  // Available registers for CP.
2213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  CopyPropagation CopyP(HRI, MRI);
2214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed |= visitBlock(Entry, CopyP, ACP);
2215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed = DeadCodeElimination(MF, *MDT).run() || Changed;
2217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BT.run();
2219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet ABS;  // Available registers for BS.
2220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitSimplification BitS(BT, HII, MRI);
2221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed |= visitBlock(Entry, BitS, ABS);
2222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Changed = DeadCodeElimination(MF, *MDT).run() || Changed;
2224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Changed) {
2226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto &B : MF)
2227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      for (auto &I : B)
2228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        I.clearKillInfo();
2229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DeadCodeElimination(MF, *MDT).run();
2230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
2232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Recognize loops where the code at the end of the loop matches the code
2236f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// before the entry of the loop, and the matching code is such that is can
2237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// be simplified. This pass relies on the bit simplification above and only
2238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// prepares code in a way that can be handled by the bit simplifcation.
2239f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
2240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// This is the motivating testcase (and explanation):
2241f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
2242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2243f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   loop0(.LBB0_2, r1)      // %for.body.preheader
2244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r5:4 = memd(r0++#8)
2245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r3 = lsr(r4, #16)
2248f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r7:6 = combine(r5, r5)
2249f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r3 = insert(r5, #16, #16)
2252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r7:6 = vlsrw(r7:6, #16)
2253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// .LBB0_2:
2255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#4) = r5
2257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#6) = r6            # R6 is really R5.H
2258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r2 = add(r2, #8)
2261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#0) = r4
2262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#2) = r3            # R3 is really R4.H
2263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r5:4 = memd(r0++#8)
2266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {                             # "Shuffling" code that sets up R3 and R6
2268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r3 = lsr(r4, #16)           # so that their halves can be stored in the
2269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r7:6 = combine(r5, r5)      # next iteration. This could be folded into
2270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }                             # the stores if the code was at the beginning
2271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {                             # of the loop iteration. Since the same code
2272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r3 = insert(r5, #16, #16)   # precedes the loop, it can actually be moved
2273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r7:6 = vlsrw(r7:6, #16)     # there.
2274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }:endloop0
2275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
2276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
2277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// The outcome:
2278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//
2279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   loop0(.LBB0_2, r1)
2281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r5:4 = memd(r0++#8)
2282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// .LBB0_2:
2284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#4) = r5
2286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#6) = r5.h
2287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r2 = add(r2, #8)
2290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#0) = r4
2291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   memh(r2+#2) = r4.h
2292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }
2293f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// {
2294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//   r5:4 = memd(r0++#8)
2295f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// }:endloop0
2296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace llvm {
2298f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  FunctionPass *createHexagonLoopRescheduling();
2299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void initializeHexagonLoopReschedulingPass(PassRegistry&);
2300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarnamespace {
2303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  class HexagonLoopRescheduling : public MachineFunctionPass {
2304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  public:
2305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static char ID;
2306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HexagonLoopRescheduling() : MachineFunctionPass(ID),
2307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        HII(0), HRI(0), MRI(0), BTP(0) {
2308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      initializeHexagonLoopReschedulingPass(*PassRegistry::getPassRegistry());
2309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool runOnMachineFunction(MachineFunction &MF) override;
2312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  private:
2314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonInstrInfo *HII;
2315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const HexagonRegisterInfo *HRI;
2316f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineRegisterInfo *MRI;
2317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BitTracker *BTP;
2318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    struct LoopCand {
2320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      LoopCand(MachineBasicBlock *lb, MachineBasicBlock *pb,
2321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            MachineBasicBlock *eb) : LB(lb), PB(pb), EB(eb) {}
2322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineBasicBlock *LB, *PB, *EB;
2323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    };
2324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    typedef std::vector<MachineInstr*> InstrList;
2325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    struct InstrGroup {
2326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef Inp, Out;
2327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      InstrList Ins;
2328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    };
2329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    struct PhiInfo {
2330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PhiInfo(MachineInstr &P, MachineBasicBlock &B);
2331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned DefR;
2332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      BitTracker::RegisterRef LR, PR;
2333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineBasicBlock *LB, *PB;
2334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    };
2335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    static unsigned getDefReg(const MachineInstr *MI);
2337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isConst(unsigned Reg) const;
2338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isBitShuffle(const MachineInstr *MI, unsigned DefR) const;
2339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isStoreInput(const MachineInstr *MI, unsigned DefR) const;
2340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isShuffleOf(unsigned OutR, unsigned InpR) const;
2341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool isSameShuffle(unsigned OutR1, unsigned InpR1, unsigned OutR2,
2342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned &InpR2) const;
2343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    void moveGroup(InstrGroup &G, MachineBasicBlock &LB, MachineBasicBlock &PB,
2344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MachineBasicBlock::iterator At, unsigned OldPhiR, unsigned NewPredR);
2345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool processLoop(LoopCand &C);
2346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
2347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarchar HexagonLoopRescheduling::ID = 0;
2350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarINITIALIZE_PASS(HexagonLoopRescheduling, "hexagon-loop-resched",
2352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  "Hexagon Loop Rescheduling", false, false)
2353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarHexagonLoopRescheduling::PhiInfo::PhiInfo(MachineInstr &P,
2356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineBasicBlock &B) {
2357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DefR = HexagonLoopRescheduling::getDefReg(&P);
2358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  LB = &B;
2359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  PB = nullptr;
2360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 1, n = P.getNumOperands(); i < n; i += 2) {
2361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MachineOperand &OpB = P.getOperand(i+1);
2362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (OpB.getMBB() == &B) {
2363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      LR = P.getOperand(i);
2364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    PB = OpB.getMBB();
2367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    PR = P.getOperand(i);
2368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarunsigned HexagonLoopRescheduling::getDefReg(const MachineInstr *MI) {
2373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegisterSet Defs;
2374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HBS::getInstrDefs(*MI, Defs);
2375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Defs.count() != 1)
2376f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return 0;
2377f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Defs.find_first();
2378f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::isConst(unsigned Reg) const {
2382f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BTP->has(Reg))
2383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &RC = BTP->lookup(Reg);
2385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0, w = RC.width(); i < w; ++i) {
2386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::BitValue &V = RC[i];
2387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!V.is(0) && !V.is(1))
2388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
2391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::isBitShuffle(const MachineInstr *MI,
2395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned DefR) const {
2396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opc = MI->getOpcode();
2397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (Opc) {
2398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case TargetOpcode::COPY:
2399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_lsr_i_r:
2400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_asr_i_r:
2401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_asl_i_r:
2402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_lsr_i_p:
2403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_asr_i_p:
2404f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_asl_i_p:
2405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::S2_insert:
2406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_or:
2407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_orp:
2408f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_and:
2409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_andp:
2410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combinew:
2411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineri:
2412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineir:
2413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combineii:
2414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A4_combineii:
2415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combine_ll:
2416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combine_lh:
2417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combine_hl:
2418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Hexagon::A2_combine_hh:
2419f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2420f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
2422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2423f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::isStoreInput(const MachineInstr *MI,
2426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned InpR) const {
2427f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) {
2428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MachineOperand &Op = MI->getOperand(i);
2429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!Op.isReg())
2430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Op.getReg() == InpR)
2432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return i == n-1;
2433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
2435f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::isShuffleOf(unsigned OutR, unsigned InpR) const {
2439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BTP->has(OutR) || !BTP->has(InpR))
2440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &OutC = BTP->lookup(OutR);
2442f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0, w = OutC.width(); i < w; ++i) {
2443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::BitValue &V = OutC[i];
2444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V.Type != BitTracker::BitValue::Ref)
2445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V.RefI.Reg != InpR)
2447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
2450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::isSameShuffle(unsigned OutR1, unsigned InpR1,
2454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned OutR2, unsigned &InpR2) const {
2455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!BTP->has(OutR1) || !BTP->has(InpR1) || !BTP->has(OutR2))
2456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &OutC1 = BTP->lookup(OutR1);
2458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const BitTracker::RegisterCell &OutC2 = BTP->lookup(OutR2);
2459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned W = OutC1.width();
2460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned MatchR = 0;
2461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (W != OutC2.width())
2462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0; i < W; ++i) {
2464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const BitTracker::BitValue &V1 = OutC1[i], &V2 = OutC2[i];
2465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V1.Type != V2.Type || V1.Type == BitTracker::BitValue::One)
2466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V1.Type != BitTracker::BitValue::Ref)
2468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V1.RefI.Pos != V2.RefI.Pos)
2470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V1.RefI.Reg != InpR1)
2472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (V2.RefI.Reg == 0 || V2.RefI.Reg == OutR2)
2474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!MatchR)
2476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MatchR = V2.RefI.Reg;
2477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if (V2.RefI.Reg != MatchR)
2478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  InpR2 = MatchR;
2481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
2482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarvoid HexagonLoopRescheduling::moveGroup(InstrGroup &G, MachineBasicBlock &LB,
2486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineBasicBlock &PB, MachineBasicBlock::iterator At, unsigned OldPhiR,
2487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned NewPredR) {
2488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DenseMap<unsigned,unsigned> RegMap;
2489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const TargetRegisterClass *PhiRC = MRI->getRegClass(NewPredR);
2491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned PhiR = MRI->createVirtualRegister(PhiRC);
2492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BuildMI(LB, At, At->getDebugLoc(), HII->get(TargetOpcode::PHI), PhiR)
2493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    .addReg(NewPredR)
2494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    .addMBB(&PB)
2495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    .addReg(G.Inp.Reg)
2496f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    .addMBB(&LB);
2497f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  RegMap.insert(std::make_pair(G.Inp.Reg, PhiR));
2498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = G.Ins.size(); i > 0; --i) {
2500f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MachineInstr *SI = G.Ins[i-1];
2501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned DR = getDefReg(SI);
2502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const TargetRegisterClass *RC = MRI->getRegClass(DR);
2503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned NewDR = MRI->createVirtualRegister(RC);
2504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DebugLoc DL = SI->getDebugLoc();
2505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto MIB = BuildMI(LB, At, DL, HII->get(SI->getOpcode()), NewDR);
2507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned j = 0, m = SI->getNumOperands(); j < m; ++j) {
2508f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const MachineOperand &Op = SI->getOperand(j);
2509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Op.isReg()) {
2510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        MIB.addOperand(Op);
2511f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2512f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
2513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Op.isUse())
2514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned UseR = RegMap[Op.getReg()];
2516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MIB.addReg(UseR, 0, Op.getSubReg());
2517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegMap.insert(std::make_pair(DR, NewDR));
2519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HBS::replaceReg(OldPhiR, RegMap[G.Out.Reg], *MRI);
2522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::processLoop(LoopCand &C) {
2526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DEBUG(dbgs() << "Processing loop in BB#" << C.LB->getNumber() << "\n");
2527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::vector<PhiInfo> Phis;
2528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &I : *C.LB) {
2529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!I.isPHI())
2530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned PR = getDefReg(&I);
2532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isConst(PR))
2533f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool BadUse = false, GoodUse = false;
2535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto UI = MRI->use_begin(PR), UE = MRI->use_end(); UI != UE; ++UI) {
2536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineInstr *UseI = UI->getParent();
2537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (UseI->getParent() != C.LB) {
2538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        BadUse = true;
2539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        break;
2540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
2541f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (isBitShuffle(UseI, PR) || isStoreInput(UseI, PR))
2542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        GoodUse = true;
2543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2544f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (BadUse || !GoodUse)
2545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2546f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2547f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Phis.push_back(PhiInfo(I, *C.LB));
2548f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DEBUG({
2551f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    dbgs() << "Phis: {";
2552f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto &I : Phis) {
2553f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      dbgs() << ' ' << PrintReg(I.DefR, HRI) << "=phi("
2554f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar             << PrintReg(I.PR.Reg, HRI, I.PR.Sub) << ":b" << I.PB->getNumber()
2555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar             << ',' << PrintReg(I.LR.Reg, HRI, I.LR.Sub) << ":b"
2556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar             << I.LB->getNumber() << ')';
2557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    dbgs() << " }\n";
2559f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  });
2560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Phis.empty())
2562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2563f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2564f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
2565f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  InstrList ShufIns;
2566f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2567f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Go backwards in the block: for each bit shuffling instruction, check
2568f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // if that instruction could potentially be moved to the front of the loop:
2569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // the output of the loop cannot be used in a non-shuffling instruction
2570f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // in this loop.
2571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto I = C.LB->rbegin(), E = C.LB->rend(); I != E; ++I) {
2572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (I->isTerminator())
2573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2574f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (I->isPHI())
2575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet Defs;
2578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::getInstrDefs(*I, Defs);
2579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Defs.count() != 1)
2580f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned DefR = Defs.find_first();
2582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!TargetRegisterInfo::isVirtualRegister(DefR))
2583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2584f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!isBitShuffle(&*I, DefR))
2585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool BadUse = false;
2588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto UI = MRI->use_begin(DefR), UE = MRI->use_end(); UI != UE; ++UI) {
2589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineInstr *UseI = UI->getParent();
2590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (UseI->getParent() == C.LB) {
2591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (UseI->isPHI()) {
2592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // If the use is in a phi node in this loop, then it should be
2593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          // the value corresponding to the back edge.
2594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          unsigned Idx = UI.getOperandNo();
2595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          if (UseI->getOperand(Idx+1).getMBB() != C.LB)
2596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            BadUse = true;
2597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        } else {
2598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          auto F = std::find(ShufIns.begin(), ShufIns.end(), UseI);
2599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          if (F == ShufIns.end())
2600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            BadUse = true;
2601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        }
2602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
2603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // There is a use outside of the loop, but there is no epilog block
2604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // suitable for a copy-out.
2605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (C.EB == nullptr)
2606f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          BadUse = true;
2607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
2608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (BadUse)
2609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        break;
2610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (BadUse)
2613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ShufIns.push_back(&*I);
2615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Partition the list of shuffling instructions into instruction groups,
2618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // where each group has to be moved as a whole (i.e. a group is a chain of
2619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // dependent instructions). A group produces a single live output register,
2620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // which is meant to be the input of the loop phi node (although this is
2621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // not checked here yet). It also uses a single register as its input,
2622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // which is some value produced in the loop body. After moving the group
2623f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // to the beginning of the loop, that input register would need to be
2624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // the loop-carried register (through a phi node) instead of the (currently
2625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // loop-carried) output register.
2626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  typedef std::vector<InstrGroup> InstrGroupList;
2627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  InstrGroupList Groups;
2628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0, n = ShufIns.size(); i < n; ++i) {
2630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineInstr *SI = ShufIns[i];
2631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SI == nullptr)
2632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2634f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    InstrGroup G;
2635f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    G.Ins.push_back(SI);
2636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    G.Out.Reg = getDefReg(SI);
2637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegisterSet Inputs;
2638f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    HBS::getInstrUses(*SI, Inputs);
2639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2640f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned j = i+1; j < n; ++j) {
2641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MachineInstr *MI = ShufIns[j];
2642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (MI == nullptr)
2643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      RegisterSet Defs;
2645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      HBS::getInstrDefs(*MI, Defs);
2646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If this instruction does not define any pending inputs, skip it.
2647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!Defs.intersects(Inputs))
2648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Otherwise, add it to the current group and remove the inputs that
2650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // are defined by MI.
2651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      G.Ins.push_back(MI);
2652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Inputs.remove(Defs);
2653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Then add all registers used by MI.
2654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      HBS::getInstrUses(*MI, Inputs);
2655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ShufIns[j] = nullptr;
2656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Only add a group if it requires at most one register.
2659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inputs.count() > 1)
2660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto LoopInpEq = [G] (const PhiInfo &P) -> bool {
2662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return G.Out.Reg == P.LR.Reg;
2663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    };
2664f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (std::find_if(Phis.begin(), Phis.end(), LoopInpEq) == Phis.end())
2665f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    G.Inp.Reg = Inputs.find_first();
2668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Groups.push_back(G);
2669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2670f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2671f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DEBUG({
2672f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (unsigned i = 0, n = Groups.size(); i < n; ++i) {
2673f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      InstrGroup &G = Groups[i];
2674f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      dbgs() << "Group[" << i << "] inp: "
2675f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar             << PrintReg(G.Inp.Reg, HRI, G.Inp.Sub)
2676f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar             << "  out: " << PrintReg(G.Out.Reg, HRI, G.Out.Sub) << "\n";
2677f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      for (unsigned j = 0, m = G.Ins.size(); j < m; ++j)
2678f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        dbgs() << "  " << *G.Ins[j];
2679f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2680f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  });
2681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (unsigned i = 0, n = Groups.size(); i < n; ++i) {
2683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    InstrGroup &G = Groups[i];
2684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!isShuffleOf(G.Out.Reg, G.Inp.Reg))
2685f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto LoopInpEq = [G] (const PhiInfo &P) -> bool {
2687f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return G.Out.Reg == P.LR.Reg;
2688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    };
2689f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    auto F = std::find_if(Phis.begin(), Phis.end(), LoopInpEq);
2690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (F == Phis.end())
2691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned PredR = 0;
2693f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!isSameShuffle(G.Out.Reg, G.Inp.Reg, F->PR.Reg, PredR)) {
2694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const MachineInstr *DefPredR = MRI->getVRegDef(F->PR.Reg);
2695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      unsigned Opc = DefPredR->getOpcode();
2696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Opc != Hexagon::A2_tfrsi && Opc != Hexagon::A2_tfrpi)
2697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!DefPredR->getOperand(1).isImm())
2699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2700f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (DefPredR->getOperand(1).getImm() != 0)
2701f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2702f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      const TargetRegisterClass *RC = MRI->getRegClass(G.Inp.Reg);
2703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (RC != MRI->getRegClass(F->PR.Reg)) {
2704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        PredR = MRI->createVirtualRegister(RC);
2705f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        unsigned TfrI = (RC == &Hexagon::IntRegsRegClass) ? Hexagon::A2_tfrsi
2706f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                          : Hexagon::A2_tfrpi;
2707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        auto T = C.PB->getFirstTerminator();
2708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        DebugLoc DL = (T != C.PB->end()) ? T->getDebugLoc() : DebugLoc();
2709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        BuildMI(*C.PB, T, DL, HII->get(TfrI), PredR)
2710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          .addImm(0);
2711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
2712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        PredR = F->PR.Reg;
2713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
2714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(MRI->getRegClass(PredR) == MRI->getRegClass(G.Inp.Reg));
2716f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    moveGroup(G, *F->LB, *F->PB, F->LB->getFirstNonPHI(), F->DefR, PredR);
2717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed = true;
2718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2719f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2720f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
2721f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2722f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2723f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2724f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool HexagonLoopRescheduling::runOnMachineFunction(MachineFunction &MF) {
2725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (skipFunction(*MF.getFunction()))
2726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
2727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2728f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  auto &HST = MF.getSubtarget<HexagonSubtarget>();
2729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HII = HST.getInstrInfo();
2730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  HRI = HST.getRegisterInfo();
2731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MRI = &MF.getRegInfo();
2732f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const HexagonEvaluator HE(*HRI, *MRI, *HII, MF);
2733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BitTracker BT(HE, MF);
2734f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  DEBUG(BT.trace(true));
2735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BT.run();
2736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  BTP = &BT;
2737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  std::vector<LoopCand> Cand;
2739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &B : MF) {
2741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (B.pred_size() != 2 || B.succ_size() != 2)
2742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineBasicBlock *PB = nullptr;
2744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    bool IsLoop = false;
2745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto PI = B.pred_begin(), PE = B.pred_end(); PI != PE; ++PI) {
2746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (*PI != &B)
2747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        PB = *PI;
2748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else
2749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        IsLoop = true;
2750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!IsLoop)
2752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      continue;
2753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MachineBasicBlock *EB = nullptr;
2755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    for (auto SI = B.succ_begin(), SE = B.succ_end(); SI != SE; ++SI) {
2756f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (*SI == &B)
2757f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        continue;
2758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Set EP to the epilog block, if it has only 1 predecessor (i.e. the
2759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // edge from B to EP is non-critical.
2760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((*SI)->pred_size() == 1)
2761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        EB = *SI;
2762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Cand.push_back(LoopCand(&B, PB, EB));
2766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Changed = false;
2769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (auto &C : Cand)
2770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Changed |= processLoop(C);
2771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Changed;
2773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2774f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2775f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
2776f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//                         Public Constructor Functions
2777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
2778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createHexagonLoopRescheduling() {
2780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return new HexagonLoopRescheduling();
2781f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2782f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarFunctionPass *llvm::createHexagonBitSimplify() {
2784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return new HexagonBitSimplify();
2785f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2787