|
12 | 12 | //===----------------------------------------------------------------------===// |
13 | 13 |
|
14 | 14 | #include "LLVMContextImpl.h" |
| 15 | +#include "llvm/ADT/SetVector.h" |
15 | 16 | #include "llvm/IR/ConstantRange.h" |
16 | 17 | #include "llvm/IR/Constants.h" |
17 | 18 | #include "llvm/IR/DerivedTypes.h" |
@@ -671,3 +672,80 @@ void GlobalIFunc::applyAlongResolverPath( |
671 | 672 | DenseSet<const GlobalAlias *> Aliases; |
672 | 673 | findBaseObject(getResolver(), Aliases, Op); |
673 | 674 | } |
| 675 | + |
| 676 | +static void collectUsedGlobals(GlobalVariable *GV, |
| 677 | + SmallSetVector<Constant *, 16> &Init) { |
| 678 | + if (!GV || !GV->hasInitializer()) |
| 679 | + return; |
| 680 | + |
| 681 | + auto *CA = cast<ConstantArray>(GV->getInitializer()); |
| 682 | + for (Use &Op : CA->operands()) |
| 683 | + Init.insert(cast<Constant>(Op)); |
| 684 | +} |
| 685 | + |
| 686 | +static void appendToUsedList(Module &M, StringRef Name, |
| 687 | + ArrayRef<GlobalValue *> Values) { |
| 688 | + GlobalVariable *GV = M.getGlobalVariable(Name); |
| 689 | + |
| 690 | + SmallSetVector<Constant *, 16> Init; |
| 691 | + collectUsedGlobals(GV, Init); |
| 692 | + Type *ArrayEltTy = GV ? GV->getValueType()->getArrayElementType() |
| 693 | + : PointerType::getUnqual(M.getContext()); |
| 694 | + if (GV) |
| 695 | + GV->eraseFromParent(); |
| 696 | + |
| 697 | + for (auto *V : Values) |
| 698 | + Init.insert(ConstantExpr::getPointerBitCastOrAddrSpaceCast(V, ArrayEltTy)); |
| 699 | + |
| 700 | + if (Init.empty()) |
| 701 | + return; |
| 702 | + |
| 703 | + ArrayType *ATy = ArrayType::get(ArrayEltTy, Init.size()); |
| 704 | + GV = new GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, |
| 705 | + ConstantArray::get(ATy, Init.getArrayRef()), Name); |
| 706 | + GV->setSection("llvm.metadata"); |
| 707 | +} |
| 708 | + |
| 709 | +void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { |
| 710 | + appendToUsedList(M, "llvm.used", Values); |
| 711 | +} |
| 712 | + |
| 713 | +void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { |
| 714 | + appendToUsedList(M, "llvm.compiler.used", Values); |
| 715 | +} |
| 716 | + |
| 717 | +static void removeFromUsedList(Module &M, StringRef Name, |
| 718 | + function_ref<bool(Constant *)> ShouldRemove) { |
| 719 | + GlobalVariable *GV = M.getNamedGlobal(Name); |
| 720 | + if (!GV) |
| 721 | + return; |
| 722 | + |
| 723 | + SmallSetVector<Constant *, 16> Init; |
| 724 | + collectUsedGlobals(GV, Init); |
| 725 | + |
| 726 | + Type *ArrayEltTy = cast<ArrayType>(GV->getValueType())->getElementType(); |
| 727 | + |
| 728 | + SmallVector<Constant *, 16> NewInit; |
| 729 | + for (Constant *MaybeRemoved : Init) { |
| 730 | + if (!ShouldRemove(MaybeRemoved->stripPointerCasts())) |
| 731 | + NewInit.push_back(MaybeRemoved); |
| 732 | + } |
| 733 | + |
| 734 | + if (!NewInit.empty()) { |
| 735 | + ArrayType *ATy = ArrayType::get(ArrayEltTy, NewInit.size()); |
| 736 | + GlobalVariable *NewGV = |
| 737 | + new GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, |
| 738 | + ConstantArray::get(ATy, NewInit), "", GV, |
| 739 | + GV->getThreadLocalMode(), GV->getAddressSpace()); |
| 740 | + NewGV->setSection(GV->getSection()); |
| 741 | + NewGV->takeName(GV); |
| 742 | + } |
| 743 | + |
| 744 | + GV->eraseFromParent(); |
| 745 | +} |
| 746 | + |
| 747 | +void llvm::removeFromUsedLists(Module &M, |
| 748 | + function_ref<bool(Constant *)> ShouldRemove) { |
| 749 | + removeFromUsedList(M, "llvm.used", ShouldRemove); |
| 750 | + removeFromUsedList(M, "llvm.compiler.used", ShouldRemove); |
| 751 | +} |
0 commit comments