44 #define DEBUG_TYPE "mem2reg"
46 STATISTIC(NumLocalPromoted,
"Number of alloca's promoted within one block");
47 STATISTIC(NumSingleStore,
"Number of alloca's promoted with a single store");
48 STATISTIC(NumDeadAlloca,
"Number of dead alloca's removed");
49 STATISTIC(NumPHIInsert,
"Number of PHI nodes inserted");
58 if (
const LoadInst *LI = dyn_cast<LoadInst>(U)) {
63 }
else if (
const StoreInst *
SI = dyn_cast<StoreInst>(U)) {
64 if (
SI->getOperand(0) == AI)
70 }
else if (
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
71 if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
72 II->getIntrinsicID() != Intrinsic::lifetime_end)
74 }
else if (
const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
82 if (!GEPI->hasAllZeroIndices())
102 bool OnlyUsedInOneBlock;
104 Value *AllocaPointerVal;
108 DefiningBlocks.clear();
112 OnlyUsedInOneBlock =
true;
113 AllocaPointerVal =
nullptr;
114 DbgDeclare =
nullptr;
130 DefiningBlocks.push_back(
SI->getParent());
131 AllocaPointerVal =
SI->getOperand(0);
134 LoadInst *LI = cast<LoadInst>(User);
138 AllocaPointerVal = LI;
141 if (OnlyUsedInOneBlock) {
145 OnlyUsedInOneBlock =
false;
154 class RenamePassData {
156 typedef std::vector<Value *> ValVector;
158 RenamePassData() : BB(nullptr), Pred(nullptr), Values() {}
160 : BB(B), Pred(P), Values(V) {}
165 void swap(RenamePassData &RHS) {
168 Values.swap(RHS.Values);
177 class LargeBlockInfo {
188 static bool isInterestingInstruction(
const Instruction *
I) {
189 return (isa<LoadInst>(I) && isa<AllocaInst>(I->
getOperand(0))) ||
190 (isa<StoreInst>(
I) && isa<AllocaInst>(I->
getOperand(1)));
194 unsigned getInstructionIndex(
const Instruction *I) {
195 assert(isInterestingInstruction(I) &&
196 "Not a load/store to/from an alloca?");
200 if (It != InstNumbers.
end())
210 if (isInterestingInstruction(BBI))
211 InstNumbers[BBI] = InstNo++;
212 It = InstNumbers.
find(I);
214 assert(It != InstNumbers.
end() &&
"Didn't insert instruction?");
220 void clear() { InstNumbers.clear(); }
223 struct PromoteMem2Reg {
225 std::vector<AllocaInst *> Allocas;
253 std::vector<Value *> PointerAllocaValues;
274 : Allocas(Allocas.
begin(), Allocas.
end()), DT(DT),
281 void RemoveFromAllocasList(
unsigned &AllocaIdx) {
282 Allocas[AllocaIdx] = Allocas.back();
288 unsigned &NP = BBNumPreds[BB];
294 void ComputeLiveInBlocks(
AllocaInst *AI, AllocaInfo &Info,
298 RenamePassData::ValVector &IncVals,
299 std::vector<RenamePassData> &Worklist);
312 if (isa<LoadInst>(I) || isa<StoreInst>(
I))
342 bool StoringGlobalVal = !isa<Instruction>(OnlyStore->
getOperand(0));
347 Info.UsingBlocks.clear();
351 if (!isa<LoadInst>(UserInst)) {
352 assert(UserInst == OnlyStore &&
"Should only have load/stores");
355 LoadInst *LI = cast<LoadInst>(UserInst);
361 if (!StoringGlobalVal) {
366 if (StoreIndex == -1)
367 StoreIndex = LBI.getInstructionIndex(OnlyStore);
369 if (
unsigned(StoreIndex) > LBI.getInstructionIndex(LI)) {
371 Info.UsingBlocks.push_back(StoreBB);
380 Info.UsingBlocks.push_back(LI->
getParent());
399 if (!Info.UsingBlocks.empty())
408 DDI->eraseFromParent();
409 LBI.deleteValue(DDI);
412 Info.OnlyStore->eraseFromParent();
413 LBI.deleteValue(Info.OnlyStore);
445 StoresByIndexTy StoresByIndex;
447 for (User *U : AI->
users())
449 StoresByIndex.
push_back(std::make_pair(LBI.getInstructionIndex(
SI),
SI));
453 std::sort(StoresByIndex.begin(), StoresByIndex.end(),
less_first());
462 unsigned LoadIdx = LBI.getInstructionIndex(LI);
465 StoresByIndexTy::iterator I =
466 std::lower_bound(StoresByIndex.begin(), StoresByIndex.end(),
467 std::make_pair(LoadIdx,
468 static_cast<StoreInst *>(
nullptr)),
471 if (I == StoresByIndex.begin())
504 DDI->eraseFromParent();
505 LBI.deleteValue(DDI);
511 void PromoteMem2Reg::run() {
512 Function &
F = *DT.getRoot()->getParent();
515 PointerAllocaValues.resize(Allocas.size());
516 AllocaDbgDeclares.resize(Allocas.size());
522 for (
unsigned AllocaNum = 0; AllocaNum != Allocas.size(); ++AllocaNum) {
527 "All allocas should be in the same function, which is same as DF!");
534 AST->deleteValue(AI);
538 RemoveFromAllocasList(AllocaNum);
545 Info.AnalyzeAlloca(AI);
549 if (Info.DefiningBlocks.size() == 1) {
552 RemoveFromAllocasList(AllocaNum);
560 if (Info.OnlyUsedInOneBlock) {
564 RemoveFromAllocasList(AllocaNum);
570 if (BBNumbers.empty()) {
573 BBNumbers[&BB] = ID++;
579 PointerAllocaValues[AllocaNum] = Info.AllocaPointerVal;
583 AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;
586 AllocaLookup[Allocas[AllocaNum]] = AllocaNum;
596 DefBlocks.
insert(Info.DefiningBlocks.begin(), Info.DefiningBlocks.end());
601 ComputeLiveInBlocks(AI, Info, DefBlocks, LiveInBlocks);
607 IDF.setLiveInBlocks(LiveInBlocks);
608 IDF.setDefiningBlocks(DefBlocks);
610 IDF.calculate(PHIBlocks);
611 if (PHIBlocks.
size() > 1)
612 std::sort(PHIBlocks.
begin(), PHIBlocks.
end(),
614 return BBNumbers.lookup(A) < BBNumbers.lookup(B);
617 unsigned CurrentVersion = 0;
618 for (
unsigned i = 0, e = PHIBlocks.
size(); i != e; ++i)
619 QueuePhiNode(PHIBlocks[i], AllocaNum, CurrentVersion);
631 RenamePassData::ValVector Values(Allocas.size());
632 for (
unsigned i = 0, e = Allocas.size(); i != e; ++i)
638 std::vector<RenamePassData> RenamePassWorkList;
639 RenamePassWorkList.emplace_back(F.
begin(),
nullptr, std::move(Values));
642 RPD.swap(RenamePassWorkList.back());
643 RenamePassWorkList.pop_back();
645 RenamePass(RPD.BB, RPD.Pred, RPD.Values, RenamePassWorkList);
646 }
while (!RenamePassWorkList.empty());
652 for (
unsigned i = 0, e = Allocas.size(); i != e; ++i) {
668 for (
unsigned i = 0, e = AllocaDbgDeclares.size(); i != e; ++i)
670 DDI->eraseFromParent();
676 bool EliminatedAPHI =
true;
677 while (EliminatedAPHI) {
678 EliminatedAPHI =
false;
685 I = NewPhiNodes.begin(),
686 E = NewPhiNodes.end();
693 AST->deleteValue(PN);
696 NewPhiNodes.
erase(I++);
697 EliminatedAPHI =
true;
711 I = NewPhiNodes.begin(),
712 E = NewPhiNodes.end();
718 if (&BB->
front() != SomePHI)
733 std::sort(Preds.begin(), Preds.end());
742 "PHI node has entry for a block which is not a predecessor!");
754 while ((SomePHI = dyn_cast<PHINode>(BBI++)) &&
757 for (
unsigned pred = 0, e = Preds.size();
pred != e; ++
pred)
770 void PromoteMem2Reg::ComputeLiveInBlocks(
779 Info.UsingBlocks.end());
784 for (
unsigned i = 0, e = LiveInBlockWorklist.size(); i != e; ++i) {
786 if (!DefBlocks.
count(BB))
792 if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
793 if (
SI->getOperand(1) != AI)
798 LiveInBlockWorklist[i] = LiveInBlockWorklist.
back();
799 LiveInBlockWorklist.pop_back();
804 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
817 while (!LiveInBlockWorklist.empty()) {
818 BasicBlock *BB = LiveInBlockWorklist.pop_back_val();
822 if (!LiveInBlocks.
insert(BB).second)
832 if (DefBlocks.
count(P))
836 LiveInBlockWorklist.push_back(P);
844 bool PromoteMem2Reg::QueuePhiNode(
BasicBlock *BB,
unsigned AllocaNo,
847 PHINode *&PN = NewPhiNodes[std::make_pair(BBNumbers[BB], AllocaNo)];
855 PN =
PHINode::Create(Allocas[AllocaNo]->getAllocatedType(), getNumPreds(BB),
859 PhiToAllocaMap[PN] = AllocaNo;
862 AST->copyValue(PointerAllocaValues[AllocaNo], PN);
873 RenamePassData::ValVector &IncomingVals,
874 std::vector<RenamePassData> &Worklist) {
881 if (PhiToAllocaMap.count(APN)) {
888 unsigned NewPHINumOperands = APN->getNumOperands();
891 assert(NumEdges &&
"Must be at least one edge from Pred to BB!");
896 unsigned AllocaNo = PhiToAllocaMap[APN];
899 for (
unsigned i = 0; i != NumEdges; ++i)
900 APN->addIncoming(IncomingVals[AllocaNo], Pred);
903 IncomingVals[AllocaNo] = APN;
913 }
while (APN->getNumOperands() == NewPHINumOperands);
918 if (!Visited.insert(BB).second)
924 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
930 if (AI == AllocaLookup.
end())
933 Value *V = IncomingVals[AI->second];
938 AST->deleteValue(LI);
940 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
948 if (ai == AllocaLookup.
end())
952 IncomingVals[ai->second] =
SI->getOperand(0);
975 if (VisitedSuccs.
insert(*I).second)
976 Worklist.emplace_back(*I, Pred, IncomingVals);
987 PromoteMem2Reg(Allocas, DT, AST, AC).run();
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
const_iterator end(StringRef path)
Get end iterator over path.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
const Instruction & back() const
STATISTIC(NumFunctions,"Total number of functions")
DbgDeclareInst * FindAllocaDbgDeclare(Value *V)
FindAllocaDbgDeclare - Finds the llvm.dbg.declare intrinsic corresponding to an alloca, if any.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
A cache of .assume calls within a function.
const_iterator begin(StringRef path)
Get begin iterator over path.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
unsigned getAddressSpace() const
Return the address space of the Pointer type.
LoadInst - an instruction for reading from memory.
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
iterator begin()
Instruction iterator methods.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static StringRef getName(Value *V)
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AliasSetTracker *AST=nullptr, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
This class represents a no-op cast from one type to another.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
StoreInst - an instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Interval::succ_iterator succ_end(Interval *I)
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
GetElementPtrInst - an instruction for type-safe pointer arithmetic to access elements of arrays and ...
bool erase(const KeyT &Val)
LLVM Basic Block Representation.
PointerType * getType() const
getType - Overload to return most specific pointer type
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool onlyUsedByLifetimeMarkers(const Value *V)
onlyUsedByLifetimeMarkers - Return true if the only users of this pointer are lifetime markers...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
BasicBlock * getIncomingBlock(unsigned i) const
getIncomingBlock - Return incoming basic block number i.
const InstListType & getInstList() const
Return the underlying instruction list container.
Value * getOperand(unsigned i) const
Interval::pred_iterator pred_end(Interval *I)
Value * getPointerOperand()
bool empty() const
empty - Check if the array is empty.
bool isPointerTy() const
isPointerTy - True if this is an instance of PointerType.
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
iterator erase(iterator where)
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
bool ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder)
===---------------------------------------------------------------——===// Dbg Intrinsic utilities ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Instruction * user_back()
user_back - Specialize the methods defined in Value, as we know that an instruction can only be used ...
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
iterator_range< user_iterator > users()
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
iterator find(const KeyT &Val)
Determine the iterated dominance frontier, given a set of defining blocks, and optionally, a set of live-in blocks.
user_iterator user_begin()
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
static const Function * getParent(const Value *V)
Value * SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr)
SimplifyInstruction - See if we can compute a simplified version of this instruction.
DbgDeclareInst - This represents the llvm.dbg.declare instruction.
Function object to check whether the first component of a std::pair compares less than the first comp...
const BasicBlock * getParent() const
void deleteValue(Value *PtrVal)
deleteValue method - This method is used to remove a pointer value from the AliasSetTracker entirely...
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
AllocaInst - an instruction to allocate memory on the stack.