34#define DEBUG_TYPE "gen-pred"
54 const PrintRegister &PR) {
55 return OS <<
printReg(PR.Reg.Reg, &PR.TRI, PR.Reg.SubReg);
65 return "Hexagon generate predicate operations";
91 unsigned getPredForm(
unsigned Opc);
93 bool isScalarCmp(
unsigned Opc);
102char HexagonGenPredicate::ID = 0;
105 "Hexagon generate predicate operations",
false,
false)
110bool HexagonGenPredicate::isPredReg(
Register R) {
114 return RC == &Hexagon::PredRegsRegClass;
117unsigned HexagonGenPredicate::getPredForm(
unsigned Opc) {
118 using namespace Hexagon;
157 static_assert(
PHI == 0,
"Use different value for <none>");
161bool HexagonGenPredicate::isConvertibleToPredForm(
const MachineInstr *
MI) {
162 unsigned Opc =
MI->getOpcode();
163 if (getPredForm(
Opc) != 0)
171 case Hexagon::C2_cmpeqi:
172 case Hexagon::C4_cmpneqi:
173 if (
MI->getOperand(2).isImm() &&
MI->getOperand(2).getImm() == 0)
180void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {
181 for (MachineBasicBlock &
B : MF) {
182 for (MachineInstr &
MI :
B) {
183 unsigned Opc =
MI.getOpcode();
185 case Hexagon::C2_tfrpr:
186 case TargetOpcode::COPY:
203 use_iterator
I =
MRI->use_begin(
Reg.Reg),
E =
MRI->use_end();
207 MachineInstr *DefI =
MRI->getVRegDef(
Reg.Reg);
212 for (;
I !=
E; ++
I) {
213 MachineInstr *UseI =
I->getParent();
214 if (isConvertibleToPredForm(UseI))
224 RegToRegMap::iterator
F = G2P.
find(
Reg);
229 MachineInstr *DefI =
MRI->getVRegDef(
Reg.Reg);
232 if (
Opc == Hexagon::C2_tfrpr ||
Opc == TargetOpcode::COPY) {
242 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
243 Register NewPR =
MRI->createVirtualRegister(PredRC);
247 if (isConvertibleToPredForm(DefI)) {
260bool HexagonGenPredicate::isScalarCmp(
unsigned Opc) {
262 case Hexagon::C2_cmpeq:
263 case Hexagon::C2_cmpgt:
264 case Hexagon::C2_cmpgtu:
265 case Hexagon::C2_cmpeqp:
266 case Hexagon::C2_cmpgtp:
267 case Hexagon::C2_cmpgtup:
268 case Hexagon::C2_cmpeqi:
269 case Hexagon::C2_cmpgti:
270 case Hexagon::C2_cmpgtui:
271 case Hexagon::C2_cmpgei:
272 case Hexagon::C2_cmpgeui:
273 case Hexagon::C4_cmpneqi:
274 case Hexagon::C4_cmpltei:
275 case Hexagon::C4_cmplteui:
276 case Hexagon::C4_cmpneq:
277 case Hexagon::C4_cmplte:
278 case Hexagon::C4_cmplteu:
279 case Hexagon::A4_cmpbeq:
280 case Hexagon::A4_cmpbeqi:
281 case Hexagon::A4_cmpbgtu:
282 case Hexagon::A4_cmpbgtui:
283 case Hexagon::A4_cmpbgt:
284 case Hexagon::A4_cmpbgti:
285 case Hexagon::A4_cmpheq:
286 case Hexagon::A4_cmphgt:
287 case Hexagon::A4_cmphgtu:
288 case Hexagon::A4_cmpheqi:
289 case Hexagon::A4_cmphgti:
290 case Hexagon::A4_cmphgtui:
296bool HexagonGenPredicate::isScalarPred(
RegSubRegPair PredReg) {
297 std::queue<RegSubRegPair> WorkQ;
300 while (!WorkQ.empty()) {
303 const MachineInstr *DefI =
MRI->getVRegDef(PR.
Reg);
308 case TargetOpcode::COPY: {
309 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
310 if (
MRI->getRegClass(PR.
Reg) != PredRC)
315 case Hexagon::C2_and:
316 case Hexagon::C2_andn:
317 case Hexagon::C4_and_and:
318 case Hexagon::C4_and_andn:
319 case Hexagon::C4_and_or:
321 case Hexagon::C2_orn:
322 case Hexagon::C4_or_and:
323 case Hexagon::C4_or_andn:
324 case Hexagon::C4_or_or:
325 case Hexagon::C4_or_orn:
326 case Hexagon::C2_xor:
328 for (
const MachineOperand &MO : DefI->
operands())
329 if (MO.isReg() && MO.isUse())
335 return isScalarCmp(DefOpc);
342bool HexagonGenPredicate::convertToPredForm(MachineInstr *
MI) {
345 unsigned Opc =
MI->getOpcode();
346 assert(isConvertibleToPredForm(
MI));
347 unsigned NumOps =
MI->getNumOperands();
348 for (
unsigned i = 0; i <
NumOps; ++i) {
349 MachineOperand &MO =
MI->getOperand(i);
353 if (
Reg.SubReg &&
Reg.SubReg != Hexagon::isub_lo)
359 MachineBasicBlock &
B = *
MI->getParent();
362 unsigned NewOpc = getPredForm(
Opc);
366 case Hexagon::C2_cmpeqi:
367 NewOpc = Hexagon::C2_not;
369 case Hexagon::C4_cmpneqi:
370 NewOpc = TargetOpcode::COPY;
380 if (!isScalarPred(PR))
388 MachineOperand &Op0 =
MI->getOperand(0);
395 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
400 for (
unsigned i = 1; i <
NumOps; ++i) {
409 const TargetRegisterClass *RC =
MRI->getRegClass(OutR.Reg);
413 MRI->replaceRegWith(OutR.Reg, NewOutR);
414 MI->eraseFromParent();
422 processPredicateGPR(R);
427bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {
429 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
443 for (MachineBasicBlock &
MBB : MF) {
444 for (MachineInstr &
MI :
MBB) {
445 if (
MI.getOpcode() != TargetOpcode::COPY)
453 if (
MRI->getRegClass(DR.
Reg) != PredRC)
455 if (
MRI->getRegClass(SR.
Reg) != PredRC)
464 for (MachineInstr *
MI : Erase)
465 MI->eraseFromParent();
470bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {
482 collectPredicateGPR(MF);
484 processPredicateGPR(R);
489 VectOfInst Processed,
Copy;
492 for (MachineInstr *
MI : Copy) {
493 bool Done = convertToPredForm(
MI);
495 Processed.insert(
MI);
501 auto Done = [Processed] (MachineInstr *
MI) ->
bool {
502 return Processed.count(
MI);
507 Changed |= eliminatePredCopies(MF);
512 return new HexagonGenPredicate();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
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 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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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.
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear 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.