LLVM: lib/Transforms/Utils/MoveAutoInit.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

26

27using namespace llvm;

28

29#define DEBUG_TYPE "move-auto-init"

30

31STATISTIC(NumMoved, "Number of instructions moved");

32

35 cl::desc("Maximum instructions to analyze per moved initialization"));

36

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"); });

41}

42

49 else

50 return std::nullopt;

51

53 return ML;

54 else

55 return {};

56}

57

58

59

60

63 BasicBlock *CurrentDominator = nullptr;

66

68

71

72 while (!WorkList.empty()) {

74 if (!Visited.insert(MA).second)

75 continue;

76

78 return nullptr;

79

80 bool FoundClobberingUser = false;

83

84

85

86

88 MI->isLifetimeStartOrEnd() && MI != I) {

89 FoundClobberingUser = true;

90 CurrentDominator = CurrentDominator

92 MI->getParent())

93 : MI->getParent();

94 }

95 }

96 if (!FoundClobberingUser) {

97 auto UsersAsMemoryAccesses = map_range(MA->users(), AsMemoryAccess);

98 append_range(WorkList, UsersAsMemoryAccesses);

99 }

100 }

101 return CurrentDominator;

102}

103

107

108

109

110

113 continue;

114

116 if (ML)

117 continue;

118

119 if (I.isVolatile())

120 continue;

121

123 if (!UsersDominator)

124 continue;

125

126 if (UsersDominator == &EntryBB)

127 continue;

128

129

132 bool HasCycle = false;

133 while (!WorkList.empty()) {

135 if (CurrBB == UsersDominator)

136

137

138 HasCycle = true;

141 continue;

143 }

144 }

145

146

147

148 if (HasCycle) {

149 BasicBlock *UsersDominatorHead = UsersDominator;

150 while (BasicBlock *UniquePredecessor =

152 UsersDominatorHead = UniquePredecessor;

153

154 if (UsersDominatorHead == &EntryBB)

155 continue;

156

157 BasicBlock *DominatingPredecessor = nullptr;

159

160

161

162 if (TransitiveSuccessors.count(Pred))

163 continue;

164

166 continue;

167

168 DominatingPredecessor =

169 DominatingPredecessor

171 : Pred;

172 }

173

174 if (!DominatingPredecessor || DominatingPredecessor == &EntryBB)

175 continue;

176

177 UsersDominator = DominatingPredecessor;

178 }

179

180

181

186 }

187

188

189

190 if (UsersDominator != &EntryBB)

192 }

193

194

195

196

197 if (JobList.empty())

198 return false;

199

201

202

203

204

205 for (auto &Job : reverse(JobList)) {

206 Job.first->moveBefore(*Job.second, Job.second->getFirstInsertionPt());

209 }

210

213

214 NumMoved += JobList.size();

215

216 return true;

217}

218

221

226

231 return PA;

232}

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)

Definition MoveAutoInit.cpp:104

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...

Definition MoveAutoInit.cpp:61

static bool hasAutoInitMetadata(const Instruction &I)

Definition MoveAutoInit.cpp:37

static std::optional< MemoryLocation > writeToAlloca(const Instruction &I)

Definition MoveAutoInit.cpp:43

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

LLVM Basic Block Representation.

LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const

Returns an iterator to the first instruction in this block that is not a PHINode instruction.

LLVM_ABI 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...

Represents analyses that only rely on functions' control flow.

Analysis pass which computes a DominatorTree.

Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.

LLVM_ABI bool isReachableFromEntry(const Use &U) const

Provide an overload for a Use.

LLVM_ABI 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 LLVM_ABI MemoryLocation get(const LoadInst *LI)

Return a location with information about the memory reference by the given instruction.

static LLVM_ABI 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.

LLVM_ABI void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)

Encapsulates MemorySSA, including all data associated with memory accesses.

LLVM_ABI 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)

Definition MoveAutoInit.cpp:219

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.

PreservedAnalyses & preserveSet()

Mark an analysis set as preserved.

PreservedAnalyses & 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

Abstract Attribute helper functions.

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

auto successors(const MachineBasicBlock *BB)

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

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 isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

@ NoModRef

The access neither references nor modifies the value stored in memory.

LLVM_ABI bool VerifyMemorySSA

Enables verification of MemorySSA.

DWARFExpression::Operation Op

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

auto predecessors(const MachineBasicBlock *BB)

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)

This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....