1 | //===- HexagonMCChecker.h - Instruction bundle checking ---------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This implements the checking of insns inside a bundle according to the |
10 | // packet constraint rules of the Hexagon ISA. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H |
15 | #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H |
16 | |
17 | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
18 | #include "MCTargetDesc/HexagonMCTargetDesc.h" |
19 | #include "llvm/ADT/DenseMap.h" |
20 | #include "llvm/Support/SMLoc.h" |
21 | #include <set> |
22 | #include <utility> |
23 | |
24 | namespace llvm { |
25 | |
26 | class MCContext; |
27 | class MCInst; |
28 | class MCInstrInfo; |
29 | class MCRegisterInfo; |
30 | class MCSubtargetInfo; |
31 | |
32 | /// Check for a valid bundle. |
33 | class HexagonMCChecker { |
34 | MCContext &Context; |
35 | MCInst &MCB; |
36 | const MCRegisterInfo &RI; |
37 | MCInstrInfo const &MCII; |
38 | MCSubtargetInfo const &STI; |
39 | bool ReportErrors; |
40 | |
41 | /// Set of definitions: register #, if predicated, if predicated true. |
42 | using PredSense = std::pair<unsigned, bool>; |
43 | static const PredSense Unconditional; |
44 | using PredSet = std::multiset<PredSense>; |
45 | using PredSetIterator = std::multiset<PredSense>::iterator; |
46 | |
47 | using DefsIterator = DenseMap<unsigned, PredSet>::iterator; |
48 | DenseMap<unsigned, PredSet> Defs; |
49 | |
50 | /// Set of weak definitions whose clashes should be enforced selectively. |
51 | using SoftDefsIterator = std::set<unsigned>::iterator; |
52 | std::set<unsigned> SoftDefs; |
53 | |
54 | /// Set of temporary definitions not committed to the register file. |
55 | using TmpDefsIterator = std::set<unsigned>::iterator; |
56 | std::set<unsigned> TmpDefs; |
57 | |
58 | /// Set of new predicates used. |
59 | using NewPredsIterator = std::set<unsigned>::iterator; |
60 | std::set<unsigned> NewPreds; |
61 | |
62 | /// Set of predicates defined late. |
63 | using LatePredsIterator = std::multiset<unsigned>::iterator; |
64 | std::multiset<unsigned> LatePreds; |
65 | |
66 | /// Set of uses. |
67 | using UsesIterator = std::set<unsigned>::iterator; |
68 | std::set<unsigned> Uses; |
69 | |
70 | /// Pre-defined set of read-only registers. |
71 | using ReadOnlyIterator = std::set<unsigned>::iterator; |
72 | std::set<unsigned> ReadOnly; |
73 | |
74 | // Contains the vector-pair-registers with the even number |
75 | // first ("v0:1", e.g.) used/def'd in this packet. |
76 | std::set<unsigned> ReversePairs; |
77 | |
78 | void init(); |
79 | void init(MCInst const &); |
80 | void initReg(MCInst const &, unsigned, unsigned &PredReg, bool &isTrue); |
81 | |
82 | bool registerUsed(unsigned Register); |
83 | |
84 | /// \return a tuple of: pointer to the producer instruction or nullptr if |
85 | /// none was found, the operand index, and the PredicateInfo for the |
86 | /// producer. |
87 | std::tuple<MCInst const *, unsigned, HexagonMCInstrInfo::PredicateInfo> |
88 | registerProducer(unsigned Register, |
89 | HexagonMCInstrInfo::PredicateInfo Predicated); |
90 | |
91 | // Checks performed. |
92 | bool checkBranches(); |
93 | bool checkPredicates(); |
94 | bool checkNewValues(); |
95 | bool checkRegisters(); |
96 | bool checkRegistersReadOnly(); |
97 | void checkRegisterCurDefs(); |
98 | bool checkSolo(); |
99 | bool checkShuffle(); |
100 | bool checkSlots(); |
101 | bool checkAXOK(); |
102 | bool checkHWLoop(); |
103 | bool checkCOFMax1(); |
104 | bool checkLegalVecRegPair(); |
105 | bool checkValidTmpDst(); |
106 | bool checkHVXAccum(); |
107 | |
108 | static void compoundRegisterMap(unsigned &); |
109 | |
110 | bool isLoopRegister(unsigned R) const { |
111 | return (Hexagon::SA0 == R || Hexagon::LC0 == R || Hexagon::SA1 == R || |
112 | Hexagon::LC1 == R); |
113 | } |
114 | |
115 | public: |
116 | explicit HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII, |
117 | MCSubtargetInfo const &STI, MCInst &mcb, |
118 | const MCRegisterInfo &ri, bool ReportErrors = true); |
119 | explicit HexagonMCChecker(HexagonMCChecker const &Check, |
120 | MCSubtargetInfo const &STI, bool CopyReportErrors); |
121 | |
122 | bool check(bool FullCheck = true); |
123 | void reportErrorRegisters(unsigned Register); |
124 | void reportErrorNewValue(unsigned Register); |
125 | void reportError(SMLoc Loc, Twine const &Msg); |
126 | void reportNote(SMLoc Loc, Twine const &Msg); |
127 | void reportError(Twine const &Msg); |
128 | void reportWarning(Twine const &Msg); |
129 | void reportBranchErrors(); |
130 | }; |
131 | |
132 | } // end namespace llvm |
133 | |
134 | #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCCHECKER_H |
135 | |