mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-16 12:24:03 +00:00
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:
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
Reference in New Issue
Block a user