aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineFunction.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse@sony.com>2020-10-15 11:20:29 +0100
committerJeremy Morse <jeremy.morse@sony.com>2020-10-15 11:30:14 +0100
commitc521e44defb53d38a46f39e29870c628f25d124a (patch)
treeb3f3aa028b69b4ea1841a8d900cd790f225f2361 /llvm/lib/CodeGen/MachineFunction.cpp
parentfadd152317598aa71538948613ce24b094c5c7c2 (diff)
downloadllvm-c521e44defb53d38a46f39e29870c628f25d124a.zip
llvm-c521e44defb53d38a46f39e29870c628f25d124a.tar.gz
llvm-c521e44defb53d38a46f39e29870c628f25d124a.tar.bz2
[DebugInstrRef] Support recording of instruction reference substitutions
Add a table recording "substitutions" between pairs of <instruction, operand> numbers, from old pairs to new pairs. Post-isel optimizations are able to record the outcome of an optimization in this way. For example, if there were a divide instruction that generated the quotient and remainder, and it were replaced by one that only generated the quotient: $rax, $rcx = DIV-AND-REMAINDER $rdx, $rsi, debug-instr-num 1 DBG_INSTR_REF 1, 0 DBG_INSTR_REF 1, 1 Became: $rax = DIV $rdx, $rsi, debug-instr-num 2 DBG_INSTR_REF 1, 0 DBG_INSTR_REF 1, 1 We could enter a substitution from <1, 0> to <2, 0>, and no substitution for <1, 1> as it's no longer generated. This approach means that if an instruction or value is deleted once we've left SSA form, all variables that used the value implicitly become "optimized out", something that isn't true of the current DBG_VALUE approach. Differential Revision: https://reviews.llvm.org/D85749
Diffstat (limited to 'llvm/lib/CodeGen/MachineFunction.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index f9fc775..60af658 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -947,6 +947,38 @@ void MachineFunction::setDebugInstrNumberingCount(unsigned Num) {
DebugInstrNumberingCount = Num;
}
+void MachineFunction::makeDebugValueSubstitution(DebugInstrOperandPair A,
+ DebugInstrOperandPair B) {
+ auto Result = DebugValueSubstitutions.insert(std::make_pair(A, B));
+ (void)Result;
+ assert(Result.second && "Substitution for an already substituted value?");
+}
+
+void MachineFunction::substituteDebugValuesForInst(const MachineInstr &Old,
+ MachineInstr &New) {
+ // If the Old instruction wasn't tracked at all, there is no work to do.
+ unsigned OldInstrNum = Old.peekDebugInstrNum();
+ if (!OldInstrNum)
+ return;
+
+ // Iterate over all operands looking for defs to create substitutions for.
+ // Avoid creating new instr numbers unless we create a new substitution.
+ // While this has no functional effect, it risks confusing someone reading
+ // MIR output.
+ for (unsigned int I = 0; I < Old.getNumOperands(); ++I) {
+ const auto &OldMO = Old.getOperand(I);
+ auto &NewMO = Old.getOperand(I);
+
+ if (!OldMO.isReg() || !OldMO.isDef())
+ continue;
+ assert(NewMO.isDef());
+
+ unsigned NewInstrNum = New.getDebugInstrNum();
+ makeDebugValueSubstitution(std::make_pair(OldInstrNum, I),
+ std::make_pair(NewInstrNum, I));
+ }
+}
+
/// \}
//===----------------------------------------------------------------------===//