Use a SparseSet in LiveRegUnits.

Some clients may add block live ins and may track liveness over a
large scope. This guarantees an efficient implementation in all cases
with no memory allocation/deallocation, independent of the number of
target registers. It could be slightly less convenient but is fine in
the expected case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192622 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick
2013-10-14 20:45:17 +00:00
parent eb3b9f8ed9
commit 7c489ab365
2 changed files with 31 additions and 26 deletions

View File

@ -17,9 +17,9 @@
#ifndef LLVM_CODEGEN_LIVEREGUNITS_H #ifndef LLVM_CODEGEN_LIVEREGUNITS_H
#define LLVM_CODEGEN_LIVEREGUNITS_H #define LLVM_CODEGEN_LIVEREGUNITS_H
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SparseSet.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
#include <cassert> #include <cassert>
namespace llvm { namespace llvm {
@ -29,17 +29,23 @@ class MachineInstr;
/// A set of live register units with functions to track liveness when walking /// A set of live register units with functions to track liveness when walking
/// backward/forward through a basic block. /// backward/forward through a basic block.
class LiveRegUnits { class LiveRegUnits {
SmallSet<unsigned, 32> LiveUnits; SparseSet<unsigned> LiveUnits;
LiveRegUnits(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
LiveRegUnits &operator=(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
public: public:
/// \brief Constructs a new empty LiveRegUnits set. /// \brief Constructs a new empty LiveRegUnits set.
LiveRegUnits() {} LiveRegUnits() {}
/// \brief Constructs a new LiveRegUnits set by copying @p Other. void init(const TargetRegisterInfo *TRI) {
LiveRegUnits(const LiveRegUnits &Other) LiveUnits.clear();
: LiveUnits(Other.LiveUnits) { LiveUnits.setUniverse(TRI->getNumRegs());
} }
void clear() { LiveUnits.clear(); }
bool empty() const { return LiveUnits.empty(); }
/// \brief Adds a register to the set. /// \brief Adds a register to the set.
void addReg(unsigned Reg, const MCRegisterInfo &MCRI) { void addReg(unsigned Reg, const MCRegisterInfo &MCRI) {
for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
@ -73,7 +79,7 @@ public:
/// instruction(bundle): Remove killed-uses, add defs. /// instruction(bundle): Remove killed-uses, add defs.
void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI); void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
/// Adds all registers in the live-in list of block @p BB. /// \brief Adds all registers in the live-in list of block @p BB.
void addLiveIns(const MachineBasicBlock &BB, const MCRegisterInfo &MCRI); void addLiveIns(const MachineBasicBlock &BB, const MCRegisterInfo &MCRI);
}; };

View File

@ -162,6 +162,9 @@ namespace {
const MachineBranchProbabilityInfo *MBPI; const MachineBranchProbabilityInfo *MBPI;
MachineRegisterInfo *MRI; MachineRegisterInfo *MRI;
LiveRegUnits Redefs;
LiveRegUnits DontKill;
bool PreRegAlloc; bool PreRegAlloc;
bool MadeChange; bool MadeChange;
int FnNum; int FnNum;
@ -202,12 +205,9 @@ namespace {
void PredicateBlock(BBInfo &BBI, void PredicateBlock(BBInfo &BBI,
MachineBasicBlock::iterator E, MachineBasicBlock::iterator E,
SmallVectorImpl<MachineOperand> &Cond, SmallVectorImpl<MachineOperand> &Cond,
LiveRegUnits &Redefs,
SmallSet<unsigned, 4> *LaterRedefs = 0); SmallSet<unsigned, 4> *LaterRedefs = 0);
void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
SmallVectorImpl<MachineOperand> &Cond, SmallVectorImpl<MachineOperand> &Cond,
LiveRegUnits &Redefs,
const LiveRegUnits *DontKill = 0,
bool IgnoreBr = false); bool IgnoreBr = false);
void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges = true); void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges = true);
@ -1048,27 +1048,27 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
// Initialize liveins to the first BB. These are potentiall redefined by // Initialize liveins to the first BB. These are potentiall redefined by
// predicated instructions. // predicated instructions.
LiveRegUnits Redefs; Redefs.init(TRI);
Redefs.addLiveIns(*(CvtBBI->BB), *TRI); Redefs.addLiveIns(*(CvtBBI->BB), *TRI);
Redefs.addLiveIns(*(NextBBI->BB), *TRI); Redefs.addLiveIns(*(NextBBI->BB), *TRI);
// Compute a set of registers which must not be killed by instructions in // Compute a set of registers which must not be killed by instructions in
// BB1: This is everything live-in to BB2. // BB1: This is everything live-in to BB2.
LiveRegUnits DontKill; DontKill.init(TRI);
DontKill.addLiveIns(*(NextBBI->BB), *TRI); DontKill.addLiveIns(*(NextBBI->BB), *TRI);
if (CvtBBI->BB->pred_size() > 1) { if (CvtBBI->BB->pred_size() > 1) {
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
// Copy instructions in the true block, predicate them, and add them to // Copy instructions in the true block, predicate them, and add them to
// the entry block. // the entry block.
CopyAndPredicateBlock(BBI, *CvtBBI, Cond, Redefs, &DontKill); CopyAndPredicateBlock(BBI, *CvtBBI, Cond);
// RemoveExtraEdges won't work if the block has an unanalyzable branch, so // RemoveExtraEdges won't work if the block has an unanalyzable branch, so
// explicitly remove CvtBBI as a successor. // explicitly remove CvtBBI as a successor.
BBI.BB->removeSuccessor(CvtBBI->BB); BBI.BB->removeSuccessor(CvtBBI->BB);
} else { } else {
RemoveKills(CvtBBI->BB->begin(), CvtBBI->BB->end(), DontKill, *TRI); RemoveKills(CvtBBI->BB->begin(), CvtBBI->BB->end(), DontKill, *TRI);
PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond, Redefs); PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond);
// Merge converted block into entry block. // Merge converted block into entry block.
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
@ -1153,16 +1153,18 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
// Initialize liveins to the first BB. These are potentially redefined by // Initialize liveins to the first BB. These are potentially redefined by
// predicated instructions. // predicated instructions.
LiveRegUnits Redefs; Redefs.init(TRI);
Redefs.addLiveIns(*(CvtBBI->BB), *TRI); Redefs.addLiveIns(*(CvtBBI->BB), *TRI);
Redefs.addLiveIns(*(NextBBI->BB), *TRI); Redefs.addLiveIns(*(NextBBI->BB), *TRI);
DontKill.clear();
bool HasEarlyExit = CvtBBI->FalseBB != NULL; bool HasEarlyExit = CvtBBI->FalseBB != NULL;
if (CvtBBI->BB->pred_size() > 1) { if (CvtBBI->BB->pred_size() > 1) {
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
// Copy instructions in the true block, predicate them, and add them to // Copy instructions in the true block, predicate them, and add them to
// the entry block. // the entry block.
CopyAndPredicateBlock(BBI, *CvtBBI, Cond, Redefs, 0, true); CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true);
// RemoveExtraEdges won't work if the block has an unanalyzable branch, so // RemoveExtraEdges won't work if the block has an unanalyzable branch, so
// explicitly remove CvtBBI as a successor. // explicitly remove CvtBBI as a successor.
@ -1170,7 +1172,7 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
} else { } else {
// Predicate the 'true' block after removing its branch. // Predicate the 'true' block after removing its branch.
CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB);
PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond, Redefs); PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond);
// Now merge the entry of the triangle with the true block. // Now merge the entry of the triangle with the true block.
BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB);
@ -1281,7 +1283,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
// Initialize liveins to the first BB. These are potentially redefined by // Initialize liveins to the first BB. These are potentially redefined by
// predicated instructions. // predicated instructions.
LiveRegUnits Redefs; Redefs.init(TRI);
Redefs.addLiveIns(*(BBI1->BB), *TRI); Redefs.addLiveIns(*(BBI1->BB), *TRI);
// Remove the duplicated instructions at the beginnings of both paths. // Remove the duplicated instructions at the beginnings of both paths.
@ -1312,7 +1314,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
// Compute a set of registers which must not be killed by instructions in BB1: // Compute a set of registers which must not be killed by instructions in BB1:
// This is everything used+live in BB2 after the duplicated instructions. We // This is everything used+live in BB2 after the duplicated instructions. We
// can compute this set by simulating liveness backwards from the end of BB2. // can compute this set by simulating liveness backwards from the end of BB2.
LiveRegUnits DontKill; DontKill.init(TRI);
for (MachineBasicBlock::reverse_iterator I = BBI2->BB->rbegin(), for (MachineBasicBlock::reverse_iterator I = BBI2->BB->rbegin(),
E = MachineBasicBlock::reverse_iterator(DI2); I != E; ++I) { E = MachineBasicBlock::reverse_iterator(DI2); I != E; ++I) {
DontKill.stepBackward(*I, *TRI); DontKill.stepBackward(*I, *TRI);
@ -1401,10 +1403,10 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
} }
// Predicate the 'true' block. // Predicate the 'true' block.
PredicateBlock(*BBI1, BBI1->BB->end(), *Cond1, Redefs, &RedefsByFalse); PredicateBlock(*BBI1, BBI1->BB->end(), *Cond1, &RedefsByFalse);
// Predicate the 'false' block. // Predicate the 'false' block.
PredicateBlock(*BBI2, DI2, *Cond2, Redefs); PredicateBlock(*BBI2, DI2, *Cond2);
// Merge the true block into the entry of the diamond. // Merge the true block into the entry of the diamond.
MergeBlocks(BBI, *BBI1, TailBB == 0); MergeBlocks(BBI, *BBI1, TailBB == 0);
@ -1479,7 +1481,6 @@ static bool MaySpeculate(const MachineInstr *MI,
void IfConverter::PredicateBlock(BBInfo &BBI, void IfConverter::PredicateBlock(BBInfo &BBI,
MachineBasicBlock::iterator E, MachineBasicBlock::iterator E,
SmallVectorImpl<MachineOperand> &Cond, SmallVectorImpl<MachineOperand> &Cond,
LiveRegUnits &Redefs,
SmallSet<unsigned, 4> *LaterRedefs) { SmallSet<unsigned, 4> *LaterRedefs) {
bool AnyUnpred = false; bool AnyUnpred = false;
bool MaySpec = LaterRedefs != 0; bool MaySpec = LaterRedefs != 0;
@ -1522,8 +1523,6 @@ void IfConverter::PredicateBlock(BBInfo &BBI,
/// the destination block. Skip end of block branches if IgnoreBr is true. /// the destination block. Skip end of block branches if IgnoreBr is true.
void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
SmallVectorImpl<MachineOperand> &Cond, SmallVectorImpl<MachineOperand> &Cond,
LiveRegUnits &Redefs,
const LiveRegUnits *DontKill,
bool IgnoreBr) { bool IgnoreBr) {
MachineFunction &MF = *ToBBI.BB->getParent(); MachineFunction &MF = *ToBBI.BB->getParent();
@ -1556,8 +1555,8 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
UpdatePredRedefs(MI, Redefs, TRI); UpdatePredRedefs(MI, Redefs, TRI);
// Some kill flags may not be correct anymore. // Some kill flags may not be correct anymore.
if (DontKill != 0) if (!DontKill.empty())
RemoveKills(*MI, *DontKill, *TRI); RemoveKills(*MI, DontKill, *TRI);
} }
if (!IgnoreBr) { if (!IgnoreBr) {