16 #define DEBUG_TYPE "systemz-elim-compare"
31 STATISTIC(BranchOnCounts,
"Number of branch-on-count instructions");
32 STATISTIC(EliminatedComparisons,
"Number of eliminated comparisons");
33 STATISTIC(FusedComparisons,
"Number of fused compare-and-branch instructions");
42 Reference &
operator|=(
const Reference &Other) {
44 IndirectDef |= Other.IndirectDef;
46 IndirectUse |= Other.IndirectUse;
69 virtual const char *getPassName()
const {
70 return "SystemZ Comparison Elimination";
96 return new SystemZElimCompare(TM);
102 SE = MBB->
succ_end(); SI != SE; ++SI)
103 if ((*SI)->isLiveIn(SystemZ::CC))
145 if (
unsigned MOReg = MO.
getReg()) {
146 if (MOReg == Reg || TRI->regsOverlap(MOReg, Reg)) {
149 Ref.IndirectUse |= (MOReg !=
Reg);
153 Ref.IndirectDef |= (MOReg !=
Reg);
171 if (Opcode == SystemZ::AHI)
172 BRCT = SystemZ::BRCT;
173 else if (Opcode == SystemZ::AGHI)
174 BRCT = SystemZ::BRCTG;
181 if (CCUsers.
size() != 1)
184 if (Branch->
getOpcode() != SystemZ::BRC ||
194 for (++MBBI; MBBI != MBBE; ++MBBI)
195 if (getRegReferences(MBBI, SrcReg))
215 bool SystemZElimCompare::convertToLoadAndTest(
MachineInstr *MI) {
231 bool SystemZElimCompare::
236 unsigned MIFlags = Desc.
TSFlags;
246 if (ReusableCCMask == 0)
250 assert((ReusableCCMask & ~CCValues) == 0 &&
"Invalid CCValues");
254 for (
unsigned int I = 0, E = CCUsers.
size();
I != E; ++
I) {
272 unsigned OutValid = ~ReusableCCMask & CCValid;
273 unsigned OutMask = ~ReusableCCMask & CCMask;
274 if (OutMask != 0 && OutMask != OutValid)
282 for (
unsigned I = 0, E = AlterMasks.
size();
I != E;
I += 2) {
283 AlterMasks[
I]->setImm(CCValues);
284 unsigned CCMask = AlterMasks[
I + 1]->getImm();
285 if (CCMask & ~ReusableCCMask)
286 AlterMasks[
I + 1]->setImm((CCMask & ReusableCCMask) |
287 (CCValues & ~ReusableCCMask));
292 assert(CCDef >= 0 &&
"Couldn't find CC set");
297 for (++MBBI; MBBI != MBBE; ++MBBI)
298 MBBI->clearRegisterKills(SystemZ::CC, TRI);
306 case SystemZ::LTEBRCompare:
307 case SystemZ::LTDBRCompare:
308 case SystemZ::LTXBRCompare:
322 bool SystemZElimCompare::
335 while (MBBI != MBBE) {
342 if (!CCRefs.Use && !SrcRefs && convertToBRCT(MI, Compare, CCUsers)) {
347 if ((!CCRefs && convertToLoadAndTest(MI)) ||
348 (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) {
349 EliminatedComparisons += 1;
353 SrcRefs |= getRegReferences(MI, SrcReg);
356 CCRefs |= getRegReferences(MI, SystemZ::CC);
357 if (CCRefs.Use && CCRefs.Def)
365 bool SystemZElimCompare::
369 unsigned FusedOpcode =
TII->getCompareAndBranch(Compare->
getOpcode(),
375 if (CCUsers.
size() != 1)
386 for (++MBBI; MBBI != MBBE; ++MBBI)
387 if (MBBI->modifiesRegister(SrcReg, TRI) ||
388 (SrcReg2 && MBBI->modifiesRegister(SrcReg2, TRI)))
395 "Invalid condition-code mask for integer comparison");
398 int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC,
false, TRI);
399 assert(CCUse >= 0 &&
"BRC must use CC");
416 for (++MBBI; MBBI != MBBE; ++MBBI) {
417 MBBI->clearRegisterKills(SrcReg, TRI);
419 MBBI->clearRegisterKills(SrcReg2, TRI);
421 FusedComparisons += 1;
428 bool Changed =
false;
436 while (MBBI != MBB->
begin()) {
438 if (CompleteCCUsers &&
440 (optimizeCompareZero(MI, CCUsers) ||
441 fuseCompareAndBranch(MI, CCUsers))) {
446 CompleteCCUsers =
true;
450 Reference CCRefs(getRegReferences(MI, SystemZ::CC));
453 CompleteCCUsers = !CCRefs.IndirectDef;
455 if (CompleteCCUsers && CCRefs.Use)
465 bool Changed =
false;
468 Changed |= processBlock(MFI);
void push_back(const T &Elt)
const MachineFunction * getParent() const
const MCInstrDesc & getDesc() const
void setIsDead(bool Val=true)
const unsigned CCMASK_ICMP
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.
std::vector< MachineBasicBlock * >::iterator succ_iterator
ID
LLVM Calling Convention Representation.
unsigned getNumOperands() const
void RemoveOperand(unsigned i)
STATISTIC(BranchOnCounts,"Number of branch-on-count instructions")
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
const MachineOperand & getOperand(unsigned i) const
unsigned getNumExplicitOperands() const
static bool isCompareZero(MachineInstr *Compare)
succ_iterator succ_begin()
unsigned getSubReg() const
static bool resultTests(MachineInstr *MI, unsigned Reg, unsigned SubReg)
virtual const TargetInstrInfo * getInstrInfo() const
static unsigned getCompareZeroCCMask(unsigned int Flags)
void setDesc(const MCInstrDesc &tid)
const unsigned CCMASK_CMP_EQ
const unsigned CCMASK_CMP_NE
bool isCompare(QueryType Type=IgnoreBundle) const
isCompare - Return true if this instruction is a comparison.
static unsigned getCCValues(unsigned int Flags)
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=NULL) const
const TargetMachine & getTarget() const
MachineInstr * removeFromParent()
static bool isCCLiveOut(MachineBasicBlock *MBB)
FunctionPass * createSystemZElimComparePass(SystemZTargetMachine &TM)
unsigned getReg() const
getReg - Returns the register number.
virtual const HexagonRegisterInfo & getRegisterInfo() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const