Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 10 additions & 27 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3325,35 +3325,18 @@ void CodeGenModule::addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV) {
LLVMUsed.emplace_back(GV);
}

static void emitUsed(CodeGenModule &CGM, StringRef Name,
std::vector<llvm::WeakTrackingVH> &List) {
// Don't create llvm.used if there is no need.
if (List.empty())
return;

llvm::PointerType *UnqualPtr =
llvm::PointerType::getUnqual(CGM.getLLVMContext());

// Convert List to what ConstantArray needs.
SmallVector<llvm::Constant*, 8> UsedArray;
UsedArray.resize(List.size());
for (unsigned i = 0, e = List.size(); i != e; ++i) {
UsedArray[i] = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
cast<llvm::Constant>(&*List[i]), UnqualPtr);
}

llvm::ArrayType *ATy = llvm::ArrayType::get(UnqualPtr, UsedArray.size());

auto *GV = new llvm::GlobalVariable(
CGM.getModule(), ATy, false, llvm::GlobalValue::AppendingLinkage,
llvm::ConstantArray::get(ATy, UsedArray), Name);
void CodeGenModule::emitLLVMUsed() {
auto CastToGlobal = [](llvm::WeakTrackingVH &VH) {
return cast<llvm::GlobalValue>(VH);
};

GV->setSection("llvm.metadata");
}
SmallVector<llvm::GlobalValue *> LLVMUsedGV(LLVMUsed.size());
llvm::transform(LLVMUsed, LLVMUsedGV.begin(), CastToGlobal);
llvm::appendToUsed(getModule(), LLVMUsedGV);

void CodeGenModule::emitLLVMUsed() {
emitUsed(*this, "llvm.used", LLVMUsed);
emitUsed(*this, "llvm.compiler.used", LLVMCompilerUsed);
SmallVector<llvm::GlobalValue *> LLVMCompilerUsedGV(LLVMCompilerUsed.size());
llvm::transform(LLVMCompilerUsed, LLVMCompilerUsedGV.begin(), CastToGlobal);
llvm::appendToCompilerUsed(getModule(), LLVMCompilerUsedGV);
}

void CodeGenModule::AppendLinkerOptions(StringRef Opts) {
Expand Down
12 changes: 12 additions & 0 deletions llvm/include/llvm/IR/GlobalValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,18 @@ class GlobalValue : public Constant {
LLVM_ABI bool canBeOmittedFromSymbolTable() const;
};

/// Adds global values to the llvm.used list.
LLVM_ABI void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values);

/// Adds global values to the llvm.compiler.used list.
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);

/// Removes global values from the llvm.used and llvm.compiler.used arrays. \p
/// ShouldRemove should return true for any initializer field that should not be
/// included in the replacement global.
LLVM_ABI void removeFromUsedLists(Module &M,
function_ref<bool(Constant *)> ShouldRemove);

} // end namespace llvm

#endif // LLVM_IR_GLOBALVALUE_H
12 changes: 0 additions & 12 deletions llvm/include/llvm/Transforms/Utils/ModuleUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,6 @@ getOrCreateSanitizerCtorAndInitFunctions(
/// the list of public globals in the module.
LLVM_ABI bool nameUnamedGlobals(Module &M);

/// Adds global values to the llvm.used list.
LLVM_ABI void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values);

/// Adds global values to the llvm.compiler.used list.
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);

/// Removes global values from the llvm.used and llvm.compiler.used arrays. \p
/// ShouldRemove should return true for any initializer field that should not be
/// included in the replacement global.
LLVM_ABI void removeFromUsedLists(Module &M,
function_ref<bool(Constant *)> ShouldRemove);

