LLVM: lib/Remarks/BitstreamRemarkParser.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

17#include

18

19using namespace llvm;

21

22namespace {

23

24template <typename... Ts> Error error(char const *Fmt, const Ts &...Vals) {

25 std::string Buffer;

27 OS << formatv(Fmt, Vals...);

29 std::move(Buffer),

30 std::make_error_code(std::errc::illegal_byte_sequence));

31}

32

33}

34

36 return error("Unknown record entry ({}).", AbbrevID);

37}

38

40 return error("Unexpected record entry ({}).", RecordName);

41}

42

44 return error("Malformed record entry ({}).", RecordName);

45}

46

48 return error("Unexpected subblock ({}).", Code);

49}

50

54 return Next.takeError();

55 switch (Next->Kind) {

57 return Next->ID;

60 return error("Expected subblock, but got unexpected record.");

62 return error("Expected subblock, but got unexpected end of bitstream.");

63 }

65}

66

69 if (!MaybeBlockID)

70 return MaybeBlockID.takeError();

71 if (*MaybeBlockID != BlockID)

72 return error("Expected {} block, but got unexpected block ({}).", BlockName,

73 *MaybeBlockID);

75}

76

82

84

85

89 if (!RecordID)

91

92 switch (*RecordID) {

94 if (Record.size() != 2)

97

98

100 return ::error(

101 "Unsupported remark container version (expected: {}, read: {}). "

102 "Please upgrade/downgrade your toolchain to read this container.",

104 }

105 break;

106 }

108 if (Record.size() != 1)

111

112

114 return ::error(

115 "Unsupported remark version in container (expected: {}, read: {}). "

116 "Please upgrade/downgrade your toolchain to read this container.",

118 }

119 break;

120 }

122 if (Record.size() != 0)

125 break;

126 }

128 if (Record.size() != 0)

131 break;

132 }

133 default:

135 }

137}

138

143 if (!MaybeRecordID)

144 return MaybeRecordID.takeError();

147}

148

152 if (Record.size() != 4)

158 break;

159 }

161 if (Record.size() != 3)

164 break;

165 }

167 if (Record.size() != 1)

170 break;

171 }

173 if (Record.size() != 5)

177 break;

178 }

180 if (Record.size() != 2)

183 break;

184 }

185 default:

187 }

189}

190

192 Type.reset();

197 Loc.reset();

198 Args.clear();

199

201}

202

204 std::array<char, 4> Result;

205 for (unsigned I = 0; I < 4; ++I)

207 Result[I] = *R;

208 else

209 return R.takeError();

210

213 return error("Unknown magic number: expecting {}, got {}.",

216}

217

221 return Next.takeError();

225 "Error while parsing BLOCKINFO_BLOCK: expecting [ENTER_SUBBLOCK, "

226 "BLOCKINFO_BLOCK, ...].");

227

229 Stream.ReadBlockInfoBlock();

230 if (!MaybeBlockInfo)

231 return MaybeBlockInfo.takeError();

232

233 if (!*MaybeBlockInfo)

234 return error("Missing BLOCKINFO_BLOCK.");

235

237

240}

241

244 return E;

246 return E;

247

248

250 return E;

252 return E;

253

254

255 while (Stream.AtEndOfStream()) {

257 if (!MaybeBlockID)

258 return MaybeBlockID.takeError();

260 break;

262 return error("Unexpected block between meta blocks.");

263

267 return E;

268 }

269

270

271 if (Stream.AtEndOfStream())

273

274

276 return E;

278}

279

283 } else {

285 if (!MaybeBlockID)

286 return MaybeBlockID.takeError();

289 }

291}

292

295 StringRef Buf, std::optional ExternalFilePrependPath) {

296 auto Parser = std::make_unique(Buf);

297

298 if (ExternalFilePrependPath)

299 Parser->ExternalFilePrependPath = std::string(*ExternalFilePrependPath);

300

301 return std::move(Parser);

302}

303

306

309

312

314 return std::move(E);

316

317

320 "Container is non-empty, but does not contain any remarks blocks.");

321

324 return std::move(E);

326 }

327

329 return std::move(E);

330 return processRemark();

331}

332

335 return E;

336 if (Error E = processCommonMeta())

337 return E;

338

341 return processExternalFilePath();

343 return processFileContainerMeta();

344 }

345 llvm_unreachable("Unknown BitstreamRemarkContainerType enum");

346}

347

