10 #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);
90 return "Hexagon generate predicate operations";
103 typedef std::set<Register> SetOfReg;
104 typedef std::map<Register,Register> RegToRegMap;
116 unsigned getPredForm(
unsigned Opc);
118 bool isScalarCmp(
unsigned Opc);
119 bool isScalarPred(
Register PredReg);
130 "Hexagon generate predicate operations",
false,
false)
135 bool HexagonGenPredicate::
isPredReg(
unsigned R) {
139 return RC == &Hexagon::PredRegsRegClass;
142 unsigned HexagonGenPredicate::getPredForm(
unsigned Opc) {
143 using namespace Hexagon;
182 static_assert(PHI == 0,
"Use different value for <none>");
186 bool HexagonGenPredicate::isConvertibleToPredForm(
const MachineInstr *
MI) {
188 if (getPredForm(Opc) != 0)
196 case Hexagon::C2_cmpeqi:
197 case Hexagon::C4_cmpneqi:
212 case Hexagon::C2_tfrpr:
213 case TargetOpcode::COPY:
225 void HexagonGenPredicate::processPredicateGPR(
const Register &
Reg) {
227 <<
PrintReg(Reg.R, TRI, Reg.S) <<
"\n");
229 use_iterator
I =
MRI->use_begin(Reg.R),
E =
MRI->use_end();
237 for (; I !=
E; ++
I) {
239 if (isConvertibleToPredForm(UseI))
249 RegToRegMap::iterator
F = G2P.find(Reg);
253 DEBUG(
dbgs() << __func__ <<
": " << PrintRegister(Reg, *TRI));
257 if (Opc == Hexagon::C2_tfrpr || Opc == TargetOpcode::COPY) {
260 G2P.insert(std::make_pair(Reg, PR));
261 DEBUG(
dbgs() <<
" -> " << PrintRegister(PR, *TRI) <<
'\n');
268 unsigned NewPR =
MRI->createVirtualRegister(PredRC);
272 if (isConvertibleToPredForm(DefI)) {
274 BuildMI(B, std::next(DefIt), DL,
TII->get(TargetOpcode::COPY), NewPR)
275 .addReg(Reg.R, 0, Reg.S);
276 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)
338 case Hexagon::C2_and:
339 case Hexagon::C2_andn:
340 case Hexagon::C4_and_and:
341 case Hexagon::C4_and_andn:
342 case Hexagon::C4_and_or:
344 case Hexagon::C2_orn:
345 case Hexagon::C4_or_and:
346 case Hexagon::C4_or_andn:
347 case Hexagon::C4_or_or:
348 case Hexagon::C4_or_orn:
349 case Hexagon::C2_xor:
352 if (MO.isReg() && MO.isUse())
358 return isScalarCmp(DefOpc);
365 bool HexagonGenPredicate::convertToPredForm(
MachineInstr *MI) {
366 DEBUG(
dbgs() << __func__ <<
": " << MI <<
" " << *MI);
369 assert(isConvertibleToPredForm(MI));
371 for (
unsigned i = 0;
i < NumOps; ++
i) {
376 if (Reg.S && Reg.S != Hexagon::isub_lo)
378 if (!PredGPRs.count(Reg))
385 unsigned NewOpc = getPredForm(Opc);
389 case Hexagon::C2_cmpeqi:
390 NewOpc = Hexagon::C2_not;
392 case Hexagon::C4_cmpneqi:
393 NewOpc = TargetOpcode::COPY;
403 if (!isScalarPred(PR))
419 Register NewPR =
MRI->createVirtualRegister(PredRC);
423 for (
unsigned i = 1;
i < NumOps; ++
i) {
426 MIB.
addReg(Pred.R, 0, Pred.S);
433 unsigned NewOutR =
MRI->createVirtualRegister(RC);
434 BuildMI(B, MI, DL,
TII->get(TargetOpcode::COPY), NewOutR)
435 .addReg(NewPR.R, 0, NewPR.S);
436 MRI->replaceRegWith(OutR.R, NewOutR);
445 processPredicateGPR(R);
453 bool Changed =
false;
468 if (MI.
getOpcode() != TargetOpcode::COPY)
476 if (
MRI->getRegClass(DR.R) != PredRC)
478 if (
MRI->getRegClass(SR.R) != PredRC)
480 assert(!DR.S && !SR.S &&
"Unexpected subregister");
481 MRI->replaceRegWith(DR.R, SR.R);
487 for (VectOfInst::iterator I = Erase.begin(),
E = Erase.end(); I !=
E; ++
I)
488 (*I)->eraseFromParent();
504 bool Changed =
false;
505 collectPredicateGPR(MF);
506 for (SetOfReg::iterator I = PredGPRs.begin(),
E = PredGPRs.end(); I !=
E; ++
I)
507 processPredicateGPR(*I);
512 VectOfInst Processed,
Copy;
514 typedef VectOfInst::iterator iterator;
516 for (iterator I = Copy.begin(),
E = Copy.end(); I !=
E; ++
I) {
518 bool Done = convertToPredForm(MI);
520 Processed.insert(MI);
527 return Processed.count(MI);
529 PUsers.remove_if(Done);
532 Changed |= eliminatePredCopies(MF);
537 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...
class llvm::RegisterBankInfo GPR
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...
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mop_iterator > operands()
hexagon gen Hexagon generate predicate operations
FunctionPass * createHexagonGenPredicate()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
hexagon gen Hexagon generate predicate false
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
#define LLVM_ATTRIBUTE_UNUSED
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
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...
#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
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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.
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.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
unsigned getReg() const
getReg - Returns the register number.
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...
bool operator==(uint64_t V1, const APInt &V2)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
reg_begin/reg_end - Provide iteration support to walk over all definitions and uses of a register wit...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...