/// Filter out potentially dead comdat functions where other entries keep the
/// entire comdat group alive.
///
Expand Down
60 changes: 20 additions & 40 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5865,25 +5865,12 @@ static const char *getSectionNameForCommandline(const Triple &T) {
void llvm::embedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
bool EmbedBitcode, bool EmbedCmdline,
const std::vector<uint8_t> &CmdArgs) {
// Save llvm.compiler.used and remove it.
SmallVector<Constant *, 2> UsedArray;
SmallVector<GlobalValue *, 4> UsedGlobals;
GlobalVariable *Used = collectUsedGlobalVariables(M, UsedGlobals, true);
Type *UsedElementType = Used ? Used->getValueType()->getArrayElementType()
: PointerType::getUnqual(M.getContext());
for (auto *GV : UsedGlobals) {
if (GV->getName() != "llvm.embedded.module" &&
GV->getName() != "llvm.cmdline")
UsedArray.push_back(
ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
}
if (Used)
Used->eraseFromParent();

// Embed the bitcode for the llvm module.
std::string Data;
ArrayRef<uint8_t> ModuleData;
Triple T(M.getTargetTriple());
SmallVector<GlobalValue *, 2> NewGlobals;

if (EmbedBitcode) {
if (Buf.getBufferSize() == 0 ||
Expand All @@ -5902,23 +5889,24 @@ void llvm::embedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
}
llvm::Constant *ModuleConstant =
llvm::ConstantDataArray::get(M.getContext(), ModuleData);
llvm::GlobalVariable *GV = new llvm::GlobalVariable(
llvm::GlobalVariable *EmbeddedModule = new llvm::GlobalVariable(
M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage,
ModuleConstant);
GV->setSection(getSectionNameForBitcode(T));
EmbeddedModule->setSection(getSectionNameForBitcode(T));
// Set alignment to 1 to prevent padding between two contributions from input
// sections after linking.
GV->setAlignment(Align(1));
UsedArray.push_back(
ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
EmbeddedModule->setAlignment(Align(1));
NewGlobals.push_back(EmbeddedModule);
if (llvm::GlobalVariable *Old =
M.getGlobalVariable("llvm.embedded.module", true)) {
removeFromUsedLists(
M, [](Constant *C) { return C->getName() == "llvm.embedded.module"; });
assert(Old->hasZeroLiveUses() &&
"llvm.embedded.module can only be used once in llvm.compiler.used");
GV->takeName(Old);
EmbeddedModule->takeName(Old);
Old->eraseFromParent();
} else {
GV->setName("llvm.embedded.module");
EmbeddedModule->setName("llvm.embedded.module");
}

// Skip if only bitcode needs to be embedded.
Expand All @@ -5928,30 +5916,22 @@ void llvm::embedBitcodeInModule(llvm::Module &M, llvm::MemoryBufferRef Buf,
CmdArgs.size());
llvm::Constant *CmdConstant =
llvm::ConstantDataArray::get(M.getContext(), CmdData);
GV = new llvm::GlobalVariable(M, CmdConstant->getType(), true,
llvm::GlobalValue::PrivateLinkage,
CmdConstant);
GV->setSection(getSectionNameForCommandline(T));
GV->setAlignment(Align(1));
UsedArray.push_back(
ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
GlobalVariable *CmdLine = new llvm::GlobalVariable(
M, CmdConstant->getType(), true, llvm::GlobalValue::PrivateLinkage,
CmdConstant);
CmdLine->setSection(getSectionNameForCommandline(T));
CmdLine->setAlignment(Align(1));
if (llvm::GlobalVariable *Old = M.getGlobalVariable("llvm.cmdline", true)) {
removeFromUsedLists(
M, [](Constant *C) { return C->getName() == "llvm.cmdline"; });
assert(Old->hasZeroLiveUses() &&
"llvm.cmdline can only be used once in llvm.compiler.used");
GV->takeName(Old);
CmdLine->takeName(Old);
Old->eraseFromParent();
} else {
GV->setName("llvm.cmdline");
CmdLine->setName("llvm.cmdline");
}
NewGlobals.push_back(CmdLine);
appendToCompilerUsed(M, NewGlobals);
}

if (UsedArray.empty())
return;

// Recreate llvm.compiler.used.
ArrayType *ATy = ArrayType::get(UsedElementType, UsedArray.size());
auto *NewUsed = new GlobalVariable(
M, ATy, false, llvm::GlobalValue::AppendingLinkage,
llvm::ConstantArray::get(ATy, UsedArray), "llvm.compiler.used");
NewUsed->setSection("llvm.metadata");
}
1 change: 0 additions & 1 deletion llvm/lib/CodeGen/JMCInstrumenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "llvm/Pass.h"
#include "llvm/Support/DJB.h"
#include "llvm/Support/Path.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;

Expand Down
77 changes: 77 additions & 0 deletions llvm/lib/IR/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//

#include "LLVMContextImpl.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
Expand Down Expand Up @@ -671,3 +672,79 @@ void GlobalIFunc::applyAlongResolverPath(
DenseSet<const GlobalAlias *> Aliases;
findBaseObject(getResolver(), Aliases, Op);
}

static void collectUsedGlobals(GlobalVariable *GV,
SmallSetVector<Constant *, 16> &Init) {
if (!GV || !GV->hasInitializer())
return;

auto *CA = cast<ConstantArray>(GV->getInitializer());
for (Use &Op : CA->operands())
Init.insert(cast<Constant>(Op));
}

static void appendToUsedList(Module &M, StringRef Name,
ArrayRef<GlobalValue *> Values) {
GlobalVariable *GV = M.getGlobalVariable(Name);

SmallSetVector<Constant *, 16> Init;
collectUsedGlobals(GV, Init);
if (GV)
GV->eraseFromParent();

Type *ArrayEltTy = PointerType::getUnqual(M.getContext());
for (auto *V : Values)
Init.insert(ConstantExpr::getPointerBitCastOrAddrSpaceCast(V, ArrayEltTy));

if (Init.empty())
return;

ArrayType *ATy = ArrayType::get(ArrayEltTy, Init.size());
GV = new GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
ConstantArray::get(ATy, Init.getArrayRef()), Name);
GV->setSection("llvm.metadata");
}

void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) {
appendToUsedList(M, "llvm.used", Values);
}

void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
appendToUsedList(M, "llvm.compiler.used", Values);
}

static void removeFromUsedList(Module &M, StringRef Name,
function_ref<bool(Constant *)> ShouldRemove) {
GlobalVariable *GV = M.getNamedGlobal(Name);
if (!GV)
return;

SmallSetVector<Constant *, 16> Init;
collectUsedGlobals(GV, Init);

Type *ArrayEltTy = cast<ArrayType>(GV->getValueType())->getElementType();

SmallVector<Constant *, 16> NewInit;
for (Constant *MaybeRemoved : Init) {
if (!ShouldRemove(MaybeRemoved->stripPointerCasts()))
NewInit.push_back(MaybeRemoved);
}

if (!NewInit.empty()) {
ArrayType *ATy = ArrayType::get(ArrayEltTy, NewInit.size());
GlobalVariable *NewGV =
new GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
ConstantArray::get(ATy, NewInit), "", GV,
GV->getThreadLocalMode(), GV->getAddressSpace());
NewGV->setSection(GV->getSection());
NewGV->takeName(GV);
}

GV->eraseFromParent();
}

