61#include <unordered_set>
62#define HEXAGON_QFP_OPTIMIZER "QFP optimizer pass"
82#define DEBUG_TYPE "hexagon-qfp-optimizer"
88 cl::desc(
"Disable optimization of Qfloat operations."));
91const std::map<unsigned short, unsigned short> QFPInstMap{
92 {Hexagon::V6_vadd_hf, Hexagon::V6_vadd_qf16_mix},
93 {Hexagon::V6_vadd_qf16_mix, Hexagon::V6_vadd_qf16},
94 {Hexagon::V6_vadd_sf, Hexagon::V6_vadd_qf32_mix},
95 {Hexagon::V6_vadd_qf32_mix, Hexagon::V6_vadd_qf32},
96 {Hexagon::V6_vsub_hf, Hexagon::V6_vsub_qf16_mix},
97 {Hexagon::V6_vsub_qf16_mix, Hexagon::V6_vsub_qf16},
98 {Hexagon::V6_vsub_sf, Hexagon::V6_vsub_qf32_mix},
99 {Hexagon::V6_vsub_qf32_mix, Hexagon::V6_vsub_qf32},
100 {Hexagon::V6_vmpy_qf16_hf, Hexagon::V6_vmpy_qf16_mix_hf},
101 {Hexagon::V6_vmpy_qf16_mix_hf, Hexagon::V6_vmpy_qf16},
102 {Hexagon::V6_vmpy_qf32_hf, Hexagon::V6_vmpy_qf32_mix_hf},
103 {Hexagon::V6_vmpy_qf32_mix_hf, Hexagon::V6_vmpy_qf32_qf16},
104 {Hexagon::V6_vmpy_qf32_sf, Hexagon::V6_vmpy_qf32}};
120 HexagonQFPOptimizer() : MachineFunctionPass(ID) {}
122 bool runOnMachineFunction(MachineFunction &MF)
override;
124 bool optimizeQfp(MachineInstr *
MI, MachineBasicBlock *
MBB);
128 void getAnalysisUsage(AnalysisUsage &AU)
const override {
134 const HexagonSubtarget *HST =
nullptr;
135 const HexagonInstrInfo *HII =
nullptr;
136 const MachineRegisterInfo *MRI =
nullptr;
139char HexagonQFPOptimizer::ID = 0;
146 return new HexagonQFPOptimizer();
156 if (
MI->getNumOperands() < 3)
158 auto It = QFPInstMap.find(
MI->getOpcode());
159 if (It == QFPInstMap.end())
161 unsigned short InstTy = It->second;
166 MachineInstr *DefMI1 =
nullptr;
167 MachineInstr *DefMI2 =
nullptr;
169 if (
MI->getOperand(1).isReg())
170 DefMI1 =
MRI->getVRegDef(
MI->getOperand(1).getReg());
171 if (
MI->getOperand(2).isReg())
172 DefMI2 =
MRI->getVRegDef(
MI->getOperand(2).getReg());
173 if (!DefMI1 || !DefMI2)
176 MachineOperand &Res =
MI->getOperand(0);
177 MachineInstr *Inst1 =
nullptr;
178 MachineInstr *Inst2 =
nullptr;
194 MachineInstrBuilder MIB;
196 if ((Def1OP == Hexagon::V6_vconv_sf_qf32 &&
197 Def2OP == Hexagon::V6_vconv_sf_qf32) ||
198 (Def1OP == Hexagon::V6_vconv_hf_qf16 &&
199 Def2OP == Hexagon::V6_vconv_hf_qf16)) {
204 &Hexagon::HvxWRRegClass) ||
207 &Hexagon::HvxWRRegClass))
220 if (
MI->getOpcode() != Hexagon::V6_vmpy_qf32_sf) {
221 auto OuterIt = QFPInstMap.find(
MI->getOpcode());
222 if (OuterIt == QFPInstMap.end())
224 auto InnerIt = QFPInstMap.find(OuterIt->second);
225 if (InnerIt == QFPInstMap.end())
227 InstTy = InnerIt->second;
237 }
else if (((Def1OP == Hexagon::V6_vconv_sf_qf32 &&
238 Def2OP != Hexagon::V6_vconv_sf_qf32) ||
239 (Def1OP == Hexagon::V6_vconv_hf_qf16 &&
240 Def2OP != Hexagon::V6_vconv_hf_qf16)) &&
242 (
MI->getOpcode() != Hexagon::V6_vmpy_qf32_sf)) {
245 &Hexagon::HvxWRRegClass)
249 MachineOperand &Src2 =
MI->getOperand(2);
261 }
else if (((Def1OP != Hexagon::V6_vconv_sf_qf32 &&
262 Def2OP == Hexagon::V6_vconv_sf_qf32) ||
263 (Def1OP != Hexagon::V6_vconv_hf_qf16 &&
264 Def2OP == Hexagon::V6_vconv_hf_qf16)) &&
266 (
MI->getOpcode() != Hexagon::V6_vmpy_qf32_sf)) {
271 if (InstTy == Hexagon::V6_vsub_qf16_mix ||
272 InstTy == Hexagon::V6_vsub_qf32_mix)
276 &Hexagon::HvxWRRegClass)
279 MachineOperand &Src1 =
MI->getOperand(1);
296bool HexagonQFPOptimizer::runOnMachineFunction(MachineFunction &MF) {
312 <<
" Optimize intermediate conversions ===\n");
314 MachineBasicBlock *
MBB = &*
MBBI;
317 MachineInstr *
MI = &*MII;
320 if (QFPInstMap.count(
MI->getOpcode()) &&
321 MI->getOpcode() != Hexagon::V6_vconv_sf_qf32 &&
322 MI->getOpcode() != Hexagon::V6_vconv_hf_qf16) {
324 if (optimizeQfp(
MI,
MBB)) {
325 MI->eraseFromParent();
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator MBBI
cl::opt< bool > DisableQFOptimizer("disable-qfp-opt", cl::init(false), cl::desc("Disable optimization of Qfloat operations."))
#define HEXAGON_QFP_OPTIMIZER
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
FunctionPass class - This class is used to implement most global optimizations.
const HexagonInstrInfo * getInstrInfo() const override
bool useHVXV68Ops() const
instr_iterator instr_begin()
instr_iterator instr_end()
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createHexagonQFPOptimizer()
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getKillRegState(bool B)
void initializeHexagonQFPOptimizerPass(PassRegistry &)