29 #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");
44 IndirectDef |= Other.IndirectDef;
46 IndirectUse |= Other.IndirectUse;
50 explicit operator bool()
const {
return Def ||
Use; }
69 const char *getPassName()
const override {
70 return "SystemZ Comparison Elimination";
96 return new SystemZElimCompare(TM);
102 if ((*SI)->isLiveIn(SystemZ::CC))
144 if (
unsigned MOReg = MO.
getReg()) {
145 if (MOReg == Reg || TRI->regsOverlap(MOReg, Reg)) {
148 Ref.IndirectUse |= (MOReg !=
Reg);
152 Ref.IndirectDef |= (MOReg !=
Reg);
170 if (Opcode == SystemZ::AHI)
171 BRCT = SystemZ::BRCT;
172 else if (Opcode == SystemZ::AGHI)
173 BRCT = SystemZ::BRCTG;
180 if (CCUsers.
size() != 1)
183 if (Branch->
getOpcode() != SystemZ::BRC ||
193 for (++MBBI; MBBI != MBBE; ++MBBI)
194 if (getRegReferences(MBBI, SrcReg))
214 bool SystemZElimCompare::convertToLoadAndTest(
MachineInstr *MI) {
230 bool SystemZElimCompare::
235 unsigned MIFlags = Desc.
TSFlags;
245 if (ReusableCCMask == 0)
249 assert((ReusableCCMask & ~CCValues) == 0 &&
"Invalid CCValues");
253 for (
unsigned int I = 0, E = CCUsers.
size();
I != E; ++
I) {
271 unsigned OutValid = ~ReusableCCMask & CCValid;
272 unsigned OutMask = ~ReusableCCMask & CCMask;
273 if (OutMask != 0 && OutMask != OutValid)
281 for (
unsigned I = 0, E = AlterMasks.
size();
I != E;
I += 2) {
282 AlterMasks[
I]->setImm(CCValues);
283 unsigned CCMask = AlterMasks[
I + 1]->getImm();
284 if (CCMask & ~ReusableCCMask)
285 AlterMasks[
I + 1]->setImm((CCMask & ReusableCCMask) |
286 (CCValues & ~ReusableCCMask));
291 assert(CCDef >= 0 &&
"Couldn't find CC set");
296 for (++MBBI; MBBI != MBBE; ++MBBI)
297 MBBI->clearRegisterKills(SystemZ::CC, TRI);
305 case SystemZ::LTEBRCompare:
306 case SystemZ::LTDBRCompare:
307 case SystemZ::LTXBRCompare:
321 bool SystemZElimCompare::
334 while (MBBI != MBBE) {
341 if (!CCRefs.Use && !SrcRefs && convertToBRCT(MI, Compare, CCUsers)) {
346 if ((!CCRefs && convertToLoadAndTest(MI)) ||
347 (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) {
348 EliminatedComparisons += 1;
352 SrcRefs |= getRegReferences(MI, SrcReg);
355 CCRefs |= getRegReferences(MI, SystemZ::CC);
356 if (CCRefs.Use && CCRefs.Def)
364 bool SystemZElimCompare::
368 unsigned FusedOpcode =
TII->getCompareAndBranch(Compare->
getOpcode(),
374 if (CCUsers.
size() != 1)
385 for (++MBBI; MBBI != MBBE; ++MBBI)
386 if (MBBI->modifiesRegister(SrcReg, TRI) ||
387 (SrcReg2 && MBBI->modifiesRegister(SrcReg2, TRI)))
394 "Invalid condition-code mask for integer comparison");
397 int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC,
false, TRI);
398 assert(CCUse >= 0 &&
"BRC must use CC");
415 for (++MBBI; MBBI != MBBE; ++MBBI) {
416 MBBI->clearRegisterKills(SrcReg, TRI);
418 MBBI->clearRegisterKills(SrcReg2, TRI);
420 FusedComparisons += 1;
427 bool Changed =
false;
435 while (MBBI != MBB.
begin()) {
437 if (CompleteCCUsers &&
439 (optimizeCompareZero(MI, CCUsers) ||
440 fuseCompareAndBranch(MI, CCUsers))) {
445 CompleteCCUsers =
true;
449 Reference CCRefs(getRegReferences(MI, SystemZ::CC));
452 CompleteCCUsers = !CCRefs.IndirectDef;
454 if (CompleteCCUsers && CCRefs.Use)
464 bool Changed =
false;
466 Changed |= processBlock(MBB);
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
STATISTIC(NumFunctions,"Total number of functions")
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void setIsDead(bool Val=true)
const unsigned CCMASK_ICMP
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.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const HexagonRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bundle_iterator< MachineInstr, instr_iterator > iterator
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
static bool isCCLiveOut(MachineBasicBlock &MBB)
int findRegisterDefOperandIdx(unsigned Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found...
const MachineOperand & getOperand(unsigned i) const
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
static bool isCompareZero(MachineInstr *Compare)
FunctionPass class - This class is used to implement most global optimizations.
succ_iterator succ_begin()
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static bool resultTests(MachineInstr *MI, unsigned Reg, unsigned SubReg)
static unsigned getCompareZeroCCMask(unsigned int Flags)
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const unsigned CCMASK_CMP_EQ
const unsigned CCMASK_CMP_NE
bool isCompare(QueryType Type=IgnoreBundle) const
Return true if this instruction is a comparison.
Target - Wrapper for Target specific information.
Representation of each machine instruction.
static unsigned getCCValues(unsigned int Flags)
MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it. ...
FunctionPass * createSystemZElimComparePass(SystemZTargetMachine &TM)
unsigned getReg() const
getReg - Returns the register number.
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
addReg - Add a new virtual register operand...