36 #define DEBUG_TYPE "gen-pred" 52 Register(
unsigned r = 0,
unsigned s = 0) : R(r), S(s) {}
56 return R == Reg.R && S == Reg.S;
60 return R < Reg.R || (R == Reg.R && S < Reg.S);
64 struct PrintRegister {
77 return OS <<
printReg(PR.Reg.R, &PR.TRI, PR.Reg.S);
89 return "Hexagon generate predicate operations";
102 using SetOfReg = std::set<Register>;
103 using RegToRegMap = std::map<Register, Register>;
115 unsigned getPredForm(
unsigned Opc);
117 bool isScalarCmp(
unsigned Opc);
118 bool isScalarPred(
Register PredReg);
129 "Hexagon generate predicate operations",
false,
false)
134 bool HexagonGenPredicate::
isPredReg(
unsigned R) {
138 return RC == &Hexagon::PredRegsRegClass;
141 unsigned HexagonGenPredicate::getPredForm(
unsigned Opc) {
142 using namespace Hexagon;
181 static_assert(PHI == 0,
"Use different value for <none>");
185 bool HexagonGenPredicate::isConvertibleToPredForm(
const MachineInstr *
MI) {
187 if (getPredForm(Opc) != 0)
195 case Hexagon::C2_cmpeqi:
196 case Hexagon::C4_cmpneqi:
211 case Hexagon::C2_tfrpr:
212 case TargetOpcode::COPY:
224 void HexagonGenPredicate::processPredicateGPR(
const Register &
Reg) {
228 use_iterator
I =
MRI->use_begin(Reg.R),
E =
MRI->use_end();
236 for (; I !=
E; ++
I) {
238 if (isConvertibleToPredForm(UseI))
248 RegToRegMap::iterator
F = G2P.find(Reg);
256 if (Opc == Hexagon::C2_tfrpr || Opc == TargetOpcode::COPY) {
259 G2P.insert(std::make_pair(Reg, PR));
267 unsigned NewPR =
MRI->createVirtualRegister(PredRC);
271 if (isConvertibleToPredForm(DefI)) {
273 BuildMI(B, std::next(DefIt), DL,
TII->get(TargetOpcode::COPY), NewPR)
274 .addReg(Reg.R, 0, Reg.S);
275 G2P.insert(std::make_pair(Reg,
Register(NewPR)));
284 bool HexagonGenPredicate::isScalarCmp(
unsigned Opc) {
286 case Hexagon::C2_cmpeq:
287 case Hexagon::C2_cmpgt:
288 case Hexagon::C2_cmpgtu:
289 case Hexagon::C2_cmpeqp:
290 case Hexagon::C2_cmpgtp:
291 case Hexagon::C2_cmpgtup:
292 case Hexagon::C2_cmpeqi:
293 case Hexagon::C2_cmpgti:
294 case Hexagon::C2_cmpgtui:
295 case Hexagon::C2_cmpgei:
296 case Hexagon::C2_cmpgeui:
297 case Hexagon::C4_cmpneqi:
298 case Hexagon::C4_cmpltei:
299 case Hexagon::C4_cmplteui:
300 case Hexagon::C4_cmpneq:
301 case Hexagon::C4_cmplte:
302 case Hexagon::C4_cmplteu:
303 case Hexagon::A4_cmpbeq:
304 case Hexagon::A4_cmpbeqi:
305 case Hexagon::A4_cmpbgtu:
306 case Hexagon::A4_cmpbgtui:
307 case Hexagon::A4_cmpbgt:
308 case Hexagon::A4_cmpbgti:
309 case Hexagon::A4_cmpheq:
310 case Hexagon::A4_cmphgt:
311 case Hexagon::A4_cmphgtu:
312 case Hexagon::A4_cmpheqi:
313 case Hexagon::A4_cmphgti:
314 case Hexagon::A4_cmphgtui:
320 bool HexagonGenPredicate::isScalarPred(
Register PredReg) {
321 std::queue<Register> WorkQ;
324 while (!WorkQ.empty()) {
332 case TargetOpcode::COPY: {
334 if (
MRI->getRegClass(PR.R) != PredRC)
339 case Hexagon::C2_and:
340 case Hexagon::C2_andn:
341 case Hexagon::C4_and_and:
342 case Hexagon::C4_and_andn:
343 case Hexagon::C4_and_or:
345 case Hexagon::C2_orn:
346 case Hexagon::C4_or_and:
347 case Hexagon::C4_or_andn:
348 case Hexagon::C4_or_or:
349 case Hexagon::C4_or_orn:
350 case Hexagon::C2_xor:
353 if (MO.isReg() && MO.isUse())
359 return isScalarCmp(DefOpc);
366 bool HexagonGenPredicate::convertToPredForm(
MachineInstr *MI) {
370 assert(isConvertibleToPredForm(MI));
372 for (
unsigned i = 0; i < NumOps; ++i) {
377 if (Reg.S && Reg.S != Hexagon::isub_lo)
379 if (!PredGPRs.count(Reg))
386 unsigned NewOpc = getPredForm(Opc);
390 case Hexagon::C2_cmpeqi:
391 NewOpc = Hexagon::C2_not;
393 case Hexagon::C4_cmpneqi:
394 NewOpc = TargetOpcode::COPY;
404 if (!isScalarPred(PR))
420 Register NewPR =
MRI->createVirtualRegister(PredRC);
424 for (
unsigned i = 1; i < NumOps; ++i) {
427 MIB.
addReg(Pred.R, 0, Pred.S);
434 unsigned NewOutR =
MRI->createVirtualRegister(RC);
435 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), NewOutR)
436 .addReg(NewPR.R, 0, NewPR.S);
437 MRI->replaceRegWith(OutR.R, NewOutR);
446 processPredicateGPR(R);
454 bool Changed =
false;
469 if (MI.
getOpcode() != TargetOpcode::COPY)
477 if (
MRI->getRegClass(DR.R) != PredRC)
479 if (
MRI->getRegClass(SR.R) != PredRC)
481 assert(!DR.S && !SR.S &&
"Unexpected subregister");
482 MRI->replaceRegWith(DR.R, SR.R);
488 for (VectOfInst::iterator
I = Erase.begin(),
E = Erase.end();
I !=
E; ++
I)
489 (*I)->eraseFromParent();
505 bool Changed =
false;
506 collectPredicateGPR(MF);
507 for (SetOfReg::iterator
I = PredGPRs.begin(),
E = PredGPRs.end();
I !=
E; ++
I)
508 processPredicateGPR(*
I);
513 VectOfInst Processed, Copy;
515 using iterator = VectOfInst::iterator;
518 for (iterator
I = Copy.begin(),
E = Copy.end();
I !=
E; ++
I) {
520 bool Done = convertToPredForm(MI);
522 Processed.insert(MI);
529 return Processed.count(MI);
531 PUsers.remove_if(Done);
534 Changed |= eliminatePredCopies(MF);
539 return new HexagonGenPredicate();
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
class llvm::RegisterBankInfo GPR
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
A global registry used in conjunction with static constructors to make pluggable components (like tar...
unsigned getSubReg() const
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
hexagon gen Hexagon generate predicate operations
FunctionPass * createHexagonGenPredicate()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getNumOperands() const
Retuns the total number of operands.
Printable printReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
zlib-gnu style compression
INITIALIZE_PASS_BEGIN(HexagonGenPredicate, "hexagon-gen-pred", "Hexagon generate predicate operations", false, false) INITIALIZE_PASS_END(HexagonGenPredicate
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Represent the analysis usage information of a pass.
defusechain_iterator< true, false, false, true, false, false > use_iterator
use_iterator/use_begin/use_end - Walk all uses of the specified register.
FunctionPass class - This class is used to implement most global optimizations.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
Promote Memory to Register
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
void initializeHexagonGenPredicatePass(PassRegistry &Registry)
Representation of each machine instruction.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator<(int64_t V1, const APSInt &V2)
bool isPredReg(unsigned Reg)
A vector that has set insertion semantics.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
#define LLVM_ATTRIBUTE_UNUSED
bool operator==(uint64_t V1, const APInt &V2)
const MachineOperand & getOperand(unsigned i) const
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...