Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- HexagonConstPropagation.cpp ----------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "HexagonInstrInfo.h"
10
#include "HexagonRegisterInfo.h"
11
#include "HexagonSubtarget.h"
12
#include "llvm/ADT/APFloat.h"
13
#include "llvm/ADT/APInt.h"
14
#include "llvm/ADT/PostOrderIterator.h"
15
#include "llvm/ADT/SetVector.h"
16
#include "llvm/ADT/SmallVector.h"
17
#include "llvm/ADT/StringRef.h"
18
#include "llvm/CodeGen/MachineBasicBlock.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineFunctionPass.h"
21
#include "llvm/CodeGen/MachineInstr.h"
22
#include "llvm/CodeGen/MachineInstrBuilder.h"
23
#include "llvm/CodeGen/MachineOperand.h"
24
#include "llvm/CodeGen/MachineRegisterInfo.h"
25
#include "llvm/CodeGen/TargetRegisterInfo.h"
26
#include "llvm/CodeGen/TargetSubtargetInfo.h"
27
#include "llvm/IR/Constants.h"
28
#include "llvm/IR/Type.h"
29
#include "llvm/Pass.h"
30
#include "llvm/Support/Casting.h"
31
#include "llvm/Support/Compiler.h"
32
#include "llvm/Support/Debug.h"
33
#include "llvm/Support/ErrorHandling.h"
34
#include "llvm/Support/MathExtras.h"
35
#include "llvm/Support/raw_ostream.h"
36
#include <cassert>
37
#include <cstdint>
38
#include <cstring>
39
#include <iterator>
40
#include <map>
41
#include <queue>
42
#include <set>
43
#include <utility>
44
#include <vector>
45
46
0
#define DEBUG_TYPE "hcp"
47
48
using namespace llvm;
49
50
namespace {
51
52
  // Properties of a value that are tracked by the propagation.
53
  // A property that is marked as present (i.e. bit is set) dentes that the
54
  // value is known (proven) to have this property. Not all combinations
55
  // of bits make sense, for example Zero and NonZero are mutually exclusive,
56
  // but on the other hand, Zero implies Finite. In this case, whenever
57
  // the Zero property is present, Finite should also be present.
58
  class ConstantProperties {
59
  public:
60
    enum {
61
      Unknown   = 0x0000,
62
      Zero      = 0x0001,
63
      NonZero   = 0x0002,
64
      Finite    = 0x0004,
65
      Infinity  = 0x0008,
66
      NaN       = 0x0010,
67
      SignedZero = 0x0020,
68
      NumericProperties = (Zero|NonZero|Finite|Infinity|NaN|SignedZero),
69
      PosOrZero       = 0x0100,
70
      NegOrZero       = 0x0200,
71
      SignProperties  = (PosOrZero|NegOrZero),
72
      Everything      = (NumericProperties|SignProperties)
73
    };
74
75
    // For a given constant, deduce the set of trackable properties that this
76
    // constant has.
77
    static uint32_t deduce(const Constant *C);
78
  };
79
80
  // A representation of a register as it can appear in a MachineOperand,
81
  // i.e. a pair register:subregister.
82
83
  // FIXME: Use TargetInstrInfo::RegSubRegPair. Also duplicated in
84
  // HexagonGenPredicate
85
  struct RegisterSubReg {
86
    Register Reg;
87
    unsigned SubReg;
88
89
0
    explicit RegisterSubReg(unsigned R, unsigned SR = 0) : Reg(R), SubReg(SR) {}
90
    explicit RegisterSubReg(const MachineOperand &MO)
91
1.06M
      : Reg(MO.getReg()), SubReg(MO.getSubReg()) {}
92
93
0
    void print(const TargetRegisterInfo *TRI = nullptr) const {
94
0
      dbgs() << printReg(Reg, TRI, SubReg);
95
0
    }
96
97
0
    bool operator== (const RegisterSubReg &R) const {
98
0
      return (Reg == R.Reg) && (SubReg == R.SubReg);
99
0
    }
100
  };
101
102
  // Lattice cell, based on that was described in the W-Z paper on constant
103
  // propagation.
104
  // Latice cell will be allowed to hold multiple constant values. While
105
  // multiple values would normally indicate "bottom", we can still derive
106
  // some useful information from them. For example, comparison X > 0
107
  // could be folded if all the values in the cell associated with X are
108
  // positive.
109
  class LatticeCell {
110
  private:
111
    enum { Normal, Top, Bottom };
112
113
    static const unsigned MaxCellSize = 4;
114
115
    unsigned Kind:2;
116
    unsigned Size:3;
117
    unsigned IsSpecial:1;
118
    unsigned :0;
119
120
  public:
121
    union {
122
      uint32_t Properties;
123
      const Constant *Value;
124
      const Constant *Values[MaxCellSize];
125
    };
126
127
1.67M
    LatticeCell() : Kind(Top), Size(0), IsSpecial(false) {
128
1.67M
      for (const Constant *&Value : Values)
129
6.68M
        Value = nullptr;
130
1.67M
    }
131
132
    bool meet(const LatticeCell &L);
133
    bool add(const Constant *C);
134
    bool add(uint32_t Property);
135
    uint32_t properties() const;
136
11.0k
    unsigned size() const { return Size; }
137
138
83.6k
    LatticeCell(const LatticeCell &L) {
139
      // This memcpy also copies Properties (when L.Size == 0).
140
83.6k
      uint32_t N =
141
83.6k
          L.IsSpecial ? sizeof L.Properties : L.Size * sizeof(const Constant *);
142
83.6k
      memcpy(Values, L.Values, N);
143
83.6k
      Kind = L.Kind;
144
83.6k
      Size = L.Size;
145
83.6k
      IsSpecial = L.IsSpecial;
146
83.6k
    }
147
148
516k
    LatticeCell &operator=(const LatticeCell &L) {
149
516k
      if (this != &L) {
150
        // This memcpy also copies Properties (when L.Size == 0).
151
516k
        uint32_t N = L.IsSpecial ? sizeof L.Properties
152
516k
                                 : L.Size * sizeof(const Constant *);
153
516k
        memcpy(Values, L.Values, N);
154
516k
        Kind = L.Kind;
155
516k
        Size = L.Size;
156
516k
        IsSpecial = L.IsSpecial;
157
516k
      }
158
516k
      return *this;
159
516k
    }
160
161
8.78k
    bool isSingle() const { return size() == 1; }
162
39.8k
    bool isProperty() const { return IsSpecial; }
163
640k
    bool isTop() const { return Kind == Top; }
164
824k
    bool isBottom() const { return Kind == Bottom; }
165
166
563k
    bool setBottom() {
167
563k
      bool Changed = (Kind != Bottom);
168
563k
      Kind = Bottom;
169
563k
      Size = 0;
170
563k
      IsSpecial = false;
171
563k
      return Changed;
172
563k
    }
173
174
    void print(raw_ostream &os) const;
175
176
  private:
177
12
    void setProperty() {
178
12
      IsSpecial = true;
179
12
      Size = 0;
180
12
      Kind = Normal;
181
12
    }
182
183
    bool convertToProperty();
184
  };
185
186
#ifndef NDEBUG
187
0
  raw_ostream &operator<< (raw_ostream &os, const LatticeCell &L) {
188
0
    L.print(os);
189
0
    return os;
190
0
  }
191
#endif
192
193
  class MachineConstEvaluator;
194
195
  class MachineConstPropagator {
196
  public:
197
8.46k
    MachineConstPropagator(MachineConstEvaluator &E) : MCE(E) {
198
8.46k
      Bottom.setBottom();
199
8.46k
    }
200
201
    // Mapping: vreg -> cell
202
    // The keys are registers _without_ subregisters. This won't allow
203
    // definitions in the form of "vreg:subreg = ...". Such definitions
204
    // would be questionable from the point of view of SSA, since the "vreg"
205
    // could not be initialized in its entirety (specifically, an instruction
206
    // defining the "other part" of "vreg" would also count as a definition
207
    // of "vreg", which would violate the SSA).
208
    // If a value of a pair vreg:subreg needs to be obtained, the cell for
209
    // "vreg" needs to be looked up, and then the value of subregister "subreg"
210
    // needs to be evaluated.
211
    class CellMap {
212
    public:
213
554k
      CellMap() {
214
554k
        assert(Top.isTop());
215
0
        Bottom.setBottom();
216
554k
      }
217
218
8.46k
      void clear() { Map.clear(); }
219
220
460k
      bool has(Register R) const {
221
        // All non-virtual registers are considered "bottom".
222
460k
        if (!R.isVirtual())
223
0
          return true;
224
460k
        MapType::const_iterator F = Map.find(R);
225
460k
        return F != Map.end();
226
460k
      }
227
228
831k
      const LatticeCell &get(Register R) const {
229
831k
        if (!R.isVirtual())
230
0
          return Bottom;
231
831k
        MapType::const_iterator F = Map.find(R);
232
831k
        if (F != Map.end())
233
435k
          return F->second;
234
395k
        return Top;
235
831k
      }
236
237
      // Invalidates any const references.
238
389k
      void update(Register R, const LatticeCell &L) { Map[R] = L; }
239
240
      void print(raw_ostream &os, const TargetRegisterInfo &TRI) const;
241
242
    private:
243
      using MapType = std::map<Register, LatticeCell>;
244
245
      MapType Map;
246
      // To avoid creating "top" entries, return a const reference to
247
      // this cell in "get". Also, have a "Bottom" cell to return from
248
      // get when a value of a physical register is requested.
249
      LatticeCell Top, Bottom;
250
251
    public:
252
      using const_iterator = MapType::const_iterator;
253
254
0
      const_iterator begin() const { return Map.begin(); }
255
0
      const_iterator end() const { return Map.end(); }
256
    };
257
258
    bool run(MachineFunction &MF);
259
260
  private:
261
    void visitPHI(const MachineInstr &PN);
262
    void visitNonBranch(const MachineInstr &MI);
263
    void visitBranchesFrom(const MachineInstr &BrI);
264
    void visitUsesOf(unsigned R);
265
    bool computeBlockSuccessors(const MachineBasicBlock *MB,
266
          SetVector<const MachineBasicBlock*> &Targets);
267
    void removeCFGEdge(MachineBasicBlock *From, MachineBasicBlock *To);
268
269
    void propagate(MachineFunction &MF);
270
    bool rewrite(MachineFunction &MF);
271
272
    MachineRegisterInfo      *MRI = nullptr;
273
    MachineConstEvaluator    &MCE;
274
275
    using CFGEdge = std::pair<unsigned, unsigned>;
276
    using SetOfCFGEdge = std::set<CFGEdge>;
277
    using SetOfInstr = std::set<const MachineInstr *>;
278
    using QueueOfCFGEdge = std::queue<CFGEdge>;
279
280
    LatticeCell     Bottom;
281
    CellMap         Cells;
282
    SetOfCFGEdge    EdgeExec;
283
    SetOfInstr      InstrExec;
284
    QueueOfCFGEdge  FlowQ;
285
  };
286
287
  // The "evaluator/rewriter" of machine instructions. This is an abstract
288
  // base class that provides the interface that the propagator will use,
289
  // as well as some helper functions that are target-independent.
290
  class MachineConstEvaluator {
291
  public:
292
    MachineConstEvaluator(MachineFunction &Fn)
293
      : TRI(*Fn.getSubtarget().getRegisterInfo()),
294
8.46k
        MF(Fn), CX(Fn.getFunction().getContext()) {}
295
8.46k
    virtual ~MachineConstEvaluator() = default;
296
297
    // The required interface:
298
    // - A set of three "evaluate" functions. Each returns "true" if the
299
    //       computation succeeded, "false" otherwise.
300
    //   (1) Given an instruction MI, and the map with input values "Inputs",
301
    //       compute the set of output values "Outputs". An example of when
302
    //       the computation can "fail" is if MI is not an instruction that
303
    //       is recognized by the evaluator.
304
    //   (2) Given a register R (as reg:subreg), compute the cell that
305
    //       corresponds to the "subreg" part of the given register.
306
    //   (3) Given a branch instruction BrI, compute the set of target blocks.
307
    //       If the branch can fall-through, add null (0) to the list of
308
    //       possible targets.
309
    // - A function "rewrite", that given the cell map after propagation,
310
    //   could rewrite instruction MI in a more beneficial form. Return
311
    //   "true" if a change has been made, "false" otherwise.
312
    using CellMap = MachineConstPropagator::CellMap;
313
    virtual bool evaluate(const MachineInstr &MI, const CellMap &Inputs,
314
                          CellMap &Outputs) = 0;
315
    virtual bool evaluate(const RegisterSubReg &R, const LatticeCell &SrcC,
316
                          LatticeCell &Result) = 0;
317
    virtual bool evaluate(const MachineInstr &BrI, const CellMap &Inputs,
318
                          SetVector<const MachineBasicBlock*> &Targets,
319
                          bool &CanFallThru) = 0;
320
    virtual bool rewrite(MachineInstr &MI, const CellMap &Inputs) = 0;
321
322
    const TargetRegisterInfo &TRI;
323
324
  protected:
325
    MachineFunction &MF;
326
    LLVMContext     &CX;
327
328
    struct Comparison {
329
      enum {
330
        Unk = 0x00,
331
        EQ  = 0x01,
332
        NE  = 0x02,
333
        L   = 0x04, // Less-than property.
334
        G   = 0x08, // Greater-than property.
335
        U   = 0x40, // Unsigned property.
336
        LTs = L,
337
        LEs = L | EQ,
338
        GTs = G,
339
        GEs = G | EQ,
340
        LTu = L      | U,
341
        LEu = L | EQ | U,
342
        GTu = G      | U,
343
        GEu = G | EQ | U
344
      };
345
346
0
      static uint32_t negate(uint32_t Cmp) {
347
0
        if (Cmp == EQ)
348
0
          return NE;
349
0
        if (Cmp == NE)
350
0
          return EQ;
351
0
        assert((Cmp & (L|G)) != (L|G));
352
0
        return Cmp ^ (L|G);
353
0
      }
354
    };
355
356
    // Helper functions.
357
358
    bool getCell(const RegisterSubReg &R, const CellMap &Inputs, LatticeCell &RC);
359
    bool constToInt(const Constant *C, APInt &Val) const;
360
    const ConstantInt *intToConst(const APInt &Val) const;
361
362
    // Compares.
363
    bool evaluateCMPrr(uint32_t Cmp, const RegisterSubReg &R1, const RegisterSubReg &R2,
364
          const CellMap &Inputs, bool &Result);
365
    bool evaluateCMPri(uint32_t Cmp, const RegisterSubReg &R1, const APInt &A2,
366
          const CellMap &Inputs, bool &Result);
367
    bool evaluateCMPrp(uint32_t Cmp, const RegisterSubReg &R1, uint64_t Props2,
368
          const CellMap &Inputs, bool &Result);
369
    bool evaluateCMPii(uint32_t Cmp, const APInt &A1, const APInt &A2,
370
          bool &Result);
371
    bool evaluateCMPpi(uint32_t Cmp, uint32_t Props, const APInt &A2,
372
          bool &Result);
373
    bool evaluateCMPpp(uint32_t Cmp, uint32_t Props1, uint32_t Props2,
374
          bool &Result);
375
376
    bool evaluateCOPY(const RegisterSubReg &R1, const CellMap &Inputs,
377
          LatticeCell &Result);
378
379
    // Logical operations.
380
    bool evaluateANDrr(const RegisterSubReg &R1, const RegisterSubReg &R2,
381
          const CellMap &Inputs, LatticeCell &Result);
382
    bool evaluateANDri(const RegisterSubReg &R1, const APInt &A2,
383
          const CellMap &Inputs, LatticeCell &Result);
384
    bool evaluateANDii(const APInt &A1, const APInt &A2, APInt &Result);
385
    bool evaluateORrr(const RegisterSubReg &R1, const RegisterSubReg &R2,
386
          const CellMap &Inputs, LatticeCell &Result);
387
    bool evaluateORri(const RegisterSubReg &R1, const APInt &A2,
388
          const CellMap &Inputs, LatticeCell &Result);
389
    bool evaluateORii(const APInt &A1, const APInt &A2, APInt &Result);
390
    bool evaluateXORrr(const RegisterSubReg &R1, const RegisterSubReg &R2,
391
          const CellMap &Inputs, LatticeCell &Result);
392
    bool evaluateXORri(const RegisterSubReg &R1, const APInt &A2,
393
          const CellMap &Inputs, LatticeCell &Result);
394
    bool evaluateXORii(const APInt &A1, const APInt &A2, APInt &Result);
395
396
    // Extensions.
397
    bool evaluateZEXTr(const RegisterSubReg &R1, unsigned Width, unsigned Bits,
398
          const CellMap &Inputs, LatticeCell &Result);
399
    bool evaluateZEXTi(const APInt &A1, unsigned Width, unsigned Bits,
400
          APInt &Result);
401
    bool evaluateSEXTr(const RegisterSubReg &R1, unsigned Width, unsigned Bits,
402
          const CellMap &Inputs, LatticeCell &Result);
403
    bool evaluateSEXTi(const APInt &A1, unsigned Width, unsigned Bits,
404
          APInt &Result);
405
406
    // Leading/trailing bits.
407
    bool evaluateCLBr(const RegisterSubReg &R1, bool Zeros, bool Ones,
408
          const CellMap &Inputs, LatticeCell &Result);
409
    bool evaluateCLBi(const APInt &A1, bool Zeros, bool Ones, APInt &Result);
410
    bool evaluateCTBr(const RegisterSubReg &R1, bool Zeros, bool Ones,
411
          const CellMap &Inputs, LatticeCell &Result);
412
    bool evaluateCTBi(const APInt &A1, bool Zeros, bool Ones, APInt &Result);
413
414
    // Bitfield extract.
415
    bool evaluateEXTRACTr(const RegisterSubReg &R1, unsigned Width, unsigned Bits,
416
          unsigned Offset, bool Signed, const CellMap &Inputs,
417
          LatticeCell &Result);
418
    bool evaluateEXTRACTi(const APInt &A1, unsigned Bits, unsigned Offset,
419
          bool Signed, APInt &Result);
420
    // Vector operations.
421
    bool evaluateSplatr(const RegisterSubReg &R1, unsigned Bits, unsigned Count,
422
          const CellMap &Inputs, LatticeCell &Result);
423
    bool evaluateSplati(const APInt &A1, unsigned Bits, unsigned Count,
424
          APInt &Result);
425
  };
426
427
} // end anonymous namespace
428
429
806
uint32_t ConstantProperties::deduce(const Constant *C) {
430
806
  if (isa<ConstantInt>(C)) {
431
806
    const ConstantInt *CI = cast<ConstantInt>(C);
432
806
    if (CI->isZero())
433
0
      return Zero | PosOrZero | NegOrZero | Finite;
434
806
    uint32_t Props = (NonZero | Finite);
435
806
    if (CI->isNegative())
436
209
      return Props | NegOrZero;
437
597
    return Props | PosOrZero;
438
806
  }
439
440
0
  if (isa<ConstantFP>(C)) {
441
0
    const ConstantFP *CF = cast<ConstantFP>(C);
442
0
    uint32_t Props = CF->isNegative() ? (NegOrZero|NonZero)
443
0
                                      : PosOrZero;
444
0
    if (CF->isZero())
445
0
      return (Props & ~NumericProperties) | (Zero|Finite);
446
0
    Props = (Props & ~NumericProperties) | NonZero;
447
0
    if (CF->isNaN())
448
0
      return (Props & ~NumericProperties) | NaN;
449
0
    const APFloat &Val = CF->getValueAPF();
450
0
    if (Val.isInfinity())
451
0
      return (Props & ~NumericProperties) | Infinity;
452
0
    Props |= Finite;
453
0
    return Props;
454
0
  }
455
456
0
  return Unknown;
457
0
}
458
459
// Convert a cell from a set of specific values to a cell that tracks
460
// properties.
461
12
bool LatticeCell::convertToProperty() {
462
12
  if (isProperty())
463
0
    return false;
464
  // Corner case: converting a fresh (top) cell to "special".
465
  // This can happen, when adding a property to a top cell.
466
12
  uint32_t Everything = ConstantProperties::Everything;
467
12
  uint32_t Ps = !isTop() ? properties()
468
12
                         : Everything;
469
12
  if (Ps != ConstantProperties::Unknown) {
470
12
    Properties = Ps;
471
12
    setProperty();
472
12
  } else {
473
0
    setBottom();
474
0
  }
475
12
  return true;
476
12
}
477
478
#ifndef NDEBUG
479
0
void LatticeCell::print(raw_ostream &os) const {
480
0
  if (isProperty()) {
481
0
    os << "{ ";
482
0
    uint32_t Ps = properties();
483
0
    if (Ps & ConstantProperties::Zero)
484
0
      os << "zero ";
485
0
    if (Ps & ConstantProperties::NonZero)
486
0
      os << "nonzero ";
487
0
    if (Ps & ConstantProperties::Finite)
488
0
      os << "finite ";
489
0
    if (Ps & ConstantProperties::Infinity)
490
0
      os << "infinity ";
491
0
    if (Ps & ConstantProperties::NaN)
492
0
      os << "nan ";
493
0
    if (Ps & ConstantProperties::PosOrZero)
494
0
      os << "poz ";
495
0
    if (Ps & ConstantProperties::NegOrZero)
496
0
      os << "nez ";
497
0
    os << '}';
498
0
    return;
499
0
  }
500
501
0
  os << "{ ";
502
0
  if (isBottom()) {
503
0
    os << "bottom";
504
0
  } else if (isTop()) {
505
0
    os << "top";
506
0
  } else {
507
0
    for (unsigned i = 0; i < size(); ++i) {
508
0
      const Constant *C = Values[i];
509
0
      if (i != 0)
510
0
        os << ", ";
511
0
      C->print(os);
512
0
    }
513
0
  }
514
0
  os << " }";
515
0
}
516
#endif
517
518
// "Meet" operation on two cells. This is the key of the propagation
519
// algorithm.
520
38.3k
bool LatticeCell::meet(const LatticeCell &L) {
521
38.3k
  bool Changed = false;
522
38.3k
  if (L.isBottom())
523
0
    Changed = setBottom();
524
38.3k
  if (isBottom() || L.isTop())
525
0
    return Changed;
526
38.3k
  if (isTop()) {
527
38.3k
    *this = L;
528
    // L can be neither Top nor Bottom, so *this must have changed.
529
38.3k
    return true;
530
38.3k
  }
531
532
  // Top/bottom cases covered. Need to integrate L's set into ours.
533
0
  if (L.isProperty())
534
0
    return add(L.properties());
535
0
  for (unsigned i = 0; i < L.size(); ++i) {
536
0
    const Constant *LC = L.Values[i];
537
0
    Changed |= add(LC);
538
0
  }
539
0
  return Changed;
540
0
}
541
542
// Add a new constant to the cell. This is actually where the cell update
543
// happens. If a cell has room for more constants, the new constant is added.
544
// Otherwise, the cell is converted to a "property" cell (i.e. a cell that
545
// will track properties of the associated values, and not the values
546
// themselves. Care is taken to handle special cases, like "bottom", etc.
547
38.3k
bool LatticeCell::add(const Constant *LC) {
548
38.3k
  assert(LC);
549
38.3k
  if (isBottom())
550
0
    return false;
551
552
38.3k
  if (!isProperty()) {
553
    // Cell is not special. Try to add the constant here first,
554
    // if there is room.
555
38.3k
    unsigned Index = 0;
556
38.3k
    while (Index < Size) {
557
0
      const Constant *C = Values[Index];
558
      // If the constant is already here, no change is needed.
559
0
      if (C == LC)
560
0
        return false;
561
0
      Index++;
562
0
    }
563
38.3k
    if (Index < MaxCellSize) {
564
38.3k
      Values[Index] = LC;
565
38.3k
      Kind = Normal;
566
38.3k
      Size++;
567
38.3k
      return true;
568
38.3k
    }
569
38.3k
  }
570
571
0
  bool Changed = false;
572
573
  // This cell is special, or is not special, but is full. After this
574
  // it will be special.
575
0
  Changed = convertToProperty();
576
0
  uint32_t Ps = properties();
577
0
  uint32_t NewPs = Ps & ConstantProperties::deduce(LC);
578
0
  if (NewPs == ConstantProperties::Unknown) {
579
0
    setBottom();
580
0
    return true;
581
0
  }
582
0
  if (Ps != NewPs) {
583
0
    Properties = NewPs;
584
0
    Changed = true;
585
0
  }
586
0
  return Changed;
587
0
}
588
589
// Add a property to the cell. This will force the cell to become a property-
590
// tracking cell.
591
12
bool LatticeCell::add(uint32_t Property) {
592
12
  bool Changed = convertToProperty();
593
12
  uint32_t Ps = properties();
594
12
  if (Ps == (Ps & Property))
595
0
    return Changed;
596
12
  Properties = Property & Ps;
597
12
  return true;
598
12
}
599
600
// Return the properties of the values in the cell. This is valid for any
601
// cell, and does not alter the cell itself.
602
818
uint32_t LatticeCell::properties() const {
603
818
  if (isProperty())
604
12
    return Properties;
605
806
  assert(!isTop() && "Should not call this for a top cell");
606
806
  if (isBottom())
607
0
    return ConstantProperties::Unknown;
608
609
806
  assert(size() > 0 && "Empty cell");
610
0
  uint32_t Ps = ConstantProperties::deduce(Values[0]);
611
806
  for (unsigned i = 1; i < size(); ++i) {
612
0
    if (Ps == ConstantProperties::Unknown)
613
0
      break;
614
0
    Ps &= ConstantProperties::deduce(Values[i]);
615
0
  }
616
806
  return Ps;
617
806
}
618
619
#ifndef NDEBUG
620
void MachineConstPropagator::CellMap::print(raw_ostream &os,
621
0
      const TargetRegisterInfo &TRI) const {
622
0
  for (auto &I : Map)
623
0
    dbgs() << "  " << printReg(I.first, &TRI) << " -> " << I.second << '\n';
624
0
}
625
#endif
626
627
0
void MachineConstPropagator::visitPHI(const MachineInstr &PN) {
628
0
  const MachineBasicBlock *MB = PN.getParent();
629
0
  unsigned MBN = MB->getNumber();
630
0
  LLVM_DEBUG(dbgs() << "Visiting FI(" << printMBBReference(*MB) << "): " << PN);
631
632
0
  const MachineOperand &MD = PN.getOperand(0);
633
0
  RegisterSubReg DefR(MD);
634
0
  assert(DefR.Reg.isVirtual());
635
636
0
  bool Changed = false;
637
638
  // If the def has a sub-register, set the corresponding cell to "bottom".
639
0
  if (DefR.SubReg) {
640
0
Bottomize:
641
0
    const LatticeCell &T = Cells.get(DefR.Reg);
642
0
    Changed = !T.isBottom();
643
0
    Cells.update(DefR.Reg, Bottom);
644
0
    if (Changed)
645
0
      visitUsesOf(DefR.Reg);
646
0
    return;
647
0
  }
648
649
0
  LatticeCell DefC = Cells.get(DefR.Reg);
650
651
0
  for (unsigned i = 1, n = PN.getNumOperands(); i < n; i += 2) {
652
0
    const MachineBasicBlock *PB = PN.getOperand(i+1).getMBB();
653
0
    unsigned PBN = PB->getNumber();
654
0
    if (!EdgeExec.count(CFGEdge(PBN, MBN))) {
655
0
      LLVM_DEBUG(dbgs() << "  edge " << printMBBReference(*PB) << "->"
656
0
                        << printMBBReference(*MB) << " not executable\n");
657
0
      continue;
658
0
    }
659
0
    const MachineOperand &SO = PN.getOperand(i);
660
0
    RegisterSubReg UseR(SO);
661
    // If the input is not a virtual register, we don't really know what
662
    // value it holds.
663
0
    if (!UseR.Reg.isVirtual())
664
0
      goto Bottomize;
665
    // If there is no cell for an input register, it means top.
666
0
    if (!Cells.has(UseR.Reg))
667
0
      continue;
668
669
0
    LatticeCell SrcC;
670
0
    bool Eval = MCE.evaluate(UseR, Cells.get(UseR.Reg), SrcC);
671
0
    LLVM_DEBUG(dbgs() << "  edge from " << printMBBReference(*PB) << ": "
672
0
                      << printReg(UseR.Reg, &MCE.TRI, UseR.SubReg) << SrcC
673
0
                      << '\n');
674
0
    Changed |= Eval ? DefC.meet(SrcC)
675
0
                    : DefC.setBottom();
676
0
    Cells.update(DefR.Reg, DefC);
677
0
    if (DefC.isBottom())
678
0
      break;
679
0
  }
680
0
  if (Changed)
681
0
    visitUsesOf(DefR.Reg);
682
0
}
683
684
546k
void MachineConstPropagator::visitNonBranch(const MachineInstr &MI) {
685
546k
  LLVM_DEBUG(dbgs() << "Visiting MI(" << printMBBReference(*MI.getParent())
686
546k
                    << "): " << MI);
687
546k
  CellMap Outputs;
688
546k
  bool Eval = MCE.evaluate(MI, Cells, Outputs);
689
546k
  LLVM_DEBUG({
690
546k
    if (Eval) {
691
546k
      dbgs() << "  outputs:";
692
546k
      for (auto &I : Outputs)
693
546k
        dbgs() << ' ' << I.second;
694
546k
      dbgs() << '\n';
695
546k
    }
696
546k
  });
697
698
  // Update outputs. If the value was not computed, set all the
699
  // def cells to bottom.
700
1.83M
  for (const MachineOperand &MO : MI.operands()) {
701
1.83M
    if (!MO.isReg() || !MO.isDef())
702
1.31M
      continue;
703
519k
    RegisterSubReg DefR(MO);
704
    // Only track virtual registers.
705
519k
    if (!DefR.Reg.isVirtual())
706
168k
      continue;
707
350k
    bool Changed = false;
708
    // If the evaluation failed, set cells for all output registers to bottom.
709
350k
    if (!Eval) {
710
312k
      const LatticeCell &T = Cells.get(DefR.Reg);
711
312k
      Changed = !T.isBottom();
712
312k
      Cells.update(DefR.Reg, Bottom);
713
312k
    } else {
714
      // Find the corresponding cell in the computed outputs.
715
      // If it's not there, go on to the next def.
716
38.3k
      if (!Outputs.has(DefR.Reg))
717
0
        continue;
718
38.3k
      LatticeCell RC = Cells.get(DefR.Reg);
719
38.3k
      Changed = RC.meet(Outputs.get(DefR.Reg));
720
38.3k
      Cells.update(DefR.Reg, RC);
721
38.3k
    }
722
350k
    if (Changed)
723
350k
      visitUsesOf(DefR.Reg);
724
350k
  }
725
546k
}
726
727
// Starting at a given branch, visit remaining branches in the block.
728
// Traverse over the subsequent branches for as long as the preceding one
729
// can fall through. Add all the possible targets to the flow work queue,
730
// including the potential fall-through to the layout-successor block.
731
9.34k
void MachineConstPropagator::visitBranchesFrom(const MachineInstr &BrI) {
732
9.34k
  const MachineBasicBlock &B = *BrI.getParent();
733
9.34k
  unsigned MBN = B.getNumber();
734
9.34k
  MachineBasicBlock::const_iterator It = BrI.getIterator();
735
9.34k
  MachineBasicBlock::const_iterator End = B.end();
736
737
9.34k
  SetVector<const MachineBasicBlock*> Targets;
738
9.34k
  bool EvalOk = true, FallsThru = true;
739
19.2k
  while (It != End) {
740
10.6k
    const MachineInstr &MI = *It;
741
10.6k
    InstrExec.insert(&MI);
742
10.6k
    LLVM_DEBUG(dbgs() << "Visiting " << (EvalOk ? "BR" : "br") << "("
743
10.6k
                      << printMBBReference(B) << "): " << MI);
744
    // Do not evaluate subsequent branches if the evaluation of any of the
745
    // previous branches failed. Keep iterating over the branches only
746
    // to mark them as executable.
747
10.6k
    EvalOk = EvalOk && MCE.evaluate(MI, Cells, Targets, FallsThru);
748
10.6k
    if (!EvalOk)
749
9.92k
      FallsThru = true;
750
10.6k
    if (!FallsThru)
751
730
      break;
752
9.92k
    ++It;
753
9.92k
  }
754
755
9.34k
  if (B.mayHaveInlineAsmBr())
756
0
    EvalOk = false;
757
758
9.34k
  if (EvalOk) {
759
    // Need to add all CFG successors that lead to EH landing pads.
760
    // There won't be explicit branches to these blocks, but they must
761
    // be processed.
762
730
    for (const MachineBasicBlock *SB : B.successors()) {
763
730
      if (SB->isEHPad())
764
0
        Targets.insert(SB);
765
730
    }
766
730
    if (FallsThru) {
767
0
      const MachineFunction &MF = *B.getParent();
768
0
      MachineFunction::const_iterator BI = B.getIterator();
769
0
      MachineFunction::const_iterator Next = std::next(BI);
770
0
      if (Next != MF.end())
771
0
        Targets.insert(&*Next);
772
0
    }
773
8.61k
  } else {
774
    // If the evaluation of the branches failed, make "Targets" to be the
775
    // set of all successors of the block from the CFG.
776
    // If the evaluation succeeded for all visited branches, then if the
777
    // last one set "FallsThru", then add an edge to the layout successor
778
    // to the targets.
779
8.61k
    Targets.clear();
780
8.61k
    LLVM_DEBUG(dbgs() << "  failed to evaluate a branch...adding all CFG "
781
8.61k
                         "successors\n");
782
8.61k
    for (const MachineBasicBlock *SB : B.successors())
783
2.62k
      Targets.insert(SB);
784
8.61k
  }
785
786
9.34k
  for (const MachineBasicBlock *TB : Targets) {
787
3.35k
    unsigned TBN = TB->getNumber();
788
3.35k
    LLVM_DEBUG(dbgs() << "  pushing edge " << printMBBReference(B) << " -> "
789
3.35k
                      << printMBBReference(*TB) << "\n");
790
3.35k
    FlowQ.push(CFGEdge(MBN, TBN));
791
3.35k
  }
792
9.34k
}
793
794
350k
void MachineConstPropagator::visitUsesOf(unsigned Reg) {
795
350k
  LLVM_DEBUG(dbgs() << "Visiting uses of " << printReg(Reg, &MCE.TRI)
796
350k
                    << Cells.get(Reg) << '\n');
797
499k
  for (MachineInstr &MI : MRI->use_nodbg_instructions(Reg)) {
798
    // Do not process non-executable instructions. They can become exceutable
799
    // later (via a flow-edge in the work queue). In such case, the instruc-
800
    // tion will be visited at that time.
801
499k
    if (!InstrExec.count(&MI))
802
499k
      continue;
803
0
    if (MI.isPHI())
804
0
      visitPHI(MI);
805
0
    else if (!MI.isBranch())
806
0
      visitNonBranch(MI);
807
0
    else
808
0
      visitBranchesFrom(MI);
809
0
  }
810
350k
}
811
812
bool MachineConstPropagator::computeBlockSuccessors(const MachineBasicBlock *MB,
813
10.5k
      SetVector<const MachineBasicBlock*> &Targets) {
814
10.5k
  Targets.clear();
815
816
10.5k
  MachineBasicBlock::const_iterator FirstBr = MB->end();
817
555k
  for (const MachineInstr &MI : *MB) {
818
555k
    if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
819
0
      return false;
820
555k
    if (MI.isDebugInstr())
821
0
      continue;
822
555k
    if (MI.isBranch()) {
823
9.34k
      FirstBr = MI.getIterator();
824
9.34k
      break;
825
9.34k
    }
826
555k
  }
827
828
10.5k
  MachineBasicBlock::const_iterator End = MB->end();
829
830
10.5k
  bool DoNext = true;
831
10.5k
  for (MachineBasicBlock::const_iterator I = FirstBr; I != End; ++I) {
832
9.34k
    const MachineInstr &MI = *I;
833
    // Can there be debug instructions between branches?
834
9.34k
    if (MI.isDebugInstr())
835
0
      continue;
836
9.34k
    if (!InstrExec.count(&MI))
837
0
      continue;
838
9.34k
    bool Eval = MCE.evaluate(MI, Cells, Targets, DoNext);
839
9.34k
    if (!Eval)
840
8.61k
      return false;
841
730
    if (!DoNext)
842
730
      break;
843
730
  }
844
  // If the last branch could fall-through, add block's layout successor.
845
1.93k
  if (DoNext) {
846
1.20k
    MachineFunction::const_iterator BI = MB->getIterator();
847
1.20k
    MachineFunction::const_iterator NextI = std::next(BI);
848
1.20k
    if (NextI != MB->getParent()->end())
849
1.20k
      Targets.insert(&*NextI);
850
1.20k
  }
851
852
  // Add all the EH landing pads.
853
1.93k
  for (const MachineBasicBlock *SB : MB->successors())
854
1.93k
    if (SB->isEHPad())
855
0
      Targets.insert(SB);
856
857
1.93k
  return true;
858
10.5k
}
859
860
void MachineConstPropagator::removeCFGEdge(MachineBasicBlock *From,
861
0
      MachineBasicBlock *To) {
862
  // First, remove the CFG successor/predecessor information.
863
0
  From->removeSuccessor(To);
864
  // Remove all corresponding PHI operands in the To block.
865
0
  for (MachineInstr &PN : To->phis()) {
866
    // reg0 = PHI reg1, bb2, reg3, bb4, ...
867
0
    int N = PN.getNumOperands() - 2;
868
0
    while (N > 0) {
869
0
      if (PN.getOperand(N + 1).getMBB() == From) {
870
0
        PN.removeOperand(N + 1);
871
0
        PN.removeOperand(N);
872
0
      }
873
0
      N -= 2;
874
0
    }
875
0
  }
876
0
}
877
878
8.46k
void MachineConstPropagator::propagate(MachineFunction &MF) {
879
8.46k
  MachineBasicBlock *Entry = GraphTraits<MachineFunction*>::getEntryNode(&MF);
880
8.46k
  unsigned EntryNum = Entry->getNumber();
881
882
  // Start with a fake edge, just to process the entry node.
883
8.46k
  FlowQ.push(CFGEdge(EntryNum, EntryNum));
884
885
21.4k
  while (!FlowQ.empty()) {
886
13.0k
    CFGEdge Edge = FlowQ.front();
887
13.0k
    FlowQ.pop();
888
889
13.0k
    LLVM_DEBUG(
890
13.0k
        dbgs() << "Picked edge "
891
13.0k
               << printMBBReference(*MF.getBlockNumbered(Edge.first)) << "->"
892
13.0k
               << printMBBReference(*MF.getBlockNumbered(Edge.second)) << '\n');
893
13.0k
    if (Edge.first != EntryNum)
894
3.36k
      if (EdgeExec.count(Edge))
895
0
        continue;
896
13.0k
    EdgeExec.insert(Edge);
897
13.0k
    MachineBasicBlock *SB = MF.getBlockNumbered(Edge.second);
898
899
    // Process the block in three stages:
900
    // - visit all PHI nodes,
901
    // - visit all non-branch instructions,
902
    // - visit block branches.
903
13.0k
    MachineBasicBlock::const_iterator It = SB->begin(), End = SB->end();
904
905
    // Visit PHI nodes in the successor block.
906
13.0k
    while (It != End && It->isPHI()) {
907
0
      InstrExec.insert(&*It);
908
0
      visitPHI(*It);
909
0
      ++It;
910
0
    }
911
912
    // If the successor block just became executable, visit all instructions.
913
    // To see if this is the first time we're visiting it, check the first
914
    // non-debug instruction to see if it is executable.
915
13.0k
    while (It != End && It->isDebugInstr())
916
0
      ++It;
917
13.0k
    assert(It == End || !It->isPHI());
918
    // If this block has been visited, go on to the next one.
919
13.0k
    if (It != End && InstrExec.count(&*It))
920
2.04k
      continue;
921
    // For now, scan all non-branch instructions. Branches require different
922
    // processing.
923
557k
    while (It != End && !It->isBranch()) {
924
546k
      if (!It->isDebugInstr()) {
925
546k
        InstrExec.insert(&*It);
926
546k
        visitNonBranch(*It);
927
546k
      }
928
546k
      ++It;
929
546k
    }
930
931
    // Time to process the end of the block. This is different from
932
    // processing regular (non-branch) instructions, because there can
933
    // be multiple branches in a block, and they can cause the block to
934
    // terminate early.
935
10.9k
    if (It != End) {
936
9.34k
      visitBranchesFrom(*It);
937
9.34k
    } else {
938
      // If the block didn't have a branch, add all successor edges to the
939
      // work queue. (There should really be only one successor in such case.)
940
1.64k
      unsigned SBN = SB->getNumber();
941
1.64k
      for (const MachineBasicBlock *SSB : SB->successors())
942
1.20k
        FlowQ.push(CFGEdge(SBN, SSB->getNumber()));
943
1.64k
    }
944
10.9k
  } // while (FlowQ)
945
946
8.46k
  LLVM_DEBUG({
947
8.46k
    dbgs() << "Cells after propagation:\n";
948
8.46k
    Cells.print(dbgs(), MCE.TRI);
949
8.46k
    dbgs() << "Dead CFG edges:\n";
950
8.46k
    for (const MachineBasicBlock &B : MF) {
951
8.46k
      unsigned BN = B.getNumber();
952
8.46k
      for (const MachineBasicBlock *SB : B.successors()) {
953
8.46k
        unsigned SN = SB->getNumber();
954
8.46k
        if (!EdgeExec.count(CFGEdge(BN, SN)))
955
8.46k
          dbgs() << "  " << printMBBReference(B) << " -> "
956
8.46k
                 << printMBBReference(*SB) << '\n';
957
8.46k
      }
958
8.46k
    }
959
8.46k
  });
960
8.46k
}
961
962
8.46k
bool MachineConstPropagator::rewrite(MachineFunction &MF) {
963
8.46k
  bool Changed = false;
964
  // Rewrite all instructions based on the collected cell information.
965
  //
966
  // Traverse the instructions in a post-order, so that rewriting an
967
  // instruction can make changes "downstream" in terms of control-flow
968
  // without affecting the rewriting process. (We should not change
969
  // instructions that have not yet been visited by the rewriter.)
970
  // The reason for this is that the rewriter can introduce new vregs,
971
  // and replace uses of old vregs (which had corresponding cells
972
  // computed during propagation) with these new vregs (which at this
973
  // point would not have any cells, and would appear to be "top").
974
  // If an attempt was made to evaluate an instruction with a fresh
975
  // "top" vreg, it would cause an error (abend) in the evaluator.
976
977
  // Collect the post-order-traversal block ordering. The subsequent
978
  // traversal/rewrite will update block successors, so it's safer
979
  // if the visiting order it computed ahead of time.
980
8.46k
  std::vector<MachineBasicBlock*> POT;
981
8.46k
  for (MachineBasicBlock *B : post_order(&MF))
982
10.9k
    if (!B->empty())
983
10.5k
      POT.push_back(B);
984
985
10.5k
  for (MachineBasicBlock *B : POT) {
986
    // Walk the block backwards (which usually begin with the branches).
987
    // If any branch is rewritten, we may need to update the successor
988
    // information for this block. Unless the block's successors can be
989
    // precisely determined (which may not be the case for indirect
990
    // branches), we cannot modify any branch.
991
992
    // Compute the successor information.
993
10.5k
    SetVector<const MachineBasicBlock*> Targets;
994
10.5k
    bool HaveTargets = computeBlockSuccessors(B, Targets);
995
    // Rewrite the executable instructions. Skip branches if we don't
996
    // have block successor information.
997
565k
    for (MachineInstr &MI : llvm::reverse(*B)) {
998
565k
      if (InstrExec.count(&MI)) {
999
557k
        if (MI.isBranch() && !HaveTargets)
1000
9.92k
          continue;
1001
547k
        Changed |= MCE.rewrite(MI, Cells);
1002
547k
      }
1003
565k
    }
1004
    // The rewriting could rewrite PHI nodes to non-PHI nodes, causing
1005
    // regular instructions to appear in between PHI nodes. Bring all
1006
    // the PHI nodes to the beginning of the block.
1007
10.5k
    for (auto I = B->begin(), E = B->end(); I != E; ++I) {
1008
10.5k
      if (I->isPHI())
1009
0
        continue;
1010
      // I is not PHI. Find the next PHI node P.
1011
10.5k
      auto P = I;
1012
565k
      while (++P != E)
1013
554k
        if (P->isPHI())
1014
0
          break;
1015
      // Not found.
1016
10.5k
      if (P == E)
1017
10.5k
        break;
1018
      // Splice P right before I.
1019
0
      B->splice(I, B, P);
1020
      // Reset I to point at the just spliced PHI node.
1021
0
      --I;
1022
0
    }
1023
    // Update the block successor information: remove unnecessary successors.
1024
10.5k
    if (HaveTargets) {
1025
1.93k
      SmallVector<MachineBasicBlock*,2> ToRemove;
1026
1.93k
      for (MachineBasicBlock *SB : B->successors()) {
1027
1.93k
        if (!Targets.count(SB))
1028
0
          ToRemove.push_back(const_cast<MachineBasicBlock*>(SB));
1029
1.93k
        Targets.remove(SB);
1030
1.93k
      }
1031
1.93k
      for (MachineBasicBlock *MBB : ToRemove)
1032
0
        removeCFGEdge(B, MBB);
1033
      // If there are any blocks left in the computed targets, it means that
1034
      // we think that the block could go somewhere, but the CFG does not.
1035
      // This could legitimately happen in blocks that have non-returning
1036
      // calls---we would think that the execution can continue, but the
1037
      // CFG will not have a successor edge.
1038
1.93k
    }
1039
10.5k
  }
1040
  // Need to do some final post-processing.
1041
  // If a branch was not executable, it will not get rewritten, but should
1042
  // be removed (or replaced with something equivalent to a A2_nop). We can't
1043
  // erase instructions during rewriting, so this needs to be delayed until
1044
  // now.
1045
10.9k
  for (MachineBasicBlock &B : MF) {
1046
10.9k
    for (MachineInstr &MI : llvm::make_early_inc_range(B))
1047
565k
      if (MI.isBranch() && !InstrExec.count(&MI))
1048
0
        B.erase(&MI);
1049
10.9k
  }
1050
8.46k
  return Changed;
1051
8.46k
}
1052
1053
// This is the constant propagation algorithm as described by Wegman-Zadeck.
1054
// Most of the terminology comes from there.
1055
8.46k
bool MachineConstPropagator::run(MachineFunction &MF) {
1056
8.46k
  LLVM_DEBUG(MF.print(dbgs() << "Starting MachineConstPropagator\n", nullptr));
1057
1058
8.46k
  MRI = &MF.getRegInfo();
1059
1060
8.46k
  Cells.clear();
1061
8.46k
  EdgeExec.clear();
1062
8.46k
  InstrExec.clear();
1063
8.46k
  assert(FlowQ.empty());
1064
1065
0
  propagate(MF);
1066
8.46k
  bool Changed = rewrite(MF);
1067
1068
8.46k
  LLVM_DEBUG({
1069
8.46k
    dbgs() << "End of MachineConstPropagator (Changed=" << Changed << ")\n";
1070
8.46k
    if (Changed)
1071
8.46k
      MF.print(dbgs(), nullptr);
1072
8.46k
  });
1073
8.46k
  return Changed;
1074
8.46k
}
1075
1076
// --------------------------------------------------------------------
1077
// Machine const evaluator.
1078
1079
bool MachineConstEvaluator::getCell(const RegisterSubReg &R, const CellMap &Inputs,
1080
122k
      LatticeCell &RC) {
1081
122k
  if (!R.Reg.isVirtual())
1082
25.5k
    return false;
1083
96.5k
  const LatticeCell &L = Inputs.get(R.Reg);
1084
96.5k
  if (!R.SubReg) {
1085
88.2k
    RC = L;
1086
88.2k
    return !RC.isBottom();
1087
88.2k
  }
1088
8.31k
  bool Eval = evaluate(R, L, RC);
1089
8.31k
  return Eval && !RC.isBottom();
1090
96.5k
}
1091
1092
bool MachineConstEvaluator::constToInt(const Constant *C,
1093
9.02k
      APInt &Val) const {
1094
9.02k
  const ConstantInt *CI = dyn_cast<ConstantInt>(C);
1095
9.02k
  if (!CI)
1096
0
    return false;
1097
9.02k
  Val = CI->getValue();
1098
9.02k
  return true;
1099
9.02k
}
1100
1101
0
const ConstantInt *MachineConstEvaluator::intToConst(const APInt &Val) const {
1102
0
  return ConstantInt::get(CX, Val);
1103
0
}
1104
1105
bool MachineConstEvaluator::evaluateCMPrr(uint32_t Cmp, const RegisterSubReg &R1,
1106
11.7k
      const RegisterSubReg &R2, const CellMap &Inputs, bool &Result) {
1107
11.7k
  assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg));
