diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-01-01 10:05:26 +0000 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-01-01 10:05:26 +0000 |
commit | bc9986e9adb057c5824398c381204db04214ffeb (patch) | |
tree | bc3479316342a6489d5a42ae4469690fe41c54fc /llvm/include | |
parent | e00606a1b28cc3eacf14b779e6725eee8a6a18da (diff) | |
download | bcm5719-llvm-bc9986e9adb057c5824398c381204db04214ffeb.tar.gz bcm5719-llvm-bc9986e9adb057c5824398c381204db04214ffeb.zip |
Reapply "[BDCE][DemandedBits] Detect dead uses of undead instructions"
This (mostly) fixes https://bugs.llvm.org/show_bug.cgi?id=39771.
BDCE currently detects instructions that don't have any demanded bits
and replaces their uses with zero. However, if an instruction has
multiple uses, then some of the uses may be dead (have no demanded bits)
even though the instruction itself is still live. This patch extends
DemandedBits/BDCE to detect such uses and replace them with zero.
While this will not immediately render any instructions dead, it may
lead to simplifications (in the motivating case, by converting a rotate
into a simple shift), break dependencies, etc.
The implementation tries to strike a balance between analysis power and
complexity/memory usage. Originally I wanted to track demanded bits on
a per-use level, but ultimately we're only really interested in whether
a use is entirely dead or not. I'm using an extra set to track which uses
are dead. However, as initially all uses are dead, I'm not storing uses
those user is also dead. This case is checked separately instead.
The previous attempt to land this lead to miscompiles, because cases
where uses were initially dead but were later found to be live during
further analysis were not always correctly removed from the DeadUses
set. This is fixed now and the added test case demanstrates such an
instance.
Differential Revision: https://reviews.llvm.org/D55563
llvm-svn: 350188
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm/Analysis/DemandedBits.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/DemandedBits.h b/llvm/include/llvm/Analysis/DemandedBits.h index f751d2edcff..f16d12552f7 100644 --- a/llvm/include/llvm/Analysis/DemandedBits.h +++ b/llvm/include/llvm/Analysis/DemandedBits.h @@ -57,6 +57,9 @@ public: /// Return true if, during analysis, I could not be reached. bool isInstructionDead(Instruction *I); + /// Return whether this use is dead by means of not having any demanded bits. + bool isUseDead(Use *U); + void print(raw_ostream &OS); private: @@ -75,6 +78,9 @@ private: // The set of visited instructions (non-integer-typed only). SmallPtrSet<Instruction*, 32> Visited; DenseMap<Instruction *, APInt> AliveBits; + // Uses with no demanded bits. If the user also has no demanded bits, the use + // might not be stored explicitly in this map, to save memory during analysis. + SmallPtrSet<Use *, 16> DeadUses; }; class DemandedBitsWrapperPass : public FunctionPass { |