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

1

2

3

4

5

6

7

8

9

10

11

12

13

41#include

42#include

43#include

44#include

45

46using namespace llvm;

47

48#define DEBUG_TYPE "value-mapper"

49

50

51void ValueMapTypeRemapper::anchor() {}

52void ValueMaterializer::anchor() {}

53

54namespace {

55

56

57

58struct DelayedBasicBlock {

60 std::unique_ptr TempBB;

61

62 DelayedBasicBlock(const BlockAddress &Old)

63 : OldBB(Old.getBasicBlock()),

65};

66

67struct WorklistEntry {

68 enum EntryKind {

69 MapGlobalInit,

70 MapAppendingVar,

71 MapAliasOrIFunc,

73 };

74 struct GVInitTy {

75 GlobalVariable *GV;

77 };

78 struct AppendingGVTy {

79 GlobalVariable *GV;

80 GlobalVariable *OldGV;

81 };

82 struct AliasOrIFuncTy {

83 GlobalValue *GV;

85 };

86

87 unsigned Kind : 2;

88 unsigned MCID : 29;

89 unsigned AppendingGVIsOldCtorDtor : 1;

90 unsigned AppendingGVNumNewMembers;

91 union {

92 GVInitTy GVInit;

93 AppendingGVTy AppendingGV;

94 AliasOrIFuncTy AliasOrIFunc;

97};

98

99struct MappingContext {

101 ValueMaterializer *Materializer = nullptr;

102

103

105 ValueMaterializer *Materializer = nullptr)

106 : VM(&VM), Materializer(Materializer) {}

107};

108

109class Mapper {

110 friend class MDNodeMapper;

111

112#ifndef NDEBUG

113 DenseSet<GlobalValue *> AlreadyScheduled;

114#endif

115

117 ValueMapTypeRemapper *TypeMapper;

118 unsigned CurrentMCID = 0;

124

125public:

127 ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer,

129 : Flags(Flags), TypeMapper(TypeMapper),

130 MCs(1, MappingContext(VM, Materializer)), IdentityMD(IdentityMD) {}

131

132

133 ~Mapper() { assert(!hasWorkToDo() && "Expected to be flushed"); }

134

135 bool hasWorkToDo() const { return !Worklist.empty(); }

136

137 unsigned

139 ValueMaterializer *Materializer = nullptr) {

140 MCs.push_back(MappingContext(VM, Materializer));

141 return MCs.size() - 1;

142 }

143

145

146 void remapGlobalObjectMetadata(GlobalObject &GO);

147

149 void remapInstruction(Instruction *I);

150 void remapFunction(Function &F);

151 void remapDbgRecord(DbgRecord &DVR);

152

153 Constant *mapConstant(const Constant *C) {

155 }

156

157

158

159

160

162

163 void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,

164 unsigned MCID);

165 void scheduleMapAppendingVariable(GlobalVariable &GV, GlobalVariable *OldGV,

166 bool IsOldCtorDtor,

168 unsigned MCID);

169 void scheduleMapAliasOrIFunc(GlobalValue &GV, Constant &Target,

170 unsigned MCID);

171 void scheduleRemapFunction(Function &F, unsigned MCID);

172

173 void flush();

174

175private:

176 void mapAppendingVariable(GlobalVariable &GV, GlobalVariable *OldGV,

177 bool IsOldCtorDtor,

179

181 ValueMaterializer *getMaterializer() { return MCs[CurrentMCID].Materializer; }

182

183 Value *mapBlockAddress(const BlockAddress &BA);

184

185

186 std::optional<Metadata *> mapSimpleMetadata(const Metadata *MD);

187

190};

191

192class MDNodeMapper {

193 Mapper &M;

194

195

196 struct Data {

197 bool HasChanged = false;

198 unsigned ID = std::numeric_limits::max();

199 TempMDNode Placeholder;

200 };

201

202

203 struct UniquedGraph {

204 SmallDenseMap<const Metadata *, Data, 32> Info;

206

207

208

209

210

211 void propagateChanges();

212

213

214 Metadata &getFwdReference(MDNode &Op);

215 };

216

217

219

220

221 SmallDenseMap<const Metadata *, Data, 32> InfoStorage;

223

224public:

225 MDNodeMapper(Mapper &M) : M(M) {}

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

246

247private:

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267 Metadata *mapTopLevelUniquedNode(const MDNode &FirstN);

268

269

270

271

272

273

274

275

276

277

278 std::optional<Metadata *> tryToMapOperand(const Metadata *Op);

279

280

281

282

283

284

285

286

287 MDNode *mapDistinctNode(const MDNode &N);

288

289

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306 bool createPOT(UniquedGraph &G, const MDNode &FirstN);

307

308

309

310

311

312

313

314

317

318

319

320

321

322

323

324

325

326

327 void mapNodesInPOT(UniquedGraph &G);

328

329

330

331

332

333

334

335 template

336 void remapOperands(MDNode &N, OperandMapper mapOperand);

337};

