LLVM: lib/CodeGen/BasicBlockSectionsProfileReader.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

31

32using namespace llvm;

33

36 "bbsections-profile-reader",

37 "Reads and parses a basic block sections profile.", false,

38 false)

39

43 S.split(Parts, '.');

44 if (Parts.size() > 2)

45 return createProfileParseError(Twine("unable to parse basic block id: '") +

46 S + "'");

47 unsigned long long BaseBBID;

49 return createProfileParseError(

50 Twine("unable to parse BB id: '" + Parts[0]) +

51 "': unsigned integer expected");

52 unsigned long long CloneID = 0;

54 return createProfileParseError(Twine("unable to parse clone id: '") +

55 Parts[1] + "': unsigned integer expected");

56 return UniqueBBID{static_cast<unsigned>(BaseBBID),

57 static_cast<unsigned>(CloneID)};

58}

59

62}

63

67 auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));

68 return R != ProgramPathAndClusterInfo.end() ? R->second.ClusterInfo

70}

71

75 auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));

76 return R != ProgramPathAndClusterInfo.end()

77 ? R->second.ClonePaths

79}

80

84 auto It = ProgramPathAndClusterInfo.find(getAliasName(FuncName));

85 if (It == ProgramPathAndClusterInfo.end())

86 return 0;

87 auto NodeIt = It->second.EdgeCounts.find(SrcBBID);

88 if (NodeIt == It->second.EdgeCounts.end())

89 return 0;

90 auto EdgeIt = NodeIt->second.find(SinkBBID);

91 if (EdgeIt == NodeIt->second.end())

92 return 0;

93 return EdgeIt->second;

94}

95

96std::pair<bool, FunctionPathAndClusterInfo>

99 auto R = ProgramPathAndClusterInfo.find(getAliasName(FuncName));

100 return R != ProgramPathAndClusterInfo.end()

101 ? std::pair(true, R->second)

102 : std::pair(false, FunctionPathAndClusterInfo());

103}

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160Error BasicBlockSectionsProfileReader::ReadV1Profile() {

161 auto FI = ProgramPathAndClusterInfo.end();

162

163

164 unsigned CurrentCluster = 0;

165

166 unsigned CurrentPosition = 0;

167

168

169

170 DenseSet FuncBBIDs;

171

172

173

174 StringRef DIFilename;

175

176 for (; !LineIt.is_at_eof(); ++LineIt) {

177 StringRef S(*LineIt);

179 S = S.drop_front().trim();

181 S.split(Values, ' ');

182 switch (Specifier) {

183 case '@':

184 continue;

185 case 'm':

186 if (Values.size() != 1) {

187 return createProfileParseError(Twine("invalid module name value: '") +

188 S + "'");

189 }

191 continue;

192 case 'f': {

193 bool FunctionFound = any_of(Values, [&](StringRef Alias) {

194 auto It = FunctionNameToDIFilename.find(Alias);

195

196 if (It == FunctionNameToDIFilename.end())

197 return false;

198

199

200 return DIFilename.empty() || It->second == DIFilename;

201 });

202 if (!FunctionFound) {

203

204

205 FI = ProgramPathAndClusterInfo.end();

206 DIFilename = "";

207 continue;

208 }

209 for (size_t i = 1; i < Values.size(); ++i)

210 FuncAliasMap.try_emplace(Values[i], Values.front());

211

212

213

214 auto R = ProgramPathAndClusterInfo.try_emplace(Values.front());

215

216

217 if (R.second)

218 return createProfileParseError("duplicate profile for function '" +

219 Values.front() + "'");

220 FI = R.first;

221 CurrentCluster = 0;

222 FuncBBIDs.clear();

223

224

225 DIFilename = "";

226 continue;

227 }

228 case 'c':

229

230

231 if (FI == ProgramPathAndClusterInfo.end())

232 continue;

233

234 CurrentPosition = 0;

235 for (auto BasicBlockIDStr : Values) {

236 auto BasicBlockID = parseUniqueBBID(BasicBlockIDStr);

237 if (!BasicBlockID)

238 return BasicBlockID.takeError();

239 if (!FuncBBIDs.insert(*BasicBlockID).second)

240 return createProfileParseError(

241 Twine("duplicate basic block id found '") + BasicBlockIDStr +

242 "'");

243

244 FI->second.ClusterInfo.emplace_back(BBClusterInfo{

245 *std::move(BasicBlockID), CurrentCluster, CurrentPosition++});

246 }

247 CurrentCluster++;

248 continue;

249 case 'p': {

250

251

252 if (FI == ProgramPathAndClusterInfo.end())

253 continue;

254 SmallSet<unsigned, 5> BBsInPath;

255 FI->second.ClonePaths.push_back({});

256 for (size_t I = 0; I < Values.size(); ++I) {

257 auto BaseBBIDStr = Values[I];

258 unsigned long long BaseBBID = 0;

260 return createProfileParseError(Twine("unsigned integer expected: '") +

261 BaseBBIDStr + "'");

262 if (I != 0 && !BBsInPath.insert(BaseBBID).second)

263 return createProfileParseError(

264 Twine("duplicate cloned block in path: '") + BaseBBIDStr + "'");

265 FI->second.ClonePaths.back().push_back(BaseBBID);

266 }

267 continue;

268 }

269 case 'g': {

270

271

272 if (FI == ProgramPathAndClusterInfo.end())

273 continue;

274

275

276 for (auto BasicBlockEdgeProfile : Values) {

277 if (BasicBlockEdgeProfile.empty())

278 continue;

280 BasicBlockEdgeProfile.split(NodeEdgeCounts, ',');

281 UniqueBBID SrcBBID;

282 for (size_t i = 0; i < NodeEdgeCounts.size(); ++i) {

283 auto [BBIDStr, CountStr] = NodeEdgeCounts[i].split(':');

284 auto BBID = parseUniqueBBID(BBIDStr);

285 if (!BBID)

286 return BBID.takeError();

287 unsigned long long Count = 0;

289 return createProfileParseError(

290 Twine("unsigned integer expected: '") + CountStr + "'");

291 if (i == 0) {

292

293 FI->second.NodeCounts[SrcBBID = *BBID] = Count;

294 continue;

295 }

296 FI->second.EdgeCounts[SrcBBID][*BBID] = Count;

297 }

298 }

299 continue;

300 }

301 case 'h': {

302

303

304 if (FI == ProgramPathAndClusterInfo.end())

305 continue;

306 for (auto BBIDHashStr : Values) {

307 auto [BBIDStr, HashStr] = BBIDHashStr.split(':');

308 unsigned long long BBID = 0, Hash = 0;

310 return createProfileParseError(Twine("unsigned integer expected: '") +

311 BBIDStr + "'");

313 return createProfileParseError(

314 Twine("unsigned integer expected in hex format: '") + HashStr +

315 "'");

316 FI->second.BBHashes[BBID] = Hash;

317 }

318 continue;

319 }

320 default:

321 return createProfileParseError(Twine("invalid specifier: '") +

322 Twine(Specifier) + "'");

323 }

324 llvm_unreachable("should not break from this switch statement");

325 }

327}

