diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 |
commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/CodeGen/MachineSink.cpp | |
parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) |
Notes
Diffstat (limited to 'lib/CodeGen/MachineSink.cpp')
-rw-r--r-- | lib/CodeGen/MachineSink.cpp | 92 |
1 files changed, 58 insertions, 34 deletions
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index 1fd40f757351..cdc597db6401 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -513,25 +513,6 @@ bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI, return true; } -/// collectDebgValues - Scan instructions following MI and collect any -/// matching DBG_VALUEs. -static void collectDebugValues(MachineInstr &MI, - SmallVectorImpl<MachineInstr *> &DbgValues) { - DbgValues.clear(); - if (!MI.getOperand(0).isReg()) - return; - - MachineBasicBlock::iterator DI = MI; ++DI; - for (MachineBasicBlock::iterator DE = MI.getParent()->end(); - DI != DE; ++DI) { - if (!DI->isDebugValue()) - return; - if (DI->getOperand(0).isReg() && - DI->getOperand(0).getReg() == MI.getOperand(0).getReg()) - DbgValues.push_back(&*DI); - } -} - /// isProfitableToSinkTo - Return true if it is profitable to sink MI. bool MachineSinking::isProfitableToSinkTo(unsigned Reg, MachineInstr &MI, MachineBasicBlock *MBB, @@ -735,9 +716,12 @@ static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, !PredBB->getTerminator()->getMetadata(LLVMContext::MD_make_implicit)) return false; - unsigned BaseReg; + MachineOperand *BaseOp; int64_t Offset; - if (!TII->getMemOpBaseRegImmOfs(MI, BaseReg, Offset, TRI)) + if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, TRI)) + return false; + + if (!BaseOp->isReg()) return false; if (!(MI.mayLoad() && !MI.isPredicable())) @@ -750,15 +734,21 @@ static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, return MBP.LHS.isReg() && MBP.RHS.isImm() && MBP.RHS.getImm() == 0 && (MBP.Predicate == MachineBranchPredicate::PRED_NE || MBP.Predicate == MachineBranchPredicate::PRED_EQ) && - MBP.LHS.getReg() == BaseReg; + MBP.LHS.getReg() == BaseOp->getReg(); } -/// Sink an instruction and its associated debug instructions. +/// Sink an instruction and its associated debug instructions. If the debug +/// instructions to be sunk are already known, they can be provided in DbgVals. static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo, - MachineBasicBlock::iterator InsertPos) { - // Collect matching debug values. + MachineBasicBlock::iterator InsertPos, + SmallVectorImpl<MachineInstr *> *DbgVals = nullptr) { + // If debug values are provided use those, otherwise call collectDebugValues. SmallVector<MachineInstr *, 2> DbgValuesToSink; - collectDebugValues(MI, DbgValuesToSink); + if (DbgVals) + DbgValuesToSink.insert(DbgValuesToSink.begin(), + DbgVals->begin(), DbgVals->end()); + else + MI.collectDebugValues(DbgValuesToSink); // If we cannot find a location to use (merge with), then we erase the debug // location to prevent debug-info driven tools from potentially reporting @@ -970,6 +960,9 @@ private: /// Track which register units have been modified and used. LiveRegUnits ModifiedRegUnits, UsedRegUnits; + /// Track DBG_VALUEs of (unmodified) register units. + DenseMap<unsigned, TinyPtrVector<MachineInstr*>> SeenDbgInstrs; + /// Sink Copy instructions unused in the same block close to their uses in /// successors. bool tryToSinkCopy(MachineBasicBlock &BB, MachineFunction &MF, @@ -1056,8 +1049,11 @@ static void clearKillFlags(MachineInstr *MI, MachineBasicBlock &CurBB, static void updateLiveIn(MachineInstr *MI, MachineBasicBlock *SuccBB, SmallVectorImpl<unsigned> &UsedOpsInCopy, SmallVectorImpl<unsigned> &DefedRegsInCopy) { - for (auto DefReg : DefedRegsInCopy) - SuccBB->removeLiveIn(DefReg); + MachineFunction &MF = *SuccBB->getParent(); + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + for (unsigned DefReg : DefedRegsInCopy) + for (MCSubRegIterator S(DefReg, TRI, true); S.isValid(); ++S) + SuccBB->removeLiveIn(*S); for (auto U : UsedOpsInCopy) { unsigned Reg = MI->getOperand(U).getReg(); if (!SuccBB->isLiveIn(Reg)) @@ -1121,11 +1117,34 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, // block and the current instruction. ModifiedRegUnits.clear(); UsedRegUnits.clear(); + SeenDbgInstrs.clear(); for (auto I = CurBB.rbegin(), E = CurBB.rend(); I != E;) { MachineInstr *MI = &*I; ++I; + // Track the operand index for use in Copy. + SmallVector<unsigned, 2> UsedOpsInCopy; + // Track the register number defed in Copy. + SmallVector<unsigned, 2> DefedRegsInCopy; + + // We must sink this DBG_VALUE if its operand is sunk. To avoid searching + // for DBG_VALUEs later, record them when they're encountered. + if (MI->isDebugValue()) { + auto &MO = MI->getOperand(0); + if (MO.isReg() && TRI->isPhysicalRegister(MO.getReg())) { + // Bail if we can already tell the sink would be rejected, rather + // than needlessly accumulating lots of DBG_VALUEs. + if (hasRegisterDependency(MI, UsedOpsInCopy, DefedRegsInCopy, + ModifiedRegUnits, UsedRegUnits)) + continue; + + // Record debug use of this register. + SeenDbgInstrs[MO.getReg()].push_back(MI); + } + continue; + } + if (MI->isDebugInstr()) continue; @@ -1139,11 +1158,6 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, continue; } - // Track the operand index for use in Copy. - SmallVector<unsigned, 2> UsedOpsInCopy; - // Track the register number defed in Copy. - SmallVector<unsigned, 2> DefedRegsInCopy; - // Don't sink the COPY if it would violate a register dependency. if (hasRegisterDependency(MI, UsedOpsInCopy, DefedRegsInCopy, ModifiedRegUnits, UsedRegUnits)) { @@ -1165,11 +1179,21 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, assert((SuccBB->pred_size() == 1 && *SuccBB->pred_begin() == &CurBB) && "Unexpected predecessor"); + // Collect DBG_VALUEs that must sink with this copy. + SmallVector<MachineInstr *, 4> DbgValsToSink; + for (auto &MO : MI->operands()) { + if (!MO.isReg() || !MO.isDef()) + continue; + unsigned reg = MO.getReg(); + for (auto *MI : SeenDbgInstrs.lookup(reg)) + DbgValsToSink.push_back(MI); + } + // Clear the kill flag if SrcReg is killed between MI and the end of the // block. clearKillFlags(MI, CurBB, UsedOpsInCopy, UsedRegUnits, TRI); MachineBasicBlock::iterator InsertPos = SuccBB->getFirstNonPHI(); - performSink(*MI, *SuccBB, InsertPos); + performSink(*MI, *SuccBB, InsertPos, &DbgValsToSink); updateLiveIn(MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy); Changed = true; |