1108
0
  LatticeCell LS1, LS2;
1109
11.7k
  if (!getCell(R1, Inputs, LS1) || !getCell(R2, Inputs, LS2))
1110
11.7k
    return false;
1111
1112
0
  bool IsProp1 = LS1.isProperty();
1113
0
  bool IsProp2 = LS2.isProperty();
1114
0
  if (IsProp1) {
1115
0
    uint32_t Prop1 = LS1.properties();
1116
0
    if (IsProp2)
1117
0
      return evaluateCMPpp(Cmp, Prop1, LS2.properties(), Result);
1118
0
    uint32_t NegCmp = Comparison::negate(Cmp);
1119
0
    return evaluateCMPrp(NegCmp, R2, Prop1, Inputs, Result);
1120
0
  }
1121
0
  if (IsProp2) {
1122
0
    uint32_t Prop2 = LS2.properties();
1123
0
    return evaluateCMPrp(Cmp, R1, Prop2, Inputs, Result);
1124
0
  }
1125
1126
0
  APInt A;
1127
0
  bool IsTrue = true, IsFalse = true;
1128
0
  for (unsigned i = 0; i < LS2.size(); ++i) {
1129
0
    bool Res;
1130
0
    bool Computed = constToInt(LS2.Values[i], A) &&
1131
0
                    evaluateCMPri(Cmp, R1, A, Inputs, Res);
1132
0
    if (!Computed)
1133
0
      return false;
1134
0
    IsTrue &= Res;
1135
0
    IsFalse &= !Res;
1136
0
  }
