summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2016-09-28 17:51:14 +0000
committerAdrian Prantl <aprantl@apple.com>2016-09-28 17:51:14 +0000
commit7f5866c227a716cb063b268b6f0edaccb1029605 (patch)
treef4b38040c7bf4ca7a2327988945b6954477432b0 /llvm/lib
parentd4d9dc82529d5788fdf6a18f413584e3aa0b3fd4 (diff)
downloadbcm5719-llvm-7f5866c227a716cb063b268b6f0edaccb1029605.tar.gz
bcm5719-llvm-7f5866c227a716cb063b268b6f0edaccb1029605.zip
Teach LiveDebugValues about lexical scopes.
This addresses PR26055 LiveDebugValues is very slow. Contrary to the old LiveDebugVariables pass LiveDebugValues currently doesn't look at the lexical scopes before inserting a DBG_VALUE intrinsic. This means that we often propagate DBG_VALUEs much further down than necessary. This is especially noticeable in large C++ functions with many inlined method calls that all use the same "this"-pointer. For example, in the following code it makes no sense to propagate the inlined variable a from the first inlined call to f() into any of the subsequent basic blocks, because the variable will always be out of scope: void sink(int a); void __attribute((always_inline)) f(int a) { sink(a); } void foo(int i) { f(i); if (i) f(i); f(i); } This patch reuses the LexicalScopes infrastructure we have for LiveDebugVariables to take this into account. The effect on compile time and memory consumption is quite noticeable: I tested a benchmark that is a large C++ source with an enormous amount of inlined "this"-pointers that would previously eat >24GiB (most of them for DBG_VALUE intrinsics) and whose compile time was dominated by LiveDebugValues. With this patch applied the memory consumption is 1GiB and 1.7% of the time is spent in LiveDebugValues. https://reviews.llvm.org/D24994 Thanks to Daniel Berlin and Keith Walker for reviewing! llvm-svn: 282611
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues.cpp51
1 files changed, 43 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp
index 7d9461214ef..c945376560f 100644
--- a/llvm/lib/CodeGen/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/UniqueVector.h"
+#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -60,6 +61,26 @@ class LiveDebugValues : public MachineFunctionPass {
private:
const TargetRegisterInfo *TRI;
const TargetInstrInfo *TII;
+ LexicalScopes LS;
+
+ /// Keeps track of lexical scopes associated with a user value's source
+ /// location.
+ class UserValueScopes {
+ DebugLoc DL;
+ LexicalScopes &LS;
+ SmallPtrSet<const MachineBasicBlock *, 4> LBlocks;
+
+ public:
+ UserValueScopes(DebugLoc D, LexicalScopes &L) : DL(std::move(D)), LS(L) {}
+
+ /// Return true if current scope dominates at least one machine
+ /// instruction in a given machine basic block.
+ bool dominates(MachineBasicBlock *MBB) {
+ if (LBlocks.empty())
+ LS.getMachineBasicBlocks(DL, LBlocks);
+ return LBlocks.count(MBB) != 0 || LS.dominates(DL, MBB);
+ }
+ };
/// Based on std::pair so it can be used as an index into a DenseMap.
typedef std::pair<const DILocalVariable *, const DILocation *>
@@ -83,7 +104,7 @@ private:
struct VarLoc {
const DebugVariable Var;
const MachineInstr &MI; ///< Only used for cloning a new DBG_VALUE.
-
+ mutable UserValueScopes UVS;
enum { InvalidKind = 0, RegisterKind } Kind;
/// The value location. Stored separately to avoid repeatedly
@@ -96,9 +117,9 @@ private:
uint64_t Hash;
} Loc;
- VarLoc(const MachineInstr &MI)
+ VarLoc(const MachineInstr &MI, LexicalScopes &LS)
: Var(MI.getDebugVariable(), MI.getDebugLoc()->getInlinedAt()), MI(MI),
- Kind(InvalidKind) {
+ UVS(MI.getDebugLoc(), LS), Kind(InvalidKind) {
static_assert((sizeof(Loc) == sizeof(uint64_t)),
"hash does not cover all members of Loc");
assert(MI.isDebugValue() && "not a DBG_VALUE");
@@ -125,6 +146,10 @@ private:
return 0;
}
+ /// Determine whether the lexical scope of this value's debug location
+ /// dominates MBB.
+ bool dominates(MachineBasicBlock &MBB) const { return UVS.dominates(&MBB); }
+
void dump() const { MI.dump(); }
bool operator==(const VarLoc &Other) const {
@@ -229,6 +254,7 @@ public:
/// Calculate the liveness information for the given machine function.
bool runOnMachineFunction(MachineFunction &MF) override;
};
+
} // namespace
//===----------------------------------------------------------------------===//
@@ -295,7 +321,7 @@ void LiveDebugValues::transferDebugValue(const MachineInstr &MI,
// Add the VarLoc to OpenRanges from this DBG_VALUE.
// TODO: Currently handles DBG_VALUE which has only reg as location.
if (isDbgValueDescribedByReg(MI)) {
- VarLoc VL(MI);
+ VarLoc VL(MI, LS);
unsigned ID = VarLocIDs.insert(VL);
OpenRanges.insert(ID, VL.Var);
}
@@ -399,6 +425,13 @@ bool LiveDebugValues::join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs,
NumVisited++;
}
+ // Filter out DBG_VALUES that are out of scope.
+ VarLocSet KillSet;
+ for (auto ID : InLocsT)
+ if (!VarLocIDs[ID].dominates(MBB))
+ KillSet.set(ID);
+ InLocsT.intersectWithComplement(KillSet);
+
// As we are processing blocks in reverse post-order we
// should have processed at least one predecessor, unless it
// is the entry block which has no predecessor.
@@ -520,12 +553,14 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
}
bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
+ if (!MF.getFunction()->getSubprogram())
+ // LiveDebugValues will already have removed all DBG_VALUEs.
+ return false;
+
TRI = MF.getSubtarget().getRegisterInfo();
TII = MF.getSubtarget().getInstrInfo();
+ LS.initialize(MF);
- bool Changed = false;
-
- Changed |= ExtendRanges(MF);
-
+ bool Changed = ExtendRanges(MF);
return Changed;
}
OpenPOWER on IntegriCloud