llvm.org GIT mirror llvm / c742e3a
Linker: Don't use MDNode::replaceOperandWith() `MDNode::replaceOperandWith()` changes all instances of metadata. Stop using it when linking module flags, since (due to uniquing) the flag values could be used by other metadata. Instead, use new API `NamedMDNode::setOperand()` to update the reference directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225397 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
5 changed file(s) with 61 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
846846 MDNode *getOperand(unsigned i) const;
847847 unsigned getNumOperands() const;
848848 void addOperand(MDNode *M);
849 void setOperand(unsigned I, MDNode *New);
849850 StringRef getName() const;
850851 void print(raw_ostream &ROS) const;
851852 void dump() const;
835835
836836 void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); }
837837
838 void NamedMDNode::setOperand(unsigned I, MDNode *New) {
839 assert(I < getNumOperands() && "Invalid operand number");
840 getNMDOps(Operands)[I].reset(New);
841 }
842
838843 void NamedMDNode::eraseFromParent() {
839844 getParent()->eraseNamedMetadata(this);
840845 }
13111311 }
13121312
13131313 // First build a map of the existing module flags and requirements.
1314 DenseMap*, MDNode*> Flags;
1314 DenseMap *, std::pair> Flags;
13151315 SmallSetVector Requirements;
13161316 for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) {
13171317 MDNode *Op = DstModFlags->getOperand(I);
13211321 if (Behavior->getZExtValue() == Module::Require) {
13221322 Requirements.insert(cast(Op->getOperand(2)));
13231323 } else {
1324 Flags[ID] = Op;
1324 Flags[ID] = std::make_pair(Op, I);
13251325 }
13261326 }
13271327
13331333 ConstantInt *SrcBehavior =
13341334 mdconst::extract(SrcOp->getOperand(0));
13351335 MDString *ID = cast(SrcOp->getOperand(1));
1336 MDNode *DstOp = Flags.lookup(ID);
1336 MDNode *DstOp;
1337 unsigned DstIndex;
1338 std::tie(DstOp, DstIndex) = Flags.lookup(ID);
13371339 unsigned SrcBehaviorValue = SrcBehavior->getZExtValue();
13381340
13391341 // If this is a requirement, add it and continue.
13481350
13491351 // If there is no existing flag with this ID, just add it.
13501352 if (!DstOp) {
1351 Flags[ID] = SrcOp;
1353 Flags[ID] = std::make_pair(SrcOp, DstModFlags->getNumOperands());
13521354 DstModFlags->addOperand(SrcOp);
13531355 continue;
13541356 }
13691371 continue;
13701372 } else if (SrcBehaviorValue == Module::Override) {
13711373 // Update the destination flag to that of the source.
1372 DstOp->replaceOperandWith(0, ConstantAsMetadata::get(SrcBehavior));
1373 DstOp->replaceOperandWith(2, SrcOp->getOperand(2));
1374 DstModFlags->setOperand(DstIndex, SrcOp);
1375 Flags[ID].first = SrcOp;
13741376 continue;
13751377 }
13761378
13801382 "': IDs have conflicting behaviors");
13811383 continue;
13821384 }
1385
1386 auto replaceDstValue = [&](MDNode *New) {
1387 Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New};
1388 MDNode *Flag = MDNode::get(DstM->getContext(), FlagOps);
1389 DstModFlags->setOperand(DstIndex, Flag);
1390 Flags[ID].first = Flag;
1391 };
13831392
13841393 // Perform the merge for standard behavior types.
13851394 switch (SrcBehaviorValue) {
14101419 MDs.push_back(DstValue->getOperand(i));
14111420 for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i)
14121421 MDs.push_back(SrcValue->getOperand(i));
1413 DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), MDs));
1422
1423 replaceDstValue(MDNode::get(DstM->getContext(), MDs));
14141424 break;
14151425 }
14161426 case Module::AppendUnique: {
14211431 Elts.insert(DstValue->getOperand(i));
14221432 for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i)
14231433 Elts.insert(SrcValue->getOperand(i));
1424 DstOp->replaceOperandWith(
1425 2, MDNode::get(DstM->getContext(),
1426 makeArrayRef(Elts.begin(), Elts.end())));
1434
1435 replaceDstValue(MDNode::get(DstM->getContext(),
1436 makeArrayRef(Elts.begin(), Elts.end())));
14271437 break;
14281438 }
14291439 }
14351445 MDString *Flag = cast(Requirement->getOperand(0));
14361446 Metadata *ReqValue = Requirement->getOperand(1);
14371447
1438 MDNode *Op = Flags[Flag];
1448 MDNode *Op = Flags[Flag].first;
14391449 if (!Op || Op->getOperand(2) != ReqValue) {
14401450 HasErr |= emitError("linking module flags '" + Flag->getString() +
14411451 "': does not have the required value");
0 !llvm.module.flags = !{!3, !4, !5}
1
2 !0 = !{}
3 !1 = !{!0}
4 !2 = !{!0, !1}
5 !3 = !{i32 4, !"foo", i32 37} ; Override the "foo" value.
6 !4 = !{i32 5, !"bar", !1}
7 !5 = !{i32 6, !"baz", !2}
0 ; RUN: llvm-link %s %S/Inputs/module-flags-dont-change-others.ll -S -o - | FileCheck %s
1
2 ; Test that module-flag linking doesn't change other metadata. In particular,
3 ; !named should still point at the unmodified tuples (!3, !4, and !5) that
4 ; happen to also serve as module flags.
5
6 ; CHECK: !named = !{!0, !1, !2, !3, !4, !5}
7 ; CHECK: !llvm.module.flags = !{!6, !7, !8}
8 !named = !{!0, !1, !2, !3, !4, !5}
9 !llvm.module.flags = !{!3, !4, !5}
10
11 ; CHECK: !0 = !{}
12 ; CHECK: !1 = !{!0}
13 ; CHECK: !2 = !{!0, !1}
14 ; CHECK: !3 = !{i32 1, !"foo", i32 927}
15 ; CHECK: !4 = !{i32 5, !"bar", !0}
16 ; CHECK: !5 = !{i32 6, !"baz", !1}
17 ; CHECK: !6 = !{i32 4, !"foo", i32 37}
18 ; CHECK: !7 = !{i32 5, !"bar", !1}
19 ; CHECK: !8 = !{i32 6, !"baz", !2}
20 !0 = !{}
21 !1 = !{!0}
22 !2 = !{!0, !1}
23 !3 = !{i32 1, !"foo", i32 927}
24 !4 = !{i32 5, !"bar", !0}
25 !5 = !{i32 6, !"baz", !1}