1137
0
  assert(!IsTrue || !IsFalse);
1138
  // The actual logical value of the comparison is same as IsTrue.
1139
0
  Result = IsTrue;
1140
  // Return true if the result was proven to be true or proven to be false.
1141
0
  return IsTrue || IsFalse;
1142
0
}
1143
1144
bool MachineConstEvaluator::evaluateCMPri(uint32_t Cmp, const RegisterSubReg &R1,
1145
8.23k
      const APInt &A2, const CellMap &Inputs, bool &Result) {
1146
8.23k
  assert(Inputs.has(R1.Reg));
1147
0
  LatticeCell LS;
1148
8.23k
  if (!getCell(R1, Inputs, LS))
1149
8.23k
    return false;
1150
0
  if (LS.isProperty())
1151
0
    return evaluateCMPpi(Cmp, LS.properties(), A2, Result);
1152
1153
0
  APInt A;
1154
0
  bool IsTrue = true, IsFalse = true;
1155
0
  for (unsigned i = 0; i < LS.size(); ++i) {
1156
0
    bool Res;
1157
0
    bool Computed = constToInt(LS.Values[i], A) &&
1158
0
                    evaluateCMPii(Cmp, A, A2, Res);
1159
0
    if (!Computed)
1160
0
      return false;
1161
0
    IsTrue &= Res;
1162
0
    IsFalse &= !Res;
1163
0
  }
1164
0
  assert(!IsTrue || !IsFalse);
1165
  // The actual logical value of the comparison is same as IsTrue.
1166
0
  Result = IsTrue;
1167
  // Return true if the result was proven to be true or proven to be false.
1168
0
  return IsTrue || IsFalse;
1169
0
}
1170
1171
bool MachineConstEvaluator::evaluateCMPrp(uint32_t Cmp, const RegisterSubReg &R1,
1172
0
      uint64_t Props2, const CellMap &Inputs, bool &Result) {
1173
0
  assert(Inputs.has(R1.Reg));
1174
0
  LatticeCell LS;
1175
0
  if (!getCell(R1, Inputs, LS))
1176
0
    return false;
1177
0
  if (LS.isProperty())
1178
0
    return evaluateCMPpp(Cmp, LS.properties(), Props2, Result);
1179
1180
0
  APInt A;
1181
0
  uint32_t NegCmp = Comparison::negate(Cmp);
1182
0
  bool IsTrue = true, IsFalse = true;
1183
0
  for (unsigned i = 0; i < LS.size(); ++i) {
1184
0
    bool Res;
1185
0
    bool Computed = constToInt(LS.Values[i], A) &&
1186
0
                    evaluateCMPpi(NegCmp, Props2, A, Res);
1187
0
    if (!Computed)
1188
0
      return false;
1189
0
    IsTrue &= Res;
1190
0
    IsFalse &= !Res;
1191
0
  }
1192
0
  assert(!IsTrue || !IsFalse);
1193
0
  Result = IsTrue;
1194
0
  return IsTrue || IsFalse;
1195
0
}
1196
1197
bool MachineConstEvaluator::evaluateCMPii(uint32_t Cmp, const APInt &A1,
1198
0
      const APInt &A2, bool &Result) {
1199
  // NE is a special kind of comparison (not composed of smaller properties).
1200
0
  if (Cmp == Comparison::NE) {
1201
0
    Result = !APInt::isSameValue(A1, A2);
1202
0
    return true;
1203
0
  }
1204
0
  if (Cmp == Comparison::EQ) {
1205
0
    Result = APInt::isSameValue(A1, A2);
1206
0
    return true;
1207
0
  }
1208
0
  if (Cmp & Comparison::EQ) {
1209
0
    if (APInt::isSameValue(A1, A2))
1210
0
      return (Result = true);
1211
0
  }
1212
0
  assert((Cmp & (Comparison::L | Comparison::G)) && "Malformed comparison");
1213
0
  Result = false;
1214
1215
0
  unsigned W1 = A1.getBitWidth();
1216
0
  unsigned W2 = A2.getBitWidth();
1217
0
  unsigned MaxW = (W1 >= W2) ? W1 : W2;
1218
0
  if (Cmp & Comparison::U) {
1219
0
    APInt Zx1 = A1.zext(MaxW);
1220
0
    APInt Zx2 = A2.zext(MaxW);
1221
0
    if (Cmp & Comparison::L)
1222
0
      Result = Zx1.ult(Zx2);
1223
0
    else if (Cmp & Comparison::G)
1224
0
      Result = Zx2.ult(Zx1);
1225
0
    return true;
1226
0
  }
1227
1228
  // Signed comparison.
1229
0
  APInt Sx1 = A1.sext(MaxW);
1230
0
  APInt Sx2 = A2.sext(MaxW);
1231
0
  if (Cmp & Comparison::L)
1232
0
    Result = Sx1.slt(Sx2);
1233
0
  else if (Cmp & Comparison::G)
1234
0
    Result = Sx2.slt(Sx1);
1235
0
  return true;
1236
0
}
1237
1238
bool MachineConstEvaluator::evaluateCMPpi(uint32_t Cmp, uint32_t Props,
1239
0
      const APInt &A2, bool &Result) {
1240
0
  if (Props == ConstantProperties::Unknown)
1241
0
    return false;
1242
1243
  // Should never see NaN here, but check for it for completeness.
1244
0
  if (Props & ConstantProperties::NaN)
1245
0
    return false;
1246
  // Infinity could theoretically be compared to a number, but the
1247
  // presence of infinity here would be very suspicious. If we don't
1248
  // know for sure that the number is finite, bail out.
1249
0
  if (!(Props & ConstantProperties::Finite))
1250
0
    return false;
1251
1252
  // Let X be a number that has properties Props.
1253
1254
0
  if (Cmp & Comparison::U) {
1255
    // In case of unsigned comparisons, we can only compare against 0.
1256
0
    if (A2 == 0) {
1257
      // Any x!=0 will be considered >0 in an unsigned comparison.
1258
0
      if (Props & ConstantProperties::Zero)
1259
0
        Result = (Cmp & Comparison::EQ);
1260
0
      else if (Props & ConstantProperties::NonZero)
1261
0
        Result = (Cmp & Comparison::G) || (Cmp == Comparison::NE);
1262
0
      else
1263
0
        return false;
1264
0
      return true;
1265
0
    }
1266
    // A2 is not zero. The only handled case is if X = 0.
1267
0
    if (Props & ConstantProperties::Zero) {
1268
0
      Result = (Cmp & Comparison::L) || (Cmp == Comparison::NE);
1269
0
      return true;
1270
0
    }
1271
0
    return false;
1272
0
  }
1273
1274
  // Signed comparisons are different.
1275
0
  if (Props & ConstantProperties::Zero) {
1276
0
    if (A2 == 0)
1277
0
      Result = (Cmp & Comparison::EQ);
1278
0
    else
1279
0
      Result = (Cmp == Comparison::NE) ||
1280
0
               ((Cmp & Comparison::L) && !A2.isNegative()) ||
1281
0
               ((Cmp & Comparison::G) &&  A2.isNegative());
1282
0
    return true;
1283
0
  }
1284
0
  if (Props & ConstantProperties::PosOrZero) {
1285
    // X >= 0 and !(A2 < 0) => cannot compare
1286
0
    if (!A2.isNegative())
1287
0
      return false;
1288
    // X >= 0 and A2 < 0
1289
0
    Result = (Cmp & Comparison::G) || (Cmp == Comparison::NE);
1290
0
    return true;
1291
0
  }
1292
0
  if (Props & ConstantProperties::NegOrZero) {
1293
    // X <= 0 and Src1 < 0 => cannot compare
1294
0
    if (A2 == 0 || A2.isNegative())
1295
0
      return false;
1296
    // X <= 0 and A2 > 0
1297
0
    Result = (Cmp & Comparison::L) || (Cmp == Comparison::NE);
1298
0
    return true;
1299
0
  }
1300
1301
0
  return false;
1302
0
}
1303
1304
bool MachineConstEvaluator::evaluateCMPpp(uint32_t Cmp, uint32_t Props1,
1305
0
      uint32_t Props2, bool &Result) {
1306
0
  using P = ConstantProperties;
1307
1308
0
  if ((Props1 & P::NaN) && (Props2 & P::NaN))
1309
0
    return false;
1310
0
  if (!(Props1 & P::Finite) || !(Props2 & P::Finite))
1311
0
    return false;
1312
1313
0
  bool Zero1 = (Props1 & P::Zero), Zero2 = (Props2 & P::Zero);
1314
0
  bool NonZero1 = (Props1 & P::NonZero), NonZero2 = (Props2 & P::NonZero);
1315
0
  if (Zero1 && Zero2) {
1316
0
    Result = (Cmp & Comparison::EQ);
1317
0
    return true;
1318
0
  }
1319
0
  if (Cmp == Comparison::NE) {
1320
0
    if ((Zero1 && NonZero2) || (NonZero1 && Zero2))
1321
0
      return (Result = true);
1322
0
    return false;
1323
0
  }
1324
1325
0
  if (Cmp & Comparison::U) {
1326
    // In unsigned comparisons, we can only compare against a known zero,
1327
    // or a known non-zero.
1328
0
    if (Zero1 && NonZero2) {
1329
0
      Result = (Cmp & Comparison::L);
1330
0
      return true;
1331
0
    }
1332
0
    if (NonZero1 && Zero2) {
1333
0
      Result = (Cmp & Comparison::G);
1334
0
      return true;
1335
0
    }
1336
0
    return false;
1337
0
  }
1338
1339
  // Signed comparison. The comparison is not NE.
1340
0
  bool Poz1 = (Props1 & P::PosOrZero), Poz2 = (Props2 & P::PosOrZero);
1341
0
  bool Nez1 = (Props1 & P::NegOrZero), Nez2 = (Props2 & P::NegOrZero);
1342
0
  if (Nez1 && Poz2) {
1343
0
    if (NonZero1 || NonZero2) {
1344
0
      Result = (Cmp & Comparison::L);
1345
0
      return true;
1346
0
    }
1347
    // Either (or both) could be zero. Can only say that X <= Y.
1348
0
    if ((Cmp & Comparison::EQ) && (Cmp & Comparison::L))
1349
0
      return (Result = true);
1350
0
  }
1351
0
  if (Poz1 && Nez2) {
1352
0
    if (NonZero1 || NonZero2) {
1353
0
      Result = (Cmp & Comparison::G);
1354
0
      return true;
1355
0
    }
1356
    // Either (or both) could be zero. Can only say that X >= Y.
1357
0
    if ((Cmp & Comparison::EQ) && (Cmp & Comparison::G))
1358
0
      return (Result = true);
1359
0
  }
1360
1361
0
  return false;
1362
0
}
1363
1364
bool MachineConstEvaluator::evaluateCOPY(const RegisterSubReg &R1,
1365
26.3k
      const CellMap &Inputs, LatticeCell &Result) {
1366
26.3k
  return getCell(R1, Inputs, Result);
1367
26.3k
}
1368
1369
bool MachineConstEvaluator::evaluateANDrr(const RegisterSubReg &R1,
1370
2.39k
      const RegisterSubReg &R2, const CellMap &Inputs, LatticeCell &Result) {
1371
2.39k
  assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg));