338

339}

340

341Value *Mapper::mapValue(const Value *V) {

343

344

345 if (I != getVM().end()) {

346 assert(I->second && "Unexpected null mapping");

347 return I->second;

348 }

349

350

351 if (auto *Materializer = getMaterializer()) {

352 if (Value *NewV = Materializer->materialize(const_cast<Value *>(V))) {

353 getVM()[V] = NewV;

354 return NewV;

355 }

356 }

357

358

359

362 return nullptr;

363 return getVM()[V] = const_cast<Value *>(V);

364 }

365

367

369 if (TypeMapper) {

371

372 if (NewTy != IA->getFunctionType())

374 IA->hasSideEffects(), IA->isAlignStack(),

375 IA->getDialect(), IA->canThrow());

376 }

377

378 return getVM()[V] = const_cast<Value *>(V);

379 }

380

382 const Metadata *MD = MDV->getMetadata();

383

385

386 if (Value *LV = mapValue(LAM->getValue())) {

387 if (V == LAM->getValue())

388 return const_cast<Value *>(V);

390 }

391

392

393

395 ? nullptr

398 }

401 for (auto *VAM : AL->getArgs()) {

402

403

404

405

406

409 } else if (Value *LV = mapValue(VAM->getValue())) {

414 } else {

415

418 }

419 }

422 }

423

424

425

427 return getVM()[V] = const_cast<Value *>(V);

428

429

430 auto *MappedMD = mapMetadata(MD);

431 if (MD == MappedMD)

432 return getVM()[V] = const_cast<Value *>(V);

434 }

435

436

437

439 if (C)

440 return nullptr;

441

443 return mapBlockAddress(*BA);

444

446 auto *Val = mapValue(E->getGlobalValue());

448 if (GV)

450

452 Type *NewTy = E->getType();

453 if (TypeMapper)

454 NewTy = TypeMapper->remapType(NewTy);

457 }

458

460 auto *Val = mapValue(NC->getGlobalValue());

463 }

464

465 auto mapValueOrNull = [this](Value *V) {

466 auto Mapped = mapValue(V);

468 "Unexpected null mapping for constant operand without "

469 "NullMapMissingGlobalValues flag");

470 return Mapped;

471 };

472

473

474

475 unsigned OpNo = 0, NumOperands = C->getNumOperands();

476 Value *Mapped = nullptr;

477 for (; OpNo != NumOperands; ++OpNo) {

478 Value *Op = C->getOperand(OpNo);

479 Mapped = mapValueOrNull(Op);

480 if (!Mapped)

481 return nullptr;

482 if (Mapped != Op)

483 break;

484 }

485

486

487 Type *NewTy = C->getType();

488 if (TypeMapper)

489 NewTy = TypeMapper->remapType(NewTy);

490

491

492

493 if (OpNo == NumOperands && NewTy == C->getType())

494 return getVM()[V] = C;

495

496

497

500 for (unsigned j = 0; j != OpNo; ++j)

502

503

504 if (OpNo != NumOperands) {

506

507

508 for (++OpNo; OpNo != NumOperands; ++OpNo) {

509 Mapped = mapValueOrNull(C->getOperand(OpNo));

510 if (!Mapped)

511 return nullptr;

513 }

514 }

515 Type *NewSrcTy = nullptr;

516 if (TypeMapper)

518 NewSrcTy = TypeMapper->remapType(GEPO->getSourceElementType());

519

521 return getVM()[V] = CE->getWithOperands(Ops, NewTy, false, NewSrcTy);

529 return getVM()[V] =

532

543}

544

545void Mapper::remapDbgRecord(DbgRecord &DR) {

546

547 auto *MappedDILoc = mapMetadata(DR.getDebugLoc());

549

551

552 DLR->setLabel(cast(mapMetadata(DLR->getLabel())));

553 return;

554 }

555

557

558 auto *MappedVar = mapMetadata(V.getVariable());

560

562

563 if (V.isDbgAssign()) {

564 auto *NewAddr = mapValue(V.getAddress());

565 if (!IgnoreMissingLocals && !NewAddr)

566 V.setKillAddress();

567 else if (NewAddr)

568 V.setAddress(NewAddr);

570 }

571

572

575 for (Value *Val : Vals)

