34#define DEBUG_TYPE "gen-pred"
54 const PrintRegister &PR);
56 return OS <<
printReg(PR.Reg.Reg, &PR.TRI, PR.Reg.SubReg);
66 return "Hexagon generate predicate operations";
92 unsigned getPredForm(
unsigned Opc);
94 bool isScalarCmp(
unsigned Opc);
103char HexagonGenPredicate::ID = 0;
106 "Hexagon generate predicate operations",
false,
false)
111bool HexagonGenPredicate::isPredReg(
Register R) {
115 return RC == &Hexagon::PredRegsRegClass;
118unsigned HexagonGenPredicate::getPredForm(
unsigned Opc) {
119 using namespace Hexagon;
158 static_assert(
PHI == 0,
"Use different value for <none>");
162bool HexagonGenPredicate::isConvertibleToPredForm(
const MachineInstr *
MI) {
163 unsigned Opc =
MI->getOpcode();
164 if (getPredForm(
Opc) != 0)
172 case Hexagon::C2_cmpeqi:
173 case Hexagon::C4_cmpneqi:
174 if (
MI->getOperand(2).isImm() &&
MI->getOperand(2).getImm() == 0)
181void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {
182 for (MachineBasicBlock &
B : MF) {
183 for (MachineInstr &
MI :
B) {
184 unsigned Opc =
MI.getOpcode();
186 case Hexagon::C2_tfrpr:
187 case TargetOpcode::COPY:
204 use_iterator
I =
MRI->use_begin(
Reg.Reg),
E =
MRI->use_end();
208 MachineInstr *DefI =
MRI->getVRegDef(
Reg.Reg);
213 for (;
I !=
E; ++
I) {
214 MachineInstr *UseI =
I->getParent();
215 if (isConvertibleToPredForm(UseI))
225 RegToRegMap::iterator
F = G2P.
find(
Reg);
230 MachineInstr *DefI =
MRI->getVRegDef(
Reg.Reg);
233 if (
Opc == Hexagon::C2_tfrpr ||
Opc == TargetOpcode::COPY) {
243 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
244 Register NewPR =
MRI->createVirtualRegister(PredRC);
248 if (isConvertibleToPredForm(DefI)) {
250 BuildMI(
B, std::next(DefIt),
DL,
TII->get(TargetOpcode::COPY), NewPR)
261bool HexagonGenPredicate::isScalarCmp(
unsigned Opc) {
263 case Hexagon::C2_cmpeq:
264 case Hexagon::C2_cmpgt:
265 case Hexagon::C2_cmpgtu:
266 case Hexagon::C2_cmpeqp:
267 case Hexagon::C2_cmpgtp:
268 case Hexagon::C2_cmpgtup:
269 case Hexagon::C2_cmpeqi:
270 case Hexagon::C2_cmpgti:
271 case Hexagon::C2_cmpgtui:
272 case Hexagon::C2_cmpgei:
273 case Hexagon::C2_cmpgeui:
274 case Hexagon::C4_cmpneqi:
275 case Hexagon::C4_cmpltei:
276 case Hexagon::C4_cmplteui:
277 case Hexagon::C4_cmpneq:
278 case Hexagon::C4_cmplte:
279 case Hexagon::C4_cmplteu:
280 case Hexagon::A4_cmpbeq:
281 case Hexagon::A4_cmpbeqi:
282 case Hexagon::A4_cmpbgtu:
283 case Hexagon::A4_cmpbgtui:
284 case Hexagon::A4_cmpbgt:
285 case Hexagon::A4_cmpbgti:
286 case Hexagon::A4_cmpheq:
287 case Hexagon::A4_cmphgt:
288 case Hexagon::A4_cmphgtu:
289 case Hexagon::A4_cmpheqi:
290 case Hexagon::A4_cmphgti:
291 case Hexagon::A4_cmphgtui:
297bool HexagonGenPredicate::isScalarPred(
RegSubRegPair PredReg) {
298 std::queue<RegSubRegPair> WorkQ;
301 while (!WorkQ.empty()) {
304 const MachineInstr *DefI =
MRI->getVRegDef(PR.
Reg);
309 case TargetOpcode::COPY: {
310 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
311 if (
MRI->getRegClass(PR.
Reg) != PredRC)
316 case Hexagon::C2_and:
317 case Hexagon::C2_andn:
318 case Hexagon::C4_and_and:
319 case Hexagon::C4_and_andn:
320 case Hexagon::C4_and_or:
322 case Hexagon::C2_orn:
323 case Hexagon::C4_or_and:
324 case Hexagon::C4_or_andn:
325 case Hexagon::C4_or_or:
326 case Hexagon::C4_or_orn:
327 case Hexagon::C2_xor:
329 for (
const MachineOperand &MO : DefI->
operands())
330 if (MO.isReg() && MO.isUse())
336 return isScalarCmp(DefOpc);
343bool HexagonGenPredicate::convertToPredForm(MachineInstr *
MI) {
346 unsigned Opc =
MI->getOpcode();
347 assert(isConvertibleToPredForm(
MI));
348 unsigned NumOps =
MI->getNumOperands();
349 for (
unsigned i = 0; i <
NumOps; ++i) {
350 MachineOperand &MO =
MI->getOperand(i);
354 if (
Reg.SubReg &&
Reg.SubReg != Hexagon::isub_lo)
360 MachineBasicBlock &
B = *
MI->getParent();
363 unsigned NewOpc = getPredForm(
Opc);
367 case Hexagon::C2_cmpeqi:
368 NewOpc = Hexagon::C2_not;
370 case Hexagon::C4_cmpneqi:
371 NewOpc = TargetOpcode::COPY;
381 if (!isScalarPred(PR))
389 MachineOperand &Op0 =
MI->getOperand(0);
396 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
401 for (
unsigned i = 1; i <
NumOps; ++i) {
410 const TargetRegisterClass *RC =
MRI->getRegClass(OutR.Reg);
414 MRI->replaceRegWith(OutR.Reg, NewOutR);
415 MI->eraseFromParent();
423 processPredicateGPR(R);
428bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {
430 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
444 for (MachineBasicBlock &
MBB : MF) {
445 for (MachineInstr &
MI :
MBB) {
446 if (
MI.getOpcode() != TargetOpcode::COPY)
454 if (
MRI->getRegClass(DR.
Reg) != PredRC)
456 if (
MRI->getRegClass(SR.
Reg) != PredRC)
465 for (MachineInstr *
MI : Erase)
466 MI->eraseFromParent();
471bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {
483 collectPredicateGPR(MF);
485 processPredicateGPR(R);
490 VectOfInst Processed,
Copy;
493 for (MachineInstr *
MI : Copy) {
494 bool Done = convertToPredForm(
MI);
496 Processed.insert(
MI);
502 auto Done = [Processed] (MachineInstr *
MI) ->
bool {
503 return Processed.count(
MI);
508 Changed |= eliminatePredCopies(MF);
513 return new HexagonGenPredicate();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_iterator< true, false, false, true, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
A vector that has set insertion semantics.
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
void clear()
Completely clear the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
StringRef - Represent a constant reference to a string, i.e.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
bool isPredReg(MCRegisterInfo const &MRI, MCRegister Reg)
This is an optimization pass for GlobalISel generic memory operations.
TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O)
Create RegSubRegPair from a register MachineOperand.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonGenPredicate()
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
A pair composed of a register and a sub-register index.