28 #define DEBUG_TYPE "systemz-elim-compare"
30 STATISTIC(BranchOnCounts,
"Number of branch-on-count instructions");
31 STATISTIC(LoadAndTraps,
"Number of load-and-trap instructions");
32 STATISTIC(EliminatedComparisons,
"Number of eliminated comparisons");
33 STATISTIC(FusedComparisons,
"Number of fused compare-and-branch instructions");
42 Reference &
operator|=(
const Reference &Other) {
48 explicit operator bool()
const {
return Def ||
Use; }
63 return "SystemZ Comparison Elimination";
95 return new SystemZElimCompare(TM);
101 if ((*SI)->isLiveIn(SystemZ::CC))
138 if (
unsigned MOReg = MO.
getReg()) {
139 if (TRI->regsOverlap(MOReg, Reg)) {
156 return (MI.
getOpcode() == SystemZ::LTEBR ||
178 bool SystemZElimCompare::convertToBRCT(
184 if (Opcode == SystemZ::AHI)
185 BRCT = SystemZ::BRCT;
186 else if (Opcode == SystemZ::AGHI)
187 BRCT = SystemZ::BRCTG;
188 else if (Opcode == SystemZ::AIH)
189 BRCT = SystemZ::BRCTH;
196 if (CCUsers.
size() != 1)
199 if (Branch->
getOpcode() != SystemZ::BRC ||
209 for (++MBBI; MBBI != MBBE; ++MBBI)
210 if (getRegReferences(*MBBI, SrcReg))
225 if (BRCT != SystemZ::BRCTH)
234 bool SystemZElimCompare::convertToLoadAndTrap(
237 unsigned LATOpcode =
TII->getLoadAndTrap(MI.
getOpcode());
242 if (CCUsers.
size() != 1)
245 if (Branch->
getOpcode() != SystemZ::CondTrap ||
255 for (++MBBI; MBBI != MBBE; ++MBBI)
256 if (getRegReferences(*MBBI, SrcReg))
274 bool SystemZElimCompare::convertToLoadAndTest(
MachineInstr &MI) {
290 bool SystemZElimCompare::adjustCCMasksForInstr(
295 unsigned MIFlags = Desc.
TSFlags;
305 if (ReusableCCMask == 0)
309 assert((ReusableCCMask & ~CCValues) == 0 &&
"Invalid CCValues");
313 for (
unsigned int I = 0,
E = CCUsers.
size();
I !=
E; ++
I) {
331 unsigned OutValid = ~ReusableCCMask & CCValid;
332 unsigned OutMask = ~ReusableCCMask & CCMask;
333 if (OutMask != 0 && OutMask != OutValid)
341 for (
unsigned I = 0,
E = AlterMasks.
size();
I !=
E;
I += 2) {
342 AlterMasks[
I]->setImm(CCValues);
343 unsigned CCMask = AlterMasks[
I + 1]->getImm();
344 if (CCMask & ~ReusableCCMask)
345 AlterMasks[
I + 1]->setImm((CCMask & ReusableCCMask) |
346 (CCValues & ~ReusableCCMask));
351 assert(CCDef >= 0 &&
"Couldn't find CC set");
356 for (++MBBI; MBBI != MBBE; ++MBBI)
357 MBBI->clearRegisterKills(SystemZ::CC, TRI);
365 case SystemZ::LTEBRCompare:
366 case SystemZ::LTDBRCompare:
367 case SystemZ::LTXBRCompare:
384 bool SystemZElimCompare::optimizeCompareZero(
395 while (MBBI != MBBE) {
402 if (!CCRefs.Use && !SrcRefs) {
403 if (convertToBRCT(MI, Compare, CCUsers)) {
407 if (convertToLoadAndTrap(MI, Compare, CCUsers)) {
413 if ((!CCRefs && convertToLoadAndTest(MI)) ||
414 (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) {
415 EliminatedComparisons += 1;
419 SrcRefs |= getRegReferences(MI, SrcReg);
422 CCRefs |= getRegReferences(MI, SystemZ::CC);
423 if (CCRefs.Use && CCRefs.Def)
431 bool SystemZElimCompare::fuseCompareOperations(
434 if (CCUsers.
size() != 1)
442 case SystemZ::CondReturn:
445 case SystemZ::CallBCR:
448 case SystemZ::CondTrap:
456 unsigned FusedOpcode =
469 for (++MBBI; MBBI != MBBE; ++MBBI)
470 if (MBBI->modifiesRegister(SrcReg, TRI) ||
471 (SrcReg2 && MBBI->modifiesRegister(SrcReg2, TRI)))
477 "Invalid condition-code mask for integer comparison");
483 RegMask = MBBI->getOperand(2).getRegMask();
486 int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC,
false, TRI);
487 assert(CCUse >= 0 &&
"BRC/BCR must use CC");
499 unsigned SrcNOps = 2;
500 if (FusedOpcode == SystemZ::CLT || FusedOpcode == SystemZ::CLGT)
504 for (
unsigned I = 0;
I < SrcNOps;
I++)
521 for (++MBBI; MBBI != MBBE; ++MBBI) {
522 MBBI->clearRegisterKills(SrcReg, TRI);
524 MBBI->clearRegisterKills(SrcReg2, TRI);
526 FusedComparisons += 1;
533 bool Changed =
false;
541 while (MBBI != MBB.
begin()) {
544 (optimizeCompareZero(MI, CCUsers) ||
545 fuseCompareOperations(MI, CCUsers))) {
555 CompleteCCUsers =
true;
570 bool Changed =
false;
572 Changed |= processBlock(MBB);
void push_back(const T &Elt)
const MachineFunction * getParent() const
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.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
static bool resultTests(MachineInstr &MI, unsigned Reg)
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
void setIsDead(bool Val=true)
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
const unsigned CCMASK_ICMP
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
struct fuzzer::@269 Flags
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.
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.
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
const HexagonRegisterInfo & getRegisterInfo() const
HexagonInstrInfo specifics.
Function Alias Analysis false
static bool isCompareZero(MachineInstr &Compare)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
bool operator|=(SparseBitVector< ElementSize > &LHS, const SparseBitVector< ElementSize > *RHS)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
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.
FunctionPass class - This class is used to implement most global optimizations.
succ_iterator succ_begin()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool definesRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr fully defines the specified register.
bool readsRegister(unsigned Reg, const TargetRegisterInfo *TRI=nullptr) const
Return true if the MachineInstr reads the specified register.
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
static const char * Target
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.
MachineFunctionProperties & set(Property P)
static unsigned getCompareSourceReg(MachineInstr &Compare)
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static unsigned getCCValues(unsigned int Flags)
FunctionPass * createSystemZElimComparePass(SystemZTargetMachine &TM)
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
StringRef - Represent a constant reference to a string, i.e.
static bool isLoadAndTestAsCmp(MachineInstr &MI)
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Properties which a MachineFunction may have at a given point in time.