576 NewVals.push_back(mapValue(Val));

577

578

579 if (Vals == NewVals)

580 return;

581

582

584 V.setKillLocation();

585 } else {

586

587

588 for (unsigned int I = 0; I < Vals.size(); ++I)

589 if (NewVals[I])

590 V.replaceVariableLocationOp(I, NewVals[I]);

591 }

592}

593

596

597

598

599

601 if (F->empty()) {

602 DelayedBBs.push_back(DelayedBasicBlock(BA));

603 BB = DelayedBBs.back().TempBB.get();

604 } else {

606 }

607

609}

610

612 getVM().MD()[Key].reset(Val);

613 return Val;

614}

615

617 return mapToMetadata(MD, const_cast<Metadata *>(MD));

618}

619

620std::optional<Metadata *> MDNodeMapper::tryToMapOperand(const Metadata *Op) {

621 if (Op)

622 return nullptr;

623

624 if (std::optional<Metadata *> MappedOp = M.mapSimpleMetadata(Op)) {

625#ifndef NDEBUG

627 assert((!*MappedOp || M.getVM().count(CMD->getValue()) ||

628 M.getVM().getMappedMD(Op)) &&

629 "Expected Value to be memoized");

630 else

632 "Expected result to be memoized");

633#endif

634 return *MappedOp;

635 }

636

638 if (N.isDistinct())

639 return mapDistinctNode(N);

640 return std::nullopt;

641}

642

643MDNode *MDNodeMapper::mapDistinctNode(const MDNode &N) {

644 assert(N.isDistinct() && "Expected a distinct node");

645 assert(M.getVM().getMappedMD(&N) && "Expected an unmapped node");

647

649 NewM = M.mapToSelf(&N);

650 } else {

653 << "To " << *NewM << "\n\n");

654 M.mapToMetadata(&N, NewM);

655 }

656 DistinctWorklist.push_back(cast(NewM));

657

658 return DistinctWorklist.back();

659}

660

667

668std::optional<Metadata *> MDNodeMapper::getMappedOp(const Metadata *Op) const {

669 if (Op)

670 return nullptr;

671

672 if (std::optional<Metadata *> MappedOp = M.getVM().getMappedMD(Op))

673 return *MappedOp;

674

677

680

681 return std::nullopt;

682}

683

684Metadata &MDNodeMapper::UniquedGraph::getFwdReference(MDNode &Op) {

685 auto Where = Info.find(&Op);

686 assert(Where != Info.end() && "Expected a valid reference");

687

688 auto &OpD = Where->second;

689 if (!OpD.HasChanged)

690 return Op;

691

692

693 if (!OpD.Placeholder)

694 OpD.Placeholder = Op.clone();

695

696 return *OpD.Placeholder;

697}

698

699template

700void MDNodeMapper::remapOperands(MDNode &N, OperandMapper mapOperand) {

701 assert(N.isUniqued() && "Expected distinct or temporary nodes");

702 for (unsigned I = 0, E = N.getNumOperands(); I != E; ++I) {

705 if (Old != New)

706 LLVM_DEBUG(dbgs() << "Replacing Op " << Old << " with " << New << " in "

707 << N << "\n");

708

709 if (Old != New)

710 N.replaceOperandWith(I, New);

711 }

712}

713

714namespace {

715

716

717struct POTWorklistEntry {

718 MDNode *N;

720

721

722

723 bool HasChanged = false;

724

725 POTWorklistEntry(MDNode &N) : N(&N), Op(N.op_begin()) {}

726};

727

728}

729

730bool MDNodeMapper::createPOT(UniquedGraph &G, const MDNode &FirstN) {

731 assert(G.Info.empty() && "Expected a fresh traversal");

732 assert(FirstN.isUniqued() && "Expected uniqued node in POT");

733

734

735 bool AnyChanges = false;

737 Worklist.push_back(POTWorklistEntry(const_cast<MDNode &>(FirstN)));

738 (void)G.Info[&FirstN];

739 while (!Worklist.empty()) {

740

741 auto &WE = Worklist.back();

742 if (MDNode *N = visitOperands(G, WE.Op, WE.N->op_end(), WE.HasChanged)) {

743

744 Worklist.push_back(POTWorklistEntry(*N));

745 continue;

746 }

747

748

749 assert(WE.N->isUniqued() && "Expected only uniqued nodes");

750 assert(WE.Op == WE.N->op_end() && "Expected to visit all operands");

751 auto &D = G.Info[WE.N];

752 AnyChanges |= D.HasChanged = WE.HasChanged;

753 D.ID = G.POT.size();

754 G.POT.push_back(WE.N);

755

756

758 }

759 return AnyChanges;

760}

