1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[Debug-info][InstrRef] Avoid an unnecessary map ordering

We keep a record of substitutions between debug value numbers post-isel,
however we never actually look them up until the end of compilation. As a
result, there's nothing gained by the collection being a std::map. This
patch downgrades it to being a vector, that's then sorted at the end of
compilation in LiveDebugValues.

Differential Revision: https://reviews.llvm.org/D105029
This commit is contained in:
Jeremy Morse 2021-07-09 15:32:30 +01:00
parent 2e5d9743cb
commit fe3b28eeca
4 changed files with 61 additions and 29 deletions

View File

@ -451,24 +451,37 @@ public:
/// Pair of instruction number and operand number.
using DebugInstrOperandPair = std::pair<unsigned, unsigned>;
/// Replacement definition for a debug instruction reference. Made up of an
/// instruction / operand pair, and a qualifying subregister indicating what
/// bits in the operand make up the substitution. For example, a debug user
/// Replacement definition for a debug instruction reference. Made up of a
/// source instruction / operand pair, destination pair, and a qualifying
/// subregister indicating what bits in the operand make up the substitution.
// For example, a debug user
/// of %1:
/// %0:gr32 = someinst, debug-instr-number 2
/// %1:gr16 = %0.some_16_bit_subreg
/// Would receive the substitution {{2, 0}, $subreg}, where $subreg is the
/// subregister number for some_16_bit_subreg.
struct DebugSubstitution {
/// %0:gr32 = someinst, debug-instr-number 1
/// %1:gr16 = %0.some_16_bit_subreg, debug-instr-number 2
/// Would receive the substitution {{2, 0}, {1, 0}, $subreg}, where $subreg is
/// the subregister number for some_16_bit_subreg.
class DebugSubstitution {
public:
DebugInstrOperandPair Src; ///< Source instruction / operand pair.
DebugInstrOperandPair Dest; ///< Replacement instruction / operand pair.
unsigned Subreg; ///< Qualifier for which part of Dest is read.
DebugSubstitution(const DebugInstrOperandPair &Src,
const DebugInstrOperandPair &Dest, unsigned Subreg)
: Src(Src), Dest(Dest), Subreg(Subreg) {}
/// Order only by source instruction / operand pair: there should never
/// be duplicate entries for the same source in any collection.
bool operator<(const DebugSubstitution &Other) const {
return Src < Other.Src;
}
};
/// Substitution map: from one <inst,operand> pair identifying a value,
/// to a DebugSubstitution identifying another. Used to record changes in
/// where a value is defined, so that debug variable locations can find it
/// later.
std::map<DebugInstrOperandPair, DebugSubstitution> DebugValueSubstitutions;
/// Debug value substitutions: a collection of DebugSubstitution objects,
/// recording changes in where a value is defined. For example, when one
/// instruction is substituted for another. Keeping a record allows recovery
/// of variable locations after compilation finishes.
SmallVector<DebugSubstitution, 8> DebugValueSubstitutions;
/// Location of a PHI instruction that is also a debug-info variable value,
/// for the duration of register allocation. Loaded by the PHI-elimination

View File

@ -1827,16 +1827,22 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
// Various optimizations may have happened to the value during codegen,
// recorded in the value substitution table. Apply any substitutions to
// the instruction / operand number in this DBG_INSTR_REF.
auto Sub = MF.DebugValueSubstitutions.find(std::make_pair(InstNo, OpNo));
// Collect any subregister extractions performed during optimization.
// the instruction / operand number in this DBG_INSTR_REF, and collect
// any subregister extractions performed during optimization.
// Create dummy substitution with Src set, for lookup.
auto SoughtSub =
MachineFunction::DebugSubstitution({InstNo, OpNo}, {0, 0}, 0);
SmallVector<unsigned, 4> SeenSubregs;
while (Sub != MF.DebugValueSubstitutions.end()) {
std::tie(InstNo, OpNo) = Sub->second.Dest;
unsigned Subreg = Sub->second.Subreg;
if (Subreg)
auto LowerBoundIt = llvm::lower_bound(MF.DebugValueSubstitutions, SoughtSub);
while (LowerBoundIt != MF.DebugValueSubstitutions.end() &&
LowerBoundIt->Src == SoughtSub.Src) {
std::tie(InstNo, OpNo) = LowerBoundIt->Dest;
SoughtSub.Src = LowerBoundIt->Dest;
if (unsigned Subreg = LowerBoundIt->Subreg)
SeenSubregs.push_back(Subreg);
Sub = MF.DebugValueSubstitutions.find(std::make_pair(InstNo, OpNo));
LowerBoundIt = llvm::lower_bound(MF.DebugValueSubstitutions, SoughtSub);
}
// Default machine value number is <None> -- if no instruction defines
@ -3542,6 +3548,21 @@ void InstrRefBasedLDV::initialSetup(MachineFunction &MF) {
BBNumToRPO[MBB->getNumber()] = RPONumber;
++RPONumber;
}
// Order value substitutions by their "source" operand pair, for quick lookup.
llvm::sort(MF.DebugValueSubstitutions);
#ifdef EXPENSIVE_CHECKS
// As an expensive check, test whether there are any duplicate substitution
// sources in the collection.
if (MF.DebugValueSubstitutions.size() > 2) {
for (auto It = MF.DebugValueSubstitutions.begin();
It != std::prev(MF.DebugValueSubstitutions.end()); ++It) {
assert(It->Src != std::next(It)->Src && "Duplicate variable location "
"substitution seen");
}
}
#endif
}
/// Calculate the liveness information for the given machine function and

View File

@ -225,12 +225,12 @@ void MIRPrinter::print(const MachineFunction &MF) {
convertStackObjects(YamlMF, MF, MST);
convertCallSiteObjects(YamlMF, MF, MST);
for (const auto &Sub : MF.DebugValueSubstitutions) {
auto &SubSrc = Sub.first;
const MachineFunction::DebugSubstitution &SubDest = Sub.second;
const auto &SubSrc = Sub.Src;
const auto &SubDest = Sub.Dest;
YamlMF.DebugValueSubstitutions.push_back({SubSrc.first, SubSrc.second,
SubDest.Dest.first,
SubDest.Dest.second,
SubDest.Subreg});
SubDest.first,
SubDest.second,
Sub.Subreg});
}
if (const auto *ConstantPool = MF.getConstantPool())
convert(YamlMF, *ConstantPool);

View File

@ -973,9 +973,7 @@ void MachineFunction::makeDebugValueSubstitution(DebugInstrOperandPair A,
unsigned Subreg) {
// Catch any accidental self-loops.
assert(A.first != B.first);
auto Result = DebugValueSubstitutions.insert({A, {B, Subreg}});
(void)Result;
assert(Result.second && "Substitution for an already substituted value?");
DebugValueSubstitutions.push_back({A, B, Subreg});
}
void MachineFunction::substituteDebugValuesForInst(const MachineInstr &Old,