328

329Error BasicBlockSectionsProfileReader::ReadV0Profile() {

330 auto FI = ProgramPathAndClusterInfo.end();

331

332 unsigned CurrentCluster = 0;

333

334 unsigned CurrentPosition = 0;

335

336

337

338 SmallSet<unsigned, 4> FuncBBIDs;

339

340 for (; !LineIt.is_at_eof(); ++LineIt) {

341 StringRef S(*LineIt);

342 if (S[0] == '@')

343 continue;

344

345 if (!S.consume_front("!") || S.empty())

346 break;

347

348 if (S.consume_front("!")) {

349

350

351 if (FI == ProgramPathAndClusterInfo.end())

352 continue;

354 S.split(BBIDs, ' ');

355

356 CurrentPosition = 0;

357 for (auto BBIDStr : BBIDs) {

358 unsigned long long BBID;

360 return createProfileParseError(Twine("unsigned integer expected: '") +

361 BBIDStr + "'");

362 if (!FuncBBIDs.insert(BBID).second)

363 return createProfileParseError(

364 Twine("duplicate basic block id found '") + BBIDStr + "'");

365

366 FI->second.ClusterInfo.emplace_back(

367 BBClusterInfo({{static_cast<unsigned>(BBID), 0},

368 CurrentCluster,

369 CurrentPosition++}));

370 }

371 CurrentCluster++;

372 } else {

373

374

375 auto [AliasesStr, DIFilenameStr] = S.split(' ');

376 SmallString<128> DIFilename;

377 if (DIFilenameStr.starts_with("M=")) {

378 DIFilename =

380 if (DIFilename.empty())

381 return createProfileParseError("empty module name specifier");

382 } else if (!DIFilenameStr.empty()) {

383 return createProfileParseError("unknown string found: '" +

384 DIFilenameStr + "'");

385 }

386

387

388

390 AliasesStr.split(Aliases, '/');

391 bool FunctionFound = any_of(Aliases, [&](StringRef Alias) {

392 auto It = FunctionNameToDIFilename.find(Alias);

393

394 if (It == FunctionNameToDIFilename.end())

395 return false;

396

397

398 return DIFilename.empty() || It->second == DIFilename;

399 });

400 if (!FunctionFound) {

401

402

403 FI = ProgramPathAndClusterInfo.end();

404 continue;

405 }

406 for (size_t i = 1; i < Aliases.size(); ++i)

407 FuncAliasMap.try_emplace(Aliases[i], Aliases.front());

408

409

410

411 auto R = ProgramPathAndClusterInfo.try_emplace(Aliases.front());

412

413

414 if (R.second)

415 return createProfileParseError("duplicate profile for function '" +

416 Aliases.front() + "'");

417 FI = R.first;

418 CurrentCluster = 0;

419 FuncBBIDs.clear();

420 }

421 }

423}

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442Error BasicBlockSectionsProfileReader::ReadProfile() {

444

445 unsigned long long Version = 0;

446 StringRef FirstLine(*LineIt);

447 if (FirstLine.consume_front("v")) {

449 return createProfileParseError(Twine("version number expected: '") +

450 FirstLine + "'");

451 }

453 return createProfileParseError(Twine("invalid profile version: ") +

455 }

456 ++LineIt;

457 }