761

764 while (I != E) {

765 Metadata *Op = *I++;

766 if (std::optional<Metadata *> MappedOp = tryToMapOperand(Op)) {

767

768 HasChanged |= Op != *MappedOp;

769 continue;

770 }

771

772

775 "Only uniqued operands cannot be mapped immediately");

776 if (G.Info.try_emplace(&OpN).second)

777 return &OpN;

778 }

779 return nullptr;

780}

781

782void MDNodeMapper::UniquedGraph::propagateChanges() {

783 bool AnyChanges;

784 do {

785 AnyChanges = false;

788 if (D.HasChanged)

789 continue;

790

792 auto Where = Info.find(Op);

793 return Where != Info.end() && Where->second.HasChanged;

794 }))

795 continue;

796

797 AnyChanges = D.HasChanged = true;

798 }

799 } while (AnyChanges);

800}

801

802void MDNodeMapper::mapNodesInPOT(UniquedGraph &G) {

803

805 for (auto *N : G.POT) {

806 auto &D = G.Info[N];

807 if (D.HasChanged) {

808

809 M.mapToSelf(N);

810 continue;

811 }

812

813

814 bool HadPlaceholder(D.Placeholder);

815

816

817 TempMDNode ClonedN = D.Placeholder ? std::move(D.Placeholder) : N->clone();

819 if (std::optional<Metadata *> MappedOp = getMappedOp(Old))

820 return *MappedOp;

821 (void)D;

822 assert(G.Info[Old].ID > D.ID && "Expected a forward reference");

824 });

825

827 if (N && NewN && N != NewN) {

829 << "To " << *NewN << "\n\n");

830 }

831

832 M.mapToMetadata(N, NewN);

833

834

835

836 if (HadPlaceholder)

838 }

839

840

841 for (auto *N : CyclicNodes)

842 if (N->isResolved())

843 N->resolveCycles();

844}

845

847 assert(DistinctWorklist.empty() && "MDNodeMapper::map is not recursive");

849 "MDNodeMapper::map assumes module-level changes");

850

851

852 assert(N.isResolved() && "Unexpected unresolved node");

853

855 N.isUniqued() ? mapTopLevelUniquedNode(N) : mapDistinctNode(N);

856 while (!DistinctWorklist.empty())

858 if (std::optional<Metadata *> MappedOp = tryToMapOperand(Old))

859 return *MappedOp;

860 return mapTopLevelUniquedNode(*cast(Old));

861 });

862 return MappedN;

863}

864

865Metadata *MDNodeMapper::mapTopLevelUniquedNode(const MDNode &FirstN) {

867

868

869 UniquedGraph G;

870 if (!createPOT(G, FirstN)) {

871

872 for (const MDNode *N : G.POT)

873 M.mapToSelf(N);

874 return &const_cast<MDNode &>(FirstN);

875 }

876

877

878 G.propagateChanges();

879

880

881 mapNodesInPOT(G);

882

883

885}

886

887std::optional<Metadata *> Mapper::mapSimpleMetadata(const Metadata *MD) {

888

889 if (std::optional<Metadata *> NewMD = getVM().getMappedMD(MD))

890 return *NewMD;

891

893 return const_cast<Metadata *>(MD);

894

895

896

898 return const_cast<Metadata *>(MD);

899

901

902

903

904

906 }

907

908

909

910

911 if (IdentityMD && (*IdentityMD)(MD))

913

915

916 return std::nullopt;

917}

918

920 assert(MD && "Expected valid metadata");

922

923 if (std::optional<Metadata *> NewMD = mapSimpleMetadata(MD))

924 return *NewMD;

925

926 return MDNodeMapper(*this).map(*cast(MD));

927}

928

929void Mapper::flush() {

930

931 while (!Worklist.empty()) {

933 CurrentMCID = E.MCID;

934 switch (E.Kind) {

935 case WorklistEntry::MapGlobalInit:

936 E.Data.GVInit.GV->setInitializer(mapConstant(E.Data.GVInit.Init));

937 remapGlobalObjectMetadata(*E.Data.GVInit.GV);

938 break;

939 case WorklistEntry::MapAppendingVar: {

940 unsigned PrefixSize = AppendingInits.size() - E.AppendingGVNumNewMembers;

941

942

943

945 drop_begin(AppendingInits, PrefixSize));

946 AppendingInits.resize(PrefixSize);

947 mapAppendingVariable(*E.Data.AppendingGV.GV,

948 E.Data.AppendingGV.OldGV,

949 E.AppendingGVIsOldCtorDtor, ArrayRef(NewInits));

950 break;

951 }

952 case WorklistEntry::MapAliasOrIFunc: {

954 Constant *Target = mapConstant(E.Data.AliasOrIFunc.Target);

956 GA->setAliasee(Target);

958 GI->setResolver(Target);

959 else

961 break;

962 }

963 case WorklistEntry::RemapFunction:

964 remapFunction(*E.Data.RemapF);

965 break;

966 }

967 }