1372
0
  const LatticeCell &L1 = Inputs.get(R2.Reg);
1373
2.39k
  const LatticeCell &L2 = Inputs.get(R2.Reg);
1374
  // If both sources are bottom, exit. Otherwise try to evaluate ANDri
1375
  // with the non-bottom argument passed as the immediate. This is to
1376
  // catch cases of ANDing with 0.
1377
2.39k
  if (L2.isBottom()) {
1378
1.81k
    if (L1.isBottom())
1379
1.81k
      return false;
1380
0
    return evaluateANDrr(R2, R1, Inputs, Result);
1381
1.81k
  }
1382
579
  LatticeCell LS2;
1383
579
  if (!evaluate(R2, L2, LS2))
1384
0
    return false;
1385
579
  if (LS2.isBottom() || LS2.isProperty())
1386
0
    return false;
1387
1388
579
  APInt A;
1389
579
  for (unsigned i = 0; i < LS2.size(); ++i) {
1390
579
    LatticeCell RC;
1391
579
    bool Eval = constToInt(LS2.Values[i], A) &&
1392
579
                evaluateANDri(R1, A, Inputs, RC);
1393
579
    if (!Eval)
1394
579
      return false;
1395
0
    Result.meet(RC);
1396
0
  }
1397
0
  return !Result.isBottom();
1398
579
}
1399
1400
bool MachineConstEvaluator::evaluateANDri(const RegisterSubReg &R1,
1401
4.16k
      const APInt &A2, const CellMap &Inputs, LatticeCell &Result) {
1402
4.16k
  assert(Inputs.has(R1.Reg));
1403
4.16k
  if (A2 == -1)
1404
0
    return getCell(R1, Inputs, Result);
1405
4.16k
  if (A2 == 0) {
1406
0
    LatticeCell RC;
1407
0
    RC.add(intToConst(A2));
1408
    // Overwrite Result.
1409
0
    Result = RC;
1410
0
    return true;
1411
0
  }
1412
4.16k
  LatticeCell LS1;
1413
4.16k
  if (!getCell(R1, Inputs, LS1))
1414
4.16k
    return false;
1415
0
  if (LS1.isBottom() || LS1.isProperty())
1416
0
    return false;
1417
1418
0
  APInt A, ResA;
1419
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1420
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1421
0
                evaluateANDii(A, A2, ResA);
1422
0
    if (!Eval)
1423
0
      return false;
1424
0
    const Constant *C = intToConst(ResA);
1425
0
    Result.add(C);
1426
0
  }
1427
0
  return !Result.isBottom();
1428
0
}
1429
1430
bool MachineConstEvaluator::evaluateANDii(const APInt &A1,
1431
0
      const APInt &A2, APInt &Result) {
1432
0
  Result = A1 & A2;
1433
0
  return true;
1434
0
}
1435
1436
bool MachineConstEvaluator::evaluateORrr(const RegisterSubReg &R1,
1437
1.14k
      const RegisterSubReg &R2, const CellMap &Inputs, LatticeCell &Result) {
1438
1.14k
  assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg));
1439
0
  const LatticeCell &L1 = Inputs.get(R2.Reg);
1440
1.14k
  const LatticeCell &L2 = Inputs.get(R2.Reg);
1441
  // If both sources are bottom, exit. Otherwise try to evaluate ORri
1442
  // with the non-bottom argument passed as the immediate. This is to
1443
  // catch cases of ORing with -1.
1444
1.14k
  if (L2.isBottom()) {
1445
1.02k
    if (L1.isBottom())
1446
1.02k
      return false;
1447
0
    return evaluateORrr(R2, R1, Inputs, Result);
1448
1.02k
  }
1449
121
  LatticeCell LS2;
1450
121
  if (!evaluate(R2, L2, LS2))
1451
0
    return false;
1452
121
  if (LS2.isBottom() || LS2.isProperty())
1453
0
    return false;
1454
1455
121
  APInt A;
1456
121
  for (unsigned i = 0; i < LS2.size(); ++i) {
1457
121
    LatticeCell RC;
1458
121
    bool Eval = constToInt(LS2.Values[i], A) &&
1459
121
                evaluateORri(R1, A, Inputs, RC);
1460
121
    if (!Eval)
1461
121
      return false;
1462
0
    Result.meet(RC);
1463
0
  }
1464
0
  return !Result.isBottom();
1465
121
}
1466
1467
bool MachineConstEvaluator::evaluateORri(const RegisterSubReg &R1,
1468
1.66k
      const APInt &A2, const CellMap &Inputs, LatticeCell &Result) {
1469
1.66k
  assert(Inputs.has(R1.Reg));
1470
1.66k
  if (A2 == 0)
1471
0
    return getCell(R1, Inputs, Result);
1472
1.66k
  if (A2 == -1) {
1473
0
    LatticeCell RC;
1474
0
    RC.add(intToConst(A2));
1475
    // Overwrite Result.
1476
0
    Result = RC;
1477
0
    return true;
1478
0
  }
1479
1.66k
  LatticeCell LS1;
1480
1.66k
  if (!getCell(R1, Inputs, LS1))
1481
1.66k
    return false;
1482
0
  if (LS1.isBottom() || LS1.isProperty())
1483
0
    return false;
1484
1485
0
  APInt A, ResA;
1486
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1487
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1488
0
                evaluateORii(A, A2, ResA);
1489
0
    if (!Eval)
1490
0
      return false;
1491
0
    const Constant *C = intToConst(ResA);
1492
0
    Result.add(C);
1493
0
  }
1494
0
  return !Result.isBottom();
1495
0
}
1496
1497
bool MachineConstEvaluator::evaluateORii(const APInt &A1,
1498
0
      const APInt &A2, APInt &Result) {
1499
0
  Result = A1 | A2;
1500
0
  return true;
1501
0
}
1502
1503
bool MachineConstEvaluator::evaluateXORrr(const RegisterSubReg &R1,
1504
1.60k
      const RegisterSubReg &R2, const CellMap &Inputs, LatticeCell &Result) {
1505
1.60k
  assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg));
1506
0
  LatticeCell LS1, LS2;
1507
1.60k
  if (!getCell(R1, Inputs, LS1) || !getCell(R2, Inputs, LS2))
1508
1.60k
    return false;
1509
0
  if (LS1.isProperty()) {
1510
0
    if (LS1.properties() & ConstantProperties::Zero)
1511
0
      return !(Result = LS2).isBottom();
1512
0
    return false;
1513
0
  }
1514
0
  if (LS2.isProperty()) {
1515
0
    if (LS2.properties() & ConstantProperties::Zero)
1516
0
      return !(Result = LS1).isBottom();
1517
0
    return false;
1518
0
  }
1519
1520
0
  APInt A;
1521
0
  for (unsigned i = 0; i < LS2.size(); ++i) {
1522
0
    LatticeCell RC;
1523
0
    bool Eval = constToInt(LS2.Values[i], A) &&
1524
0
                evaluateXORri(R1, A, Inputs, RC);
1525
0
    if (!Eval)
1526
0
      return false;
1527
0
    Result.meet(RC);
1528
0
  }
1529
0
  return !Result.isBottom();
1530
0
}
1531
1532
bool MachineConstEvaluator::evaluateXORri(const RegisterSubReg &R1,
1533
0
      const APInt &A2, const CellMap &Inputs, LatticeCell &Result) {
1534
0
  assert(Inputs.has(R1.Reg));
1535
0
  LatticeCell LS1;
1536
0
  if (!getCell(R1, Inputs, LS1))
1537
0
    return false;
1538
0
  if (LS1.isProperty()) {
1539
0
    if (LS1.properties() & ConstantProperties::Zero) {
1540
0
      const Constant *C = intToConst(A2);
1541
0
      Result.add(C);
1542
0
      return !Result.isBottom();
1543
0
    }
1544
0
    return false;
1545
0
  }
1546
1547
0
  APInt A, XA;
1548
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1549
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1550
0
                evaluateXORii(A, A2, XA);
1551
0
    if (!Eval)
1552
0
      return false;
1553
0
    const Constant *C = intToConst(XA);
1554
0
    Result.add(C);
1555
0
  }
1556
0
  return !Result.isBottom();
1557
0
}
1558
1559
bool MachineConstEvaluator::evaluateXORii(const APInt &A1,
1560
0
      const APInt &A2, APInt &Result) {
1561
0
  Result = A1 ^ A2;
1562
0
  return true;
1563
0
}
1564
1565
bool MachineConstEvaluator::evaluateZEXTr(const RegisterSubReg &R1, unsigned Width,
1566
1.73k
      unsigned Bits, const CellMap &Inputs, LatticeCell &Result) {
1567
1.73k
  assert(Inputs.has(R1.Reg));
1568
0
  LatticeCell LS1;
1569
1.73k
  if (!getCell(R1, Inputs, LS1))
1570
1.73k
    return false;
1571
0
  if (LS1.isProperty())
1572
0
    return false;
1573
1574
0
  APInt A, XA;
1575
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1576
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1577
0
                evaluateZEXTi(A, Width, Bits, XA);
1578
0
    if (!Eval)
1579
0
      return false;
1580
0
    const Constant *C = intToConst(XA);
1581
0
    Result.add(C);
1582
0
  }
1583
0
  return true;
1584
0
}
1585
1586
bool MachineConstEvaluator::evaluateZEXTi(const APInt &A1, unsigned Width,
1587
0
      unsigned Bits, APInt &Result) {
1588
0
  unsigned BW = A1.getBitWidth();
1589
0
  (void)BW;
1590
0
  assert(Width >= Bits && BW >= Bits);
1591
0
  APInt Mask = APInt::getLowBitsSet(Width, Bits);
1592
0
  Result = A1.zextOrTrunc(Width) & Mask;
1593
0
  return true;
1594
0
}
1595
1596
bool MachineConstEvaluator::evaluateSEXTr(const RegisterSubReg &R1, unsigned Width,
1597
3.42k
      unsigned Bits, const CellMap &Inputs, LatticeCell &Result) {
1598
3.42k
  assert(Inputs.has(R1.Reg));
1599
0
  LatticeCell LS1;
1600
3.42k
  if (!getCell(R1, Inputs, LS1))
1601
3.42k
    return false;
1602
0
  if (LS1.isBottom() || LS1.isProperty())
1603
0
    return false;
1604
1605
0
  APInt A, XA;
1606
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1607
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1608
0
                evaluateSEXTi(A, Width, Bits, XA);
1609
0
    if (!Eval)
1610
0
      return false;
1611
0
    const Constant *C = intToConst(XA);
1612
0
    Result.add(C);
1613
0
  }
1614
0
  return true;
1615
0
}
1616
1617
bool MachineConstEvaluator::evaluateSEXTi(const APInt &A1, unsigned Width,
1618
0
      unsigned Bits, APInt &Result) {
1619
0
  unsigned BW = A1.getBitWidth();
1620
0
  assert(Width >= Bits && BW >= Bits);
1621
  // Special case to make things faster for smaller source widths.
1622
  // Sign extension of 0 bits generates 0 as a result. This is consistent
1623
  // with what the HW does.
1624
0
  if (Bits == 0) {
1625
0
    Result = APInt(Width, 0);
1626
0
    return true;
1627
0
  }
1628
  // In C, shifts by 64 invoke undefined behavior: handle that case in APInt.
1629
0
  if (BW <= 64 && Bits != 0) {
1630
0
    int64_t V = A1.getSExtValue();
1631
0
    switch (Bits) {
1632
0
      case 8:
1633
0
        V = static_cast<int8_t>(V);
1634
0
        break;
1635
0
      case 16:
1636
0
        V = static_cast<int16_t>(V);
1637
0
        break;
1638
0
      case 32:
1639
0
        V = static_cast<int32_t>(V);
1640
0
        break;
1641
0
      default:
1642
        // Shift left to lose all bits except lower "Bits" bits, then shift
1643
        // the value back, replicating what was a sign bit after the first
1644
        // shift.
1645
0
        V = (V << (64-Bits)) >> (64-Bits);
1646
0
        break;
1647
0
    }
1648
    // V is a 64-bit sign-extended value. Convert it to APInt of desired
1649
    // width.
1650
0
    Result = APInt(Width, V, true);
1651
0
    return true;
1652
0
  }
1653
  // Slow case: the value doesn't fit in int64_t.
1654
0
  if (Bits < BW)
1655
0
    Result = A1.trunc(Bits).sext(Width);
1656
0
  else // Bits == BW
1657
0
    Result = A1.sext(Width);
1658
0
  return true;
1659
0
}
1660
1661
bool MachineConstEvaluator::evaluateCLBr(const RegisterSubReg &R1, bool Zeros,
1662
0
      bool Ones, const CellMap &Inputs, LatticeCell &Result) {
1663
0
  assert(Inputs.has(R1.Reg));
1664
0
  LatticeCell LS1;
1665
0
  if (!getCell(R1, Inputs, LS1))
1666
0
    return false;
1667
0
  if (LS1.isBottom() || LS1.isProperty())
1668
0
    return false;
1669
1670
0
  APInt A, CA;
1671
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1672
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1673
0
                evaluateCLBi(A, Zeros, Ones, CA);
1674
0
    if (!Eval)
1675
0
      return false;
1676
0
    const Constant *C = intToConst(CA);
1677
0
    Result.add(C);
1678
0
  }
1679
0
  return true;
