5858// are PHI inst.
5959//
6060// ===----------------------------------------------------------------------===//
61+ #include < unordered_set>
6162#define HEXAGON_QFP_OPTIMIZER " QFP optimizer pass"
6263
6364#include " Hexagon.h"
@@ -86,21 +87,7 @@ cl::opt<bool>
8687 DisableQFOptimizer (" disable-qfp-opt" , cl::init(false ),
8788 cl::desc(" Disable optimization of Qfloat operations." ));
8889
89- namespace {
90- const std::vector<unsigned short > QFPInst = {
91- Hexagon::V6_vadd_hf, Hexagon::V6_vadd_qf16,
92- Hexagon::V6_vadd_qf16_mix, Hexagon::V6_vadd_qf32,
93- Hexagon::V6_vadd_qf32_mix, Hexagon::V6_vadd_sf,
94- Hexagon::V6_vconv_hf_qf16, Hexagon::V6_vconv_hf_qf32,
95- Hexagon::V6_vconv_sf_qf32, Hexagon::V6_vmpy_qf16,
96- Hexagon::V6_vmpy_qf16_hf, Hexagon::V6_vmpy_qf16_mix_hf,
97- Hexagon::V6_vmpy_qf32, Hexagon::V6_vmpy_qf32_hf,
98- Hexagon::V6_vmpy_qf32_mix_hf, Hexagon::V6_vmpy_qf32_qf16,
99- Hexagon::V6_vmpy_qf32_sf, Hexagon::V6_vsub_hf,
100- Hexagon::V6_vsub_qf16, Hexagon::V6_vsub_qf16_mix,
101- Hexagon::V6_vsub_qf32, Hexagon::V6_vsub_qf32_mix,
102- Hexagon::V6_vsub_sf};
103-
90+ namespace {
10491const std::map<unsigned short , unsigned short > QFPInstMap{
10592 {Hexagon::V6_vadd_hf, Hexagon::V6_vadd_qf16_mix},
10693 {Hexagon::V6_vadd_qf16_mix, Hexagon::V6_vadd_qf16},
@@ -115,7 +102,7 @@ const std::map<unsigned short, unsigned short> QFPInstMap{
115102 {Hexagon::V6_vmpy_qf32_hf, Hexagon::V6_vmpy_qf32_mix_hf},
116103 {Hexagon::V6_vmpy_qf32_mix_hf, Hexagon::V6_vmpy_qf32_qf16},
117104 {Hexagon::V6_vmpy_qf32_sf, Hexagon::V6_vmpy_qf32}};
118- }
105+ } // namespace
119106
120107namespace llvm {
121108
@@ -130,7 +117,12 @@ struct HexagonQFPoptimizer : public MachineFunctionPass {
130117public:
131118 static char ID;
132119
133- HexagonQFPoptimizer () : MachineFunctionPass(ID) {}
120+ HexagonQFPoptimizer () : MachineFunctionPass(ID) {
121+ for (const auto &entry : QFPInstMap) {
122+ QFPInstSet.insert (entry.first );
123+ QFPInstSet.insert (entry.second );
124+ }
125+ }
134126
135127 bool runOnMachineFunction (MachineFunction &MF) override ;
136128
@@ -147,6 +139,7 @@ struct HexagonQFPoptimizer : public MachineFunctionPass {
147139 const HexagonSubtarget *HST = nullptr ;
148140 const HexagonInstrInfo *HII = nullptr ;
149141 const MachineRegisterInfo *MRI = nullptr ;
142+ std::unordered_set<unsigned short > QFPInstSet;
150143};
151144
152145char HexagonQFPoptimizer::ID = 0 ;
@@ -161,16 +154,22 @@ FunctionPass *llvm::createHexagonQFPoptimizer() {
161154
162155bool HexagonQFPoptimizer::optimizeQfp (MachineInstr *MI,
163156 MachineBasicBlock *MBB) {
157+
158+ // Early exit:
159+ // - if instruction is invalid or has too few operands (QFP ops need 2 sources + 1 dest),
160+ // - is not part of the QFP instruction set,
161+ // - or does not have a transformation mapping.
164162 if (MI->getNumOperands () < 3 )
165163 return false ;
166-
167- unsigned Op0F = 0 ;
168- unsigned Op1F = 0 ;
164+ if (!QFPInstSet.count (MI->getOpcode ()))
165+ return false ;
169166 auto It = QFPInstMap.find (MI->getOpcode ());
170167 if (It == QFPInstMap.end ())
171168 return false ;
172169 unsigned short InstTy = It->second ;
173170
171+ unsigned Op0F = 0 ;
172+ unsigned Op1F = 0 ;
174173 // Get the reaching defs of MI, DefMI1 and DefMI2
175174 MachineInstr *DefMI1 = nullptr ;
176175 MachineInstr *DefMI2 = nullptr ;
@@ -208,15 +207,14 @@ bool HexagonQFPoptimizer::optimizeQfp(MachineInstr *MI,
208207 Def2OP == Hexagon::V6_vconv_hf_qf16)) {
209208
210209 // If the reaching defs of DefMI are W register type, we return
211- if ((Inst1 && Inst1->getNumOperands () > 0 &&
212- Inst1->getOperand (0 ).isReg () &&
213- MRI-> getRegClass (Inst1-> getOperand ( 0 ). getReg ()) == &Hexagon::HvxWRRegClass) ||
214- (Inst2 && Inst2->getNumOperands () > 0 &&
215- Inst2->getOperand (0 ).isReg () &&
216- MRI-> getRegClass (Inst2-> getOperand ( 0 ). getReg ()) == &Hexagon::HvxWRRegClass))
210+ if ((Inst1 && Inst1->getNumOperands () > 0 && Inst1-> getOperand ( 0 ). isReg () &&
211+ MRI-> getRegClass ( Inst1->getOperand (0 ).getReg ()) ==
212+ &Hexagon::HvxWRRegClass) ||
213+ (Inst2 && Inst2->getNumOperands () > 0 && Inst2-> getOperand ( 0 ). isReg () &&
214+ MRI-> getRegClass ( Inst2->getOperand (0 ).getReg ()) ==
215+ &Hexagon::HvxWRRegClass))
217216 return false ;
218217
219-
220218 // Analyze the use operands of the conversion to get their KILL status
221219 MachineOperand &Src1 = DefMI1->getOperand (1 );
222220 MachineOperand &Src2 = DefMI2->getOperand (1 );
0 commit comments