968 CurrentMCID = 0;

969

970

971

972 while (!DelayedBBs.empty()) {

973 DelayedBasicBlock DBB = DelayedBBs.pop_back_val();

975 DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);

976 }

977}

978

979void Mapper::remapInstruction(Instruction *I) {

980

981 for (Use &Op : I->operands()) {

983

984 if (V)

986 else

988 "Referenced value not in value map!");

989 }

990

991

992

994 if (CB->getMetadata(LLVMContext::MD_callee_type) && !CB->isIndirectCall())

995 CB->setMetadata(LLVMContext::MD_callee_type, nullptr);

996 }

997

998

1000 for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {

1001 Value *V = mapValue(PN->getIncomingBlock(i));

1002

1003 if (V)

1005 else

1007 "Referenced block not in value map!");

1008 }

1009 }

1010

1011

1013 I->getAllMetadata(MDs);

1014 for (const auto &MI : MDs) {

1017 if (New != Old)

1018 I->setMetadata(MI.first, New);

1019 }

1020

1021

1024

1025 if (!TypeMapper)

1026 return;

1027

1028

1032 Tys.reserve(FTy->getNumParams());

1033 for (Type *Ty : FTy->params())

1036 TypeMapper->remapType(I->getType()), Tys, FTy->isVarArg()));

1037

1039 AttributeList Attrs = CB->getAttributes();

1040 for (unsigned i = 0; i < Attrs.getNumAttrSets(); ++i) {

1041 for (int AttrIdx = Attribute::FirstTypeAttr;

1042 AttrIdx <= Attribute::LastTypeAttr; AttrIdx++) {

1044 if (Type *Ty =

1045 Attrs.getAttributeAtIndex(i, TypedAttr).getValueAsType()) {

1046 Attrs = Attrs.replaceAttributeTypeAtIndex(C, i, TypedAttr,

1048 break;

1049 }

1050 }

1051 }

1052 CB->setAttributes(Attrs);

1053 return;

1054 }

1056 AI->setAllocatedType(TypeMapper->remapType(AI->getAllocatedType()));

1058 GEP->setSourceElementType(

1059 TypeMapper->remapType(GEP->getSourceElementType()));

1060 GEP->setResultElementType(

1061 TypeMapper->remapType(GEP->getResultElementType()));

1062 }

1063 I->mutateType(TypeMapper->remapType(I->getType()));

1064}

1065

1066void Mapper::remapGlobalObjectMetadata(GlobalObject &GO) {

1070 for (const auto &I : MDs)

1072}

1073

1074void Mapper::remapFunction(Function &F) {

1075

1076 for (Use &Op : F.operands())

1077 if (Op)

1078 Op = mapValue(Op);

1079

1080

1081 remapGlobalObjectMetadata(F);

1082

1083

1084 if (TypeMapper)

1086 A.mutateType(TypeMapper->remapType(A.getType()));

1087

1088

1091 remapInstruction(&I);

1092 for (DbgRecord &DR : I.getDbgRecordRange())

1093 remapDbgRecord(DR);

1094 }

1095 }

1096}

1097

1099 bool IsOldCtorDtor,

1103

1105 if (InitPrefix) {

1106 unsigned NumElements =

1108 for (unsigned I = 0; I != NumElements; ++I)

1113 }

1114

1116 Type *EltTy;

1117 if (IsOldCtorDtor) {

1118

1119

1122 Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};

1124 }

1125

1126 for (auto *V : NewMembers) {

1128 if (IsOldCtorDtor) {

1130 auto *E1 = cast(mapValue(S->getOperand(0)));

1131 auto *E2 = cast(mapValue(S->getOperand(1)));

1134 } else {

1136 }

1138 }

1139

1142}

1143

1145 unsigned MCID) {

1146 assert(AlreadyScheduled.insert(&GV).second && "Should not reschedule");

1147 assert(MCID < MCs.size() && "Invalid mapping context");

1148

1149 WorklistEntry WE;

1150 WE.Kind = WorklistEntry::MapGlobalInit;

1151 WE.MCID = MCID;

1152 WE.Data.GVInit.GV = &GV;

1153 WE.Data.GVInit.Init = &Init;

1155}

1156

1157void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,