1680
0
}
1681
1682
bool MachineConstEvaluator::evaluateCLBi(const APInt &A1, bool Zeros,
1683
0
      bool Ones, APInt &Result) {
1684
0
  unsigned BW = A1.getBitWidth();
1685
0
  if (!Zeros && !Ones)
1686
0
    return false;
1687
0
  unsigned Count = 0;
1688
0
  if (Zeros && (Count == 0))
1689
0
    Count = A1.countl_zero();
1690
0
  if (Ones && (Count == 0))
1691
0
    Count = A1.countl_one();
1692
0
  Result = APInt(BW, static_cast<uint64_t>(Count), false);
1693
0
  return true;
1694
0
}
1695
1696
bool MachineConstEvaluator::evaluateCTBr(const RegisterSubReg &R1, bool Zeros,
1697
0
      bool Ones, const CellMap &Inputs, LatticeCell &Result) {
1698
0
  assert(Inputs.has(R1.Reg));
1699
0
  LatticeCell LS1;
1700
0
  if (!getCell(R1, Inputs, LS1))
1701
0
    return false;
1702
0
  if (LS1.isBottom() || LS1.isProperty())
1703
0
    return false;
1704
1705
0
  APInt A, CA;
1706
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1707
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1708
0
                evaluateCTBi(A, Zeros, Ones, CA);
1709
0
    if (!Eval)
1710
0
      return false;
1711
0
    const Constant *C = intToConst(CA);
1712
0
    Result.add(C);
1713
0
  }
1714
0
  return true;
1715
0
}
1716
1717
bool MachineConstEvaluator::evaluateCTBi(const APInt &A1, bool Zeros,
1718
0
      bool Ones, APInt &Result) {
1719
0
  unsigned BW = A1.getBitWidth();
1720
0
  if (!Zeros && !Ones)
1721
0
    return false;
1722
0
  unsigned Count = 0;
1723
0
  if (Zeros && (Count == 0))
1724
0
    Count = A1.countr_zero();
1725
0
  if (Ones && (Count == 0))
1726
0
    Count = A1.countr_one();
1727
0
  Result = APInt(BW, static_cast<uint64_t>(Count), false);
1728
0
  return true;
1729
0
}
1730
1731
bool MachineConstEvaluator::evaluateEXTRACTr(const RegisterSubReg &R1,
1732
      unsigned Width, unsigned Bits, unsigned Offset, bool Signed,
1733
560
      const CellMap &Inputs, LatticeCell &Result) {
1734
560
  assert(Inputs.has(R1.Reg));
1735
0
  assert(Bits+Offset <= Width);
1736
0
  LatticeCell LS1;
1737
560
  if (!getCell(R1, Inputs, LS1))
1738
560
    return false;
1739
0
  if (LS1.isBottom())
1740
0
    return false;
1741
0
  if (LS1.isProperty()) {
1742
0
    uint32_t Ps = LS1.properties();
1743
0
    if (Ps & ConstantProperties::Zero) {
1744
0
      const Constant *C = intToConst(APInt(Width, 0, false));
1745
0
      Result.add(C);
1746
0
      return true;
1747
0
    }
1748
0
    return false;
1749
0
  }
1750
1751
0
  APInt A, CA;
1752
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1753
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1754
0
                evaluateEXTRACTi(A, Bits, Offset, Signed, CA);
1755
0
    if (!Eval)
1756
0
      return false;
1757
0
    const Constant *C = intToConst(CA);
1758
0
    Result.add(C);
1759
0
  }
1760
0
  return true;
1761
0
}
1762
1763
bool MachineConstEvaluator::evaluateEXTRACTi(const APInt &A1, unsigned Bits,
1764
0
      unsigned Offset, bool Signed, APInt &Result) {
1765
0
  unsigned BW = A1.getBitWidth();
1766
0
  assert(Bits+Offset <= BW);
1767
  // Extracting 0 bits generates 0 as a result (as indicated by the HW people).
1768
0
  if (Bits == 0) {
1769
0
    Result = APInt(BW, 0);
1770
0
    return true;
1771
0
  }
1772
0
  if (BW <= 64) {
1773
0
    int64_t V = A1.getZExtValue();
1774
0
    V <<= (64-Bits-Offset);
1775
0
    if (Signed)
1776
0
      V >>= (64-Bits);
1777
0
    else
1778
0
      V = static_cast<uint64_t>(V) >> (64-Bits);
1779
0
    Result = APInt(BW, V, Signed);
1780
0
    return true;
1781
0
  }
1782
0
  if (Signed)
1783
0
    Result = A1.shl(BW-Bits-Offset).ashr(BW-Bits);
1784
0
  else
1785
0
    Result = A1.shl(BW-Bits-Offset).lshr(BW-Bits);
1786
0
  return true;
1787
0
}
1788
1789
bool MachineConstEvaluator::evaluateSplatr(const RegisterSubReg &R1,
1790
      unsigned Bits, unsigned Count, const CellMap &Inputs,
1791
0
      LatticeCell &Result) {
1792
0
  assert(Inputs.has(R1.Reg));
1793
0
  LatticeCell LS1;
1794
0
  if (!getCell(R1, Inputs, LS1))
1795
0
    return false;
1796
0
  if (LS1.isBottom() || LS1.isProperty())
1797
0
    return false;
1798
1799
0
  APInt A, SA;
1800
0
  for (unsigned i = 0; i < LS1.size(); ++i) {
1801
0
    bool Eval = constToInt(LS1.Values[i], A) &&
1802
0
                evaluateSplati(A, Bits, Count, SA);
1803
0
    if (!Eval)
1804
0
      return false;
1805
0
    const Constant *C = intToConst(SA);
1806
0
    Result.add(C);
1807
0
  }
1808
0
  return true;
1809
0
}
1810
1811
bool MachineConstEvaluator::evaluateSplati(const APInt &A1, unsigned Bits,
1812
0
      unsigned Count, APInt &Result) {
1813
0
  assert(Count > 0);
1814
0
  unsigned BW = A1.getBitWidth(), SW = Count*Bits;
1815
0
  APInt LoBits = (Bits < BW) ? A1.trunc(Bits) : A1.zext(Bits);
1816
0
  if (Count > 1)
1817
0
    LoBits = LoBits.zext(SW);
1818
1819
0
  APInt Res(SW, 0, false);
1820
0
  for (unsigned i = 0; i < Count; ++i) {
1821
0
    Res <<= Bits;
1822
0
    Res |= LoBits;
1823
0
  }
1824
0
  Result = Res;
1825
0
  return true;
1826
0
}
1827
1828
// ----------------------------------------------------------------------
1829
// Hexagon-specific code.
1830
1831
namespace llvm {
1832
1833
  FunctionPass *createHexagonConstPropagationPass();
1834
  void initializeHexagonConstPropagationPass(PassRegistry &Registry);
1835
1836
} // end namespace llvm
1837
1838
namespace {
1839
1840
  class HexagonConstEvaluator : public MachineConstEvaluator {
1841
  public:
1842
    HexagonConstEvaluator(MachineFunction &Fn);
1843
1844
    bool evaluate(const MachineInstr &MI, const CellMap &Inputs,
1845
          CellMap &Outputs) override;
1846
    bool evaluate(const RegisterSubReg &R, const LatticeCell &SrcC,
1847
          LatticeCell &Result) override;
1848
    bool evaluate(const MachineInstr &BrI, const CellMap &Inputs,
1849
          SetVector<const MachineBasicBlock*> &Targets, bool &FallsThru)
1850
          override;
1851
    bool rewrite(MachineInstr &MI, const CellMap &Inputs) override;
1852
1853
  private:
1854
    unsigned getRegBitWidth(unsigned Reg) const;
1855
1856
    static uint32_t getCmp(unsigned Opc);
1857
    static APInt getCmpImm(unsigned Opc, unsigned OpX,
1858
          const MachineOperand &MO);
1859
    void replaceWithNop(MachineInstr &MI);
1860
1861
    bool evaluateHexRSEQ32(RegisterSubReg RL, RegisterSubReg RH, const CellMap &Inputs,
1862
          LatticeCell &Result);
1863
    bool evaluateHexCompare(const MachineInstr &MI, const CellMap &Inputs,
1864
          CellMap &Outputs);
1865
    // This is suitable to be called for compare-and-jump instructions.
1866
    bool evaluateHexCompare2(uint32_t Cmp, const MachineOperand &Src1,
1867
          const MachineOperand &Src2, const CellMap &Inputs, bool &Result);
1868
    bool evaluateHexLogical(const MachineInstr &MI, const CellMap &Inputs,
1869
          CellMap &Outputs);
1870
    bool evaluateHexCondMove(const MachineInstr &MI, const CellMap &Inputs,
1871
          CellMap &Outputs);
1872
    bool evaluateHexExt(const MachineInstr &MI, const CellMap &Inputs,
1873
          CellMap &Outputs);
1874
    bool evaluateHexVector1(const MachineInstr &MI, const CellMap &Inputs,
1875
          CellMap &Outputs);
1876
    bool evaluateHexVector2(const MachineInstr &MI, const CellMap &Inputs,
1877
          CellMap &Outputs);
1878
1879
    void replaceAllRegUsesWith(Register FromReg, Register ToReg);
1880
    bool rewriteHexBranch(MachineInstr &BrI, const CellMap &Inputs);
1881
    bool rewriteHexConstDefs(MachineInstr &MI, const CellMap &Inputs,
1882
          bool &AllDefs);
1883
    bool rewriteHexConstUses(MachineInstr &MI, const CellMap &Inputs);
1884
1885
    MachineRegisterInfo *MRI;
1886
    const HexagonInstrInfo &HII;
1887
    const HexagonRegisterInfo &HRI;
1888
  };
1889
1890
  class HexagonConstPropagation : public MachineFunctionPass {
1891
  public:
1892
    static char ID;
1893
1894
8.48k
    HexagonConstPropagation() : MachineFunctionPass(ID) {}
1895
1896
0
    StringRef getPassName() const override {
1897
0
      return "Hexagon Constant Propagation";
1898
0
    }
1899
1900
8.46k
    bool runOnMachineFunction(MachineFunction &MF) override {
1901
8.46k
      const Function &F = MF.getFunction();
1902
8.46k
      if (skipFunction(F))
1903
0
        return false;
1904
1905
8.46k
      HexagonConstEvaluator HCE(MF);
1906
8.46k
      return MachineConstPropagator(HCE).run(MF);
1907
8.46k
    }
1908
  };
1909
1910
} // end anonymous namespace
1911
1912
char HexagonConstPropagation::ID = 0;
1913
1914
INITIALIZE_PASS(HexagonConstPropagation, "hexagon-constp",
1915
  "Hexagon Constant Propagation", false, false)
1916
1917
HexagonConstEvaluator::HexagonConstEvaluator(MachineFunction &Fn)
1918
  : MachineConstEvaluator(Fn),
1919
    HII(*Fn.getSubtarget<HexagonSubtarget>().getInstrInfo()),
