Bug Summary

File:lib/Target/Hexagon/HexagonConstPropagation.cpp
Warning:line 2741, column 24
3rd function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

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