35#define DEBUG_TYPE "gen-pred"
57 return OS <<
printReg(PR.Reg.Reg, &PR.TRI, PR.Reg.SubReg);
67 return "Hexagon generate predicate operations";
93 unsigned getPredForm(
unsigned Opc);
95 bool isScalarCmp(
unsigned Opc);
104char HexagonGenPredicate::ID = 0;
107 "Hexagon generate predicate operations",
false,
false)
112bool HexagonGenPredicate::isPredReg(
Register R) {
116 return RC == &Hexagon::PredRegsRegClass;
119unsigned HexagonGenPredicate::getPredForm(
unsigned Opc) {
120 using namespace Hexagon;
159 static_assert(
PHI == 0,
"Use different value for <none>");
163bool HexagonGenPredicate::isConvertibleToPredForm(
const MachineInstr *
MI) {
164 unsigned Opc =
MI->getOpcode();
165 if (getPredForm(
Opc) != 0)
173 case Hexagon::C2_cmpeqi:
174 case Hexagon::C4_cmpneqi:
175 if (
MI->getOperand(2).isImm() &&
MI->getOperand(2).getImm() == 0)
182void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {
183 for (MachineBasicBlock &
B : MF) {
184 for (MachineInstr &
MI :
B) {
185 unsigned Opc =
MI.getOpcode();
187 case Hexagon::C2_tfrpr:
188 case TargetOpcode::COPY:
205 use_iterator
I =
MRI->use_begin(
Reg.Reg),
E =
MRI->use_end();
209 MachineInstr *DefI =
MRI->getVRegDef(
Reg.Reg);
214 for (;
I !=
E; ++
I) {
215 MachineInstr *UseI =
I->getParent();
216 if (isConvertibleToPredForm(UseI))
226 RegToRegMap::iterator
F = G2P.
find(
Reg);
231 MachineInstr *DefI =
MRI->getVRegDef(
Reg.Reg);
234 if (
Opc == Hexagon::C2_tfrpr ||
Opc == TargetOpcode::COPY) {
244 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
245 Register NewPR =
MRI->createVirtualRegister(PredRC);
249 if (isConvertibleToPredForm(DefI)) {
251 BuildMI(
B, std::next(DefIt),
DL,
TII->get(TargetOpcode::COPY), NewPR)
262bool HexagonGenPredicate::isScalarCmp(
unsigned Opc) {
264 case Hexagon::C2_cmpeq:
265 case Hexagon::C2_cmpgt:
266 case Hexagon::C2_cmpgtu:
267 case Hexagon::C2_cmpeqp:
268 case Hexagon::C2_cmpgtp:
269 case Hexagon::C2_cmpgtup:
270 case Hexagon::C2_cmpeqi:
271 case Hexagon::C2_cmpgti:
272 case Hexagon::C2_cmpgtui:
273 case Hexagon::C2_cmpgei:
274 case Hexagon::C2_cmpgeui:
275 case Hexagon::C4_cmpneqi:
276 case Hexagon::C4_cmpltei:
277 case Hexagon::C4_cmplteui:
278 case Hexagon::C4_cmpneq:
279 case Hexagon::C4_cmplte:
280 case Hexagon::C4_cmplteu:
281 case Hexagon::A4_cmpbeq:
282 case Hexagon::A4_cmpbeqi:
283 case Hexagon::A4_cmpbgtu:
284 case Hexagon::A4_cmpbgtui:
285 case Hexagon::A4_cmpbgt:
286 case Hexagon::A4_cmpbgti:
287 case Hexagon::A4_cmpheq:
288 case Hexagon::A4_cmphgt:
289 case Hexagon::A4_cmphgtu:
290 case Hexagon::A4_cmpheqi:
291 case Hexagon::A4_cmphgti:
292 case Hexagon::A4_cmphgtui:
298bool HexagonGenPredicate::isScalarPred(
RegSubRegPair PredReg) {
299 std::queue<RegSubRegPair> WorkQ;
302 while (!WorkQ.empty()) {
305 const MachineInstr *DefI =
MRI->getVRegDef(PR.
Reg);
310 case TargetOpcode::COPY: {
311 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
312 if (
MRI->getRegClass(PR.
Reg) != PredRC)
317 case Hexagon::C2_and:
318 case Hexagon::C2_andn:
319 case Hexagon::C4_and_and:
320 case Hexagon::C4_and_andn:
321 case Hexagon::C4_and_or:
323 case Hexagon::C2_orn:
324 case Hexagon::C4_or_and:
325 case Hexagon::C4_or_andn:
326 case Hexagon::C4_or_or:
327 case Hexagon::C4_or_orn:
328 case Hexagon::C2_xor:
330 for (
const MachineOperand &MO : DefI->
operands())
331 if (MO.isReg() && MO.isUse())
337 return isScalarCmp(DefOpc);
344bool HexagonGenPredicate::convertToPredForm(MachineInstr *
MI) {
347 unsigned Opc =
MI->getOpcode();
348 assert(isConvertibleToPredForm(
MI));
349 unsigned NumOps =
MI->getNumOperands();
350 for (
unsigned i = 0; i <
NumOps; ++i) {
351 MachineOperand &MO =
MI->getOperand(i);
355 if (
Reg.SubReg &&
Reg.SubReg != Hexagon::isub_lo)
361 MachineBasicBlock &
B = *
MI->getParent();
364 unsigned NewOpc = getPredForm(
Opc);
368 case Hexagon::C2_cmpeqi:
369 NewOpc = Hexagon::C2_not;
371 case Hexagon::C4_cmpneqi:
372 NewOpc = TargetOpcode::COPY;
382 if (!isScalarPred(PR))
390 MachineOperand &Op0 =
MI->getOperand(0);
397 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
402 for (
unsigned i = 1; i <
NumOps; ++i) {
411 const TargetRegisterClass *RC =
MRI->getRegClass(OutR.Reg);
415 MRI->replaceRegWith(OutR.Reg, NewOutR);
416 MI->eraseFromParent();
424 processPredicateGPR(R);
429bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {
431 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;
445 for (MachineBasicBlock &
MBB : MF) {
446 for (MachineInstr &
MI :
MBB) {
447 if (
MI.getOpcode() != TargetOpcode::COPY)
455 if (
MRI->getRegClass(DR.
Reg) != PredRC)
457 if (
MRI->getRegClass(SR.
Reg) != PredRC)
466 for (MachineInstr *
MI : Erase)
467 MI->eraseFromParent();
472bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {
484 collectPredicateGPR(MF);
486 processPredicateGPR(R);
491 VectOfInst Processed,
Copy;
494 for (MachineInstr *
MI : Copy) {
495 bool Done = convertToPredForm(
MI);
497 Processed.insert(
MI);
503 auto Done = [Processed] (MachineInstr *
MI) ->
bool {
504 return Processed.count(
MI);
509 Changed |= eliminatePredCopies(MF);
514 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")
#define LLVM_ATTRIBUTE_UNUSED
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.