Skip to content

Commit 5619e1b

Browse files
authored
Fix non-determinism in debuginfo (#68332)
Assignment tracking iterates over a SmallSet when adding metadata, which eventually results in debug metadata being added to the module in non-deterministic order. As reported in #63921, we saw some cases where DWARF DebugLoc entries could have their order reversed, even though there was no functional difference. This patch replaces the `SmallSet` with a `SmallVector`, and adds the required `DenseMapInfo` specialization to make the ordering deterministic. Fixes #63921
1 parent 28e8ade commit 5619e1b

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

llvm/include/llvm/IR/DebugInfo.h

+28-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#ifndef LLVM_IR_DEBUGINFO_H
1717
#define LLVM_IR_DEBUGINFO_H
1818

19+
#include "llvm/ADT/DenseMapInfo.h"
1920
#include "llvm/ADT/STLExtras.h"
21+
#include "llvm/ADT/SetVector.h"
2022
#include "llvm/ADT/SmallPtrSet.h"
2123
#include "llvm/ADT/SmallSet.h"
2224
#include "llvm/ADT/SmallVector.h"
@@ -259,11 +261,35 @@ struct VarRecord {
259261
}
260262
};
261263

264+
} // namespace at
265+
266+
template <> struct DenseMapInfo<at::VarRecord> {
267+
static inline at::VarRecord getEmptyKey() {
268+
return at::VarRecord(DenseMapInfo<DILocalVariable *>::getEmptyKey(),
269+
DenseMapInfo<DILocation *>::getEmptyKey());
270+
}
271+
272+
static inline at::VarRecord getTombstoneKey() {
273+
return at::VarRecord(DenseMapInfo<DILocalVariable *>::getTombstoneKey(),
274+
DenseMapInfo<DILocation *>::getTombstoneKey());
275+
}
276+
277+
static unsigned getHashValue(const at::VarRecord &Var) {
278+
return hash_combine(Var.Var, Var.DL);
279+
}
280+
281+
static bool isEqual(const at::VarRecord &A, const at::VarRecord &B) {
282+
return A == B;
283+
}
284+
};
285+
286+
namespace at {
262287
/// Map of backing storage to a set of variables that are stored to it.
263288
/// TODO: Backing storage shouldn't be limited to allocas only. Some local
264289
/// variables have their storage allocated by the calling function (addresses
265290
/// passed in with sret & byval parameters).
266-
using StorageToVarsMap = DenseMap<const AllocaInst *, SmallSet<VarRecord, 2>>;
291+
using StorageToVarsMap =
292+
DenseMap<const AllocaInst *, SmallSetVector<VarRecord, 2>>;
267293

268294
/// Track assignments to \p Vars between \p Start and \p End.
269295

@@ -314,6 +340,7 @@ class AssignmentTrackingPass : public PassInfoMixin<AssignmentTrackingPass> {
314340

315341
/// Return true if assignment tracking is enabled for module \p M.
316342
bool isAssignmentTrackingEnabled(const Module &M);
343+
317344
} // end namespace llvm
318345

319346
#endif // LLVM_IR_DEBUGINFO_H

0 commit comments

Comments
 (0)