LLVM  4.0.0
HexagonMCChecker.h
Go to the documentation of this file.
1 //===----- HexagonMCChecker.h - Instruction bundle checking ---------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This implements the checking of insns inside a bundle according to the
11 // packet constraint rules of the Hexagon ISA.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef HEXAGONMCCHECKER_H
16 #define HEXAGONMCCHECKER_H
17 
19 #include <queue>
20 #include <set>
21 
22 using namespace llvm;
23 
24 namespace llvm {
25 class MCOperandInfo;
26 
27 typedef struct {
28  unsigned Error, Warning, ShuffleError;
29  unsigned Register;
30 } ErrInfo_T;
31 
33 public:
34  enum {
36  // Errors.
38  CHECK_ERROR_NEWP = 0x00002,
39  CHECK_ERROR_NEWV = 0x00004,
42  CHECK_ERROR_LOOP = 0x00020,
44  CHECK_ERROR_SOLO = 0x00080,
48  // Warnings.
49  CHECK_WARN_CURRENT = 0x10000,
51  };
53 
54  void reset() {
58  s.Register = Hexagon::NoRegister;
59  };
61  reset();
62  };
63 
64  void setError(unsigned e, unsigned r = Hexagon::NoRegister)
65  { s.Error = e; s.Register = r; };
66  void setWarning(unsigned w, unsigned r = Hexagon::NoRegister)
67  { s.Warning = w; s.Register = r; };
68  void setShuffleError(unsigned e) { s.ShuffleError = e; };
69 };
70 
71 /// Check for a valid bundle.
73  /// Insn bundle.
74  MCInst& MCB;
75  MCInst& MCBDX;
76  const MCRegisterInfo& RI;
77  MCInstrInfo const &MCII;
78  MCSubtargetInfo const &STI;
79  bool bLoadErrInfo;
80 
81  /// Set of definitions: register #, if predicated, if predicated true.
82  typedef std::pair<unsigned, bool> PredSense;
83  static const PredSense Unconditional;
84  typedef std::multiset<PredSense> PredSet;
85  typedef std::multiset<PredSense>::iterator PredSetIterator;
86 
89 
90  /// Information about how a new-value register is defined or used:
91  /// PredReg = predicate register, 0 if use/def not predicated,
92  /// Cond = true/false for if(PredReg)/if(!PredReg) respectively,
93  /// IsFloat = true if definition produces a floating point value
94  /// (not valid for uses),
95  /// IsNVJ = true if the use is a new-value branch (not valid for
96  /// definitions).
97  struct NewSense {
98  unsigned PredReg;
99  bool IsFloat, IsNVJ, Cond;
100  // The special-case "constructors":
101  static NewSense Jmp(bool isNVJ) {
102  NewSense NS = { /*PredReg=*/ 0, /*IsFloat=*/ false, /*IsNVJ=*/ isNVJ,
103  /*Cond=*/ false };
104  return NS;
105  }
106  static NewSense Use(unsigned PR, bool True) {
107  NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ false, /*IsNVJ=*/ false,
108  /*Cond=*/ True };
109  return NS;
110  }
111  static NewSense Def(unsigned PR, bool True, bool Float) {
112  NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ Float, /*IsNVJ=*/ false,
113  /*Cond=*/ True };
114  return NS;
115  }
116  };
117  /// Set of definitions that produce new register:
121 
122  /// Set of weak definitions whose clashes should be enforced selectively.
123  typedef std::set<unsigned>::iterator SoftDefsIterator;
124  std::set<unsigned> SoftDefs;
125 
126  /// Set of current definitions committed to the register file.
127  typedef std::set<unsigned>::iterator CurDefsIterator;
128  std::set<unsigned> CurDefs;
129 
130  /// Set of temporary definitions not committed to the register file.
131  typedef std::set<unsigned>::iterator TmpDefsIterator;
132  std::set<unsigned> TmpDefs;
133 
134  /// Set of new predicates used.
135  typedef std::set<unsigned>::iterator NewPredsIterator;
136  std::set<unsigned> NewPreds;
137 
138  /// Set of predicates defined late.
139  typedef std::multiset<unsigned>::iterator LatePredsIterator;
140  std::multiset<unsigned> LatePreds;
141 
142  /// Set of uses.
143  typedef std::set<unsigned>::iterator UsesIterator;
144  std::set<unsigned> Uses;
145 
146  /// Set of new values used: new register, if new-value jump.
149 
150  /// Pre-defined set of read-only registers.
151  typedef std::set<unsigned>::iterator ReadOnlyIterator;
152  std::set<unsigned> ReadOnly;
153 
154  std::queue<ErrInfo_T> ErrInfoQ;
155  HexagonMCErrInfo CrntErrInfo;
156 
157  void getErrInfo() {
158  if (bLoadErrInfo == true) {
159  if (ErrInfoQ.empty()) {
160  CrntErrInfo.reset();
161  } else {
162  CrntErrInfo.s = ErrInfoQ.front();
163  ErrInfoQ.pop();
164  }
165  }
166  bLoadErrInfo = false;
167  }
168 
169  void init();
170  void init(MCInst const&);
171 
172  // Checks performed.
173  bool checkBranches();
174  bool checkPredicates();
175  bool checkNewValues();
176  bool checkRegisters();
177  bool checkSolo();
178  bool checkShuffle();
179  bool checkSlots();
180 
181  static void compoundRegisterMap(unsigned&);
182 
183  bool isPredicateRegister(unsigned R) const {
184  return (Hexagon::P0 == R || Hexagon::P1 == R ||
185  Hexagon::P2 == R || Hexagon::P3 == R);
186  };
187  bool isLoopRegister(unsigned R) const {
188  return (Hexagon::SA0 == R || Hexagon::LC0 == R ||
189  Hexagon::SA1 == R || Hexagon::LC1 == R);
190  };
191 
192  bool hasValidNewValueDef(const NewSense &Use,
193  const NewSenseList &Defs) const;
194 
195  public:
196  explicit HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst& mcb, MCInst &mcbdx,
197  const MCRegisterInfo& ri);
198 
199  bool check();
200 
201  /// add a new error/warning
202  void addErrInfo(HexagonMCErrInfo &err) { ErrInfoQ.push(err.s); };
203 
204  /// Return the error code for the last operation in the insn bundle.
205  unsigned getError() { getErrInfo(); return CrntErrInfo.s.Error; };
206  unsigned getWarning() { getErrInfo(); return CrntErrInfo.s.Warning; };
207  unsigned getShuffleError() { getErrInfo(); return CrntErrInfo.s.ShuffleError; };
208  unsigned getErrRegister() { getErrInfo(); return CrntErrInfo.s.Register; };
209  bool getNextErrInfo() {
210  bLoadErrInfo = true;
211  return (ErrInfoQ.empty()) ? false : (getErrInfo(), true);
212  }
213 };
214 
215 }
216 
217 #endif // HEXAGONMCCHECKER_H
HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, MCInst &mcbdx, const MCRegisterInfo &ri)
void setWarning(unsigned w, unsigned r=Hexagon::NoRegister)
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
void addErrInfo(HexagonMCErrInfo &err)
add a new error/warning
unsigned getError()
Return the error code for the last operation in the insn bundle.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
MCSubtargetInfo - Generic base class for all target subtargets.
void setShuffleError(unsigned e)
Check for a valid bundle.
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:70
void setError(unsigned e, unsigned r=Hexagon::NoRegister)