458

460 case 0:

461

462 return ReadV0Profile();

463 case 1:

464 return ReadV1Profile();

465 default:

467 }

468}

469

472 return false;

473

474 BBSPR.FunctionNameToDIFilename.clear();

477 if (F.isDeclaration())

478 continue;

480 if (Subprogram) {

482 if (CU)

484 }

485 [[maybe_unused]] bool inserted =

486 BBSPR.FunctionNameToDIFilename.try_emplace(F.getName(), DIFilename)

487 .second;

489 }

490 if (auto Err = BBSPR.ReadProfile())

492 return false;

493}

494

496

502

505 return BBSPR.isFunctionHot(FuncName);

506}

507

511 return BBSPR.getClusterInfoForFunction(FuncName);

512}

513

517 return BBSPR.getClonePathsForFunction(FuncName);

518}

519

523 return BBSPR.getEdgeCount(FuncName, SrcBBID, SinkBBID);

524}

525

526std::pair<bool, FunctionPathAndClusterInfo>

529 return BBSPR.getFunctionPathAndClusterInfo(FuncName);

530}

531

536

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file defines the StringMap class.

Function Alias Analysis false

This file defines the DenseSet and SmallDenseSet classes.

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

This file defines the SmallSet class.

This file defines the SmallString class.

This file defines the SmallVector class.

Result run(Function &F, FunctionAnalysisManager &AM)

Definition BasicBlockSectionsProfileReader.cpp:498

bool doInitialization(Module &M) override

doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...

Definition BasicBlockSectionsProfileReader.cpp:470

BasicBlockSectionsProfileReader BBSPR

BasicBlockSectionsProfileReader & getBBSPR()

Definition BasicBlockSectionsProfileReader.cpp:533

SmallVector< SmallVector< unsigned > > getClonePathsForFunction(StringRef FuncName) const

Definition BasicBlockSectionsProfileReader.cpp:515

SmallVector< BBClusterInfo > getClusterInfoForFunction(StringRef FuncName) const

Definition BasicBlockSectionsProfileReader.cpp:509

bool isFunctionHot(StringRef FuncName) const

Definition BasicBlockSectionsProfileReader.cpp:503

std::pair< bool, FunctionPathAndClusterInfo > getFunctionPathAndClusterInfo(StringRef FuncName) const

Definition BasicBlockSectionsProfileReader.cpp:527

uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID, const UniqueBBID &DestBBID) const

Definition BasicBlockSectionsProfileReader.cpp:520

std::pair< bool, FunctionPathAndClusterInfo > getFunctionPathAndClusterInfo(StringRef FuncName) const

bool isFunctionHot(StringRef FuncName) const

SmallVector< SmallVector< unsigned > > getClonePathsForFunction(StringRef FuncName) const

uint64_t getEdgeCount(StringRef FuncName, const UniqueBBID &SrcBBID, const UniqueBBID &SinkBBID) const

SmallVector< BBClusterInfo > getClusterInfoForFunction(StringRef FuncName) const

Subprogram description. Uses SubclassData1.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

ImmutablePass class - This class is used to provide information that does not need to be run.

This interface provides simple read-only access to a block of memory, and provides simple methods for...

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

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

constexpr bool empty() const

empty - Check if the string is empty.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

std::pair< iterator, bool > insert(const ValueT &V)

#define llvm_unreachable(msg)

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

LLVM_ABI StringRef remove_leading_dotslash(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)

Remove redundant leading "./" pieces and consecutive separators.

This is an optimization pass for GlobalISel generic memory operations.

ImmutablePass * createBasicBlockSectionsProfileReaderWrapperPass(const MemoryBuffer *Buf)

Definition BasicBlockSectionsProfileReader.cpp:537

bool any_of(R &&range, UnaryPredicate P)

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

FunctionAddr VTableAddr uintptr_t uintptr_t Version

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

FunctionAddr VTableAddr Count

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)

Helper functions for StringRef::getAsInteger.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

A special type used by analysis passes to provide an address that identifies that particular analysis...