1159 bool IsOldCtorDtor,

1161 unsigned MCID) {

1162 assert(AlreadyScheduled.insert(&GV).second && "Should not reschedule");

1163 assert(MCID < MCs.size() && "Invalid mapping context");

1164

1165 WorklistEntry WE;

1166 WE.Kind = WorklistEntry::MapAppendingVar;

1167 WE.MCID = MCID;

1168 WE.Data.AppendingGV.GV = &GV;

1169 WE.Data.AppendingGV.OldGV = OldGV;

1170 WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;

1171 WE.AppendingGVNumNewMembers = NewMembers.size();

1173 AppendingInits.append(NewMembers.begin(), NewMembers.end());

1174}

1175

1177 unsigned MCID) {

1178 assert(AlreadyScheduled.insert(&GV).second && "Should not reschedule");

1180 "Should be alias or ifunc");

1181 assert(MCID < MCs.size() && "Invalid mapping context");

1182

1183 WorklistEntry WE;

1184 WE.Kind = WorklistEntry::MapAliasOrIFunc;

1185 WE.MCID = MCID;

1186 WE.Data.AliasOrIFunc.GV = &GV;

1187 WE.Data.AliasOrIFunc.Target = &Target;

1189}

1190

1191void Mapper::scheduleRemapFunction(Function &F, unsigned MCID) {

1192 assert(AlreadyScheduled.insert(&F).second && "Should not reschedule");

1193 assert(MCID < MCs.size() && "Invalid mapping context");

1194

1195 WorklistEntry WE;

1196 WE.Kind = WorklistEntry::RemapFunction;

1197 WE.MCID = MCID;

1198 WE.Data.RemapF = &F;

1200}

1201

1202void Mapper::addFlags(RemapFlags Flags) {

1203 assert(!hasWorkToDo() && "Expected to have flushed the worklist");

1205}

1206

1208 return reinterpret_cast<Mapper *>(pImpl);

1209}

1210

1211namespace {

1212

1213class FlushingMapper {

1214 Mapper &M;

1215

1216public:

1217 explicit FlushingMapper(void *pImpl) : M(*getAsMapper(pImpl)) {

1218 assert(M.hasWorkToDo() && "Expected to be flushed");

1219 }

1220

1221 ~FlushingMapper() { M.flush(); }

1222

1223 Mapper *operator->() const { return &M; }

1224};

1225

1226}

1227

1232 : pImpl(new Mapper(VM, Flags, TypeMapper, Materializer, IdentityMD)) {}

1233

1235

1236unsigned

1239 return getAsMapper(pImpl)->registerAlternateMappingContext(VM, Materializer);

1240}

1241

1243 FlushingMapper(pImpl)->addFlags(Flags);

1244}

1245

1247 return FlushingMapper(pImpl)->mapValue(&V);

1248}

1249

1253

1255 return FlushingMapper(pImpl)->mapMetadata(&MD);

1256}

1257

1261

1263 FlushingMapper(pImpl)->remapInstruction(&I);

1264}

1265

1267 FlushingMapper(pImpl)->remapDbgRecord(DR);

1268}

1269

1276

1278 FlushingMapper(pImpl)->remapFunction(F);

1279}

1280

1282 FlushingMapper(pImpl)->remapGlobalObjectMetadata(GO);

1283}

1284

1287 unsigned MCID) {

1289}

1290

1293 bool IsOldCtorDtor,

1295 unsigned MCID) {

1296 getAsMapper(pImpl)->scheduleMapAppendingVariable(

1297 GV, OldGV, IsOldCtorDtor, NewMembers, MCID);

1298}

1299

1301 unsigned MCID) {

1302 getAsMapper(pImpl)->scheduleMapAliasOrIFunc(GA, Aliasee, MCID);

1303}

1304

1306 unsigned MCID) {

1308}

1309

1313

1316 if (DL)

1317 return;

1318

1319 auto AtomGroup = DL->getAtomGroup();

1320 if (!AtomGroup)

1321 return;

1322

1323 auto R = VM.AtomMap.find({DL->getInlinedAt(), AtomGroup});

1324 if (R == VM.AtomMap.end())

1325 return;

1326 AtomGroup = R->second;

1327

1328

1330 I->getContext(), DL.getLine(), DL.getCol(), DL.getScope(),

1331 DL.getInlinedAt(), DL.isImplicitCode(), AtomGroup, DL->getAtomRank());

1332 I->setDebugLoc(New);

1333}

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

static unsigned getMappedOp(unsigned PseudoOp)

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

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

Analysis containing CSE Info

This file contains the declarations for the subclasses of Constant, which represent the different fla...

