LLVM: lib/Analysis/LoopPass.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

28using namespace llvm;

29

30#define DEBUG_TYPE "loop-pass-manager"

31

32namespace {

33

34

35

36class PrintLoopPassWrapper : public LoopPass {

38 std::string Banner;

39

40public:

41 static char ID;

43 PrintLoopPassWrapper(raw_ostream &OS, const std::string &Banner)

45

48 }

49

52 if (BBI != L->blocks().end() &&

55 }

56 return false;

57 }

58

60};

61

62char PrintLoopPassWrapper::ID = 0;

63}

64

65

66

67

68

70

72 LI = nullptr;

73 CurrentLoop = nullptr;

74}

75

76

78 if (L.isOutermost()) {

79

80 LQ.push_front(&L);

81 return;

82 }

83

84

85 for (auto I = LQ.begin(), E = LQ.end(); I != E; ++I) {

86 if (*I == L.getParentLoop()) {

87

88 ++I;

89 LQ.insert(I, 1, &L);

90 return;

91 }

92 }

93}

94

95

97 LQ.push_back(L);

100}

101

102

104

105

108 Info.setPreservesAll();

109}

110

112 assert((&L == CurrentLoop || CurrentLoop->contains(&L)) &&

113 "Must not delete loop outside the current loop tree!");

114

115

116

117 assert(LQ.back() == CurrentLoop && "Loop queue back isn't the current loop!");

119

120 if (&L == CurrentLoop) {

121 CurrentLoopDeleted = true;

122

123 LQ.push_back(&L);

124 }

125}

126

127

128

130 auto &LIWP = getAnalysis();

131 LI = &LIWP.getLoopInfo();

132 Module &M = *F.getParent();

133#if 0

134 DominatorTree *DT = &getAnalysis().getDomTree();

135#endif

136 bool Changed = false;

137

138

140

141

142

143

144

145

146

147

148

149

152

153 if (LQ.empty())

154 return false;

155

156

157 for (Loop *L : LQ) {

160 Changed |= P->doInitialization(L, *this);

161 }

162 }

163

164

165 unsigned InstrCount, FunctionSize = 0;

167 bool EmitICRemark = M.shouldEmitInstrCountChangedRemark();

168

169 if (EmitICRemark) {

171 FunctionSize = F.getInstructionCount();

172 }

173 while (!LQ.empty()) {

174 CurrentLoopDeleted = false;

175 CurrentLoop = LQ.back();

176

177

180

182

186

188

189 bool LocalChanged = false;

190 {

193#ifdef EXPENSIVE_CHECKS

194 uint64_t RefHash = P->structuralHash(F);

195#endif

196 LocalChanged = P->runOnLoop(CurrentLoop, *this);

197

198#ifdef EXPENSIVE_CHECKS

199 if (!LocalChanged && (RefHash != P->structuralHash(F))) {

200 llvm::errs() << "Pass modifies its input and doesn't report it: "

201 << P->getPassName() << "\n";

202 llvm_unreachable("Pass modifies its input and doesn't report it");

203 }

204#endif

205

206 Changed |= LocalChanged;

207 if (EmitICRemark) {

208 unsigned NewSize = F.getInstructionCount();

209

210

211 if (NewSize != FunctionSize) {

212 int64_t Delta = static_cast<int64_t>(NewSize) -

213 static_cast<int64_t>(FunctionSize);

215 FunctionToInstrCount, &F);

217 FunctionSize = NewSize;

218 }

219 }

220 }

221

222 if (LocalChanged)

224 CurrentLoopDeleted ? ""

225 : CurrentLoop->getName());

227

228 if (!CurrentLoopDeleted) {

229

230

231

232

233

234 {

237 }

238

239

240

241

242

243

244#if 0

247#endif

248

249

251

252 F.getContext().yield();

253 }

254

255 if (LocalChanged)

259 CurrentLoopDeleted ? ""

262

263 if (CurrentLoopDeleted)

264

265 break;

266 }

267

268

269

270

271 if (CurrentLoopDeleted) {

275 }

276 }

277

278

279 LQ.pop_back();

280 }

281

282

285 Changed |= P->doFinalization();

286 }

287

288 return Changed;

289}

290

291

296 P->dumpPassStructure(Offset + 1);

298 }

299}

300

301

302

303

304

306 const std::string &Banner) const {

307 return new PrintLoopPassWrapper(O, Banner);

308}

309

310

311

312

313

314

315

317

318

319 while (!PMS.empty() &&

321 PMS.pop();

322

323

324

325

328 PMS.pop();

329}

330

331

334

335 while (!PMS.empty() &&

337 PMS.pop();

338

342 else {

343

344 assert (!PMS.empty() && "Unable to create Loop Pass Manager");

346

347

350

351

354

355

356

359

360

361 PMS.push(LPPM);

362 }

363

364 LPPM->add(this);

365}

366

368 return "loop";

369}

370

372 const Function *F = L->getHeader()->getParent();

373 if (F)

374 return false;

375

376 OptPassGate &Gate = F->getContext().getOptPassGate();

379 return true;

380

381 if (F->hasOptNone()) {

382

384 << F->getName() << "\n");

385

386 return true;

387 }

388 return false;

389}

390

393}

394

397 false, false)

Analysis containing CSE Info

static std::string getDescription(const CallGraphSCC &SCC)

static unsigned InstrCount

static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")

Module.h This file contains the declarations for the Module class.

static void addLoopIntoQueue(Loop *L, std::deque< Loop * > &LQ)

