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;
128 if (
StoreInst *SI = dyn_cast<StoreInst>(User)) {
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())
209 if (isInterestingInstruction(&BBI))
210 InstNumbers[&BBI] = InstNo++;
211 It = InstNumbers.
find(I);
213 assert(It != InstNumbers.
end() &&
"Didn't insert instruction?");
219 void clear() { InstNumbers.clear(); }
222 struct PromoteMem2Reg {
224 std::vector<AllocaInst *> Allocas;
252 std::vector<Value *> PointerAllocaValues;
273 : Allocas(Allocas.
begin(), Allocas.
end()), DT(DT),
280 void RemoveFromAllocasList(
unsigned &AllocaIdx) {
281 Allocas[AllocaIdx] = Allocas.back();
287 unsigned &NP = BBNumPreds[BB];
293 void ComputeLiveInBlocks(
AllocaInst *AI, AllocaInfo &Info,
297 RenamePassData::ValVector &IncVals,
298 std::vector<RenamePassData> &Worklist);
311 if (isa<LoadInst>(I) || isa<StoreInst>(
I))
341 bool StoringGlobalVal = !isa<Instruction>(OnlyStore->
getOperand(0));
346 Info.UsingBlocks.clear();
350 if (!isa<LoadInst>(UserInst)) {
351 assert(UserInst == OnlyStore &&
"Should only have load/stores");
354 LoadInst *LI = cast<LoadInst>(UserInst);
360 if (!StoringGlobalVal) {
365 if (StoreIndex == -1)
366 StoreIndex = LBI.getInstructionIndex(OnlyStore);
368 if (
unsigned(StoreIndex) > LBI.getInstructionIndex(LI)) {
370 Info.UsingBlocks.push_back(StoreBB);
379 Info.UsingBlocks.push_back(LI->
getParent());
398 if (!Info.UsingBlocks.empty())
406 DDI->eraseFromParent();
407 LBI.deleteValue(DDI);
410 Info.OnlyStore->eraseFromParent();
411 LBI.deleteValue(Info.OnlyStore);
446 StoresByIndexTy StoresByIndex;
448 for (User *U : AI->
users())
450 StoresByIndex.
push_back(std::make_pair(LBI.getInstructionIndex(
SI),
SI));
454 std::sort(StoresByIndex.begin(), StoresByIndex.end(),
less_first());
463 unsigned LoadIdx = LBI.getInstructionIndex(LI);
466 StoresByIndexTy::iterator I =
467 std::lower_bound(StoresByIndex.begin(), StoresByIndex.end(),
468 std::make_pair(LoadIdx,
469 static_cast<StoreInst *>(
nullptr)),
471 if (I == StoresByIndex.begin()) {
472 if (StoresByIndex.empty())
509 DDI->eraseFromParent();
510 LBI.deleteValue(DDI);
517 void PromoteMem2Reg::run() {
518 Function &
F = *DT.getRoot()->getParent();
521 PointerAllocaValues.resize(Allocas.size());
522 AllocaDbgDeclares.resize(Allocas.size());
528 for (
unsigned AllocaNum = 0; AllocaNum != Allocas.size(); ++AllocaNum) {
533 "All allocas should be in the same function, which is same as DF!");
540 AST->deleteValue(AI);
544 RemoveFromAllocasList(AllocaNum);
551 Info.AnalyzeAlloca(AI);
555 if (Info.DefiningBlocks.size() == 1) {
558 RemoveFromAllocasList(AllocaNum);
566 if (Info.OnlyUsedInOneBlock &&
569 RemoveFromAllocasList(AllocaNum);
575 if (BBNumbers.empty()) {
578 BBNumbers[&BB] = ID++;
584 PointerAllocaValues[AllocaNum] = Info.AllocaPointerVal;
588 AllocaDbgDeclares[AllocaNum] = Info.DbgDeclare;
591 AllocaLookup[Allocas[AllocaNum]] = AllocaNum;
601 DefBlocks.
insert(Info.DefiningBlocks.begin(), Info.DefiningBlocks.end());
606 ComputeLiveInBlocks(AI, Info, DefBlocks, LiveInBlocks);
612 IDF.setLiveInBlocks(LiveInBlocks);
613 IDF.setDefiningBlocks(DefBlocks);
615 IDF.calculate(PHIBlocks);
616 if (PHIBlocks.
size() > 1)
617 std::sort(PHIBlocks.
begin(), PHIBlocks.
end(),
619 return BBNumbers.lookup(A) < BBNumbers.lookup(
B);
623 for (
unsigned i = 0, e = PHIBlocks.
size();
i != e; ++
i)
624 QueuePhiNode(PHIBlocks[
i], AllocaNum, CurrentVersion);
636 RenamePassData::ValVector Values(Allocas.size());
637 for (
unsigned i = 0, e = Allocas.size();
i != e; ++
i)
643 std::vector<RenamePassData> RenamePassWorkList;
644 RenamePassWorkList.emplace_back(&F.
front(),
nullptr, std::move(Values));
647 RPD.swap(RenamePassWorkList.back());
648 RenamePassWorkList.pop_back();
650 RenamePass(RPD.BB, RPD.Pred, RPD.Values, RenamePassWorkList);
651 }
while (!RenamePassWorkList.empty());
657 for (
unsigned i = 0, e = Allocas.size();
i != e; ++
i) {
673 for (
unsigned i = 0, e = AllocaDbgDeclares.size();
i != e; ++
i)
675 DDI->eraseFromParent();
681 bool EliminatedAPHI =
true;
682 while (EliminatedAPHI) {
683 EliminatedAPHI =
false;
690 I = NewPhiNodes.begin(),
691 E = NewPhiNodes.end();
698 AST->deleteValue(PN);
701 NewPhiNodes.
erase(I++);
702 EliminatedAPHI =
true;
716 I = NewPhiNodes.begin(),
717 E = NewPhiNodes.end();
723 if (&BB->
front() != SomePHI)
738 std::sort(Preds.begin(), Preds.end());
747 "PHI node has entry for a block which is not a predecessor!");
759 while ((SomePHI = dyn_cast<PHINode>(BBI++)) &&
762 for (
unsigned pred = 0, e = Preds.size();
pred != e; ++
pred)
775 void PromoteMem2Reg::ComputeLiveInBlocks(
784 Info.UsingBlocks.end());
789 for (
unsigned i = 0, e = LiveInBlockWorklist.size(); i != e; ++
i) {
791 if (!DefBlocks.
count(BB))
797 if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
798 if (
SI->getOperand(1) != AI)
803 LiveInBlockWorklist[
i] = LiveInBlockWorklist.
back();
804 LiveInBlockWorklist.pop_back();
810 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
823 while (!LiveInBlockWorklist.empty()) {
824 BasicBlock *BB = LiveInBlockWorklist.pop_back_val();
828 if (!LiveInBlocks.
insert(BB).second)
838 if (DefBlocks.
count(P))
842 LiveInBlockWorklist.push_back(P);
850 bool PromoteMem2Reg::QueuePhiNode(
BasicBlock *BB,
unsigned AllocaNo,
853 PHINode *&PN = NewPhiNodes[std::make_pair(BBNumbers[BB], AllocaNo)];
861 PN =
PHINode::Create(Allocas[AllocaNo]->getAllocatedType(), getNumPreds(BB),
865 PhiToAllocaMap[PN] = AllocaNo;
868 AST->copyValue(PointerAllocaValues[AllocaNo], PN);
879 RenamePassData::ValVector &IncomingVals,
880 std::vector<RenamePassData> &Worklist) {
887 if (PhiToAllocaMap.count(APN)) {
894 unsigned NewPHINumOperands = APN->getNumOperands();
897 assert(NumEdges &&
"Must be at least one edge from Pred to BB!");
902 unsigned AllocaNo = PhiToAllocaMap[APN];
905 for (
unsigned i = 0; i != NumEdges; ++
i)
906 APN->addIncoming(IncomingVals[AllocaNo], Pred);
909 IncomingVals[AllocaNo] = APN;
921 }
while (APN->getNumOperands() == NewPHINumOperands);
926 if (!Visited.insert(BB).second)
932 if (
LoadInst *LI = dyn_cast<LoadInst>(I)) {
938 if (AI == AllocaLookup.
end())
941 Value *V = IncomingVals[AI->second];
946 AST->deleteValue(LI);
948 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(I)) {
956 if (ai == AllocaLookup.
end())
960 IncomingVals[ai->second] =
SI->getOperand(0);
983 if (VisitedSuccs.
insert(*I).second)
984 Worklist.emplace_back(*I, Pred, IncomingVals);
995 PromoteMem2Reg(Allocas, DT, AST, AC).run();
SymbolTableList< Instruction >::iterator 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)
Add an incoming value to the end of the PHI list.
const Instruction & back() const
STATISTIC(NumFunctions,"Total number of functions")
iterator erase(iterator where)
DbgDeclareInst * FindAllocaDbgDeclare(Value *V)
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.
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...
Function Alias Analysis false
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)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
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...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Interval::succ_iterator succ_end(Interval *I)
unsigned getNumIncomingValues() const
Return the number of incoming edges.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
bool erase(const KeyT &Val)
LLVM Basic Block Representation.
void ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder)
===---------------------------------------------------------------——===// Dbg Intrinsic utilities ...
PointerType * getType() const
Overload to return most specific pointer type.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool onlyUsedByLifetimeMarkers(const Value *V)
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
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
True if this is an instance of PointerType.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
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()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
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()
static void clear(coro::Shape &Shape)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
iterator find(const KeyT &Val)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Determine the iterated dominance frontier, given a set of defining blocks, and optionally, a set of live-in blocks.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
const BasicBlock & front() const
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)
See if we can compute a simplified version of this instruction.
This represents the llvm.dbg.declare instruction.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
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)
This method is used to remove a pointer value from the AliasSetTracker entirely.
A wrapper class for inspecting calls to intrinsic functions.
bool isVoidTy() const
Return true if this is 'void'.
an instruction to allocate memory on the stack