Instead of the TargetMachine cache the MachineFunction
[oota-llvm.git] / lib / CodeGen / PeepholeOptimizer.cpp
index 08ec9990ee0f336930e2aac51175b7a97a64cad5..7c195a89bd762f02d607729582ae005a58713f1d 100644 (file)
@@ -94,7 +94,7 @@ DisablePeephole("disable-peephole", cl::Hidden, cl::init(false),
                 cl::desc("Disable the peephole optimizer"));
 
 static cl::opt<bool>
-DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(true),
+DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false),
                   cl::desc("Disable advanced copy optimization"));
 
 STATISTIC(NumReuse,      "Number of extension results reused");
@@ -107,8 +107,9 @@ STATISTIC(NumRewrittenCopies, "Number of copies rewritten");
 
 namespace {
   class PeepholeOptimizer : public MachineFunctionPass {
-    const TargetMachine   *TM;
+    MachineFunction *MF;
     const TargetInstrInfo *TII;
+    const TargetRegisterInfo *TRI;
     MachineRegisterInfo   *MRI;
     MachineDominatorTree  *DT;  // Machine dominator tree
 
@@ -161,8 +162,10 @@ namespace {
     /// \brief Check whether \p MI is a copy like instruction that is
     /// not recognized by the register coalescer.
     bool isUncoalescableCopy(const MachineInstr &MI) {
-      return MI.isBitcast() || (!DisableAdvCopyOpt &&
-                                MI.isRegSequenceLike());
+      return MI.isBitcast() ||
+             (!DisableAdvCopyOpt &&
+              (MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
+               MI.isExtractSubregLike()));
     }
   };
 
@@ -325,8 +328,7 @@ optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
   // Ensure DstReg can get a register class that actually supports
   // sub-registers. Don't change the class until we commit.
   const TargetRegisterClass *DstRC = MRI->getRegClass(DstReg);
-  DstRC = TM->getSubtargetImpl()->getRegisterInfo()->getSubClassWithSubReg(
-      DstRC, SubIdx);
+  DstRC = TRI->getSubClassWithSubReg(DstRC, SubIdx);
   if (!DstRC)
     return false;
 
@@ -336,8 +338,7 @@ optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB,
   // If UseSrcSubIdx is Set, SubIdx also applies to SrcReg, and only uses of
   // SrcReg:SubIdx should be replaced.
   bool UseSrcSubIdx =
-      TM->getSubtargetImpl()->getRegisterInfo()->getSubClassWithSubReg(
-          MRI->getRegClass(SrcReg), SubIdx) != nullptr;
+      TRI->getSubClassWithSubReg(MRI->getRegClass(SrcReg), SubIdx) != nullptr;
 
   // The source has other uses. See if we can replace the other uses with use of
   // the result of the extension.
@@ -546,7 +547,6 @@ bool PeepholeOptimizer::findNextSource(unsigned &Reg, unsigned &SubReg) {
   unsigned Src;
   unsigned SrcSubReg;
   bool ShouldRewrite = false;
-  const TargetRegisterInfo &TRI = *TM->getSubtargetImpl()->getRegisterInfo();
 
   // Follow the chain of copies until we reach the top of the use-def chain
   // or find a more suitable source.
@@ -569,7 +569,7 @@ bool PeepholeOptimizer::findNextSource(unsigned &Reg, unsigned &SubReg) {
     const TargetRegisterClass *SrcRC = MRI->getRegClass(Src);
 
     // If this source does not incur a cross register bank copy, use it.
-    ShouldRewrite = shareSameRegisterFile(TRI, DefRC, DefSubReg, SrcRC,
+    ShouldRewrite = shareSameRegisterFile(*TRI, DefRC, DefSubReg, SrcRC,
                                           SrcSubReg);
   } while (!ShouldRewrite);
 
@@ -897,7 +897,11 @@ bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr *MI) {
     if (!findNextSource(NewSrc, NewSubReg) || SrcReg == NewSrc)
       continue;
     // Rewrite source.
-    Changed |= CpyRewriter->RewriteCurrentSource(NewSrc, NewSubReg);
+    if (CpyRewriter->RewriteCurrentSource(NewSrc, NewSubReg)) {
+      // We may have extended the live-range of NewSrc, account for that.
+      MRI->clearKillFlags(NewSrc);
+      Changed = true;
+    }
   }
   // TODO: We could have a clean-up method to tidy the instruction.
   // E.g., v0 = INSERT_SUBREG v1, v1.sub0, sub0
@@ -1041,24 +1045,25 @@ bool PeepholeOptimizer::foldImmediate(MachineInstr *MI, MachineBasicBlock *MBB,
   return false;
 }
 
-bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) {
-  if (skipOptnoneFunction(*MF.getFunction()))
+bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &mf) {
+  if (skipOptnoneFunction(*mf.getFunction()))
     return false;
 
   DEBUG(dbgs() << "********** PEEPHOLE OPTIMIZER **********\n");
-  DEBUG(dbgs() << "********** Function: " << MF.getName() << '\n');
+  DEBUG(dbgs() << "********** Function: " << mf.getName() << '\n');
 
   if (DisablePeephole)
     return false;
 
-  TM  = &MF.getTarget();
-  TII = TM->getSubtargetImpl()->getInstrInfo();
-  MRI = &MF.getRegInfo();
+  MF = &mf;
+  TII = MF->getSubtarget().getInstrInfo();
+  TRI = MF->getSubtarget().getRegisterInfo();
+  MRI = &MF->getRegInfo();
   DT  = Aggressive ? &getAnalysis<MachineDominatorTree>() : nullptr;
 
   bool Changed = false;
 
-  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
+  for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) {
     MachineBasicBlock *MBB = &*I;
 
     bool SeenMoveImm = false;
@@ -1270,44 +1275,26 @@ bool ValueTracker::getNextSourceFromRegSequence(unsigned &SrcReg,
   return false;
 }
 
-/// Extract the inputs from INSERT_SUBREG.
-/// INSERT_SUBREG vreg0:sub0, vreg1:sub1, sub3 would produce:
-/// - BaseReg: vreg0:sub0
-/// - InsertedReg: vreg1:sub1, sub3
-static void
-getInsertSubregInputs(const MachineInstr &MI,
-                      TargetInstrInfo::RegSubRegPair &BaseReg,
-                      TargetInstrInfo::RegSubRegPairAndIdx &InsertedReg) {
-  assert(MI.isInsertSubreg() && "Instruction do not have the proper type");
-
-  // We are looking at:
-  // Def = INSERT_SUBREG v0, v1, sub0.
-  const MachineOperand &MOBaseReg = MI.getOperand(1);
-  const MachineOperand &MOInsertedReg = MI.getOperand(2);
-  const MachineOperand &MOSubIdx = MI.getOperand(3);
-  assert(MOSubIdx.isImm() &&
-         "One of the subindex of the reg_sequence is not an immediate");
-  BaseReg.Reg = MOBaseReg.getReg();
-  BaseReg.SubReg = MOBaseReg.getSubReg();
-
-  InsertedReg.Reg = MOInsertedReg.getReg();
-  InsertedReg.SubReg = MOInsertedReg.getSubReg();
-  InsertedReg.SubIdx = (unsigned)MOSubIdx.getImm();
-}
-
 bool ValueTracker::getNextSourceFromInsertSubreg(unsigned &SrcReg,
                                                  unsigned &SrcSubReg) {
-  assert(Def->isInsertSubreg() && "Invalid definition");
+  assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) &&
+         "Invalid definition");
+
   if (Def->getOperand(DefIdx).getSubReg())
     // If we are composing subreg, bails out.
     // Same remark as getNextSourceFromRegSequence.
     // I.e., this may be turned into an assert.
     return false;
 
+  if (!TII)
+    // We could handle the REG_SEQUENCE here, but we do not want to
+    // duplicate the code from the generic TII.
+    return false;
+
   TargetInstrInfo::RegSubRegPair BaseReg;
   TargetInstrInfo::RegSubRegPairAndIdx InsertedReg;
-  assert(DefIdx == 0 && "Invalid definition");
-  getInsertSubregInputs(*Def, BaseReg, InsertedReg);
+  if (!TII->getInsertSubregInputs(*Def, DefIdx, BaseReg, InsertedReg))
+    return false;
 
   // We are looking at:
   // Def = INSERT_SUBREG v0, v1, sub1
@@ -1346,28 +1333,10 @@ bool ValueTracker::getNextSourceFromInsertSubreg(unsigned &SrcReg,
   return true;
 }
 
-/// Extract the inputs from EXTRACT_SUBREG.
-/// EXTRACT_SUBREG vreg1:sub1, sub0, would produce:
-/// - vreg1:sub1, sub0
-static void
-getExtractSubregInputs(const MachineInstr &MI,
-                       TargetInstrInfo::RegSubRegPairAndIdx &InputReg) {
-  assert(MI.isExtractSubreg() && "Instruction do not have the proper type");
-  // We are looking at:
-  // Def = EXTRACT_SUBREG v0.sub1, sub0.
-  const MachineOperand &MOReg = MI.getOperand(1);
-  const MachineOperand &MOSubIdx = MI.getOperand(2);
-  assert(MOSubIdx.isImm() &&
-         "The subindex of the extract_subreg is not an immediate");
-
-  InputReg.Reg = MOReg.getReg();
-  InputReg.SubReg = MOReg.getSubReg();
-  InputReg.SubIdx = (unsigned)MOSubIdx.getImm();
-}
-
 bool ValueTracker::getNextSourceFromExtractSubreg(unsigned &SrcReg,
                                                   unsigned &SrcSubReg) {
-  assert(Def->isExtractSubreg() && "Invalid definition");
+  assert((Def->isExtractSubreg() ||
+          Def->isExtractSubregLike()) && "Invalid definition");
   // We are looking at:
   // Def = EXTRACT_SUBREG v0, sub0
 
@@ -1376,9 +1345,14 @@ bool ValueTracker::getNextSourceFromExtractSubreg(unsigned &SrcReg,
   if (DefSubReg)
     return false;
 
+  if (!TII)
+    // We could handle the EXTRACT_SUBREG here, but we do not want to
+    // duplicate the code from the generic TII.
+    return false;
+
   TargetInstrInfo::RegSubRegPairAndIdx ExtractSubregInputReg;
-  assert(DefIdx == 0 && "Invalid definition");
-  getExtractSubregInputs(*Def, ExtractSubregInputReg);
+  if (!TII->getExtractSubregInputs(*Def, DefIdx, ExtractSubregInputReg))
+    return false;
 
   // Bails if we have to compose sub registers.
   // Likewise, if v0.subreg != 0, we would have to compose v0.subreg with sub0.
@@ -1428,9 +1402,9 @@ bool ValueTracker::getNextSourceImpl(unsigned &SrcReg, unsigned &SrcSubReg) {
     return false;
   if (Def->isRegSequence() || Def->isRegSequenceLike())
     return getNextSourceFromRegSequence(SrcReg, SrcSubReg);
-  if (Def->isInsertSubreg())
+  if (Def->isInsertSubreg() || Def->isInsertSubregLike())
     return getNextSourceFromInsertSubreg(SrcReg, SrcSubReg);
-  if (Def->isExtractSubreg())
+  if (Def->isExtractSubreg() || Def->isExtractSubregLike())
     return getNextSourceFromExtractSubreg(SrcReg, SrcSubReg);
   if (Def->isSubregToReg())
     return getNextSourceFromSubregToReg(SrcReg, SrcSubReg);