[llvm] API for encoding/decoding DWARF discriminators.
Summary:
Added a pair of APIs for encoding/decoding the 3 components of a DWARF discriminator described in http://lists.llvm.org/pipermail/llvm-dev/2016-October/106532.html: the base discriminator, the duplication factor (useful in profile-guided optimization) and the copy index (used to identify copies of code in cases like loop unrolling)
The encoding packs 3 unsigned values in 32 bits. This CL addresses 2 issues:
- communicates overflow back to the user
- supports encoding all 3 components together. Current APIs assume a sequencing of events. For example, creating a new discriminator based on an existing one by changing the base discriminator was not supported.
Reviewers: davidxl, danielcdh, wmi, dblaikie
Reviewed By: dblaikie
Subscribers: zzheng, dmgreen, aprantl, JDevlieghere, llvm-commits
Differential Revision: https://reviews.llvm.org/D55681
llvm-svn: 349973
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 3b702ce..92f3f21 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -20,6 +20,8 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
+#include <numeric>
+
using namespace llvm;
DILocation::DILocation(LLVMContext &C, StorageType Storage, unsigned Line,
@@ -113,6 +115,47 @@
return DILocation::get(Result->getContext(), 0, 0, S, L);
}
+Optional<unsigned> DILocation::encodeDiscriminator(unsigned BD, unsigned DF, unsigned CI) {
+ SmallVector<unsigned, 3> Components = {BD, DF, CI};
+ uint64_t RemainingWork = 0U;
+ // We use RemainingWork to figure out if we have no remaining components to
+ // encode. For example: if BD != 0 but DF == 0 && CI == 0, we don't need to
+ // encode anything for the latter 2.
+ // Since any of the input components is at most 32 bits, their sum will be
+ // less than 34 bits, and thus RemainingWork won't overflow.
+ RemainingWork = std::accumulate(Components.begin(), Components.end(), RemainingWork);
+
+ int I = 0;
+ unsigned Ret = 0;
+ unsigned NextBitInsertionIndex = 0;
+ while (RemainingWork > 0) {
+ unsigned C = Components[I++];
+ RemainingWork -= C;
+ unsigned EC = encodeComponent(C);
+ Ret |= (EC << NextBitInsertionIndex);
+ NextBitInsertionIndex += encodingBits(C);
+ }
+
+ // Encoding may be unsuccessful because of overflow. We determine success by
+ // checking equivalence of components before & after encoding. Alternatively,
+ // we could determine Success during encoding, but the current alternative is
+ // simpler.
+ unsigned TBD, TDF, TCI = 0;
+ decodeDiscriminator(Ret, TBD, TDF, TCI);
+ if (TBD == BD && TDF == DF && TCI == CI)
+ return Ret;
+ return None;
+}
+
+void DILocation::decodeDiscriminator(unsigned D, unsigned &BD, unsigned &DF,
+ unsigned &CI) {
+ BD = getUnsignedFromPrefixEncoding(D);
+ DF = getUnsignedFromPrefixEncoding(getNextComponentInDiscriminator(D));
+ CI = getUnsignedFromPrefixEncoding(
+ getNextComponentInDiscriminator(getNextComponentInDiscriminator(D)));
+}
+
+
DINode::DIFlags DINode::getFlag(StringRef Flag) {
return StringSwitch<DIFlags>(Flag)
#define HANDLE_DI_FLAG(ID, NAME) .Case("DIFlag" #NAME, Flag##NAME)