- /// \brief Rewrite the current source with \p NewSrcReg and \p NewSecSubReg
- /// by creating a new COPY instruction. \p DefReg and \p DefSubReg contain the
- /// definition to be rewritten from the original copylike instruction.
- /// \return The new COPY if the rewriting was possible, nullptr otherwise.
- /// This is needed to handle Uncoalescable copies, since they are copy
- /// like instructions that aren't recognized by the register allocator.
- virtual MachineInstr *RewriteCurrentSource(unsigned DefReg,
- unsigned DefSubReg,
- unsigned NewSrcReg,
- unsigned NewSrcSubReg) {
+ /// \brief Given a \p Def.Reg and Def.SubReg pair, use \p RewriteMap to find
+ /// the new source to use for rewrite. If \p HandleMultipleSources is true and
+ /// multiple sources for a given \p Def are found along the way, we found a
+ /// PHI instructions that needs to be rewritten.
+ /// TODO: HandleMultipleSources should be removed once we test PHI handling
+ /// with coalescable copies.
+ TargetInstrInfo::RegSubRegPair
+ getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
+ TargetInstrInfo::RegSubRegPair Def,
+ PeepholeOptimizer::RewriteMapTy &RewriteMap,
+ bool HandleMultipleSources = true) {
+
+ TargetInstrInfo::RegSubRegPair LookupSrc(Def.Reg, Def.SubReg);
+ do {
+ ValueTrackerResult Res = RewriteMap.lookup(LookupSrc);
+ // If there are no entries on the map, LookupSrc is the new source.
+ if (!Res.isValid())
+ return LookupSrc;
+
+ // There's only one source for this definition, keep searching...
+ unsigned NumSrcs = Res.getNumSources();
+ if (NumSrcs == 1) {
+ LookupSrc.Reg = Res.getSrcReg(0);
+ LookupSrc.SubReg = Res.getSrcSubReg(0);
+ continue;
+ }
+
+ // TODO: Remove once multiple srcs w/ coalescable copies are supported.
+ if (!HandleMultipleSources)
+ break;
+
+ // Multiple sources, recurse into each source to find a new source
+ // for it. Then, rewrite the PHI accordingly to its new edges.
+ SmallVector<TargetInstrInfo::RegSubRegPair, 4> NewPHISrcs;
+ for (unsigned i = 0; i < NumSrcs; ++i) {
+ TargetInstrInfo::RegSubRegPair PHISrc(Res.getSrcReg(i),
+ Res.getSrcSubReg(i));
+ NewPHISrcs.push_back(
+ getNewSource(MRI, TII, PHISrc, RewriteMap, HandleMultipleSources));
+ }
+
+ // Build the new PHI node and return its def register as the new source.
+ MachineInstr *OrigPHI = const_cast<MachineInstr *>(Res.getInst());
+ MachineInstr *NewPHI = insertPHI(MRI, TII, NewPHISrcs, OrigPHI);
+ DEBUG(dbgs() << "-- getNewSource\n");
+ DEBUG(dbgs() << " Replacing: " << *OrigPHI);
+ DEBUG(dbgs() << " With: " << *NewPHI);
+ const MachineOperand &MODef = NewPHI->getOperand(0);
+ return TargetInstrInfo::RegSubRegPair(MODef.getReg(), MODef.getSubReg());
+
+ } while (1);
+
+ return TargetInstrInfo::RegSubRegPair(0, 0);
+ }
+
+ /// \brief Rewrite the source found through \p Def, by using the \p RewriteMap
+ /// and create a new COPY instruction. More info about RewriteMap in
+ /// PeepholeOptimizer::findNextSource. Right now this is only used to handle
+ /// Uncoalescable copies, since they are copy like instructions that aren't
+ /// recognized by the register allocator.
+ virtual MachineInstr *
+ RewriteSource(TargetInstrInfo::RegSubRegPair Def,
+ PeepholeOptimizer::RewriteMapTy &RewriteMap) {