+/// Optimize a select instruction.
+bool PeepholeOptimizer::optimizeSelect(MachineInstr *MI) {
+ unsigned TrueOp = 0;
+ unsigned FalseOp = 0;
+ bool Optimizable = false;
+ SmallVector<MachineOperand, 4> Cond;
+ if (TII->analyzeSelect(MI, Cond, TrueOp, FalseOp, Optimizable))
+ return false;
+ if (!Optimizable)
+ return false;
+ if (!TII->optimizeSelect(MI))
+ return false;
+ MI->eraseFromParent();
+ ++NumSelects;
+ return true;
+}
+
+/// \brief Check if the registers defined by the pair (RegisterClass, SubReg)
+/// share the same register file.
+static bool shareSameRegisterFile(const TargetRegisterInfo &TRI,
+ const TargetRegisterClass *DefRC,
+ unsigned DefSubReg,
+ const TargetRegisterClass *SrcRC,
+ unsigned SrcSubReg) {
+ // Same register class.
+ if (DefRC == SrcRC)
+ return true;
+
+ // Both operands are sub registers. Check if they share a register class.
+ unsigned SrcIdx, DefIdx;
+ if (SrcSubReg && DefSubReg)
+ return TRI.getCommonSuperRegClass(SrcRC, SrcSubReg, DefRC, DefSubReg,
+ SrcIdx, DefIdx) != NULL;
+ // At most one of the register is a sub register, make it Src to avoid
+ // duplicating the test.
+ if (!SrcSubReg) {
+ std::swap(DefSubReg, SrcSubReg);
+ std::swap(DefRC, SrcRC);
+ }
+
+ // One of the register is a sub register, check if we can get a superclass.
+ if (SrcSubReg)
+ return TRI.getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg) != NULL;
+ // Plain copy.
+ return TRI.getCommonSubClass(DefRC, SrcRC) != NULL;
+}
+
+/// \brief Get the index of the definition and source for \p Copy
+/// instruction.
+/// \pre Copy.isCopy() or Copy.isBitcast().
+/// \return True if the Copy instruction has only one register source
+/// and one register definition. Otherwise, \p DefIdx and \p SrcIdx
+/// are invalid.
+static bool getCopyOrBitcastDefUseIdx(const MachineInstr &Copy,
+ unsigned &DefIdx, unsigned &SrcIdx) {
+ assert((Copy.isCopy() || Copy.isBitcast()) && "Wrong operation type.");
+ if (Copy.isCopy()) {
+ // Copy instruction are supposed to be: Def = Src.
+ if (Copy.getDesc().getNumOperands() != 2)
+ return false;
+ DefIdx = 0;
+ SrcIdx = 1;
+ assert(Copy.getOperand(DefIdx).isDef() && "Use comes before def!");
+ return true;
+ }
+ // Bitcast case.
+ // Bitcasts with more than one def are not supported.
+ if (Copy.getDesc().getNumDefs() != 1)
+ return false;
+ // Initialize SrcIdx to an undefined operand.
+ SrcIdx = Copy.getDesc().getNumOperands();
+ for (unsigned OpIdx = 0, EndOpIdx = SrcIdx; OpIdx != EndOpIdx; ++OpIdx) {
+ const MachineOperand &MO = Copy.getOperand(OpIdx);
+ if (!MO.isReg() || !MO.getReg())
+ continue;
+ if (MO.isDef())
+ DefIdx = OpIdx;
+ else if (SrcIdx != EndOpIdx)
+ // Multiple sources?
+ return false;
+ SrcIdx = OpIdx;
+ }
+ return true;
+}
+
+/// \brief Optimize a copy or bitcast instruction to avoid cross
+/// register bank copy. The optimization looks through a chain of
+/// copies and try to find a source that has a compatible register
+/// class.
+/// Two register classes are considered to be compatible if they share
+/// the same register bank.
+/// New copies issued by this optimization are register allocator
+/// friendly. This optimization does not remove any copy as it may
+/// overconstraint the register allocator, but replaces some when
+/// possible.
+/// \pre \p MI is a Copy (MI->isCopy() is true)
+/// \return True, when \p MI has been optimized. In that case, \p MI has
+/// been removed from its parent.
+bool PeepholeOptimizer::optimizeCopyOrBitcast(MachineInstr *MI) {
+ unsigned DefIdx, SrcIdx;
+ if (!MI || !getCopyOrBitcastDefUseIdx(*MI, DefIdx, SrcIdx))
+ return false;
+
+ const MachineOperand &MODef = MI->getOperand(DefIdx);
+ assert(MODef.isReg() && "Copies must be between registers.");
+ unsigned Def = MODef.getReg();
+
+ if (TargetRegisterInfo::isPhysicalRegister(Def))
+ return false;
+
+ const TargetRegisterClass *DefRC = MRI->getRegClass(Def);
+ unsigned DefSubReg = MODef.getSubReg();
+
+ unsigned Src;
+ unsigned SrcSubReg;
+ bool ShouldRewrite = false;
+ MachineInstr *Copy = MI;
+ const TargetRegisterInfo &TRI = *TM->getRegisterInfo();
+
+ // Follow the chain of copies until we reach the top or find a
+ // more suitable source.
+ do {
+ unsigned CopyDefIdx, CopySrcIdx;
+ if (!getCopyOrBitcastDefUseIdx(*Copy, CopyDefIdx, CopySrcIdx))
+ break;
+ const MachineOperand &MO = Copy->getOperand(CopySrcIdx);
+ assert(MO.isReg() && "Copies must be between registers.");
+ Src = MO.getReg();
+
+ if (TargetRegisterInfo::isPhysicalRegister(Src))
+ break;
+
+ const TargetRegisterClass *SrcRC = MRI->getRegClass(Src);
+ SrcSubReg = MO.getSubReg();
+
+ // If this source does not incur a cross register bank copy, use it.
+ ShouldRewrite = shareSameRegisterFile(TRI, DefRC, DefSubReg, SrcRC,
+ SrcSubReg);
+ // Follow the chain of copies: get the definition of Src.
+ Copy = MRI->getVRegDef(Src);
+ } while (!ShouldRewrite && Copy && (Copy->isCopy() || Copy->isBitcast()));
+
+ // If we did not find a more suitable source, there is nothing to optimize.
+ if (!ShouldRewrite || Src == MI->getOperand(SrcIdx).getReg())
+ return false;
+
+ // Rewrite the copy to avoid a cross register bank penalty.
+ unsigned NewVR = TargetRegisterInfo::isPhysicalRegister(Def) ? Def :
+ MRI->createVirtualRegister(DefRC);
+ MachineInstr *NewCopy = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
+ TII->get(TargetOpcode::COPY), NewVR)
+ .addReg(Src, 0, SrcSubReg);
+ NewCopy->getOperand(0).setSubReg(DefSubReg);
+
+ MRI->replaceRegWith(Def, NewVR);
+ MRI->clearKillFlags(NewVR);
+ MI->eraseFromParent();
+ ++NumCopiesBitcasts;
+ return true;
+}
+
+/// isLoadFoldable - Check whether MI is a candidate for folding into a later
+/// instruction. We only fold loads to virtual registers and the virtual
+/// register defined has a single use.
+bool PeepholeOptimizer::isLoadFoldable(MachineInstr *MI,
+ unsigned &FoldAsLoadDefReg) {
+ if (!MI->canFoldAsLoad() || !MI->mayLoad())
+ return false;
+ const MCInstrDesc &MCID = MI->getDesc();
+ if (MCID.getNumDefs() != 1)
+ return false;
+
+ unsigned Reg = MI->getOperand(0).getReg();
+ // To reduce compilation time, we check MRI->hasOneUse when inserting
+ // loads. It should be checked when processing uses of the load, since
+ // uses can be removed during peephole.
+ if (!MI->getOperand(0).getSubReg() &&
+ TargetRegisterInfo::isVirtualRegister(Reg) &&
+ MRI->hasOneUse(Reg)) {
+ FoldAsLoadDefReg = Reg;
+ return true;
+ }
+ return false;
+}
+