This file defines the DenseMap class.

This file defines the DenseSet and SmallDenseSet classes.

This file contains the declaration of the GlobalIFunc class, which represents a single indirect funct...

const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

This file defines the SmallVector class.

static void remapOperands(VPBlockBase *Entry, VPBlockBase *NewEntry, DenseMap< VPValue *, VPValue * > &Old2NewVPValues)

static Mapper * getAsMapper(void *pImpl)

Definition ValueMapper.cpp:1207

static ConstantAsMetadata * wrapConstantAsMetadata(const ConstantAsMetadata &CMD, Value *MappedV)

Definition ValueMapper.cpp:661

This class represents an incoming formal argument to a Function.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

const T & front() const

front - Get the first element.

size_t size() const

size - Get the array size.

AttrKind

This enumeration lists the attributes that can be associated with parameters, function results,...

LLVM Basic Block Representation.

The address of a basic block.

Function * getFunction() const

BasicBlock * getBasicBlock() const

static LLVM_ABI BlockAddress * get(Function *F, BasicBlock *BB)

Return a BlockAddress for the specified function and basic block.

static LLVM_ABI ConstantAggregateZero * get(Type *Ty)

static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)

A constant value that is initialized with an expression using other constant values.

static LLVM_ABI Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)

static LLVM_ABI ConstantPointerNull * get(PointerType *T)

Static factory methods - Return objects of the specified value.

static LLVM_ABI ConstantPtrAuth * get(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc, Constant *AddrDisc, Constant *DeactivationSymbol)

Return a pointer signed with the specified parameters.

static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)

static LLVM_ABI Constant * get(ArrayRef< Constant * > V)

This is an important base class in LLVM.

static LLVM_ABI Constant * getNullValue(Type *Ty)

Constructor to create a '0' constant of arbitrary type.

LLVM_ABI Constant * getAggregateElement(unsigned Elt) const

For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...

LLVM_ABI void destroyConstant()

Called if some element of this constant is no longer valid.

static LLVM_ABI DIArgList * get(LLVMContext &Context, ArrayRef< ValueAsMetadata * > Args)

static LLVM_ABI DSOLocalEquivalent * get(GlobalValue *GV)

Return a DSOLocalEquivalent for the specified global value.

Records a position in IR for a source label (DILabel).

Base class for non-instruction debug metadata records that have positions within IR.

DebugLoc getDebugLoc() const

void setDebugLoc(DebugLoc Loc)

Record of a variable value-assignment, aka a non instruction representation of the dbg....

Class to represent function types.

static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

LLVM_ABI void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const

Appends all metadata attached to this value to MDs, sorting by KindID.

LLVM_ABI void addMetadata(unsigned KindID, MDNode &MD)

Add a metadata attachment.

LLVM_ABI void clearMetadata()

Erase all metadata attached to this Value.

LLVM_ABI bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

Type * getValueType() const

const Constant * getInitializer() const

getInitializer - Return the initializer for this global variable.

LLVM_ABI void setInitializer(Constant *InitVal)

setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...

static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)

InlineAsm::get - Return the specified uniqued inline asm string.

This is an important class for using LLVM in a threaded context.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithDistinct(std::unique_ptr< T, TempMDNodeDeleter > N)

Replace a temporary node with a distinct one.

const MDOperand * op_iterator

static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithUniqued(std::unique_ptr< T, TempMDNodeDeleter > N)

Replace a temporary node with a uniqued one.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

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

static LLVM_ABI NoCFIValue * get(GlobalValue *GV)

Return a NoCFIValue for the specified function.

Class to represent pointers.

static PointerType * getUnqual(Type *ElementType)

This constructs a pointer to an object of the specified type in the default address space (address sp...

static LLVM_ABI PoisonValue * get(Type *T)

Static factory methods - Return an 'poison' object of the specified type.

Interface for looking up the initializer for a variable name, used by Init::resolveReferences.

void reserve(size_type N)

void append(ItTy in_start, ItTy in_end)

Add the specified range to the end of the SmallVector.

void push_back(const T &Elt)

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

static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)

This static method is the primary way to create a literal StructType.

Target - Wrapper for Target specific information.

Tracking metadata reference.

The instances of the Type class are immutable: once they are created, they are never changed.

static LLVM_ABI UndefValue * get(Type *T)

Static factory methods - Return an 'undef' object of the specified type.

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

This is a class that can be implemented by clients to remap types when cloning constants and instruct...

virtual Type * remapType(Type *SrcTy)=0

The client should implement this method if they want to remap types while mapping values.

ValueMapIteratorImpl< MapT, const Value *, false > iterator

