mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[ThinLTO] Make cloneUsedGlobalVariables deterministic
Iterating on `SmallPtrSet<GlobalValue *, 8>` with more than 8 elements is not deterministic. Use a SmallVector instead because `Used` is guaranteed to contain unique elements. While here, decrease inline element counts from 8 to 4. The number of `llvm.used`/`llvm.compiler.used` elements is usually 0 or 1. For full LTO/hybrid LTO, the number may be large, so we need to be careful. According to tejohnson's analysis https://reviews.llvm.org/D97128#2582399 , 4 is good for a large project with WholeProgramDevirt, when available_externally vtables are placed in the llvm.compiler.used set. Differential Revision: https://reviews.llvm.org/D97128
This commit is contained in:
parent
3133ac74f4
commit
7d33c2a5f8
@ -893,6 +893,12 @@ public:
|
||||
GlobalVariable *collectUsedGlobalVariables(const Module &M,
|
||||
SmallPtrSetImpl<GlobalValue *> &Set,
|
||||
bool CompilerUsed);
|
||||
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the
|
||||
/// initializer elements of that global in a SmallVector and return the global
|
||||
/// itself.
|
||||
GlobalVariable *collectUsedGlobalVariables(const Module &M,
|
||||
SmallVectorImpl<GlobalValue *> &Vec,
|
||||
bool CompilerUsed);
|
||||
|
||||
/// An raw_ostream inserter for modules.
|
||||
inline raw_ostream &operator<<(raw_ostream &O, const Module &M) {
|
||||
|
@ -658,6 +658,21 @@ VersionTuple Module::getSDKVersion() const {
|
||||
return Result;
|
||||
}
|
||||
|
||||
GlobalVariable *llvm::collectUsedGlobalVariables(
|
||||
const Module &M, SmallVectorImpl<GlobalValue *> &Vec, bool CompilerUsed) {
|
||||
const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";
|
||||
GlobalVariable *GV = M.getGlobalVariable(Name);
|
||||
if (!GV || !GV->hasInitializer())
|
||||
return GV;
|
||||
|
||||
const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
|
||||
for (Value *Op : Init->operands()) {
|
||||
GlobalValue *G = cast<GlobalValue>(Op->stripPointerCasts());
|
||||
Vec.push_back(G);
|
||||
}
|
||||
return GV;
|
||||
}
|
||||
|
||||
GlobalVariable *llvm::collectUsedGlobalVariables(
|
||||
const Module &M, SmallPtrSetImpl<GlobalValue *> &Set, bool CompilerUsed) {
|
||||
const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";
|
||||
|
@ -199,23 +199,20 @@ void forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) {
|
||||
// values whose defs were cloned into that module.
|
||||
static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM,
|
||||
bool CompilerUsed) {
|
||||
SmallPtrSet<GlobalValue *, 8> Used;
|
||||
SmallPtrSet<GlobalValue *, 8> NewUsed;
|
||||
SmallVector<GlobalValue *, 4> Used, NewUsed;
|
||||
// First collect those in the llvm[.compiler].used set.
|
||||
collectUsedGlobalVariables(SrcM, Used, CompilerUsed);
|
||||
// Next build a set of the equivalent values defined in DestM.
|
||||
for (auto *V : Used) {
|
||||
auto *GV = DestM.getNamedValue(V->getName());
|
||||
if (GV && !GV->isDeclaration())
|
||||
NewUsed.insert(GV);
|
||||
NewUsed.push_back(GV);
|
||||
}
|
||||
// Finally, add them to a llvm[.compiler].used variable in DestM.
|
||||
if (CompilerUsed)
|
||||
appendToCompilerUsed(
|
||||
DestM, std::vector<GlobalValue *>(NewUsed.begin(), NewUsed.end()));
|
||||
appendToCompilerUsed(DestM, NewUsed);
|
||||
else
|
||||
appendToUsed(DestM,
|
||||
std::vector<GlobalValue *>(NewUsed.begin(), NewUsed.end()));
|
||||
appendToUsed(DestM, NewUsed);
|
||||
}
|
||||
|
||||
// If it's possible to split M into regular and thin LTO parts, do so and write
|
||||
|
Loading…
Reference in New Issue
Block a user