LLVM API Documentation
00001 //===-- SystemZElimCompare.cpp - Eliminate comparison instructions --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass: 00011 // (1) tries to remove compares if CC already contains the required information 00012 // (2) fuses compares and branches into COMPARE AND BRANCH instructions 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "SystemZTargetMachine.h" 00017 #include "llvm/ADT/Statistic.h" 00018 #include "llvm/CodeGen/MachineFunctionPass.h" 00019 #include "llvm/CodeGen/MachineInstrBuilder.h" 00020 #include "llvm/IR/Function.h" 00021 #include "llvm/Support/CommandLine.h" 00022 #include "llvm/Support/MathExtras.h" 00023 #include "llvm/Target/TargetInstrInfo.h" 00024 #include "llvm/Target/TargetMachine.h" 00025 #include "llvm/Target/TargetRegisterInfo.h" 00026 00027 using namespace llvm; 00028 00029 #define DEBUG_TYPE "systemz-elim-compare" 00030 00031 STATISTIC(BranchOnCounts, "Number of branch-on-count instructions"); 00032 STATISTIC(EliminatedComparisons, "Number of eliminated comparisons"); 00033 STATISTIC(FusedComparisons, "Number of fused compare-and-branch instructions"); 00034 00035 namespace { 00036 // Represents the references to a particular register in one or more 00037 // instructions. 00038 struct Reference { 00039 Reference() 00040 : Def(false), Use(false), IndirectDef(false), IndirectUse(false) {} 00041 00042 Reference &operator|=(const Reference &Other) { 00043 Def |= Other.Def; 00044 IndirectDef |= Other.IndirectDef; 00045 Use |= Other.Use; 00046 IndirectUse |= Other.IndirectUse; 00047 return *this; 00048 } 00049 00050 operator bool() const { return Def || Use; } 00051 00052 // True if the register is defined or used in some form, either directly or 00053 // via a sub- or super-register. 00054 bool Def; 00055 bool Use; 00056 00057 // True if the register is defined or used indirectly, by a sub- or 00058 // super-register. 00059 bool IndirectDef; 00060 bool IndirectUse; 00061 }; 00062 00063 class SystemZElimCompare : public MachineFunctionPass { 00064 public: 00065 static char ID; 00066 SystemZElimCompare(const SystemZTargetMachine &tm) 00067 : MachineFunctionPass(ID), TII(nullptr), TRI(nullptr) {} 00068 00069 const char *getPassName() const override { 00070 return "SystemZ Comparison Elimination"; 00071 } 00072 00073 bool processBlock(MachineBasicBlock &MBB); 00074 bool runOnMachineFunction(MachineFunction &F) override; 00075 00076 private: 00077 Reference getRegReferences(MachineInstr *MI, unsigned Reg); 00078 bool convertToBRCT(MachineInstr *MI, MachineInstr *Compare, 00079 SmallVectorImpl<MachineInstr *> &CCUsers); 00080 bool convertToLoadAndTest(MachineInstr *MI); 00081 bool adjustCCMasksForInstr(MachineInstr *MI, MachineInstr *Compare, 00082 SmallVectorImpl<MachineInstr *> &CCUsers); 00083 bool optimizeCompareZero(MachineInstr *Compare, 00084 SmallVectorImpl<MachineInstr *> &CCUsers); 00085 bool fuseCompareAndBranch(MachineInstr *Compare, 00086 SmallVectorImpl<MachineInstr *> &CCUsers); 00087 00088 const SystemZInstrInfo *TII; 00089 const TargetRegisterInfo *TRI; 00090 }; 00091 00092 char SystemZElimCompare::ID = 0; 00093 } // end anonymous namespace 00094 00095 FunctionPass *llvm::createSystemZElimComparePass(SystemZTargetMachine &TM) { 00096 return new SystemZElimCompare(TM); 00097 } 00098 00099 // Return true if CC is live out of MBB. 00100 static bool isCCLiveOut(MachineBasicBlock &MBB) { 00101 for (auto SI = MBB.succ_begin(), SE = MBB.succ_end(); SI != SE; ++SI) 00102 if ((*SI)->isLiveIn(SystemZ::CC)) 00103 return true; 00104 return false; 00105 } 00106 00107 // Return true if any CC result of MI would reflect the value of subreg 00108 // SubReg of Reg. 00109 static bool resultTests(MachineInstr *MI, unsigned Reg, unsigned SubReg) { 00110 if (MI->getNumOperands() > 0 && 00111 MI->getOperand(0).isReg() && 00112 MI->getOperand(0).isDef() && 00113 MI->getOperand(0).getReg() == Reg && 00114 MI->getOperand(0).getSubReg() == SubReg) 00115 return true; 00116 00117 switch (MI->getOpcode()) { 00118 case SystemZ::LR: 00119 case SystemZ::LGR: 00120 case SystemZ::LGFR: 00121 case SystemZ::LTR: 00122 case SystemZ::LTGR: 00123 case SystemZ::LTGFR: 00124 case SystemZ::LER: 00125 case SystemZ::LDR: 00126 case SystemZ::LXR: 00127 case SystemZ::LTEBR: 00128 case SystemZ::LTDBR: 00129 case SystemZ::LTXBR: 00130 if (MI->getOperand(1).getReg() == Reg && 00131 MI->getOperand(1).getSubReg() == SubReg) 00132 return true; 00133 } 00134 00135 return false; 00136 } 00137 00138 // Describe the references to Reg in MI, including sub- and super-registers. 00139 Reference SystemZElimCompare::getRegReferences(MachineInstr *MI, unsigned Reg) { 00140 Reference Ref; 00141 for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 00142 const MachineOperand &MO = MI->getOperand(I); 00143 if (MO.isReg()) { 00144 if (unsigned MOReg = MO.getReg()) { 00145 if (MOReg == Reg || TRI->regsOverlap(MOReg, Reg)) { 00146 if (MO.isUse()) { 00147 Ref.Use = true; 00148 Ref.IndirectUse |= (MOReg != Reg); 00149 } 00150 if (MO.isDef()) { 00151 Ref.Def = true; 00152 Ref.IndirectDef |= (MOReg != Reg); 00153 } 00154 } 00155 } 00156 } 00157 } 00158 return Ref; 00159 } 00160 00161 // Compare compares the result of MI against zero. If MI is an addition 00162 // of -1 and if CCUsers is a single branch on nonzero, eliminate the addition 00163 // and convert the branch to a BRCT(G). Return true on success. 00164 bool 00165 SystemZElimCompare::convertToBRCT(MachineInstr *MI, MachineInstr *Compare, 00166 SmallVectorImpl<MachineInstr *> &CCUsers) { 00167 // Check whether we have an addition of -1. 00168 unsigned Opcode = MI->getOpcode(); 00169 unsigned BRCT; 00170 if (Opcode == SystemZ::AHI) 00171 BRCT = SystemZ::BRCT; 00172 else if (Opcode == SystemZ::AGHI) 00173 BRCT = SystemZ::BRCTG; 00174 else 00175 return false; 00176 if (MI->getOperand(2).getImm() != -1) 00177 return false; 00178 00179 // Check whether we have a single JLH. 00180 if (CCUsers.size() != 1) 00181 return false; 00182 MachineInstr *Branch = CCUsers[0]; 00183 if (Branch->getOpcode() != SystemZ::BRC || 00184 Branch->getOperand(0).getImm() != SystemZ::CCMASK_ICMP || 00185 Branch->getOperand(1).getImm() != SystemZ::CCMASK_CMP_NE) 00186 return false; 00187 00188 // We already know that there are no references to the register between 00189 // MI and Compare. Make sure that there are also no references between 00190 // Compare and Branch. 00191 unsigned SrcReg = Compare->getOperand(0).getReg(); 00192 MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch; 00193 for (++MBBI; MBBI != MBBE; ++MBBI) 00194 if (getRegReferences(MBBI, SrcReg)) 00195 return false; 00196 00197 // The transformation is OK. Rebuild Branch as a BRCT(G). 00198 MachineOperand Target(Branch->getOperand(2)); 00199 Branch->RemoveOperand(2); 00200 Branch->RemoveOperand(1); 00201 Branch->RemoveOperand(0); 00202 Branch->setDesc(TII->get(BRCT)); 00203 MachineInstrBuilder(*Branch->getParent()->getParent(), Branch) 00204 .addOperand(MI->getOperand(0)) 00205 .addOperand(MI->getOperand(1)) 00206 .addOperand(Target) 00207 .addReg(SystemZ::CC, RegState::ImplicitDefine); 00208 MI->removeFromParent(); 00209 return true; 00210 } 00211 00212 // If MI is a load instruction, try to convert it into a LOAD AND TEST. 00213 // Return true on success. 00214 bool SystemZElimCompare::convertToLoadAndTest(MachineInstr *MI) { 00215 unsigned Opcode = TII->getLoadAndTest(MI->getOpcode()); 00216 if (!Opcode) 00217 return false; 00218 00219 MI->setDesc(TII->get(Opcode)); 00220 MachineInstrBuilder(*MI->getParent()->getParent(), MI) 00221 .addReg(SystemZ::CC, RegState::ImplicitDefine); 00222 return true; 00223 } 00224 00225 // The CC users in CCUsers are testing the result of a comparison of some 00226 // value X against zero and we know that any CC value produced by MI 00227 // would also reflect the value of X. Try to adjust CCUsers so that 00228 // they test the result of MI directly, returning true on success. 00229 // Leave everything unchanged on failure. 00230 bool SystemZElimCompare:: 00231 adjustCCMasksForInstr(MachineInstr *MI, MachineInstr *Compare, 00232 SmallVectorImpl<MachineInstr *> &CCUsers) { 00233 int Opcode = MI->getOpcode(); 00234 const MCInstrDesc &Desc = TII->get(Opcode); 00235 unsigned MIFlags = Desc.TSFlags; 00236 00237 // See which compare-style condition codes are available. 00238 unsigned ReusableCCMask = SystemZII::getCompareZeroCCMask(MIFlags); 00239 00240 // For unsigned comparisons with zero, only equality makes sense. 00241 unsigned CompareFlags = Compare->getDesc().TSFlags; 00242 if (CompareFlags & SystemZII::IsLogical) 00243 ReusableCCMask &= SystemZ::CCMASK_CMP_EQ; 00244 00245 if (ReusableCCMask == 0) 00246 return false; 00247 00248 unsigned CCValues = SystemZII::getCCValues(MIFlags); 00249 assert((ReusableCCMask & ~CCValues) == 0 && "Invalid CCValues"); 00250 00251 // Now check whether these flags are enough for all users. 00252 SmallVector<MachineOperand *, 4> AlterMasks; 00253 for (unsigned int I = 0, E = CCUsers.size(); I != E; ++I) { 00254 MachineInstr *MI = CCUsers[I]; 00255 00256 // Fail if this isn't a use of CC that we understand. 00257 unsigned Flags = MI->getDesc().TSFlags; 00258 unsigned FirstOpNum; 00259 if (Flags & SystemZII::CCMaskFirst) 00260 FirstOpNum = 0; 00261 else if (Flags & SystemZII::CCMaskLast) 00262 FirstOpNum = MI->getNumExplicitOperands() - 2; 00263 else 00264 return false; 00265 00266 // Check whether the instruction predicate treats all CC values 00267 // outside of ReusableCCMask in the same way. In that case it 00268 // doesn't matter what those CC values mean. 00269 unsigned CCValid = MI->getOperand(FirstOpNum).getImm(); 00270 unsigned CCMask = MI->getOperand(FirstOpNum + 1).getImm(); 00271 unsigned OutValid = ~ReusableCCMask & CCValid; 00272 unsigned OutMask = ~ReusableCCMask & CCMask; 00273 if (OutMask != 0 && OutMask != OutValid) 00274 return false; 00275 00276 AlterMasks.push_back(&MI->getOperand(FirstOpNum)); 00277 AlterMasks.push_back(&MI->getOperand(FirstOpNum + 1)); 00278 } 00279 00280 // All users are OK. Adjust the masks for MI. 00281 for (unsigned I = 0, E = AlterMasks.size(); I != E; I += 2) { 00282 AlterMasks[I]->setImm(CCValues); 00283 unsigned CCMask = AlterMasks[I + 1]->getImm(); 00284 if (CCMask & ~ReusableCCMask) 00285 AlterMasks[I + 1]->setImm((CCMask & ReusableCCMask) | 00286 (CCValues & ~ReusableCCMask)); 00287 } 00288 00289 // CC is now live after MI. 00290 int CCDef = MI->findRegisterDefOperandIdx(SystemZ::CC, false, true, TRI); 00291 assert(CCDef >= 0 && "Couldn't find CC set"); 00292 MI->getOperand(CCDef).setIsDead(false); 00293 00294 // Clear any intervening kills of CC. 00295 MachineBasicBlock::iterator MBBI = MI, MBBE = Compare; 00296 for (++MBBI; MBBI != MBBE; ++MBBI) 00297 MBBI->clearRegisterKills(SystemZ::CC, TRI); 00298 00299 return true; 00300 } 00301 00302 // Return true if Compare is a comparison against zero. 00303 static bool isCompareZero(MachineInstr *Compare) { 00304 switch (Compare->getOpcode()) { 00305 case SystemZ::LTEBRCompare: 00306 case SystemZ::LTDBRCompare: 00307 case SystemZ::LTXBRCompare: 00308 return true; 00309 00310 default: 00311 return (Compare->getNumExplicitOperands() == 2 && 00312 Compare->getOperand(1).isImm() && 00313 Compare->getOperand(1).getImm() == 0); 00314 } 00315 } 00316 00317 // Try to optimize cases where comparison instruction Compare is testing 00318 // a value against zero. Return true on success and if Compare should be 00319 // deleted as dead. CCUsers is the list of instructions that use the CC 00320 // value produced by Compare. 00321 bool SystemZElimCompare:: 00322 optimizeCompareZero(MachineInstr *Compare, 00323 SmallVectorImpl<MachineInstr *> &CCUsers) { 00324 if (!isCompareZero(Compare)) 00325 return false; 00326 00327 // Search back for CC results that are based on the first operand. 00328 unsigned SrcReg = Compare->getOperand(0).getReg(); 00329 unsigned SrcSubReg = Compare->getOperand(0).getSubReg(); 00330 MachineBasicBlock &MBB = *Compare->getParent(); 00331 MachineBasicBlock::iterator MBBI = Compare, MBBE = MBB.begin(); 00332 Reference CCRefs; 00333 Reference SrcRefs; 00334 while (MBBI != MBBE) { 00335 --MBBI; 00336 MachineInstr *MI = MBBI; 00337 if (resultTests(MI, SrcReg, SrcSubReg)) { 00338 // Try to remove both MI and Compare by converting a branch to BRCT(G). 00339 // We don't care in this case whether CC is modified between MI and 00340 // Compare. 00341 if (!CCRefs.Use && !SrcRefs && convertToBRCT(MI, Compare, CCUsers)) { 00342 BranchOnCounts += 1; 00343 return true; 00344 } 00345 // Try to eliminate Compare by reusing a CC result from MI. 00346 if ((!CCRefs && convertToLoadAndTest(MI)) || 00347 (!CCRefs.Def && adjustCCMasksForInstr(MI, Compare, CCUsers))) { 00348 EliminatedComparisons += 1; 00349 return true; 00350 } 00351 } 00352 SrcRefs |= getRegReferences(MI, SrcReg); 00353 if (SrcRefs.Def) 00354 return false; 00355 CCRefs |= getRegReferences(MI, SystemZ::CC); 00356 if (CCRefs.Use && CCRefs.Def) 00357 return false; 00358 } 00359 return false; 00360 } 00361 00362 // Try to fuse comparison instruction Compare into a later branch. 00363 // Return true on success and if Compare is therefore redundant. 00364 bool SystemZElimCompare:: 00365 fuseCompareAndBranch(MachineInstr *Compare, 00366 SmallVectorImpl<MachineInstr *> &CCUsers) { 00367 // See whether we have a comparison that can be fused. 00368 unsigned FusedOpcode = TII->getCompareAndBranch(Compare->getOpcode(), 00369 Compare); 00370 if (!FusedOpcode) 00371 return false; 00372 00373 // See whether we have a single branch with which to fuse. 00374 if (CCUsers.size() != 1) 00375 return false; 00376 MachineInstr *Branch = CCUsers[0]; 00377 if (Branch->getOpcode() != SystemZ::BRC) 00378 return false; 00379 00380 // Make sure that the operands are available at the branch. 00381 unsigned SrcReg = Compare->getOperand(0).getReg(); 00382 unsigned SrcReg2 = (Compare->getOperand(1).isReg() ? 00383 Compare->getOperand(1).getReg() : 0); 00384 MachineBasicBlock::iterator MBBI = Compare, MBBE = Branch; 00385 for (++MBBI; MBBI != MBBE; ++MBBI) 00386 if (MBBI->modifiesRegister(SrcReg, TRI) || 00387 (SrcReg2 && MBBI->modifiesRegister(SrcReg2, TRI))) 00388 return false; 00389 00390 // Read the branch mask and target. 00391 MachineOperand CCMask(MBBI->getOperand(1)); 00392 MachineOperand Target(MBBI->getOperand(2)); 00393 assert((CCMask.getImm() & ~SystemZ::CCMASK_ICMP) == 0 && 00394 "Invalid condition-code mask for integer comparison"); 00395 00396 // Clear out all current operands. 00397 int CCUse = MBBI->findRegisterUseOperandIdx(SystemZ::CC, false, TRI); 00398 assert(CCUse >= 0 && "BRC must use CC"); 00399 Branch->RemoveOperand(CCUse); 00400 Branch->RemoveOperand(2); 00401 Branch->RemoveOperand(1); 00402 Branch->RemoveOperand(0); 00403 00404 // Rebuild Branch as a fused compare and branch. 00405 Branch->setDesc(TII->get(FusedOpcode)); 00406 MachineInstrBuilder(*Branch->getParent()->getParent(), Branch) 00407 .addOperand(Compare->getOperand(0)) 00408 .addOperand(Compare->getOperand(1)) 00409 .addOperand(CCMask) 00410 .addOperand(Target) 00411 .addReg(SystemZ::CC, RegState::ImplicitDefine); 00412 00413 // Clear any intervening kills of SrcReg and SrcReg2. 00414 MBBI = Compare; 00415 for (++MBBI; MBBI != MBBE; ++MBBI) { 00416 MBBI->clearRegisterKills(SrcReg, TRI); 00417 if (SrcReg2) 00418 MBBI->clearRegisterKills(SrcReg2, TRI); 00419 } 00420 FusedComparisons += 1; 00421 return true; 00422 } 00423 00424 // Process all comparison instructions in MBB. Return true if something 00425 // changed. 00426 bool SystemZElimCompare::processBlock(MachineBasicBlock &MBB) { 00427 bool Changed = false; 00428 00429 // Walk backwards through the block looking for comparisons, recording 00430 // all CC users as we go. The subroutines can delete Compare and 00431 // instructions before it. 00432 bool CompleteCCUsers = !isCCLiveOut(MBB); 00433 SmallVector<MachineInstr *, 4> CCUsers; 00434 MachineBasicBlock::iterator MBBI = MBB.end(); 00435 while (MBBI != MBB.begin()) { 00436 MachineInstr *MI = --MBBI; 00437 if (CompleteCCUsers && 00438 MI->isCompare() && 00439 (optimizeCompareZero(MI, CCUsers) || 00440 fuseCompareAndBranch(MI, CCUsers))) { 00441 ++MBBI; 00442 MI->removeFromParent(); 00443 Changed = true; 00444 CCUsers.clear(); 00445 CompleteCCUsers = true; 00446 continue; 00447 } 00448 00449 Reference CCRefs(getRegReferences(MI, SystemZ::CC)); 00450 if (CCRefs.Def) { 00451 CCUsers.clear(); 00452 CompleteCCUsers = !CCRefs.IndirectDef; 00453 } 00454 if (CompleteCCUsers && CCRefs.Use) 00455 CCUsers.push_back(MI); 00456 } 00457 return Changed; 00458 } 00459 00460 bool SystemZElimCompare::runOnMachineFunction(MachineFunction &F) { 00461 TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo()); 00462 TRI = &TII->getRegisterInfo(); 00463 00464 bool Changed = false; 00465 for (auto &MBB : F) 00466 Changed |= processBlock(MBB); 00467 00468 return Changed; 00469 }