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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

79#include

80#include

81#include

82

83using namespace llvm;

85

86#define DEBUG_TYPE "symbol-rewriter"

87

89 cl::desc("Symbol Rewrite Map"),

92

94 const std::string &Source,

95 const std::string &Target) {

97 auto &Comdats = M.getComdatSymbolTable();

98

100 C->setSelectionKind(CD->getSelectionKind());

102

103 Comdats.erase(Comdats.find(Source));

104 }

105}

106

107namespace {

108

112public:

113 const std::string Source;

114 const std::string Target;

115

116 ExplicitRewriteDescriptor(StringRef S, StringRef T, const bool Naked)

117 : RewriteDescriptor(DT),

118 Source(std::string(Naked ? StringRef("\01" + S.str()) : S)),

119 Target(std::string(T)) {}

120

121 bool performOnModule(Module &M) override;

122

123 static bool classof(const RewriteDescriptor *RD) {

124 return RD->getType() == DT;

125 }

126};

127

128}

129

132bool ExplicitRewriteDescriptor<DT, ValueType, Get>::performOnModule(Module &M) {

134 if (ValueType *S = (M.*Get)(Source)) {

137

139 S->setValueName(T->getValueName());

140 else

142

144 }

146}

147

148namespace {

149

153 (Module::*Iterator)()>

155public:

156 const std::string Pattern;

157 const std::string Transform;

158

159 PatternRewriteDescriptor(StringRef P, StringRef T)

160 : RewriteDescriptor(DT), Pattern(std::string(P)),

161 Transform(std::string(T)) {}

162

163 bool performOnModule(Module &M) override;

164

165 static bool classof(const RewriteDescriptor *RD) {

166 return RD->getType() == DT;

167 }

168};

169

170}

171

175 (Module::*Iterator)()>

176bool PatternRewriteDescriptor<DT, ValueType, Get, Iterator>::

177performOnModule(Module &M) {

179 for (auto &C : (M.*Iterator)()) {

180 std::string Error;

181

183 if (Error.empty())

185 M.getModuleIdentifier() + ": " + Error);

186

187 if (C.getName() == Name)

188 continue;

189

191 rewriteComdat(M, GO, std::string(C.getName()), Name);

192

193 if (Value *V = (M.*Get)(Name))

194 C.setValueName(V->getValueName());

195 else

196 C.setName(Name);

197

199 }

201}

202

203namespace {

204

205

206

207

208using ExplicitRewriteFunctionDescriptor =

209 ExplicitRewriteDescriptor<RewriteDescriptor::Type::Function, Function,

211

212

213

214

215using ExplicitRewriteGlobalVariableDescriptor =

216 ExplicitRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,

218

219

220

221using ExplicitRewriteNamedAliasDescriptor =

222 ExplicitRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,

224

225

226

227

228using PatternRewriteFunctionDescriptor =

229 PatternRewriteDescriptor<RewriteDescriptor::Type::Function, Function,

231

232

233

234

235

236using PatternRewriteGlobalVariableDescriptor =

237 PatternRewriteDescriptor<RewriteDescriptor::Type::GlobalVariable,

240

241

242

243

244using PatternRewriteNamedAliasDescriptor =

245 PatternRewriteDescriptor<RewriteDescriptor::Type::NamedAlias, GlobalAlias,

247

248}

249

254

255 if (!Mapping)

257 "': " + Mapping.getError().message());

258

259 if (parse(*Mapping, DL))

261

262 return true;

263}

264

269

270 for (auto &Document : YS) {

272

273

275 continue;

276

278 if (!DescriptorList) {

279 YS.printError(Document.getRoot(), "DescriptorList node must be a map");

280 return false;

281 }

282

283 for (auto &Descriptor : *DescriptorList)

284 if (!parseEntry(YS, Descriptor, DL))

285 return false;

286 }

287

288 return true;

289}

290

291bool RewriteMapParser::parseEntry(yaml::Stream &YS, yaml::KeyValueNode &Entry,

293 yaml::ScalarNode *Key;

294 yaml::MappingNode *Value;

295 SmallString<32> KeyStorage;

296 StringRef RewriteType;

297

299 if (Key) {

300 YS.printError(Entry.getKey(), "rewrite type must be a scalar");

301 return false;

302 }

303

306 YS.printError(Entry.getValue(), "rewrite descriptor must be a map");

307 return false;

308 }