1920
8.46k
    HRI(*Fn.getSubtarget<HexagonSubtarget>().getRegisterInfo()) {
1921
8.46k
  MRI = &Fn.getRegInfo();
1922
8.46k
}
1923
1924
bool HexagonConstEvaluator::evaluate(const MachineInstr &MI,
1925
546k
      const CellMap &Inputs, CellMap &Outputs) {
1926
546k
  if (MI.isCall())
1927
14.3k
    return false;
1928
532k
  if (MI.getNumOperands() == 0 || !MI.getOperand(0).isReg())
1929
114k
    return false;
1930
417k
  const MachineOperand &MD = MI.getOperand(0);
1931
417k
  if (!MD.isDef())
1932
29.5k
    return false;
1933
1934
388k
  unsigned Opc = MI.getOpcode();
1935
388k
  RegisterSubReg DefR(MD);
1936
388k
  assert(!DefR.SubReg);
1937
388k
  if (!DefR.Reg.isVirtual())
1938
37.5k
    return false;
1939
1940
350k
  if (MI.isCopy()) {
1941
26.3k
    LatticeCell RC;
1942
26.3k
    RegisterSubReg SrcR(MI.getOperand(1));
1943
26.3k
    bool Eval = evaluateCOPY(SrcR, Inputs, RC);
1944
26.3k
    if (!Eval)
1945
26.3k
      return false;
1946
0
    Outputs.update(DefR.Reg, RC);
1947
0
    return true;
1948
26.3k
  }
1949
324k
  if (MI.isRegSequence()) {
1950
9.83k
    unsigned Sub1 = MI.getOperand(2).getImm();
1951
9.83k
    unsigned Sub2 = MI.getOperand(4).getImm();
1952
9.83k
    const TargetRegisterClass &DefRC = *MRI->getRegClass(DefR.Reg);
1953
9.83k
    unsigned SubLo = HRI.getHexagonSubRegIndex(DefRC, Hexagon::ps_sub_lo);
1954
9.83k
    unsigned SubHi = HRI.getHexagonSubRegIndex(DefRC, Hexagon::ps_sub_hi);
1955
9.83k
    if (Sub1 != SubLo && Sub1 != SubHi)
1956
0
      return false;
1957
9.83k
    if (Sub2 != SubLo && Sub2 != SubHi)
1958
0
      return false;
1959
9.83k
    assert(Sub1 != Sub2);
1960
0
    bool LoIs1 = (Sub1 == SubLo);
1961
9.83k
    const MachineOperand &OpLo = LoIs1 ? MI.getOperand(1) : MI.getOperand(3);
1962
9.83k
    const MachineOperand &OpHi = LoIs1 ? MI.getOperand(3) : MI.getOperand(1);
1963
9.83k
    LatticeCell RC;
1964
9.83k
    RegisterSubReg SrcRL(OpLo), SrcRH(OpHi);
1965
9.83k
    bool Eval = evaluateHexRSEQ32(SrcRL, SrcRH, Inputs, RC);
1966
9.83k
    if (!Eval)
1967
9.83k
      return false;
1968
0
    Outputs.update(DefR.Reg, RC);
1969
0
    return true;
1970
9.83k
  }
1971
314k
  if (MI.isCompare()) {
1972
42.7k
    bool Eval = evaluateHexCompare(MI, Inputs, Outputs);
1973
42.7k
    return Eval;
1974
42.7k
  }
1975
1976
271k
  switch (Opc) {
1977
171k
    default:
1978
171k
      return false;
1979
26.8k
    case Hexagon::A2_tfrsi:
1980
32.1k
    case Hexagon::A2_tfrpi:
1981
32.1k
    case Hexagon::CONST32:
1982
33.8k
    case Hexagon::CONST64:
1983
33.8k
    {
1984
33.8k
      const MachineOperand &VO = MI.getOperand(1);
1985
      // The operand of CONST32 can be a blockaddress, e.g.
1986
      //   %0 = CONST32 <blockaddress(@eat, %l)>
1987
      // Do this check for all instructions for safety.
1988
33.8k
      if (!VO.isImm())
1989
3.06k
        return false;
1990
30.7k
      int64_t V = MI.getOperand(1).getImm();
1991
30.7k
      unsigned W = getRegBitWidth(DefR.Reg);
1992
30.7k
      if (W != 32 && W != 64)
1993
0
        return false;
1994
30.7k
      IntegerType *Ty = (W == 32) ? Type::getInt32Ty(CX)
1995
30.7k
                                  : Type::getInt64Ty(CX);
1996
30.7k
      const ConstantInt *CI = ConstantInt::get(Ty, V, true);
1997
30.7k
      LatticeCell RC = Outputs.get(DefR.Reg);
1998
30.7k
      RC.add(CI);
1999
30.7k
      Outputs.update(DefR.Reg, RC);
2000
30.7k
      break;
2001
30.7k
    }
2002
2003
0
    case Hexagon::PS_true:
2004
12
    case Hexagon::PS_false:
2005
12
    {
2006
12
      LatticeCell RC = Outputs.get(DefR.Reg);
2007
12
      bool NonZero = (Opc == Hexagon::PS_true);
2008
12
      uint32_t P = NonZero ? ConstantProperties::NonZero
2009
12
                           : ConstantProperties::Zero;
2010
12
      RC.add(P);
2011
12
      Outputs.update(DefR.Reg, RC);
2012
12
      break;
2013
0
    }
2014
2015
1.35k
    case Hexagon::A2_and:
2016
4.94k
    case Hexagon::A2_andir:
2017
5.97k
    case Hexagon::A2_andp:
2018
7.05k
    case Hexagon::A2_or:
2019
7.32k
    case Hexagon::A2_orir:
2020
7.39k
    case Hexagon::A2_orp:
2021
8.75k
    case Hexagon::A2_xor:
2022
9.00k
    case Hexagon::A2_xorp:
2023
9.00k
    {
2024
9.00k
      bool Eval = evaluateHexLogical(MI, Inputs, Outputs);
2025
9.00k
      if (!Eval)
2026
9.00k
        return false;
2027
0
      break;
2028
9.00k
    }
2029
2030
7.57k
    case Hexagon::A2_combineii:  // combine(#s8Ext, #s8)
2031
7.59k
    case Hexagon::A4_combineii:  // combine(#s8, #u6Ext)
2032
7.59k
    {
2033
7.59k
      if (!MI.getOperand(1).isImm() || !MI.getOperand(2).isImm())
2034
0
        return false;
2035
7.59k
      uint64_t Hi = MI.getOperand(1).getImm();
2036
7.59k
      uint64_t Lo = MI.getOperand(2).getImm();
2037
7.59k
      uint64_t Res = (Hi << 32) | (Lo & 0xFFFFFFFF);
2038
7.59k
      IntegerType *Ty = Type::getInt64Ty(CX);
2039
7.59k
      const ConstantInt *CI = ConstantInt::get(Ty, Res, false);
2040
7.59k
      LatticeCell RC = Outputs.get(DefR.Reg);
2041
7.59k
      RC.add(CI);
2042
7.59k
      Outputs.update(DefR.Reg, RC);
2043
7.59k
      break;
2044
7.59k
    }
2045
2046
1.27k
    case Hexagon::S2_setbit_i:
2047
1.27k
    {
2048
1.27k
      int64_t B = MI.getOperand(2).getImm();
2049
1.27k
      assert(B >=0 && B < 32);
2050
0
      APInt A(32, (1ull << B), false);
2051
1.27k
      RegisterSubReg R(MI.getOperand(1));
2052
1.27k
      LatticeCell RC = Outputs.get(DefR.Reg);
2053
1.27k
      bool Eval = evaluateORri(R, A, Inputs, RC);
2054
1.27k
      if (!Eval)
2055
1.27k
        return false;
2056
0
      Outputs.update(DefR.Reg, RC);
2057
0
      break;
2058
1.27k
    }
2059
2060
150
    case Hexagon::C2_mux:
2061
155
    case Hexagon::C2_muxir:
2062
239
    case Hexagon::C2_muxri:
2063
43.2k
    case Hexagon::C2_muxii:
2064
43.2k
    {
2065
43.2k
      bool Eval = evaluateHexCondMove(MI, Inputs, Outputs);
2066
43.2k
      if (!Eval)
2067
43.2k
        return false;
2068
0
      break;
2069
43.2k
    }
2070
2071
1.93k
    case Hexagon::A2_sxtb:
2072
3.42k
    case Hexagon::A2_sxth:
2073
3.42k
    case Hexagon::A2_sxtw:
2074
4.65k
    case Hexagon::A2_zxtb:
2075
5.15k
    case Hexagon::A2_zxth:
2076
5.15k
    {
2077
5.15k
      bool Eval = evaluateHexExt(MI, Inputs, Outputs);
2078
5.15k
      if (!Eval)
2079
5.15k
        return false;
2080
0
      break;
2081
5.15k
    }
2082
2083
0
    case Hexagon::S2_ct0:
2084
0
    case Hexagon::S2_ct0p:
2085
0
    case Hexagon::S2_ct1:
2086
0
    case Hexagon::S2_ct1p:
2087
0
    {
2088
0
      using namespace Hexagon;
2089
2090
0
      bool Ones = (Opc == S2_ct1) || (Opc == S2_ct1p);
2091
0
      RegisterSubReg R1(MI.getOperand(1));
2092
0
      assert(Inputs.has(R1.Reg));
2093
0
      LatticeCell T;
2094
0
      bool Eval = evaluateCTBr(R1, !Ones, Ones, Inputs, T);
2095
0
      if (!Eval)
2096
0
        return false;
2097
      // All of these instructions return a 32-bit value. The evaluate
2098
      // will generate the same type as the operand, so truncate the
2099
      // result if necessary.
2100
0
      APInt C;
2101
0
      LatticeCell RC = Outputs.get(DefR.Reg);
2102
0
      for (unsigned i = 0; i < T.size(); ++i) {
2103
0
        const Constant *CI = T.Values[i];
2104
0
        if (constToInt(CI, C) && C.getBitWidth() > 32)
2105
0
          CI = intToConst(C.trunc(32));
2106
0
        RC.add(CI);
2107
0
      }
2108
0
      Outputs.update(DefR.Reg, RC);
2109
0
      break;
2110
0
    }
2111
2112
0
    case Hexagon::S2_cl0:
2113
0
    case Hexagon::S2_cl0p:
2114
0
    case Hexagon::S2_cl1:
2115
0
    case Hexagon::S2_cl1p:
2116
0
    case Hexagon::S2_clb:
2117
0
    case Hexagon::S2_clbp:
2118
0
    {
2119
0
      using namespace Hexagon;
2120
2121
0
      bool OnlyZeros = (Opc == S2_cl0) || (Opc == S2_cl0p);
2122
0
      bool OnlyOnes =  (Opc == S2_cl1) || (Opc == S2_cl1p);
2123
0
      RegisterSubReg R1(MI.getOperand(1));
2124
0
      assert(Inputs.has(R1.Reg));
2125
0
      LatticeCell T;
2126
0
      bool Eval = evaluateCLBr(R1, !OnlyOnes, !OnlyZeros, Inputs, T);
2127
0
      if (!Eval)
2128
0
        return false;
2129
      // All of these instructions return a 32-bit value. The evaluate
2130
      // will generate the same type as the operand, so truncate the
2131
      // result if necessary.
2132
0
      APInt C;
2133
0
      LatticeCell RC = Outputs.get(DefR.Reg);
2134
0
      for (unsigned i = 0; i < T.size(); ++i) {
2135
0
        const Constant *CI = T.Values[i];
2136
0
        if (constToInt(CI, C) && C.getBitWidth() > 32)
2137
0
          CI = intToConst(C.trunc(32));
2138
0
        RC.add(CI);
2139
0
      }
2140
0
      Outputs.update(DefR.Reg, RC);
2141
0
      break;
2142
0
    }
2143
2144
19
    case Hexagon::S4_extract:
2145
23
    case Hexagon::S4_extractp:
2146
560
    case Hexagon::S2_extractu:
2147
560
    case Hexagon::S2_extractup:
2148
560
    {
2149
560
      bool Signed = (Opc == Hexagon::S4_extract) ||
2150
560
                    (Opc == Hexagon::S4_extractp);
2151
560
      RegisterSubReg R1(MI.getOperand(1));
2152
560
      unsigned BW = getRegBitWidth(R1.Reg);
2153
560
      unsigned Bits = MI.getOperand(2).getImm();
2154
560
      unsigned Offset = MI.getOperand(3).getImm();
2155
560
      LatticeCell RC = Outputs.get(DefR.Reg);
2156
560
      if (Offset >= BW) {
2157
0
        APInt Zero(BW, 0, false);
2158
0
        RC.add(intToConst(Zero));
2159
0
        break;
2160
0
      }
2161
560
      if (Offset+Bits > BW) {
2162
        // If the requested bitfield extends beyond the most significant bit,
2163
        // the extra bits are treated as 0s. To emulate this behavior, reduce
2164
        // the number of requested bits, and make the extract unsigned.
2165
0
        Bits = BW-Offset;
2166
0
        Signed = false;
2167
0
      }
2168
560
      bool Eval = evaluateEXTRACTr(R1, BW, Bits, Offset, Signed, Inputs, RC);
2169
560
      if (!Eval)
2170
560
        return false;
2171
0
      Outputs.update(DefR.Reg, RC);
2172
0
      break;
2173
560
    }
2174
2175
0
    case Hexagon::S2_vsplatrb:
2176
0
    case Hexagon::S2_vsplatrh:
2177
    // vabsh, vabsh:sat
2178
    // vabsw, vabsw:sat
2179
    // vconj:sat
2180
    // vrndwh, vrndwh:sat
2181
    // vsathb, vsathub, vsatwuh
2182
    // vsxtbh, vsxthw
2183
    // vtrunehb, vtrunohb
2184
    // vzxtbh, vzxthw
2185
0
    {
2186
0
      bool Eval = evaluateHexVector1(MI, Inputs, Outputs);
2187
0
      if (!Eval)
2188
0
        return false;
2189
0
      break;
2190
0
    }
2191
2192
    // TODO:
2193
    // A2_vaddh
2194
    // A2_vaddhs
2195
    // A2_vaddw
2196
    // A2_vaddws
2197
271k
  }
2198
2199
38.3k
  return true;
2200
271k
}
2201
2202
bool HexagonConstEvaluator::evaluate(const RegisterSubReg &R,
2203
9.01k
      const LatticeCell &Input, LatticeCell &Result) {
2204
9.01k
  if (!R.SubReg) {
2205
700
    Result = Input;
2206
700
    return true;
2207
700
  }
2208
8.31k
  const TargetRegisterClass *RC = MRI->getRegClass(R.Reg);
2209
8.31k
  if (RC != &Hexagon::DoubleRegsRegClass)
2210
0
    return false;
2211
8.31k
  if (R.SubReg != Hexagon::isub_lo && R.SubReg != Hexagon::isub_hi)
2212
0
    return false;
2213
2214
8.31k
  assert(!Input.isTop());
2215
8.31k
  if (Input.isBottom())
2216
8.31k
    return false;
2217
2218
0
  using P = ConstantProperties;
2219
2220
0
  if (Input.isProperty()) {
2221
0
    uint32_t Ps = Input.properties();
2222
0
    if (Ps & (P::Zero|P::NaN)) {
2223
0
      uint32_t Ns = (Ps & (P::Zero|P::NaN|P::SignProperties));
2224
0
      Result.add(Ns);
2225
0
      return true;
2226
0
    }
2227
0
    if (R.SubReg == Hexagon::isub_hi) {
2228
0
      uint32_t Ns = (Ps & P::SignProperties);
2229
0
      Result.add(Ns);
2230
0
      return true;
2231
0
    }
2232
0
    return false;
2233
0
  }
2234
2235
  // The Input cell contains some known values. Pick the word corresponding
2236
  // to the subregister.
2237
0
  APInt A;
2238
0
  for (unsigned i = 0; i < Input.size(); ++i) {
2239
0
    const Constant *C = Input.Values[i];
2240
0
    if (!constToInt(C, A))
2241
0
      return false;
2242
0
    if (!A.isIntN(64))
2243
0
      return false;
2244
0
    uint64_t U = A.getZExtValue();
2245
0
    if (R.SubReg == Hexagon::isub_hi)
2246
0
      U >>= 32;
2247
0
    U &= 0xFFFFFFFFULL;
2248
0
    uint32_t U32 = Lo_32(U);
2249
0
    int32_t V32;
2250
0
    memcpy(&V32, &U32, sizeof V32);
2251
0
    IntegerType *Ty = Type::getInt32Ty(CX);
2252
0
    const ConstantInt *C32 = ConstantInt::get(Ty, static_cast<int64_t>(V32));
2253
0
    Result.add(C32);
2254
0
  }
2255
0
  return true;
2256
0
}
2257
2258
bool HexagonConstEvaluator::evaluate(const MachineInstr &BrI,
2259
      const CellMap &Inputs, SetVector<const MachineBasicBlock*> &Targets,
2260
19.4k
      bool &FallsThru) {
2261
  // We need to evaluate one branch at a time. TII::analyzeBranch checks
2262
  // all the branches in a basic block at once, so we cannot use it.
2263
19.4k
  unsigned Opc = BrI.getOpcode();
2264
19.4k
  bool SimpleBranch = false;
2265
19.4k
  bool Negated = false;
2266
19.4k
  switch (Opc) {
2267
226
    case Hexagon::J2_jumpf:
2268
226
    case Hexagon::J2_jumpfnew:
2269
226
    case Hexagon::J2_jumpfnewpt:
2270
226
      Negated = true;
2271
226
      [[fallthrough]];
2272
2.62k
    case Hexagon::J2_jumpt:
2273
2.62k
    case Hexagon::J2_jumptnew:
2274
2.62k
    case Hexagon::J2_jumptnewpt:
2275
      // Simple branch:  if([!]Pn) jump ...
2276
      // i.e. Op0 = predicate, Op1 = branch target.
2277
2.62k
      SimpleBranch = true;
2278
2.62k
      break;
2279
2.19k
    case Hexagon::J2_jump:
2280
2.19k
      Targets.insert(BrI.getOperand(0).getMBB());
2281
2.19k
      FallsThru = false;
2282
2.19k
      return true;
2283
14.5k
    default:
2284
17.2k
Undetermined:
2285
      // If the branch is of unknown type, assume that all successors are
2286
      // executable.
2287
17.2k
      FallsThru = !BrI.isUnconditionalBranch();
2288
17.2k
      return false;
2289
19.4k
  }
2290
2291
2.62k
  if (SimpleBranch) {
2292
2.62k
    const MachineOperand &MD = BrI.getOperand(0);
2293
2.62k
    RegisterSubReg PR(MD);
2294
    // If the condition operand has a subregister, this is not something
2295
    // we currently recognize.
2296
2.62k
    if (PR.SubReg)
2297
0
      goto Undetermined;
2298
2.62k
    assert(Inputs.has(PR.Reg));
2299
0
    const LatticeCell &PredC = Inputs.get(PR.Reg);
2300
2.62k
    if (PredC.isBottom())
2301
2.62k
      goto Undetermined;
2302
2303
0
    uint32_t Props = PredC.properties();
2304
0
    bool CTrue = false, CFalse = false;
2305
0
    if (Props & ConstantProperties::Zero)
2306
0
      CFalse = true;
2307
0
    else if (Props & ConstantProperties::NonZero)
2308
0
      CTrue = true;
2309
    // If the condition is not known to be either, bail out.
2310
0
    if (!CTrue && !CFalse)
2311
0
      goto Undetermined;
2312
2313
0
    const MachineBasicBlock *BranchTarget = BrI.getOperand(1).getMBB();
2314
2315
0
    FallsThru = false;
2316
0
    if ((!Negated && CTrue) || (Negated && CFalse))
2317
0
      Targets.insert(BranchTarget);
2318
0
    else if ((!Negated && CFalse) || (Negated && CTrue))
2319
0
      FallsThru = true;
2320
0
    else
2321
0
      goto Undetermined;
2322
0
  }
2323
2324
0
  return true;
2325
2.62k
}
2326
2327
547k
bool HexagonConstEvaluator::rewrite(MachineInstr &MI, const CellMap &Inputs) {
2328
547k
  if (MI.isBranch())
2329
730
    return rewriteHexBranch(MI, Inputs);
2330
2331
546k
  unsigned Opc = MI.getOpcode();
2332
546k
  switch (Opc) {
2333
512k
    default:
2334
512k
      break;
2335
512k
    case Hexagon::A2_tfrsi:
2336
32.1k
    case Hexagon::A2_tfrpi:
2337
32.1k
    case Hexagon::CONST32:
2338
33.8k
    case Hexagon::CONST64:
2339
33.8k
    case Hexagon::PS_true:
2340
33.8k
    case Hexagon::PS_false:
2341
33.8k
      return false;
2342
546k
  }
2343
2344
512k
  unsigned NumOp = MI.getNumOperands();
2345
512k
  if (NumOp == 0)
2346
0
    return false;
2347
2348
512k
  bool AllDefs, Changed;
2349
512k
  Changed = rewriteHexConstDefs(MI, Inputs, AllDefs);
2350
  // If not all defs have been rewritten (i.e. the instruction defines
2351
  // a register that is not compile-time constant), then try to rewrite
2352
  // register operands that are known to be constant with immediates.
2353
512k
  if (!AllDefs)
2354
345k
    Changed |= rewriteHexConstUses(MI, Inputs);
2355
2356
512k
  return Changed;
2357
512k
}
2358
2359
44.0k
unsigned HexagonConstEvaluator::getRegBitWidth(unsigned Reg) const {
2360
44.0k
  const TargetRegisterClass *RC = MRI->getRegClass(Reg);
2361
44.0k
  if (Hexagon::IntRegsRegClass.hasSubClassEq(RC))
2362
29.2k
    return 32;
2363
14.7k
  if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC))
2364
14.7k
    return 64;
2365
0
  if (Hexagon::PredRegsRegClass.hasSubClassEq(RC))
2366
0
    return 8;
2367
0
  llvm_unreachable("Invalid register");
2368
0
  return 0;
