29#define DEBUG_TYPE "move-auto-init"
35 cl::desc(
"Maximum instructions to analyze per moved initialization"));
38 return I.hasMetadata(LLVMContext::MD_annotation) &&
39 any_of(
I.getMetadata(LLVMContext::MD_annotation)->operands(),
40 [](
const MDOperand &
Op) { return Op.equalsStr(
"auto-init"); });
45 if (
auto *
MI = dyn_cast<MemIntrinsic>(&
I))
47 else if (
auto *SI = dyn_cast<StoreInst>(&
I))
69 auto AsMemoryAccess = [](
User *U) {
return cast<MemoryAccess>(U); };
72 while (!WorkList.
empty()) {
74 if (!Visited.
insert(MA).second)
80 bool FoundClobberingUser =
false;
81 if (
auto *M = dyn_cast<MemoryUseOrDef>(MA)) {
88 !
MI->isLifetimeStartOrEnd() &&
MI !=
I) {
89 FoundClobberingUser =
true;
90 CurrentDominator = CurrentDominator
96 if (!FoundClobberingUser) {
97 auto UsersAsMemoryAccesses =
map_range(MA->
users(), AsMemoryAccess);
101 return CurrentDominator;
126 if (UsersDominator == &EntryBB)
132 bool HasCycle =
false;
133 while (!WorkList.
empty()) {
135 if (CurrBB == UsersDominator)
149 BasicBlock *UsersDominatorHead = UsersDominator;
152 UsersDominatorHead = UniquePredecessor;
154 if (UsersDominatorHead == &EntryBB)
162 if (TransitiveSuccessors.
count(Pred))
168 DominatingPredecessor =
169 DominatingPredecessor
174 if (!DominatingPredecessor || DominatingPredecessor == &EntryBB)
177 UsersDominator = DominatingPredecessor;
190 if (UsersDominator != &EntryBB)
205 for (
auto &Job :
reverse(JobList)) {
206 Job.first->moveBefore(*Job.second, Job.second->getFirstInsertionPt());
208 MemorySSA::InsertionPlace::Beginning);
214 NumMoved += JobList.
size();
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
static cl::opt< unsigned > MoveAutoInitThreshold("move-auto-init-threshold", cl::Hidden, cl::init(128), cl::desc("Maximum instructions to analyze per moved initialization"))
static bool runMoveAutoInit(Function &F, DominatorTree &DT, MemorySSA &MSSA)
static BasicBlock * usersDominator(const MemoryLocation &ML, Instruction *I, DominatorTree &DT, MemorySSA &MSSA)
Finds a BasicBlock in the CFG where instruction I can be moved to while not changing the Memory SSA o...
static bool hasAutoInitMetadata(const Instruction &I)
static std::optional< MemoryLocation > writeToAlloca(const Instruction &I)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Represents analyses that only rely on functions' control flow.
This class represents an Operation in the Expression.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
Tracking metadata reference owned by Metadata.
Representation for a specific memory location.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
An analysis that produces MemorySSA for a function.
void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
Encapsulates MemorySSA, including all data associated with memory accesses.
void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
Class that has the common methods + fields of memory uses/defs.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
void preserve()
Mark an analysis as preserved.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
iterator_range< user_iterator > users()
const ParentTy * getParent() const
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto successors(const MachineBasicBlock *BB)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
auto map_range(ContainerTy &&C, FuncTy F)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
bool VerifyMemorySSA
Enables verification of MemorySSA.
auto predecessors(const MachineBasicBlock *BB)