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