void llvm::removeFromUsedLists(Module &M,
function_ref<bool(Constant *)> ShouldRemove) {
removeFromUsedList(M, "llvm.used", ShouldRemove);
removeFromUsedList(M, "llvm.compiler.used", ShouldRemove);
}
1 change: 0 additions & 1 deletion llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;

Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/NVPTX/NVPTXCtorDtorLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MD5.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

using namespace llvm;

Expand Down
76 changes: 0 additions & 76 deletions llvm/lib/Transforms/Utils/ModuleUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,82 +123,6 @@ void llvm::transformGlobalDtors(Module &M, const GlobalCtorTransformFn &Fn) {
transformGlobalArray("llvm.global_dtors", M, Fn);
}

static void collectUsedGlobals(GlobalVariable *GV,
SmallSetVector<Constant *, 16> &Init) {
if (!GV || !GV->hasInitializer())
return;

auto *CA = cast<ConstantArray>(GV->getInitializer());
for (Use &Op : CA->operands())
Init.insert(cast<Constant>(Op));
}

static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) {
GlobalVariable *GV = M.getGlobalVariable(Name);

SmallSetVector<Constant *, 16> Init;
collectUsedGlobals(GV, Init);
if (GV)
GV->eraseFromParent();

Type *ArrayEltTy = llvm::PointerType::getUnqual(M.getContext());
for (auto *V : Values)
Init.insert(ConstantExpr::getPointerBitCastOrAddrSpaceCast(V, ArrayEltTy));

if (Init.empty())
return;

ArrayType *ATy = ArrayType::get(ArrayEltTy, Init.size());
GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
ConstantArray::get(ATy, Init.getArrayRef()),
Name);
GV->setSection("llvm.metadata");
}

void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) {
appendToUsedList(M, "llvm.used", Values);
}

void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) {
appendToUsedList(M, "llvm.compiler.used", Values);
}

static void removeFromUsedList(Module &M, StringRef Name,
function_ref<bool(Constant *)> ShouldRemove) {
GlobalVariable *GV = M.getNamedGlobal(Name);
if (!GV)
return;

SmallSetVector<Constant *, 16> Init;
collectUsedGlobals(GV, Init);

Type *ArrayEltTy = cast<ArrayType>(GV->getValueType())->getElementType();

SmallVector<Constant *, 16> NewInit;
for (Constant *MaybeRemoved : Init) {
if (!ShouldRemove(MaybeRemoved->stripPointerCasts()))
NewInit.push_back(MaybeRemoved);
}

if (!NewInit.empty()) {
ArrayType *ATy = ArrayType::get(ArrayEltTy, NewInit.size());
GlobalVariable *NewGV =
new GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage,
ConstantArray::get(ATy, NewInit), "", GV,
GV->getThreadLocalMode(), GV->getAddressSpace());
NewGV->setSection(GV->getSection());
NewGV->takeName(GV);
}

GV->eraseFromParent();
}

void llvm::removeFromUsedLists(Module &M,
function_ref<bool(Constant *)> ShouldRemove) {
removeFromUsedList(M, "llvm.used", ShouldRemove);
removeFromUsedList(M, "llvm.compiler.used", ShouldRemove);
}

void llvm::setKCFIType(Module &M, Function &F, StringRef MangledType) {
if (!M.getModuleFlag("kcfi"))
return;
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Transforms/Utils/SampleProfileLoaderBaseUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Module.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"

namespace llvm {

Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ add_llvm_unittest(IRTests
TypesTest.cpp
UseTest.cpp
UserTest.cpp
UsedGlobalTest.cpp
ValueHandleTest.cpp
ValueMapTest.cpp
ValueTest.cpp
Expand Down
Loading