diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 97ef872c5499..b850591b4aa6 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -88,12 +88,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/IPO/MergeFunctions.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/Argument.h" -#include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" @@ -113,7 +112,6 @@ #include "llvm/IR/User.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueHandle.h" -#include "llvm/IR/ValueMap.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" @@ -121,8 +119,8 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/IPO/MergeFunctions.h" #include "llvm/Transforms/Utils/FunctionComparator.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include <algorithm> #include <cassert> #include <iterator> @@ -139,10 +137,10 @@ STATISTIC(NumThunksWritten, "Number of thunks generated"); STATISTIC(NumAliasesWritten, "Number of aliases generated"); STATISTIC(NumDoubleWeak, "Number of new functions created"); -static cl::opt<unsigned> NumFunctionsForSanityCheck( - "mergefunc-sanity", - cl::desc("How many functions in module could be used for " - "MergeFunctions pass sanity check. " +static cl::opt<unsigned> NumFunctionsForVerificationCheck( + "mergefunc-verify", + cl::desc("How many functions in a module could be used for " + "MergeFunctions to pass a basic correctness check. " "'0' disables this check. Works only with '-debug' key."), cl::init(0), cl::Hidden); @@ -228,10 +226,13 @@ private: /// analyzed again. std::vector<WeakTrackingVH> Deferred; + /// Set of values marked as used in llvm.used and llvm.compiler.used. + SmallPtrSet<GlobalValue *, 4> Used; + #ifndef NDEBUG /// Checks the rules of order relation introduced among functions set. - /// Returns true, if sanity check has been passed, and false if failed. - bool doSanityCheck(std::vector<WeakTrackingVH> &Worklist); + /// Returns true, if check has been passed, and false if failed. + bool doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist); #endif /// Insert a ComparableFunction into the FnTree, or merge it away if it's @@ -330,12 +331,12 @@ PreservedAnalyses MergeFunctionsPass::run(Module &M, } #ifndef NDEBUG -bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) { - if (const unsigned Max = NumFunctionsForSanityCheck) { +bool MergeFunctions::doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist) { + if (const unsigned Max = NumFunctionsForVerificationCheck) { unsigned TripleNumber = 0; bool Valid = true; - dbgs() << "MERGEFUNC-SANITY: Started for first " << Max << " functions.\n"; + dbgs() << "MERGEFUNC-VERIFY: Started for first " << Max << " functions.\n"; unsigned i = 0; for (std::vector<WeakTrackingVH>::iterator I = Worklist.begin(), @@ -351,7 +352,7 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) { // If F1 <= F2, then F2 >= F1, otherwise report failure. if (Res1 != -Res2) { - dbgs() << "MERGEFUNC-SANITY: Non-symmetric; triple: " << TripleNumber + dbgs() << "MERGEFUNC-VERIFY: Non-symmetric; triple: " << TripleNumber << "\n"; dbgs() << *F1 << '\n' << *F2 << '\n'; Valid = false; @@ -384,7 +385,7 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) { } if (!Transitive) { - dbgs() << "MERGEFUNC-SANITY: Non-transitive; triple: " + dbgs() << "MERGEFUNC-VERIFY: Non-transitive; triple: " << TripleNumber << "\n"; dbgs() << "Res1, Res3, Res4: " << Res1 << ", " << Res3 << ", " << Res4 << "\n"; @@ -395,7 +396,7 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) { } } - dbgs() << "MERGEFUNC-SANITY: " << (Valid ? "Passed." : "Failed.") << "\n"; + dbgs() << "MERGEFUNC-VERIFY: " << (Valid ? "Passed." : "Failed.") << "\n"; return Valid; } return true; @@ -410,6 +411,11 @@ static bool isEligibleForMerging(Function &F) { bool MergeFunctions::runOnModule(Module &M) { bool Changed = false; + SmallVector<GlobalValue *, 4> UsedV; + collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/false); + collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/true); + Used.insert(UsedV.begin(), UsedV.end()); + // All functions in the module, ordered by hash. Functions with a unique // hash value are easily eliminated. std::vector<std::pair<FunctionComparator::FunctionHash, Function *>> @@ -436,7 +442,7 @@ bool MergeFunctions::runOnModule(Module &M) { std::vector<WeakTrackingVH> Worklist; Deferred.swap(Worklist); - LLVM_DEBUG(doSanityCheck(Worklist)); + LLVM_DEBUG(doFunctionalCheck(Worklist)); LLVM_DEBUG(dbgs() << "size of module: " << M.size() << '\n'); LLVM_DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n'); @@ -456,6 +462,7 @@ bool MergeFunctions::runOnModule(Module &M) { FnTree.clear(); FNodesInTree.clear(); GlobalNumbers.clear(); + Used.clear(); return Changed; } @@ -484,7 +491,7 @@ static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) { if (SrcTy->isStructTy()) { assert(DestTy->isStructTy()); assert(SrcTy->getStructNumElements() == DestTy->getStructNumElements()); - Value *Result = UndefValue::get(DestTy); + Value *Result = PoisonValue::get(DestTy); for (unsigned int I = 0, E = SrcTy->getStructNumElements(); I < E; ++I) { Value *Element = createCast( Builder, Builder.CreateExtractValue(V, makeArrayRef(I)), @@ -828,7 +835,10 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) { // For better debugability, under MergeFunctionsPDI, we do not modify G's // call sites to point to F even when within the same translation unit. if (!G->isInterposable() && !MergeFunctionsPDI) { - if (G->hasGlobalUnnamedAddr()) { + // Functions referred to by llvm.used/llvm.compiler.used are special: + // there are uses of the symbol name that are not visible to LLVM, + // usually from inline asm. + if (G->hasGlobalUnnamedAddr() && !Used.contains(G)) { // G might have been a key in our GlobalNumberState, and it's illegal // to replace a key in ValueMap<GlobalValue *> with a non-global. GlobalNumbers.erase(G); |