LLVM: lib/Transforms/Scalar/Sink.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

23using namespace llvm;

24

25#define DEBUG_TYPE "sink"

26

27STATISTIC(NumSunk, "Number of instructions sunk");

28STATISTIC(NumSinkIter, "Number of sinking iterations");

29

32

35 return false;

36 }

37

38 if (LoadInst *L = dyn_cast(Inst)) {

42 return false;

43 }

44

47 return false;

48

49 if (auto *Call = dyn_cast(Inst)) {

50

51

52 if (Call->isConvergent())

53 return false;

54

57 return false;

58 }

59

60 return true;

61}

62

63

64

67 assert(Inst && "Instruction to be sunk is null");

68 assert(SuccToSinkTo && "Candidate sink target is null");

69

70

71 if (SuccToSinkTo->isEHPad())

72 return false;

73

74

75

76

77

79

80

82 !Inst->hasMetadata(LLVMContext::MD_invariant_load))

83 return false;

84

85

86

88 return false;

89

90

93 if (succ != nullptr && succ != cur)

94 return false;

95 }

96

97 return true;

98}

99

100

101

105

106

107

108 if (AllocaInst *AI = dyn_cast(Inst))

109 if (AI->isStaticAlloca())

110 return false;

111

112

114 return false;

115

116

117

118

119

120

121

122

123

124

125

127

128

130 for (Use &U : Inst->uses()) {

131 Instruction *UseInst = cast(U.getUser());

133 if (PHINode *PN = dyn_cast(UseInst)) {

134

135

137 UseBlock = PN->getIncomingBlock(Num);

138 }

139

141 continue;

142

143 if (SuccToSinkTo)

145 else

146 SuccToSinkTo = UseBlock;

147

148 if (!DT.dominates(BB, SuccToSinkTo))

149 return false;

150 }

151

152 if (SuccToSinkTo) {

153

154

155 while (SuccToSinkTo != BB &&

158 if (SuccToSinkTo == BB)

159 SuccToSinkTo = nullptr;

160 }

161

162

163 if (!SuccToSinkTo)

164 return false;

165

167 Inst->getParent()->printAsOperand(dbgs(), false); dbgs() << " -> ";

169

170

172 return true;

173}

174

177

178

179

181

182 bool MadeChange = false;

183

184

186 --I;

187 bool ProcessedBegin = false;

189 do {

190 Instruction *Inst = &*I;

191

192

193

194 ProcessedBegin = I == BB.begin();

195 if (!ProcessedBegin)

196 --I;

197

199 continue;

200

202 ++NumSunk;

203 MadeChange = true;

204 }

205

206

207 } while (!ProcessedBegin);

208

209 return MadeChange;

210}

211

214 bool MadeChange, EverMadeChange = false;

215

216 do {

217 MadeChange = false;

218 LLVM_DEBUG(dbgs() << "Sinking iteration " << NumSinkIter << "\n");

219

222 EverMadeChange |= MadeChange;

223 NumSinkIter++;

224 } while (MadeChange);

225

226 return EverMadeChange;

227}

228

233

236

239 return PA;

240}

241

242namespace {

243 class SinkingLegacyPass : public FunctionPass {

244 public:

245 static char ID;

248 }

249

251 auto &DT = getAnalysis().getDomTree();

252 auto &LI = getAnalysis().getLoopInfo();

253 auto &AA = getAnalysis().getAAResults();

254

256 }

257

258 void getAnalysisUsage(AnalysisUsage &AU) const override {

260 FunctionPass::getAnalysisUsage(AU);

266 }

267 };

268}

269

270char SinkingLegacyPass::ID = 0;

276

static bool runOnFunction(Function &F, bool PostInlining)

static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT, const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo, MemorySSAUpdater &MSSAU, OptimizationRemarkEmitter *ORE)

When an instruction is found to only be used outside of the loop, this function moves it to the exit ...

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

static bool iterativelySinkInstructions(Function &F, DominatorTree &DT, LoopInfo &LI, AAResults &AA)

static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo, DominatorTree &DT, LoopInfo &LI)

IsAcceptableTarget - Return true if it is possible to sink the instruction in the specified basic blo...

static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA, SmallPtrSetImpl< Instruction * > &Stores)

static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI, AAResults &AA)

static bool SinkInstruction(Instruction *Inst, SmallPtrSetImpl< Instruction * > &Stores, DominatorTree &DT, LoopInfo &LI, AAResults &AA)

SinkInstruction - Determine whether it is safe to sink the specified machine instruction out of its c...

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

#define STATISTIC(VARNAME, DESC)

A manager for alias analyses.

A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.

ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)

Check whether or not an instruction may read or write the optionally specified memory location.

an instruction to allocate memory on the stack

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.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

void setPreservesCFG()

This function should be called by the pass, iff they do not:

LLVM Basic Block Representation.

iterator begin()

Instruction iterator methods.

const_iterator getFirstInsertionPt() const

Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...

const BasicBlock * getUniquePredecessor() const

Return the predecessor of this block if it has a unique predecessor block.

InstListType::iterator iterator

Instruction iterators...

bool isEHPad() const

Return true if this basic block is an exception handling block.

Represents analyses that only rely on functions' control flow.

DomTreeNodeBase * getIDom() const

Analysis pass which computes a DominatorTree.

DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const

getNode - return the (Post)DominatorTree node for the specified basic block.

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

bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

FunctionPass class - This class is used to implement most global optimizations.

bool mayThrow(bool IncludePhaseOneUnwind=false) const LLVM_READONLY

Return true if this instruction may throw an exception.

bool isDebugOrPseudoInst() const LLVM_READONLY

Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.

bool mayWriteToMemory() const LLVM_READONLY

Return true if this instruction may modify memory.

bool hasMetadata() const

Return true if this instruction has any metadata attached to it.

bool isEHPad() const

Return true if the instruction is a variety of EH-block.

bool isTerminator() const

bool mayReadFromMemory() const LLVM_READONLY

Return true if this instruction may read memory.

bool willReturn() const LLVM_READONLY

Return true if the instruction will return (unwinding is considered as a form of returning control fl...

void moveBefore(Instruction *MovePos)

Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...

An instruction for reading from memory.

Analysis pass that exposes the LoopInfo for a function.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

The legacy pass manager's analysis pass to compute loop information.

Represents a single loop in the control flow graph.

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 unsigned getIncomingValueNumForOperand(unsigned i)

static PassRegistry * getPassRegistry()

getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...

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.

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

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.

A Use represents the edge between a Value definition and its users.

void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const

Print the name of this Value out to the specified raw_ostream.

iterator_range< use_iterator > uses()

const ParentTy * getParent() const

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

This is an optimization pass for GlobalISel generic memory operations.

void initializeSinkingLegacyPassPass(PassRegistry &)

FunctionPass * createSinkingPass()

bool isModSet(const ModRefInfo MRI)

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.