DMAtomT AtomMap

Map {(InlinedAt, old atom number) -> new atom number}.

LLVM_ABI void remapDbgRecord(Module *M, DbgRecord &V)

Definition ValueMapper.cpp:1266

LLVM_ABI ~ValueMapper()

Definition ValueMapper.cpp:1234

LLVM_ABI void remapDbgRecordRange(Module *M, iterator_range< DbgRecordIterator > Range)

Definition ValueMapper.cpp:1270

LLVM_ABI MDNode * mapMDNode(const MDNode &N)

Definition ValueMapper.cpp:1258

LLVM_ABI Metadata * mapMetadata(const Metadata &MD)

Definition ValueMapper.cpp:1254

LLVM_ABI void remapInstruction(Instruction &I)

Definition ValueMapper.cpp:1262

LLVM_ABI void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init, unsigned MappingContextID=0)

Definition ValueMapper.cpp:1285

LLVM_ABI void scheduleRemapFunction(Function &F, unsigned MappingContextID=0)

Definition ValueMapper.cpp:1310

LLVM_ABI ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)

Definition ValueMapper.cpp:1228

LLVM_ABI void scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver, unsigned MappingContextID=0)

Definition ValueMapper.cpp:1305

LLVM_ABI unsigned registerAlternateMappingContext(ValueToValueMapTy &VM, ValueMaterializer *Materializer=nullptr)

Register an alternate mapping context.

Definition ValueMapper.cpp:1237

LLVM_ABI void remapFunction(Function &F)

Definition ValueMapper.cpp:1277

LLVM_ABI Constant * mapConstant(const Constant &C)

Definition ValueMapper.cpp:1250

LLVM_ABI void scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee, unsigned MappingContextID=0)

Definition ValueMapper.cpp:1300

LLVM_ABI void remapGlobalObjectMetadata(GlobalObject &GO)

Definition ValueMapper.cpp:1281

LLVM_ABI Value * mapValue(const Value &V)

Definition ValueMapper.cpp:1246

LLVM_ABI void scheduleMapAppendingVariable(GlobalVariable &GV, GlobalVariable *OldGV, bool IsOldCtorDtor, ArrayRef< Constant * > NewMembers, unsigned MappingContextID=0)

Definition ValueMapper.cpp:1291

LLVM_ABI void addFlags(RemapFlags Flags)

Add to the current RemapFlags.

Definition ValueMapper.cpp:1242

This is a class that can be implemented by clients to materialize Values on demand.

LLVM Value Representation.

Type * getType() const

All values are typed, get the type of this value.

bool hasUseList() const

Check if this Value has a use-list.

LLVM_ABI LLVMContext & getContext() const

All values hold a context through their type.

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

A range adaptor for a pair of iterators.

#define llvm_unreachable(msg)

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

constexpr char Attrs[]

Key for Kernel::Metadata::mAttrs.

unsigned ID

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

@ C

The default llvm calling convention, compatible with C.

@ BasicBlock

Various leaf nodes.

@ CE

Windows NT (Windows on ARM)

NodeAddr< FuncNode * > Func

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

FunctionAddr VTableAddr Value

std::function< bool(const Metadata *)> MetadataPredicate

decltype(auto) dyn_cast(const From &Val)

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

auto cast_or_null(const Y &Val)

RemapFlags

These are flags that the value mapping APIs allow.

@ RF_IgnoreMissingLocals

If this flag is set, the remapper ignores missing function-local entries (Argument,...

@ RF_NullMapMissingGlobalValues

Any global values not in value map are mapped to null instead of mapping to self.

@ RF_NoModuleLevelChanges

If this flag is set, the remapper knows that only local values within a function (such as an instruct...

@ RF_DoNotRemapAtoms

Do not remap source location atoms.

@ RF_ReuseAndMutateDistinctMDs

Instruct the remapper to reuse and mutate distinct metadata (remapping them in place) instead of clon...

LLVM_ABI raw_ostream & dbgs()

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

bool none_of(R &&Range, UnaryPredicate P)

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

class LLVM_GSL_OWNER SmallVector

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

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

FunctionAddr VTableAddr uintptr_t uintptr_t Data

DWARFExpression::Operation Op

ArrayRef(const T &OneElt) -> ArrayRef< T >

ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy

decltype(auto) cast(const From &Val)

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

void RemapFunction(Function &F, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)

Remap the operands, metadata, arguments, and instructions of a function.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

LLVM_ABI void RemapSourceAtom(Instruction *I, ValueToValueMapTy &VM)

Remap source location atom.

Definition ValueMapper.cpp:1314