348Error BitstreamRemarkParser::processCommonMeta() {

350 if (!Helper.Container)

351 return Helper.error("Missing container info.");

352 auto &Container = *Helper.Container;

354

356 return Helper.error("Invalid container type.");

359}

360

361Error BitstreamRemarkParser::processFileContainerMeta() {

362 if (Error E = processRemarkVersion())

363 return E;

364 if (Error E = processStrTab())

365 return E;

367}

368

369Error BitstreamRemarkParser::processStrTab() {

371 if (!Helper.StrTabBuf)

372 return Helper.error("Missing string table.");

373

374 StrTab.emplace(*Helper.StrTabBuf);

376}

377

378Error BitstreamRemarkParser::processRemarkVersion() {

380 if (!Helper.RemarkVersion)

381 return Helper.error("Missing remark version.");

384}

385

386Error BitstreamRemarkParser::processExternalFilePath() {

388 if (!Helper.ExternalFilePath)

389 return Helper.error("Missing external file path.");

390

393

394

395

396

397 ErrorOr<std::unique_ptr> BufferOrErr =

399 if (std::error_code EC = BufferOrErr.getError())

401

403

404

407

408

411 return E;

412

415 "Wrong container type in external file.");

416

418}

419

420Expected<std::unique_ptr> BitstreamRemarkParser::processRemark() {

422 std::unique_ptr Result = std::make_unique();

424

426 return Helper.error("Missing string table.");

427

428 if (!Helper.Type)

429 return Helper.error("Missing remark type.");

430

431

432 if (*Helper.Type > static_cast<uint8_t>(Type::Last))

433 return Helper.error("Unknown remark type.");

434

435 R.RemarkType = static_cast<Type>(*Helper.Type);

436

437 if (!Helper.RemarkNameIdx)

438 return Helper.error("Missing remark name.");

439

440 if (Expected RemarkName = (*StrTab)[*Helper.RemarkNameIdx])

441 R.RemarkName = *RemarkName;

442 else

443 return RemarkName.takeError();

444

445 if (!Helper.PassNameIdx)

446 return Helper.error("Missing remark pass.");

447

448 if (Expected PassName = (*StrTab)[*Helper.PassNameIdx])

450 else

452

453 if (!Helper.FunctionNameIdx)

454 return Helper.error("Missing remark function name.");

455

456 if (Expected FunctionName = (*StrTab)[*Helper.FunctionNameIdx])

457 R.FunctionName = *FunctionName;

458 else

459 return FunctionName.takeError();

460

461 if (Helper.Loc) {

462 Expected SourceFileName =

463 (*StrTab)[Helper.Loc->SourceFileNameIdx];

464 if (!SourceFileName)

465 return SourceFileName.takeError();

466 R.Loc.emplace();

467 R.Loc->SourceFilePath = *SourceFileName;

468 R.Loc->SourceLine = Helper.Loc->SourceLine;

469 R.Loc->SourceColumn = Helper.Loc->SourceColumn;

470 }

471

472 if (Helper.Hotness)

473 R.Hotness = *Helper.Hotness;

474

475 for (const BitstreamRemarkParserHelper::Argument &Arg : Helper.Args) {

477 return Helper.error("Missing key in remark argument.");

479 return Helper.error("Missing value in remark argument.");

480

481

482 auto &RArg = R.Args.emplace_back();

483

485 RArg.Key = *Key;

486 else

487 return Key.takeError();

488

490 RArg.Val = *Value;

491 else

492 return Value.takeError();

493

494 if (Arg.Loc) {

495 if (Expected SourceFileName =

496 (*StrTab)[Arg.Loc->SourceFileNameIdx]) {

497 RArg.Loc.emplace();

498 RArg.Loc->SourceFilePath = *SourceFileName;

499 RArg.Loc->SourceLine = Arg.Loc->SourceLine;

500 RArg.Loc->SourceColumn = Arg.Loc->SourceColumn;

501 } else

502 return SourceFileName.takeError();

503 }

504 }

505

506 return std::move(Result);

507}

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static const char PassName[]

This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.

Expected< BitstreamEntry > advance(unsigned Flags=0)

Advance the current bitstream, returning the next entry in the stream.

std::error_code getError() const

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.

Error takeError()

Take ownership of the stored error.

static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)

Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...

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.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

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

@ BLOCKINFO_BLOCK_ID

BLOCKINFO_BLOCK is used to define metadata about blocks, for example, standard abbrevs that should be...

LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

Error createFileError(const Twine &F, Error E)

Concatenate a source file path and/or name with an Error.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

FunctionAddr VTableAddr Next