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