2369
0
}
2370
2371
19.9k
uint32_t HexagonConstEvaluator::getCmp(unsigned Opc) {
2372
19.9k
  switch (Opc) {
2373
1.30k
    case Hexagon::C2_cmpeq:
2374
2.55k
    case Hexagon::C2_cmpeqp:
2375
2.55k
    case Hexagon::A4_cmpbeq:
2376
2.55k
    case Hexagon::A4_cmpheq:
2377
2.55k
    case Hexagon::A4_cmpbeqi:
2378
2.55k
    case Hexagon::A4_cmpheqi:
2379
4.56k
    case Hexagon::C2_cmpeqi:
2380
4.56k
    case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
2381
4.56k
    case Hexagon::J4_cmpeqn1_t_jumpnv_t:
2382
4.56k
    case Hexagon::J4_cmpeqi_t_jumpnv_nt:
2383
4.56k
    case Hexagon::J4_cmpeqi_t_jumpnv_t:
2384
4.56k
    case Hexagon::J4_cmpeq_t_jumpnv_nt:
2385
4.56k
    case Hexagon::J4_cmpeq_t_jumpnv_t:
2386
4.56k
      return Comparison::EQ;
2387
2388
0
    case Hexagon::C4_cmpneq:
2389
0
    case Hexagon::C4_cmpneqi:
2390
0
    case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
2391
0
    case Hexagon::J4_cmpeqn1_f_jumpnv_t:
2392
0
    case Hexagon::J4_cmpeqi_f_jumpnv_nt:
2393
0
    case Hexagon::J4_cmpeqi_f_jumpnv_t:
2394
0
    case Hexagon::J4_cmpeq_f_jumpnv_nt:
2395
0
    case Hexagon::J4_cmpeq_f_jumpnv_t:
2396
0
      return Comparison::NE;
2397
2398
2.84k
    case Hexagon::C2_cmpgt:
2399
4.87k
    case Hexagon::C2_cmpgtp:
2400
4.87k
    case Hexagon::A4_cmpbgt:
2401
4.87k
    case Hexagon::A4_cmphgt:
2402
4.87k
    case Hexagon::A4_cmpbgti:
2403
4.87k
    case Hexagon::A4_cmphgti:
2404
8.00k
    case Hexagon::C2_cmpgti:
2405
8.00k
    case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
2406
8.00k
    case Hexagon::J4_cmpgtn1_t_jumpnv_t:
2407
8.00k
    case Hexagon::J4_cmpgti_t_jumpnv_nt:
2408
8.00k
    case Hexagon::J4_cmpgti_t_jumpnv_t:
2409
8.00k
    case Hexagon::J4_cmpgt_t_jumpnv_nt:
2410
8.00k
    case Hexagon::J4_cmpgt_t_jumpnv_t:
2411
8.00k
      return Comparison::GTs;
2412
2413
0
    case Hexagon::C4_cmplte:
2414
0
    case Hexagon::C4_cmpltei:
2415
0
    case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
2416
0
    case Hexagon::J4_cmpgtn1_f_jumpnv_t:
2417
0
    case Hexagon::J4_cmpgti_f_jumpnv_nt:
2418
0
    case Hexagon::J4_cmpgti_f_jumpnv_t:
2419
0
    case Hexagon::J4_cmpgt_f_jumpnv_nt:
2420
0
    case Hexagon::J4_cmpgt_f_jumpnv_t:
2421
0
      return Comparison::LEs;
2422
2423
2.58k
    case Hexagon::C2_cmpgtu:
2424
4.26k
    case Hexagon::C2_cmpgtup:
2425
4.26k
    case Hexagon::A4_cmpbgtu:
2426
4.26k
    case Hexagon::A4_cmpbgtui:
2427
4.26k
    case Hexagon::A4_cmphgtu:
2428
4.26k
    case Hexagon::A4_cmphgtui:
2429
7.35k
    case Hexagon::C2_cmpgtui:
2430
7.35k
    case Hexagon::J4_cmpgtui_t_jumpnv_nt:
2431
7.35k
    case Hexagon::J4_cmpgtui_t_jumpnv_t:
2432
7.35k
    case Hexagon::J4_cmpgtu_t_jumpnv_nt:
2433
7.35k
    case Hexagon::J4_cmpgtu_t_jumpnv_t:
2434
7.35k
      return Comparison::GTu;
2435
2436
0
    case Hexagon::J4_cmpltu_f_jumpnv_nt:
2437
0
    case Hexagon::J4_cmpltu_f_jumpnv_t:
2438
0
      return Comparison::GEu;
2439
2440
0
    case Hexagon::J4_cmpltu_t_jumpnv_nt:
2441
0
    case Hexagon::J4_cmpltu_t_jumpnv_t:
2442
0
      return Comparison::LTu;
2443
2444
0
    case Hexagon::J4_cmplt_f_jumpnv_nt:
2445
0
    case Hexagon::J4_cmplt_f_jumpnv_t:
2446
0
      return Comparison::GEs;
2447
2448
0
    case Hexagon::C4_cmplteu:
2449
0
    case Hexagon::C4_cmplteui:
2450
0
    case Hexagon::J4_cmpgtui_f_jumpnv_nt:
2451
0
    case Hexagon::J4_cmpgtui_f_jumpnv_t:
2452
0
    case Hexagon::J4_cmpgtu_f_jumpnv_nt:
2453
0
    case Hexagon::J4_cmpgtu_f_jumpnv_t:
2454
0
      return Comparison::LEu;
2455
2456
0
    case Hexagon::J4_cmplt_t_jumpnv_nt:
2457
0
    case Hexagon::J4_cmplt_t_jumpnv_t:
2458
0
      return Comparison::LTs;
2459
2460
0
    default:
2461
0
      break;
2462
19.9k
  }
2463
0
  return Comparison::Unk;
2464
19.9k
}
2465
2466
APInt HexagonConstEvaluator::getCmpImm(unsigned Opc, unsigned OpX,
2467
8.23k
      const MachineOperand &MO) {
2468
8.23k
  bool Signed = false;
2469
8.23k
  switch (Opc) {
2470
0
    case Hexagon::A4_cmpbgtui:   // u7
2471
0
    case Hexagon::A4_cmphgtui:   // u7
2472
0
      break;
2473
0
    case Hexagon::A4_cmpheqi:    // s8
2474
0
    case Hexagon::C4_cmpneqi:   // s8
2475
0
      Signed = true;
2476
0
      break;
2477
0
    case Hexagon::A4_cmpbeqi:    // u8
2478
0
      break;
2479
3.08k
    case Hexagon::C2_cmpgtui:      // u9
2480
3.08k
    case Hexagon::C4_cmplteui:  // u9
2481
3.08k
      break;
2482
2.01k
    case Hexagon::C2_cmpeqi:       // s10
2483
5.14k
    case Hexagon::C2_cmpgti:       // s10
2484
5.14k
    case Hexagon::C4_cmpltei:   // s10
2485
5.14k
      Signed = true;
2486
5.14k
      break;
2487
0
    case Hexagon::J4_cmpeqi_f_jumpnv_nt:   // u5
2488
0
    case Hexagon::J4_cmpeqi_f_jumpnv_t:    // u5
2489
0
    case Hexagon::J4_cmpeqi_t_jumpnv_nt:   // u5
2490
0
    case Hexagon::J4_cmpeqi_t_jumpnv_t:    // u5
2491
0
    case Hexagon::J4_cmpgti_f_jumpnv_nt:   // u5
2492
0
    case Hexagon::J4_cmpgti_f_jumpnv_t:    // u5
2493
0
    case Hexagon::J4_cmpgti_t_jumpnv_nt:   // u5
2494
0
    case Hexagon::J4_cmpgti_t_jumpnv_t:    // u5
2495
0
    case Hexagon::J4_cmpgtui_f_jumpnv_nt:  // u5
2496
0
    case Hexagon::J4_cmpgtui_f_jumpnv_t:   // u5
2497
0
    case Hexagon::J4_cmpgtui_t_jumpnv_nt:  // u5
2498
0
    case Hexagon::J4_cmpgtui_t_jumpnv_t:   // u5
2499
0
      break;
2500
0
    default:
2501
0
      llvm_unreachable("Unhandled instruction");
2502
0
      break;
2503
8.23k
  }
2504
2505
8.23k
  uint64_t Val = MO.getImm();
2506
8.23k
  return APInt(32, Val, Signed);
2507
8.23k
}
2508
2509
0
void HexagonConstEvaluator::replaceWithNop(MachineInstr &MI) {
2510
0
  MI.setDesc(HII.get(Hexagon::A2_nop));
2511
0
  while (MI.getNumOperands() > 0)
2512
0
    MI.removeOperand(0);
2513
0
}
2514
2515
bool HexagonConstEvaluator::evaluateHexRSEQ32(RegisterSubReg RL, RegisterSubReg RH,
2516
9.83k
      const CellMap &Inputs, LatticeCell &Result) {
2517
9.83k
  assert(Inputs.has(RL.Reg) && Inputs.has(RH.Reg));
2518
0
  LatticeCell LSL, LSH;
2519
9.83k
  if (!getCell(RL, Inputs, LSL) || !getCell(RH, Inputs, LSH))
2520
9.83k
    return false;
2521
0
  if (LSL.isProperty() || LSH.isProperty())
2522
0
    return false;
2523
2524
0
  unsigned LN = LSL.size(), HN = LSH.size();
2525
0
  SmallVector<APInt,4> LoVs(LN), HiVs(HN);
2526
0
  for (unsigned i = 0; i < LN; ++i) {
2527
0
    bool Eval = constToInt(LSL.Values[i], LoVs[i]);
2528
0
    if (!Eval)
2529
0
      return false;
2530
0
    assert(LoVs[i].getBitWidth() == 32);
2531
0
  }
2532
0
  for (unsigned i = 0; i < HN; ++i) {
2533
0
    bool Eval = constToInt(LSH.Values[i], HiVs[i]);
2534
0
    if (!Eval)
2535
0
      return false;
2536
0
    assert(HiVs[i].getBitWidth() == 32);
2537
0
  }
2538
2539
0
  for (unsigned i = 0; i < HiVs.size(); ++i) {
2540
0
    APInt HV = HiVs[i].zext(64) << 32;
2541
0
    for (unsigned j = 0; j < LoVs.size(); ++j) {
2542
0
      APInt LV = LoVs[j].zext(64);
2543
0
      const Constant *C = intToConst(HV | LV);
2544
0
      Result.add(C);
2545
0
      if (Result.isBottom())
2546
0
        return false;
2547
0
    }
2548
0
  }
2549
0
  return !Result.isBottom();
2550
0
}
2551
2552
bool HexagonConstEvaluator::evaluateHexCompare(const MachineInstr &MI,
2553
42.7k
      const CellMap &Inputs, CellMap &Outputs) {
2554
42.7k
  unsigned Opc = MI.getOpcode();
2555
42.7k
  bool Classic = false;
2556
42.7k
  switch (Opc) {
2557
1.30k
    case Hexagon::C2_cmpeq:
2558
2.55k
    case Hexagon::C2_cmpeqp:
2559
5.40k
    case Hexagon::C2_cmpgt:
2560
7.43k
    case Hexagon::C2_cmpgtp:
2561
10.0k
    case Hexagon::C2_cmpgtu:
2562
11.7k
    case Hexagon::C2_cmpgtup:
2563
13.7k
    case Hexagon::C2_cmpeqi:
2564
16.8k
    case Hexagon::C2_cmpgti:
2565
19.9k
    case Hexagon::C2_cmpgtui:
2566
      // Classic compare:  Dst0 = CMP Src1, Src2
2567
19.9k
      Classic = true;
2568
19.9k
      break;
2569
22.7k
    default:
2570
      // Not handling other compare instructions now.
2571
22.7k
      return false;
2572
42.7k
  }
2573
2574
19.9k
  if (Classic) {
2575
19.9k
    const MachineOperand &Src1 = MI.getOperand(1);
2576
19.9k
    const MachineOperand &Src2 = MI.getOperand(2);
2577
2578
19.9k
    bool Result;
2579
19.9k
    unsigned Opc = MI.getOpcode();
2580
19.9k
    bool Computed = evaluateHexCompare2(Opc, Src1, Src2, Inputs, Result);
2581
19.9k
    if (Computed) {
2582
      // Only create a zero/non-zero cell. At this time there isn't really
2583
      // much need for specific values.
2584
0
      RegisterSubReg DefR(MI.getOperand(0));
2585
0
      LatticeCell L = Outputs.get(DefR.Reg);
2586
0
      uint32_t P = Result ? ConstantProperties::NonZero
2587
0
                          : ConstantProperties::Zero;
2588
0
      L.add(P);
2589
0
      Outputs.update(DefR.Reg, L);
2590
0
      return true;
2591
0
    }
2592
19.9k
  }
2593
2594
19.9k
  return false;
2595
19.9k
}
2596
2597
bool HexagonConstEvaluator::evaluateHexCompare2(unsigned Opc,
2598
      const MachineOperand &Src1, const MachineOperand &Src2,
2599
19.9k
      const CellMap &Inputs, bool &Result) {
2600
19.9k
  uint32_t Cmp = getCmp(Opc);
2601
19.9k
  bool Reg1 = Src1.isReg(), Reg2 = Src2.isReg();
2602
19.9k
  bool Imm1 = Src1.isImm(), Imm2 = Src2.isImm();
2603
19.9k
  if (Reg1) {
2604
19.9k
    RegisterSubReg R1(Src1);
2605
19.9k
    if (Reg2) {
2606
11.7k
      RegisterSubReg R2(Src2);
2607
11.7k
      return evaluateCMPrr(Cmp, R1, R2, Inputs, Result);
2608
11.7k
    } else if (Imm2) {
2609
8.23k
      APInt A2 = getCmpImm(Opc, 2, Src2);
2610
8.23k
      return evaluateCMPri(Cmp, R1, A2, Inputs, Result);
2611
8.23k
    }
2612
19.9k
  } else if (Imm1) {
2613
0
    APInt A1 = getCmpImm(Opc, 1, Src1);
2614
0
    if (Reg2) {
2615
0
      RegisterSubReg R2(Src2);
2616
0
      uint32_t NegCmp = Comparison::negate(Cmp);
2617
0
      return evaluateCMPri(NegCmp, R2, A1, Inputs, Result);
2618
0
    } else if (Imm2) {
2619
0
      APInt A2 = getCmpImm(Opc, 2, Src2);
2620
0
      return evaluateCMPii(Cmp, A1, A2, Result);
2621
0
    }
2622
0
  }
2623
  // Unknown kind of comparison.
2624
0
  return false;
2625
19.9k
}
2626
2627
bool HexagonConstEvaluator::evaluateHexLogical(const MachineInstr &MI,
2628
9.00k
      const CellMap &Inputs, CellMap &Outputs) {
2629
9.00k
  unsigned Opc = MI.getOpcode();
2630
9.00k
  if (MI.getNumOperands() != 3)
2631
0
    return false;
2632
9.00k
  const MachineOperand &Src1 = MI.getOperand(1);
2633
9.00k
  const MachineOperand &Src2 = MI.getOperand(2);
2634
9.00k
  RegisterSubReg R1(Src1);
2635
9.00k
  bool Eval = false;
2636
9.00k
  LatticeCell RC;
2637
9.00k
  switch (Opc) {
2638
0
    default:
2639
0
      return false;
2640
1.35k
    case Hexagon::A2_and:
2641
2.39k
    case Hexagon::A2_andp:
2642
2.39k
      Eval = evaluateANDrr(R1, RegisterSubReg(Src2), Inputs, RC);
2643
2.39k
      break;
2644
3.58k
    case Hexagon::A2_andir: {
2645
3.58k
      if (!Src2.isImm())
2646
0
        return false;
2647
3.58k
      APInt A(32, Src2.getImm(), true);
2648
3.58k
      Eval = evaluateANDri(R1, A, Inputs, RC);
2649
3.58k
      break;
2650
3.58k
    }
2651
1.07k
    case Hexagon::A2_or:
2652
1.14k
    case Hexagon::A2_orp:
2653
1.14k
      Eval = evaluateORrr(R1, RegisterSubReg(Src2), Inputs, RC);
2654
1.14k
      break;
2655
270
    case Hexagon::A2_orir: {
2656
270
      if (!Src2.isImm())
2657
0
        return false;
2658
270
      APInt A(32, Src2.getImm(), true);
2659
270
      Eval = evaluateORri(R1, A, Inputs, RC);
2660
270
      break;
2661
270
    }
2662
1.35k
    case Hexagon::A2_xor:
2663
1.60k
    case Hexagon::A2_xorp:
2664
1.60k
      Eval = evaluateXORrr(R1, RegisterSubReg(Src2), Inputs, RC);
2665
1.60k
      break;
2666
9.00k
  }
2667
9.00k
  if (Eval) {
2668
0
    RegisterSubReg DefR(MI.getOperand(0));
2669
0
    Outputs.update(DefR.Reg, RC);
2670
0
  }
2671
9.00k
  return Eval;
2672
9.00k
}
2673
2674
bool HexagonConstEvaluator::evaluateHexCondMove(const MachineInstr &MI,
2675
43.2k
      const CellMap &Inputs, CellMap &Outputs) {
2676
  // Dst0 = Cond1 ? Src2 : Src3
2677
43.2k
  RegisterSubReg CR(MI.getOperand(1));
2678
43.2k
  assert(Inputs.has(CR.Reg));
2679
0
  LatticeCell LS;
2680
43.2k
  if (!getCell(CR, Inputs, LS))
2681
43.2k
    return false;
2682
0
  uint32_t Ps = LS.properties();
2683
0
  unsigned TakeOp;
2684
0
  if (Ps & ConstantProperties::Zero)
2685
0
    TakeOp = 3;
2686
0
  else if (Ps & ConstantProperties::NonZero)
2687
0
    TakeOp = 2;
2688
0
  else
2689
0
    return false;
2690
2691
0
  const MachineOperand &ValOp = MI.getOperand(TakeOp);
2692
0
  RegisterSubReg DefR(MI.getOperand(0));
2693
0
  LatticeCell RC = Outputs.get(DefR.Reg);
2694
2695
0
  if (ValOp.isImm()) {
2696
0
    int64_t V = ValOp.getImm();
2697
0
    unsigned W = getRegBitWidth(DefR.Reg);
2698
0
    APInt A(W, V, true);
2699
0
    const Constant *C = intToConst(A);
2700
0
    RC.add(C);
2701
0
    Outputs.update(DefR.Reg, RC);
2702
0
    return true;
2703
0
  }
2704
0
  if (ValOp.isReg()) {
2705
0
    RegisterSubReg R(ValOp);
2706
0
    const LatticeCell &LR = Inputs.get(R.Reg);
2707
0
    LatticeCell LSR;
2708
0
    if (!evaluate(R, LR, LSR))
2709
0
      return false;
2710
0
    RC.meet(LSR);
2711
0
    Outputs.update(DefR.Reg, RC);
2712
0
    return true;
2713
0
  }
2714
0
  return false;
2715
0
}
2716
2717
bool HexagonConstEvaluator::evaluateHexExt(const MachineInstr &MI,
2718
5.15k
      const CellMap &Inputs, CellMap &Outputs) {
2719
  // Dst0 = ext R1
2720
5.15k
  RegisterSubReg R1(MI.getOperand(1));
2721
5.15k
  assert(Inputs.has(R1.Reg));
2722
2723
0
  unsigned Opc = MI.getOpcode();
2724
5.15k
  unsigned Bits;
2725
5.15k
  switch (Opc) {
2726
1.93k
    case Hexagon::A2_sxtb:
2727
3.16k
    case Hexagon::A2_zxtb:
2728
3.16k
      Bits = 8;
2729
3.16k
      break;
2730
1.48k
    case Hexagon::A2_sxth:
2731
1.99k
    case Hexagon::A2_zxth:
2732
1.99k
      Bits = 16;
2733
1.99k
      break;
2734
0
    case Hexagon::A2_sxtw:
2735
0
      Bits = 32;
2736
0
      break;
2737
0
    default:
2738
0
      llvm_unreachable("Unhandled extension opcode");
2739
5.15k
  }
2740
2741
5.15k
  bool Signed = false;
2742
5.15k
  switch (Opc) {
2743
1.93k
    case Hexagon::A2_sxtb:
2744
3.42k
    case Hexagon::A2_sxth:
2745
3.42k
    case Hexagon::A2_sxtw:
2746
3.42k
      Signed = true;
2747
3.42k
      break;
2748
5.15k
  }
2749
2750
5.15k
  RegisterSubReg DefR(MI.getOperand(0));
2751
5.15k
  unsigned BW = getRegBitWidth(DefR.Reg);
2752
5.15k
  LatticeCell RC = Outputs.get(DefR.Reg);
2753
5.15k
  bool Eval = Signed ? evaluateSEXTr(R1, BW, Bits, Inputs, RC)
2754
5.15k
                     : evaluateZEXTr(R1, BW, Bits, Inputs, RC);
2755
5.15k
  if (!Eval)
2756
5.15k
    return false;
2757
0
  Outputs.update(DefR.Reg, RC);
2758
0
  return true;
2759
5.15k
}
2760
2761
bool HexagonConstEvaluator::evaluateHexVector1(const MachineInstr &MI,
2762
0
      const CellMap &Inputs, CellMap &Outputs) {
2763
  // DefR = op R1
2764
0
  RegisterSubReg DefR(MI.getOperand(0));
2765
0
  RegisterSubReg R1(MI.getOperand(1));
2766
0
  assert(Inputs.has(R1.Reg));
2767
0
  LatticeCell RC = Outputs.get(DefR.Reg);
2768
0
  bool Eval;
2769
2770
0
  unsigned Opc = MI.getOpcode();
2771
0
  switch (Opc) {
2772
0
    case Hexagon::S2_vsplatrb:
2773
      // Rd = 4 times Rs:0..7
2774
0
      Eval = evaluateSplatr(R1, 8, 4, Inputs, RC);
2775
0
      break;
2776
0
    case Hexagon::S2_vsplatrh:
2777
      // Rdd = 4 times Rs:0..15
2778
0
      Eval = evaluateSplatr(R1, 16, 4, Inputs, RC);
2779
0
      break;
2780
0
    default:
2781
0
      return false;
2782
0
  }
2783
2784
0
  if (!Eval)
2785
0
    return false;
2786
0
  Outputs.update(DefR.Reg, RC);
2787
0
  return true;
2788
0
}
2789
2790
bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &MI,
2791
512k
      const CellMap &Inputs, bool &AllDefs) {
2792
512k
  AllDefs = false;
2793
2794
  // Some diagnostics.
2795
  // LLVM_DEBUG({...}) gets confused with all this code as an argument.
2796
512k
#ifndef NDEBUG
2797
512k
  bool Debugging = DebugFlag && isCurrentDebugType(DEBUG_TYPE);
2798
512k
  if (Debugging) {
2799
0
    bool Const = true, HasUse = false;
2800
0
    for (const MachineOperand &MO : MI.operands()) {
2801
0
      if (!MO.isReg() || !MO.isUse() || MO.isImplicit())
2802
0
        continue;
2803
0
      RegisterSubReg R(MO);
2804
0
      if (!R.Reg.isVirtual())
2805
0
        continue;
2806
0
      HasUse = true;
2807
      // PHIs can legitimately have "top" cells after propagation.
2808
0
      if (!MI.isPHI() && !Inputs.has(R.Reg)) {
2809
0
        dbgs() << "Top " << printReg(R.Reg, &HRI, R.SubReg)
2810
0
               << " in MI: " << MI;
2811
0
        continue;
2812
0
      }
2813
0
      const LatticeCell &L = Inputs.get(R.Reg);
2814
0
      Const &= L.isSingle();
2815
0
      if (!Const)
2816
0
        break;
2817
0
    }
2818
0
    if (HasUse && Const) {
2819
0
      if (!MI.isCopy()) {
2820
0
        dbgs() << "CONST: " << MI;
2821
0
        for (const MachineOperand &MO : MI.operands()) {
2822
0
          if (!MO.isReg() || !MO.isUse() || MO.isImplicit())
2823
0
            continue;
2824
0
          Register R = MO.getReg();
2825
0
          dbgs() << printReg(R, &TRI) << ": " << Inputs.get(R) << "\n";
2826
0
        }
2827
0
      }
2828
0
    }
2829
0
  }
2830
512k
#endif
2831
2832
  // Avoid generating TFRIs for register transfers---this will keep the
2833
  // coalescing opportunities.
2834
512k
  if (MI.isCopy())
2835
62.4k
    return false;
2836
2837
450k
  MachineFunction *MF = MI.getParent()->getParent();
2838
450k
  auto &HST = MF->getSubtarget<HexagonSubtarget>();
2839
2840
  // Collect all virtual register-def operands.
2841
450k
  SmallVector<unsigned,2> DefRegs;
2842
1.63M
  for (const MachineOperand &MO : MI.operands()) {
2843
1.63M
    if (!MO.isReg() || !MO.isDef())
2844
1.21M
      continue;
2845
423k
    Register R = MO.getReg();
2846
423k
    if (!R.isVirtual())
2847
132k
      continue;
2848
290k
    assert(!MO.getSubReg());
2849
0
    assert(Inputs.has(R));
2850
0
    DefRegs.push_back(R);
2851
290k
  }
2852
2853
450k
  MachineBasicBlock &B = *MI.getParent();
2854
450k
  const DebugLoc &DL = MI.getDebugLoc();
2855
450k
  unsigned ChangedNum = 0;
2856
450k
#ifndef NDEBUG
2857
450k
  SmallVector<const MachineInstr*,4> NewInstrs;
2858
450k
#endif
2859
2860
  // For each defined register, if it is a constant, create an instruction
2861
  //   NewR = const
2862
  // and replace all uses of the defined register with NewR.
2863
450k
  for (unsigned R : DefRegs) {
2864
290k
    const LatticeCell &L = Inputs.get(R);
2865
290k
    if (L.isBottom())
2866
282k
      continue;
2867
7.59k
    const TargetRegisterClass *RC = MRI->getRegClass(R);
2868
7.59k
    MachineBasicBlock::iterator At = MI.getIterator();
2869
2870
7.59k
    if (!L.isSingle()) {
2871
      // If this a zero/non-zero cell, we can fold a definition
2872
      // of a predicate register.
2873
0
      using P = ConstantProperties;
2874
2875
0
      uint64_t Ps = L.properties();
2876
0
      if (!(Ps & (P::Zero|P::NonZero)))
2877
0
        continue;
2878
0
      const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
2879
0
      if (RC != PredRC)
2880
0
        continue;
2881
0
      const MCInstrDesc *NewD = (Ps & P::Zero) ?
2882
0
        &HII.get(Hexagon::PS_false) :
2883
0
        &HII.get(Hexagon::PS_true);
2884
0
      Register NewR = MRI->createVirtualRegister(PredRC);
2885
0
      const MachineInstrBuilder &MIB = BuildMI(B, At, DL, *NewD, NewR);
2886
0
      (void)MIB;
2887
0
#ifndef NDEBUG
2888
0
      NewInstrs.push_back(&*MIB);
2889
0
#endif
2890
0
      replaceAllRegUsesWith(R, NewR);
2891
7.59k
    } else {
2892
      // This cell has a single value.
2893
7.59k
      APInt A;
2894
7.59k
      if (!constToInt(L.Value, A) || !A.isSignedIntN(64))
2895
0
        continue;
2896
7.59k
      const TargetRegisterClass *NewRC;
2897
7.59k
      const MCInstrDesc *NewD;
2898
2899
7.59k
      unsigned W = getRegBitWidth(R);
2900
7.59k
      int64_t V = A.getSExtValue();
2901
7.59k
      assert(W == 32 || W == 64);
2902
7.59k
      if (W == 32)
2903
0
        NewRC = &Hexagon::IntRegsRegClass;
2904
7.59k
      else
2905
7.59k
        NewRC = &Hexagon::DoubleRegsRegClass;
2906
7.59k
      Register NewR = MRI->createVirtualRegister(NewRC);
2907
7.59k
      const MachineInstr *NewMI;
2908
2909
7.59k
      if (W == 32) {
2910
0
        NewD = &HII.get(Hexagon::A2_tfrsi);
2911
0
        NewMI = BuildMI(B, At, DL, *NewD, NewR)
2912
0
                  .addImm(V);
2913
7.59k
      } else {
2914
7.59k
        if (A.isSignedIntN(8)) {
2915
0
          NewD = &HII.get(Hexagon::A2_tfrpi);
2916
0
          NewMI = BuildMI(B, At, DL, *NewD, NewR)
2917
0
                    .addImm(V);
2918
7.59k
        } else {
2919
7.59k
          int32_t Hi = V >> 32;
2920
7.59k
          int32_t Lo = V & 0xFFFFFFFFLL;
2921
7.59k
          if (isInt<8>(Hi) && isInt<8>(Lo)) {
2922
1.12k
            NewD = &HII.get(Hexagon::A2_combineii);
2923
1.12k
            NewMI = BuildMI(B, At, DL, *NewD, NewR)
2924
1.12k
                      .addImm(Hi)
2925
1.12k
                      .addImm(Lo);
2926
6.46k
          } else if (MF->getFunction().hasOptSize() || !HST.isTinyCore()) {
2927
            // Disable CONST64 for tiny core since it takes a LD resource.
2928
6.46k
            NewD = &HII.get(Hexagon::CONST64);
2929
6.46k
            NewMI = BuildMI(B, At, DL, *NewD, NewR)
2930
6.46k
                      .addImm(V);
2931
6.46k
          } else
2932
0
            return false;
2933
7.59k
        }
2934
7.59k
      }
2935
7.59k
      (void)NewMI;
2936
7.59k
#ifndef NDEBUG
2937
7.59k
      NewInstrs.push_back(NewMI);
2938
7.59k
#endif
2939
7.59k
      replaceAllRegUsesWith(R, NewR);
2940
7.59k
    }
2941
7.59k
    ChangedNum++;
2942
7.59k
  }
2943
2944
450k
  LLVM_DEBUG({
2945
450k
    if (!NewInstrs.empty()) {
2946
450k
      MachineFunction &MF = *MI.getParent()->getParent();
2947
450k
      dbgs() << "In function: " << MF.getName() << "\n";
2948
450k
      dbgs() << "Rewrite: for " << MI << "  created " << *NewInstrs[0];
2949
450k
      for (unsigned i = 1; i < NewInstrs.size(); ++i)
2950
450k
        dbgs() << "          " << *NewInstrs[i];
2951
450k
    }
2952
450k
  });
2953
2954
450k
  AllDefs = (ChangedNum == DefRegs.size());
2955
450k
  return ChangedNum > 0;
2956
450k
}
2957
2958
bool HexagonConstEvaluator::rewriteHexConstUses(MachineInstr &MI,
2959
345k
      const CellMap &Inputs) {
2960
345k
  bool Changed = false;
2961
345k
  unsigned Opc = MI.getOpcode();
2962
345k
  MachineBasicBlock &B = *MI.getParent();
2963
345k
  const DebugLoc &DL = MI.getDebugLoc();
2964
345k
  MachineBasicBlock::iterator At = MI.getIterator();
2965
345k
  MachineInstr *NewMI = nullptr;
2966
2967
345k
  switch (Opc) {
2968
1.49k
    case Hexagon::M2_maci:
2969
    // Convert DefR += mpyi(R2, R3)
2970
    //   to   DefR += mpyi(R, #imm),
2971
    //   or   DefR -= mpyi(R, #imm).
2972
1.49k
    {
2973
1.49k
      RegisterSubReg DefR(MI.getOperand(0));
2974
1.49k
      assert(!DefR.SubReg);
2975
0
      RegisterSubReg R2(MI.getOperand(2));
2976
1.49k
      RegisterSubReg R3(MI.getOperand(3));
2977
1.49k
      assert(Inputs.has(R2.Reg) && Inputs.has(R3.Reg));
2978
0
      LatticeCell LS2, LS3;
2979
      // It is enough to get one of the input cells, since we will only try
2980
      // to replace one argument---whichever happens to be a single constant.
2981
1.49k
      bool HasC2 = getCell(R2, Inputs, LS2), HasC3 = getCell(R3, Inputs, LS3);
2982
1.49k
      if (!HasC2 && !HasC3)
2983
809
        return false;
2984
685
      bool Zero = ((HasC2 && (LS2.properties() & ConstantProperties::Zero)) ||
2985
685
                   (HasC3 && (LS3.properties() & ConstantProperties::Zero)));
2986
      // If one of the operands is zero, eliminate the multiplication.
2987
685
      if (Zero) {
2988
        // DefR == R1 (tied operands).
2989
0
        MachineOperand &Acc = MI.getOperand(1);
2990
0
        RegisterSubReg R1(Acc);
2991
0
        unsigned NewR = R1.Reg;
2992
0
        if (R1.SubReg) {
2993
          // Generate COPY. FIXME: Replace with the register:subregister.
2994
0
          const TargetRegisterClass *RC = MRI->getRegClass(DefR.Reg);
2995
0
          NewR = MRI->createVirtualRegister(RC);
2996
0
          NewMI = BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
2997
0
                    .addReg(R1.Reg, getRegState(Acc), R1.SubReg);
2998
0
        }
2999
0
        replaceAllRegUsesWith(DefR.Reg, NewR);
3000
0
        MRI->clearKillFlags(NewR);
3001
0
        Changed = true;
3002
0
        break;
3003
0
      }
3004
3005
685
      bool Swap = false;
3006
685
      if (!LS3.isSingle()) {
3007
456
        if (!LS2.isSingle())
3008
0
          return false;
3009
456
        Swap = true;
3010
456
      }
3011
685
      const LatticeCell &LI = Swap ? LS2 : LS3;
3012
685
      const MachineOperand &OpR2 = Swap ? MI.getOperand(3)
3013
685
                                        : MI.getOperand(2);
3014
      // LI is single here.
3015
685
      APInt A;
3016
685
      if (!constToInt(LI.Value, A) || !A.isSignedIntN(8))
3017
229
        return false;
3018
456
      int64_t V = A.getSExtValue();
3019
456
      const MCInstrDesc &D = (V >= 0) ? HII.get(Hexagon::M2_macsip)
3020
456
                                      : HII.get(Hexagon::M2_macsin);
3021
456
      if (V < 0)
3022
209
        V = -V;
3023
456
      const TargetRegisterClass *RC = MRI->getRegClass(DefR.Reg);
3024
456
      Register NewR = MRI->createVirtualRegister(RC);
3025
456
      const MachineOperand &Src1 = MI.getOperand(1);
3026
456
      NewMI = BuildMI(B, At, DL, D, NewR)
3027
456
                .addReg(Src1.getReg(), getRegState(Src1), Src1.getSubReg())
3028
456
                .addReg(OpR2.getReg(), getRegState(OpR2), OpR2.getSubReg())
3029
456
                .addImm(V);
3030
456
      replaceAllRegUsesWith(DefR.Reg, NewR);
3031
456
      Changed = true;
3032
456
      break;
3033
685
    }
3034
3035
1.35k
    case Hexagon::A2_and:
3036
1.35k
    {
3037
1.35k
      RegisterSubReg R1(MI.getOperand(1));
3038
1.35k
      RegisterSubReg R2(MI.getOperand(2));
3039
1.35k
      assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg));
3040
0
      LatticeCell LS1, LS2;
3041
1.35k
      unsigned CopyOf = 0;
3042
      // Check if any of the operands is -1 (i.e. all bits set).
3043
1.35k
      if (getCell(R1, Inputs, LS1) && LS1.isSingle()) {
3044
1
        APInt M1;
3045
1
        if (constToInt(LS1.Value, M1) && !~M1)
3046
0
          CopyOf = 2;
3047
1
      }
3048
1.35k
      else if (getCell(R2, Inputs, LS2) && LS2.isSingle()) {
3049
50
        APInt M1;
3050
50
        if (constToInt(LS2.Value, M1) && !~M1)
3051
0
          CopyOf = 1;
3052
50
      }
3053
1.35k
      if (!CopyOf)
3054
1.35k
        return false;
3055
0
      MachineOperand &SO = MI.getOperand(CopyOf);
3056
0
      RegisterSubReg SR(SO);
3057
0
      RegisterSubReg DefR(MI.getOperand(0));
3058
0
      unsigned NewR = SR.Reg;
3059
0
      if (SR.SubReg) {
3060
0
        const TargetRegisterClass *RC = MRI->getRegClass(DefR.Reg);
3061
0
        NewR = MRI->createVirtualRegister(RC);
3062
0
        NewMI = BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
3063
0
                  .addReg(SR.Reg, getRegState(SO), SR.SubReg);
3064
0
      }
3065
0
      replaceAllRegUsesWith(DefR.Reg, NewR);
3066
0
      MRI->clearKillFlags(NewR);
3067
0
      Changed = true;
3068
0
    }
