mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
Update mem2reg's comments to conform to the new doxygen standards. No
functionality changed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186772 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5f53c3be6f
commit
02aea0116a
@ -23,19 +23,23 @@ class AllocaInst;
|
|||||||
class DominatorTree;
|
class DominatorTree;
|
||||||
class AliasSetTracker;
|
class AliasSetTracker;
|
||||||
|
|
||||||
/// isAllocaPromotable - Return true if this alloca is legal for promotion.
|
/// \brief Return true if this alloca is legal for promotion.
|
||||||
/// This is true if there are only loads and stores to the alloca...
|
|
||||||
///
|
///
|
||||||
|
/// This is true if there are only loads, stores, and lifetime markers
|
||||||
|
/// (transitively) using this alloca. This also enforces that there is only
|
||||||
|
/// ever one layer of bitcasts or GEPs between the alloca and the lifetime
|
||||||
|
/// markers.
|
||||||
bool isAllocaPromotable(const AllocaInst *AI);
|
bool isAllocaPromotable(const AllocaInst *AI);
|
||||||
|
|
||||||
/// PromoteMemToReg - Promote the specified list of alloca instructions into
|
/// \brief Promote the specified list of alloca instructions into scalar
|
||||||
/// scalar registers, inserting PHI nodes as appropriate. This function makes
|
/// registers, inserting PHI nodes as appropriate.
|
||||||
/// use of DominanceFrontier information. This function does not modify the CFG
|
///
|
||||||
/// of the function at all. All allocas must be from the same function.
|
/// This function makes use of DominanceFrontier information. This function
|
||||||
|
/// does not modify the CFG of the function at all. All allocas must be from
|
||||||
|
/// the same function.
|
||||||
///
|
///
|
||||||
/// If AST is specified, the specified tracker is updated to reflect changes
|
/// If AST is specified, the specified tracker is updated to reflect changes
|
||||||
/// made to the IR.
|
/// made to the IR.
|
||||||
///
|
|
||||||
void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
|
void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
|
||||||
DominatorTree &DT, AliasSetTracker *AST = 0);
|
DominatorTree &DT, AliasSetTracker *AST = 0);
|
||||||
|
|
||||||
|
@ -76,9 +76,6 @@ struct DenseMapInfo<std::pair<BasicBlock*, unsigned> > {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isAllocaPromotable - Return true if this alloca is legal for promotion.
|
|
||||||
/// This is true if there are only loads and stores to the alloca.
|
|
||||||
///
|
|
||||||
bool llvm::isAllocaPromotable(const AllocaInst *AI) {
|
bool llvm::isAllocaPromotable(const AllocaInst *AI) {
|
||||||
// FIXME: If the memory unit is of pointer or integer type, we can permit
|
// FIXME: If the memory unit is of pointer or integer type, we can permit
|
||||||
// assignments to subsections of the memory unit.
|
// assignments to subsections of the memory unit.
|
||||||
@ -145,26 +142,27 @@ namespace {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// LargeBlockInfo - This assigns and keeps a per-bb relative ordering of
|
/// \brief This assigns and keeps a per-bb relative ordering of load/store
|
||||||
/// load/store instructions in the block that directly load or store an alloca.
|
/// instructions in the block that directly load or store an alloca.
|
||||||
///
|
///
|
||||||
/// This functionality is important because it avoids scanning large basic
|
/// This functionality is important because it avoids scanning large basic
|
||||||
/// blocks multiple times when promoting many allocas in the same block.
|
/// blocks multiple times when promoting many allocas in the same block.
|
||||||
class LargeBlockInfo {
|
class LargeBlockInfo {
|
||||||
/// InstNumbers - For each instruction that we track, keep the index of the
|
/// \brief For each instruction that we track, keep the index of the
|
||||||
/// instruction. The index starts out as the number of the instruction from
|
/// instruction.
|
||||||
/// the start of the block.
|
///
|
||||||
|
/// The index starts out as the number of the instruction from the start of
|
||||||
|
/// the block.
|
||||||
DenseMap<const Instruction *, unsigned> InstNumbers;
|
DenseMap<const Instruction *, unsigned> InstNumbers;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// isInterestingInstruction - This code only looks at accesses to allocas.
|
/// This code only looks at accesses to allocas.
|
||||||
static bool isInterestingInstruction(const Instruction *I) {
|
static bool isInterestingInstruction(const Instruction *I) {
|
||||||
return (isa<LoadInst>(I) && isa<AllocaInst>(I->getOperand(0))) ||
|
return (isa<LoadInst>(I) && isa<AllocaInst>(I->getOperand(0))) ||
|
||||||
(isa<StoreInst>(I) && isa<AllocaInst>(I->getOperand(1)));
|
(isa<StoreInst>(I) && isa<AllocaInst>(I->getOperand(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getInstructionIndex - Get or calculate the index of the specified
|
/// Get or calculate the index of the specified instruction.
|
||||||
/// instruction.
|
|
||||||
unsigned getInstructionIndex(const Instruction *I) {
|
unsigned getInstructionIndex(const Instruction *I) {
|
||||||
assert(isInterestingInstruction(I) &&
|
assert(isInterestingInstruction(I) &&
|
||||||
"Not a load/store to/from an alloca?");
|
"Not a load/store to/from an alloca?");
|
||||||
@ -198,55 +196,51 @@ namespace {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct PromoteMem2Reg {
|
struct PromoteMem2Reg {
|
||||||
/// Allocas - The alloca instructions being promoted.
|
/// The alloca instructions being promoted.
|
||||||
///
|
|
||||||
std::vector<AllocaInst*> Allocas;
|
std::vector<AllocaInst*> Allocas;
|
||||||
DominatorTree &DT;
|
DominatorTree &DT;
|
||||||
DIBuilder *DIB;
|
DIBuilder *DIB;
|
||||||
|
|
||||||
/// AST - An AliasSetTracker object to update. If null, don't update it.
|
/// An AliasSetTracker object to update. If null, don't update it.
|
||||||
///
|
|
||||||
AliasSetTracker *AST;
|
AliasSetTracker *AST;
|
||||||
|
|
||||||
/// AllocaLookup - Reverse mapping of Allocas.
|
/// Reverse mapping of Allocas.
|
||||||
///
|
|
||||||
DenseMap<AllocaInst*, unsigned> AllocaLookup;
|
DenseMap<AllocaInst*, unsigned> AllocaLookup;
|
||||||
|
|
||||||
/// NewPhiNodes - The PhiNodes we're adding. That map is used to simplify
|
/// \brief The PhiNodes we're adding.
|
||||||
/// some Phi nodes as we iterate over it, so it should have deterministic
|
|
||||||
/// iterators. We could use a MapVector, but since we already maintain a
|
|
||||||
/// map from BasicBlock* to a stable numbering (BBNumbers), the DenseMap is
|
|
||||||
/// more efficient (also supports removal).
|
|
||||||
///
|
///
|
||||||
|
/// That map is used to simplify some Phi nodes as we iterate over it, so
|
||||||
|
/// it should have deterministic iterators. We could use a MapVector, but
|
||||||
|
/// since we already maintain a map from BasicBlock* to a stable numbering
|
||||||
|
/// (BBNumbers), the DenseMap is more efficient (also supports removal).
|
||||||
DenseMap<std::pair<unsigned, unsigned>, PHINode*> NewPhiNodes;
|
DenseMap<std::pair<unsigned, unsigned>, PHINode*> NewPhiNodes;
|
||||||
|
|
||||||
/// PhiToAllocaMap - For each PHI node, keep track of which entry in Allocas
|
/// For each PHI node, keep track of which entry in Allocas it corresponds
|
||||||
/// it corresponds to.
|
/// to.
|
||||||
DenseMap<PHINode*, unsigned> PhiToAllocaMap;
|
DenseMap<PHINode*, unsigned> PhiToAllocaMap;
|
||||||
|
|
||||||
/// PointerAllocaValues - If we are updating an AliasSetTracker, then for
|
/// If we are updating an AliasSetTracker, then for each alloca that is of
|
||||||
/// each alloca that is of pointer type, we keep track of what to copyValue
|
/// pointer type, we keep track of what to copyValue to the inserted PHI
|
||||||
/// to the inserted PHI nodes here.
|
/// nodes here.
|
||||||
///
|
|
||||||
std::vector<Value*> PointerAllocaValues;
|
std::vector<Value*> PointerAllocaValues;
|
||||||
|
|
||||||
/// AllocaDbgDeclares - For each alloca, we keep track of the dbg.declare
|
/// For each alloca, we keep track of the dbg.declare intrinsic that
|
||||||
/// intrinsic that describes it, if any, so that we can convert it to a
|
/// describes it, if any, so that we can convert it to a dbg.value
|
||||||
/// dbg.value intrinsic if the alloca gets promoted.
|
/// intrinsic if the alloca gets promoted.
|
||||||
SmallVector<DbgDeclareInst*, 8> AllocaDbgDeclares;
|
SmallVector<DbgDeclareInst*, 8> AllocaDbgDeclares;
|
||||||
|
|
||||||
/// Visited - The set of basic blocks the renamer has already visited.
|
/// The set of basic blocks the renamer has already visited.
|
||||||
///
|
///
|
||||||
SmallPtrSet<BasicBlock*, 16> Visited;
|
SmallPtrSet<BasicBlock*, 16> Visited;
|
||||||
|
|
||||||
/// BBNumbers - Contains a stable numbering of basic blocks to avoid
|
/// Contains a stable numbering of basic blocks to avoid non-determinstic
|
||||||
/// non-determinstic behavior.
|
/// behavior.
|
||||||
DenseMap<BasicBlock*, unsigned> BBNumbers;
|
DenseMap<BasicBlock*, unsigned> BBNumbers;
|
||||||
|
|
||||||
/// DomLevels - Maps DomTreeNodes to their level in the dominator tree.
|
/// Maps DomTreeNodes to their level in the dominator tree.
|
||||||
DenseMap<DomTreeNode*, unsigned> DomLevels;
|
DenseMap<DomTreeNode*, unsigned> DomLevels;
|
||||||
|
|
||||||
/// BBNumPreds - Lazily compute the number of predecessors a block has.
|
/// Lazily compute the number of predecessors a block has.
|
||||||
DenseMap<const BasicBlock*, unsigned> BBNumPreds;
|
DenseMap<const BasicBlock*, unsigned> BBNumPreds;
|
||||||
public:
|
public:
|
||||||
PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,
|
PromoteMem2Reg(const std::vector<AllocaInst*> &A, DominatorTree &dt,
|
||||||
@ -258,8 +252,7 @@ namespace {
|
|||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
/// dominates - Return true if BB1 dominates BB2 using the DominatorTree.
|
/// Return true if BB1 dominates BB2 using the DominatorTree.
|
||||||
///
|
|
||||||
bool dominates(BasicBlock *BB1, BasicBlock *BB2) const {
|
bool dominates(BasicBlock *BB1, BasicBlock *BB2) const {
|
||||||
return DT.dominates(BB1, BB2);
|
return DT.dominates(BB1, BB2);
|
||||||
}
|
}
|
||||||
@ -316,8 +309,8 @@ namespace {
|
|||||||
DbgDeclare = 0;
|
DbgDeclare = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// AnalyzeAlloca - Scan the uses of the specified alloca, filling in our
|
/// Scan the uses of the specified alloca, filling in the AllocaInfo used
|
||||||
/// ivars.
|
/// by the rest of the pass to reason about the uses of this alloca.
|
||||||
void AnalyzeAlloca(AllocaInst *AI) {
|
void AnalyzeAlloca(AllocaInst *AI) {
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
@ -675,10 +668,11 @@ void PromoteMem2Reg::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// ComputeLiveInBlocks - Determine which blocks the value is live in. These
|
/// \brief Determine which blocks the value is live in.
|
||||||
/// are blocks which lead to uses. Knowing this allows us to avoid inserting
|
///
|
||||||
/// PHI nodes into blocks which don't lead to uses (thus, the inserted phi nodes
|
/// These are blocks which lead to uses. Knowing this allows us to avoid
|
||||||
/// would be dead).
|
/// inserting PHI nodes into blocks which don't lead to uses (thus, the
|
||||||
|
/// inserted phi nodes would be dead).
|
||||||
void PromoteMem2Reg::
|
void PromoteMem2Reg::
|
||||||
ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
||||||
const SmallPtrSet<BasicBlock*, 32> &DefBlocks,
|
const SmallPtrSet<BasicBlock*, 32> &DefBlocks,
|
||||||
@ -747,10 +741,10 @@ ComputeLiveInBlocks(AllocaInst *AI, AllocaInfo &Info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DetermineInsertionPoint - At this point, we're committed to promoting the
|
/// At this point, we're committed to promoting the alloca using IDF's, and the
|
||||||
/// alloca using IDF's, and the standard SSA construction algorithm. Determine
|
/// standard SSA construction algorithm. Determine which blocks need phi nodes
|
||||||
/// which blocks need phi nodes and see if we can optimize out some work by
|
/// and see if we can optimize out some work by avoiding insertion of dead phi
|
||||||
/// avoiding insertion of dead phi nodes.
|
/// nodes.
|
||||||
void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum,
|
void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum,
|
||||||
AllocaInfo &Info) {
|
AllocaInfo &Info) {
|
||||||
// Unique the set of defining blocks for efficient lookup.
|
// Unique the set of defining blocks for efficient lookup.
|
||||||
@ -836,9 +830,8 @@ void PromoteMem2Reg::DetermineInsertionPoint(AllocaInst *AI, unsigned AllocaNum,
|
|||||||
QueuePhiNode(DFBlocks[i].second, AllocaNum, CurrentVersion);
|
QueuePhiNode(DFBlocks[i].second, AllocaNum, CurrentVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RewriteSingleStoreAlloca - If there is only a single store to this value,
|
/// If there is only a single store to this value, replace any loads of it that
|
||||||
/// replace any loads of it that are directly dominated by the definition with
|
/// are directly dominated by the definition with the value stored.
|
||||||
/// the value stored.
|
|
||||||
void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
|
void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
|
||||||
AllocaInfo &Info,
|
AllocaInfo &Info,
|
||||||
LargeBlockInfo &LBI) {
|
LargeBlockInfo &LBI) {
|
||||||
@ -902,8 +895,7 @@ void PromoteMem2Reg::RewriteSingleStoreAlloca(AllocaInst *AI,
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/// StoreIndexSearchPredicate - This is a helper predicate used to search by the
|
/// This is a helper predicate used to search by the first element of a pair.
|
||||||
/// first element of a pair.
|
|
||||||
struct StoreIndexSearchPredicate {
|
struct StoreIndexSearchPredicate {
|
||||||
bool operator()(const std::pair<unsigned, StoreInst*> &LHS,
|
bool operator()(const std::pair<unsigned, StoreInst*> &LHS,
|
||||||
const std::pair<unsigned, StoreInst*> &RHS) {
|
const std::pair<unsigned, StoreInst*> &RHS) {
|
||||||
@ -913,10 +905,10 @@ struct StoreIndexSearchPredicate {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PromoteSingleBlockAlloca - Many allocas are only used within a single basic
|
/// Many allocas are only used within a single basic block. If this is the
|
||||||
/// block. If this is the case, avoid traversing the CFG and inserting a lot of
|
/// case, avoid traversing the CFG and inserting a lot of potentially useless
|
||||||
/// potentially useless PHI nodes by just performing a single linear pass over
|
/// PHI nodes by just performing a single linear pass over the basic block
|
||||||
/// the basic block using the Alloca.
|
/// using the Alloca.
|
||||||
///
|
///
|
||||||
/// If we cannot promote this alloca (because it is read before it is written),
|
/// If we cannot promote this alloca (because it is read before it is written),
|
||||||
/// return true. This is necessary in cases where, due to control flow, the
|
/// return true. This is necessary in cases where, due to control flow, the
|
||||||
@ -926,7 +918,6 @@ struct StoreIndexSearchPredicate {
|
|||||||
/// for (...) { if (c) { A = undef; undef = B; } }
|
/// for (...) { if (c) { A = undef; undef = B; } }
|
||||||
///
|
///
|
||||||
/// ... so long as A is not used before undef is set.
|
/// ... so long as A is not used before undef is set.
|
||||||
///
|
|
||||||
void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
|
void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
|
||||||
LargeBlockInfo &LBI) {
|
LargeBlockInfo &LBI) {
|
||||||
// The trickiest case to handle is when we have large blocks. Because of this,
|
// The trickiest case to handle is when we have large blocks. Because of this,
|
||||||
@ -994,9 +985,9 @@ void PromoteMem2Reg::PromoteSingleBlockAlloca(AllocaInst *AI, AllocaInfo &Info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueuePhiNode - queues a phi-node to be added to a basic-block for a specific
|
/// \brief Queue a phi-node to be added to a basic-block for a specific Alloca.
|
||||||
// Alloca returns true if there wasn't already a phi-node for that variable
|
///
|
||||||
//
|
/// Returns true if there wasn't already a phi-node for that variable
|
||||||
bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo,
|
bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo,
|
||||||
unsigned &Version) {
|
unsigned &Version) {
|
||||||
// Look up the basic-block in question.
|
// Look up the basic-block in question.
|
||||||
@ -1019,10 +1010,11 @@ bool PromoteMem2Reg::QueuePhiNode(BasicBlock *BB, unsigned AllocaNo,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenamePass - Recursively traverse the CFG of the function, renaming loads and
|
/// \brief Recursively traverse the CFG of the function, renaming loads and
|
||||||
// stores to the allocas which we are promoting. IncomingVals indicates what
|
/// stores to the allocas which we are promoting.
|
||||||
// value each Alloca contains on exit from the predecessor block Pred.
|
///
|
||||||
//
|
/// IncomingVals indicates what value each Alloca contains on exit from the
|
||||||
|
/// predecessor block Pred.
|
||||||
void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
|
void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
|
||||||
RenamePassData::ValVector &IncomingVals,
|
RenamePassData::ValVector &IncomingVals,
|
||||||
std::vector<RenamePassData> &Worklist) {
|
std::vector<RenamePassData> &Worklist) {
|
||||||
@ -1132,14 +1124,6 @@ NextIteration:
|
|||||||
goto NextIteration;
|
goto NextIteration;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PromoteMemToReg - Promote the specified list of alloca instructions into
|
|
||||||
/// scalar registers, inserting PHI nodes as appropriate. This function does
|
|
||||||
/// not modify the CFG of the function at all. All allocas must be from the
|
|
||||||
/// same function.
|
|
||||||
///
|
|
||||||
/// If AST is specified, the specified tracker is updated to reflect changes
|
|
||||||
/// made to the IR.
|
|
||||||
///
|
|
||||||
void llvm::PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
|
void llvm::PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
|
||||||
DominatorTree &DT, AliasSetTracker *AST) {
|
DominatorTree &DT, AliasSetTracker *AST) {
|
||||||
// If there is nothing to do, bail out...
|
// If there is nothing to do, bail out...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user