309

310 RewriteType = Key->getValue(KeyStorage);

311 if (RewriteType == "function")

312 return parseRewriteFunctionDescriptor(YS, Key, Value, DL);

313 else if (RewriteType == "global variable")

314 return parseRewriteGlobalVariableDescriptor(YS, Key, Value, DL);

315 else if (RewriteType == "global alias")

316 return parseRewriteGlobalAliasDescriptor(YS, Key, Value, DL);

317

319 return false;

320}

321

322bool RewriteMapParser::

323parseRewriteFunctionDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,

324 yaml::MappingNode *Descriptor,

326 bool Naked = false;

329 std::string Transform;

330

331 for (auto &Field : *Descriptor) {

332 yaml::ScalarNode *Key;

333 yaml::ScalarNode *Value;

334 SmallString<32> KeyStorage;

335 SmallString<32> ValueStorage;

336 StringRef KeyValue;

337

339 if (Key) {

340 YS.printError(Field.getKey(), "descriptor key must be a scalar");

341 return false;

342 }

343

346 YS.printError(Field.getValue(), "descriptor value must be a scalar");

347 return false;

348 }

349

350 KeyValue = Key->getValue(KeyStorage);

351 if (KeyValue == "source") {

352 Source = std::string(Value->getValue(ValueStorage));

353 } else if (KeyValue == "target") {

354 Target = std::string(Value->getValue(ValueStorage));

355 } else if (KeyValue == "transform") {

356 Transform = std::string(Value->getValue(ValueStorage));

357 } else if (KeyValue == "naked") {

358 std::string Undecorated;

359

360 Undecorated = std::string(Value->getValue(ValueStorage));

361 Naked = StringRef(Undecorated).lower() == "true" || Undecorated == "1";

362 } else {

363 YS.printError(Field.getKey(), "unknown key for function");

364 return false;

365 }

366 }

367

368 if (Transform.empty() == Target.empty()) {

370 "exactly one of transform or target must be specified");

371 return false;

372 }

373

374

375

376 if (Target.empty()) {

377 DL->push_back(std::make_unique(

378 Source, Target, Naked));

379 return true;

380 }

381

382 {

383 std::string Error;

385 YS.printError(Descriptor, "invalid Source regex: " + Error);

386 return false;

387 }

388 }

389

391 std::make_unique(Source, Transform));

392

393 return true;

394}

395

396bool RewriteMapParser::

397parseRewriteGlobalVariableDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,

398 yaml::MappingNode *Descriptor,

402 std::string Transform;

403

404 for (auto &Field : *Descriptor) {

405 yaml::ScalarNode *Key;

406 yaml::ScalarNode *Value;

407 SmallString<32> KeyStorage;

408 SmallString<32> ValueStorage;

409 StringRef KeyValue;

410

412 if (Key) {

413 YS.printError(Field.getKey(), "descriptor Key must be a scalar");

414 return false;

415 }

416

419 YS.printError(Field.getValue(), "descriptor value must be a scalar");

420 return false;

421 }

422

423 KeyValue = Key->getValue(KeyStorage);

424 if (KeyValue == "source") {

425 Source = std::string(Value->getValue(ValueStorage));

426 } else if (KeyValue == "target") {

427 Target = std::string(Value->getValue(ValueStorage));

428 } else if (KeyValue == "transform") {

429 Transform = std::string(Value->getValue(ValueStorage));

430 } else {

431 YS.printError(Field.getKey(), "unknown Key for Global Variable");

432 return false;

433 }

434 }

435

436 if (Transform.empty() == Target.empty()) {

438 "exactly one of transform or target must be specified");

439 return false;

440 }

441

442 if (Target.empty()) {

443 DL->push_back(std::make_unique(

444 Source, Target,

445 false));

446 return true;

447 }

448

449 {

450 std::string Error;

452 YS.printError(Descriptor, "invalid Source regex: " + Error);

453 return false;

454 }

455 }

456

457 DL->push_back(std::make_unique(

458 Source, Transform));

459

460 return true;

461}

462

463bool RewriteMapParser::