3069
0
    break;
3070
3071
1.07k
    case Hexagon::A2_or:
3072
1.07k
    {
3073
1.07k
      RegisterSubReg R1(MI.getOperand(1));
3074
1.07k
      RegisterSubReg R2(MI.getOperand(2));
3075
1.07k
      assert(Inputs.has(R1.Reg) && Inputs.has(R2.Reg));
3076
0
      LatticeCell LS1, LS2;
3077
1.07k
      unsigned CopyOf = 0;
3078
3079
1.07k
      using P = ConstantProperties;
3080
3081
1.07k
      if (getCell(R1, Inputs, LS1) && (LS1.properties() & P::Zero))
3082
0
        CopyOf = 2;
3083
1.07k
      else if (getCell(R2, Inputs, LS2) && (LS2.properties() & P::Zero))
3084
0
        CopyOf = 1;
3085
1.07k
      if (!CopyOf)
3086
1.07k
        return false;
3087
0
      MachineOperand &SO = MI.getOperand(CopyOf);
3088
0
      RegisterSubReg SR(SO);
3089
0
      RegisterSubReg DefR(MI.getOperand(0));
3090
0
      unsigned NewR = SR.Reg;
3091
0
      if (SR.SubReg) {
3092
0
        const TargetRegisterClass *RC = MRI->getRegClass(DefR.Reg);
3093
0
        NewR = MRI->createVirtualRegister(RC);
3094
0
        NewMI = BuildMI(B, At, DL, HII.get(TargetOpcode::COPY), NewR)
3095
0
                  .addReg(SR.Reg, getRegState(SO), SR.SubReg);
3096
0
      }
3097
0
      replaceAllRegUsesWith(DefR.Reg, NewR);
3098
0
      MRI->clearKillFlags(NewR);
3099
0
      Changed = true;
3100
0
    }
3101
0
    break;
3102
345k
  }
3103
3104
341k
  if (NewMI) {
3105
    // clear all the kill flags of this new instruction.
3106
456
    for (MachineOperand &MO : NewMI->operands())
3107
1.82k
      if (MO.isReg() && MO.isUse())
3108
912
        MO.setIsKill(false);
3109
456
  }
3110
3111
341k
  LLVM_DEBUG({
3112
341k
    if (NewMI) {
3113
341k
      dbgs() << "Rewrite: for " << MI;
3114
341k
      if (NewMI != &MI)
3115
341k
        dbgs() << "  created " << *NewMI;
3116
341k
      else
3117
341k
        dbgs() << "  modified the instruction itself and created:" << *NewMI;
3118
341k
    }
3119
341k
  });
3120
3121
341k
  return Changed;
3122
345k
}
3123
3124
void HexagonConstEvaluator::replaceAllRegUsesWith(Register FromReg,
3125
8.04k
                                                  Register ToReg) {
3126
8.04k
  assert(FromReg.isVirtual());
3127
0
  assert(ToReg.isVirtual());
3128
0
  for (MachineOperand &O :
3129
8.04k
       llvm::make_early_inc_range(MRI->use_operands(FromReg)))
3130
8.05k
    O.setReg(ToReg);
3131
8.04k
}
3132
3133
bool HexagonConstEvaluator::rewriteHexBranch(MachineInstr &BrI,
3134
730
      const CellMap &Inputs) {
3135
730
  MachineBasicBlock &B = *BrI.getParent();
3136
730
  unsigned NumOp = BrI.getNumOperands();
3137
730
  if (!NumOp)
3138
0
    return false;
3139
3140
730
  bool FallsThru;
3141
730
  SetVector<const MachineBasicBlock*> Targets;
3142
730
  bool Eval = evaluate(BrI, Inputs, Targets, FallsThru);
3143
730
  unsigned NumTargets = Targets.size();
3144
730
  if (!Eval || NumTargets > 1 || (NumTargets == 1 && FallsThru))
3145
0
    return false;
3146
730
  if (BrI.getOpcode() == Hexagon::J2_jump)
3147
730
    return false;
3148
3149
0
  LLVM_DEBUG(dbgs() << "Rewrite(" << printMBBReference(B) << "):" << BrI);
3150
0
  bool Rewritten = false;
3151
0
  if (NumTargets > 0) {
3152
0
    assert(!FallsThru && "This should have been checked before");
3153
    // MIB.addMBB needs non-const pointer.
3154
0
    MachineBasicBlock *TargetB = const_cast<MachineBasicBlock*>(Targets[0]);
3155
0
    bool Moot = B.isLayoutSuccessor(TargetB);
3156
0
    if (!Moot) {
3157
      // If we build a branch here, we must make sure that it won't be
3158
      // erased as "non-executable". We can't mark any new instructions
3159
      // as executable here, so we need to overwrite the BrI, which we
3160
      // know is executable.
3161
0
      const MCInstrDesc &JD = HII.get(Hexagon::J2_jump);
3162
0
      auto NI = BuildMI(B, BrI.getIterator(), BrI.getDebugLoc(), JD)
3163
0
                  .addMBB(TargetB);
3164
0
      BrI.setDesc(JD);
3165
0
      while (BrI.getNumOperands() > 0)
3166
0
        BrI.removeOperand(0);
3167
      // This ensures that all implicit operands (e.g. implicit-def %r31, etc)
3168
      // are present in the rewritten branch.
3169
0
      for (auto &Op : NI->operands())
3170
0
        BrI.addOperand(Op);
3171
0
      NI->eraseFromParent();
3172
0
      Rewritten = true;
3173
0
    }
3174
0
  }
3175
3176
  // Do not erase instructions. A newly created instruction could get
3177
  // the same address as an instruction marked as executable during the
3178
  // propagation.
3179
0
  if (!Rewritten)
3180
0
    replaceWithNop(BrI);
3181
0
  return true;
3182
730
}
3183
3184
8.48k
FunctionPass *llvm::createHexagonConstPropagationPass() {
3185
8.48k
  return new HexagonConstPropagation();
3186
8.48k
}