This file declares the interface for bisecting optimizations.

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

This header defines classes/functions to handle pass execution timing information with interfaces for...

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

Represent the analysis usage information of a pass.

void setPreservesAll()

Set by analyses that do not transform their input at all.

LLVM Basic Block Representation.

Legacy analysis pass which computes a DominatorTree.

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

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

bool runOnFunction(Function &F) override

run - Execute all of the passes scheduled for execution.

Pass * getAsPass() override

void dumpPassStructure(unsigned Offset) override

Print passes managed by this manager.

void markLoopAsDeleted(Loop &L)

LoopPass * getContainedPass(unsigned N)

void getAnalysisUsage(AnalysisUsage &Info) const override

Pass Manager itself does not invalidate any analysis info.

bool contains(const LoopT *L) const

Return true if the specified loop is contained within in this loop.

void verifyLoop() const

Verify loop structure.

BlockT * getHeader() const

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

void preparePassManager(PMStack &PMS) override

Check if available pass managers are suitable for this pass or not.

Pass * createPrinterPass(raw_ostream &O, const std::string &Banner) const override

getPrinterPass - Get a pass to print the function corresponding to a Loop.

virtual bool runOnLoop(Loop *L, LPPassManager &LPM)=0

void assignPassManager(PMStack &PMS, PassManagerType PMT) override

Assign pass manager to manage this pass.

bool skipLoop(const Loop *L) const

Optional passes call this function to check whether the pass should be skipped.

Represents a single loop in the control flow graph.

StringRef getName() const

bool isRecursivelyLCSSAForm(const DominatorTree &DT, const LoopInfo &LI, bool IgnoreTokens=true) const

Return true if this Loop and all inner subloops are in LCSSA form.

A Module instance is used to store all the information related to an LLVM module.

Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...

virtual bool isEnabled() const

isEnabled() should return true before calling shouldRunPass().

virtual bool shouldRunPass(const StringRef PassName, StringRef IRDescription)

IRDescription is a textual description of the IR unit the pass is running over.

PMDataManager provides the common place to manage the analysis data used by pass managers.

void removeDeadPasses(Pass *P, StringRef Msg, enum PassDebuggingString)

Remove dead passes used by P.

void dumpLastUses(Pass *P, unsigned Offset) const

void recordAvailableAnalysis(Pass *P)

Augment AvailableAnalysis by adding analysis made available by pass P.

PMTopLevelManager * getTopLevelManager()

unsigned initSizeRemarkInfo(Module &M, StringMap< std::pair< unsigned, unsigned > > &FunctionToInstrCount)

Set the initial size of the module if the user has specified that they want remarks for size.

void dumpRequiredSet(const Pass *P) const

void initializeAnalysisImpl(Pass *P)

All Required analyses should be available to the pass as it runs! Here we fill in the AnalysisImpls m...

void verifyPreservedAnalysis(Pass *P)

verifyPreservedAnalysis – Verify analysis presreved by pass P.

void freePass(Pass *P, StringRef Msg, enum PassDebuggingString)

Remove P.

bool preserveHigherLevelAnalysis(Pass *P)

unsigned getNumContainedPasses() const

virtual PassManagerType getPassManagerType() const

void emitInstrCountChangedRemark(Pass *P, Module &M, int64_t Delta, unsigned CountBefore, StringMap< std::pair< unsigned, unsigned > > &FunctionToInstrCount, Function *F=nullptr)

Emit a remark signifying that the number of IR instructions in the module changed.

void add(Pass *P, bool ProcessAnalysis=true)

Add pass P into the PassVector.

void populateInheritedAnalysis(PMStack &PMS)

void dumpPreservedSet(const Pass *P) const

void removeNotPreservedAnalysis(Pass *P)

Remove Analysis that is not preserved by the pass.

void dumpPassInfo(Pass *P, enum PassDebuggingString S1, enum PassDebuggingString S2, StringRef Msg)

PMStack - This class implements a stack data structure of PMDataManager pointers.

PMDataManager * top() const

void push(PMDataManager *PM)

PMTopLevelManager manages LastUser info and collects common APIs used by top level pass managers.

void addIndirectPassManager(PMDataManager *Manager)

void schedulePass(Pass *P)

Schedule pass P for execution.

PassManagerPrettyStackEntry - This is used to print informative information about what pass is runnin...

static PassRegistry * getPassRegistry()

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

Pass interface - Implemented by all 'passes'.

bool mustPreserveAnalysisID(char &AID) const

mustPreserveAnalysisID - This method serves the same function as getAnalysisIfAvailable,...

virtual void getAnalysisUsage(AnalysisUsage &) const

getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

StringRef - Represent a constant reference to a string, i.e.

The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...

The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.

StringRef getName() const

Return a constant reference to the value's name.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & indent(unsigned NumSpaces)

indent - Insert 'NumSpaces' spaces.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

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

This is an optimization pass for GlobalISel generic memory operations.

void initializeLCSSAVerificationPassPass(PassRegistry &)

PassManagerType

Different types of internal pass managers.

@ PMT_LoopPassManager

LPPassManager.

void erase(Container &C, ValueType V)

Wrapper function to remove a value from a container:

Timer * getPassTimer(Pass *)

Request the timer for this legacy-pass-manager's pass instance.

auto reverse(ContainerTy &&C)

raw_ostream & dbgs()

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

bool isFunctionInPrintList(StringRef FunctionName)

raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

void printLoop(Loop &L, raw_ostream &OS, const std::string &Banner="")

Function to print a loop's contents as LLVM's text IR assembly.