464parseRewriteGlobalAliasDescriptor(yaml::Stream &YS, yaml::ScalarNode *K,

465 yaml::MappingNode *Descriptor,

469 std::string Transform;

470

471 for (auto &Field : *Descriptor) {

472 yaml::ScalarNode *Key;

473 yaml::ScalarNode *Value;

474 SmallString<32> KeyStorage;

475 SmallString<32> ValueStorage;

476 StringRef KeyValue;

477

479 if (Key) {

480 YS.printError(Field.getKey(), "descriptor key must be a scalar");

481 return false;

482 }

483

486 YS.printError(Field.getValue(), "descriptor value must be a scalar");

487 return false;

488 }

489

490 KeyValue = Key->getValue(KeyStorage);

491 if (KeyValue == "source") {

492 Source = std::string(Value->getValue(ValueStorage));

493 } else if (KeyValue == "target") {

494 Target = std::string(Value->getValue(ValueStorage));

495 } else if (KeyValue == "transform") {

496 Transform = std::string(Value->getValue(ValueStorage));

497 } else {

498 YS.printError(Field.getKey(), "unknown key for Global Alias");

499 return false;

500 }

501 }

502

503 if (Transform.empty() == Target.empty()) {

505 "exactly one of transform or target must be specified");

506 return false;

507 }

508

509 if (Target.empty()) {

510 DL->push_back(std::make_unique(

511 Source, Target,

512 false));

513 return true;

514 }

515

516 {

517 std::string Error;

519 YS.printError(Descriptor, "invalid Source regex: " + Error);

520 return false;

521 }

522 }

523

525 std::make_unique(Source, Transform));

526

527 return true;

528}

529

536

539

541 for (auto &Descriptor : Descriptors)

542 Changed |= Descriptor->performOnModule(M);

543

545}

546

547void RewriteSymbolPass::loadAndParseMapFiles() {

548 const std::vectorstd::string MapFiles(RewriteMapFiles);

550

551 for (const auto &MapFile : MapFiles)

552 Parser.parse(MapFile, &Descriptors);

553}

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Provides ErrorOr smart pointer.

static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)

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

Machine Check Debug Module

OptimizedStructLayoutField Field

static bool isValid(const char C)

Returns true if C is a valid mangled character: <0-9a-zA-Z_>.

This file defines the SmallString class.

static cl::list< std::string > RewriteMapFiles("rewrite-map-file", cl::desc("Symbol Rewrite Map"), cl::value_desc("filename"), cl::Hidden)

static void rewriteComdat(Module &M, GlobalObject *GO, const std::string &Source, const std::string &Target)

Definition SymbolRewriter.cpp:93

Represents either an error or a value T.

std::error_code getError() const

Lightweight error class with error context and mandatory checking.

LLVM_ABI void setComdat(Comdat *C)

const Comdat * getComdat() const

void push_back(MachineInstr *MI)

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

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

Function * getFunction(StringRef Name) const

Look up the specified function in the module symbol table.

iterator_range< iterator > functions()

iterator_range< alias_iterator > aliases()

iterator_range< global_iterator > globals()

GlobalVariable * getGlobalVariable(StringRef Name) const

Look up the specified global variable in the module symbol table.

GlobalAlias * getNamedAlias(StringRef Name) const

Return the global alias in the module with the specified name, of arbitrary type.

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

LLVM_ABI std::string sub(StringRef Repl, StringRef String, std::string *Error=nullptr) const

sub - Return the result of replacing the first match of the regex in String with the Repl string.

LLVM_ABI bool runImpl(Module &M)

Definition SymbolRewriter.cpp:537

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition SymbolRewriter.cpp:530

This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.

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

The basic entity representing a rewrite operation.

LLVM_ABI bool parse(const std::string &MapFile, RewriteDescriptorList *Descriptors)

Definition SymbolRewriter.cpp:250

Target - Wrapper for Target specific information.

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

LLVM Value Representation.

A range adaptor for a pair of iterators.

Represents a YAML map created from either a block map for a flow map.

This class represents a YAML stream potentially containing multiple documents.

LLVM_ABI void printError(Node *N, const Twine &Msg, SourceMgr::DiagKind Kind=SourceMgr::DK_Error)

This file defines classes to implement an intrusive doubly linked list class (i.e.

This provides a very simple, boring adaptor for a begin and end iterator into a range type.

This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.

@ C

The default llvm calling convention, compatible with C.

std::list< std::unique_ptr< RewriteDescriptor > > RewriteDescriptorList

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

decltype(auto) dyn_cast(const From &Val)

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

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

bool isa(const From &Val)

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

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

PointerUnion< const Value *, const PseudoSourceValue * > ValueType

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.