diff options
author | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2021-02-04 15:35:43 -0800 |
---|---|---|
committer | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2021-02-25 10:06:24 -0800 |
commit | d9c99043bdde5637bf32edaad10d1b8f8cd10b38 (patch) | |
tree | 9ac8f18d649b2e4542d79d5c56a9d0f85f206991 /llvm/lib/IR/Function.cpp | |
parent | 9490b9f14b899ff07f3cfab7ad64e5fed8f48746 (diff) | |
download | llvm-d9c99043bdde5637bf32edaad10d1b8f8cd10b38.zip llvm-d9c99043bdde5637bf32edaad10d1b8f8cd10b38.tar.gz llvm-d9c99043bdde5637bf32edaad10d1b8f8cd10b38.tar.bz2 |
Option to ignore llvm[.compiler].used uses in hasAddressTaken()
Differential Revision: https://reviews.llvm.org/D96087
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index c6932f0..0396fda 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -52,6 +52,7 @@ #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/SymbolTableListTraits.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" @@ -1579,10 +1580,12 @@ Optional<Function *> Intrinsic::remangleIntrinsicFunction(Function *F) { /// hasAddressTaken - returns true if there are any uses of this function /// other than direct calls or invokes to it. Optionally ignores callback -/// uses and assume like pointer annotation calls. +/// uses, assume like pointer annotation calls, and references in llvm.used +/// and llvm.compiler.used variables. bool Function::hasAddressTaken(const User **PutOffender, bool IgnoreCallbackUses, - bool IgnoreAssumeLikeCalls) const { + bool IgnoreAssumeLikeCalls, + bool IgnoreLLVMUsed) const { for (const Use &U : uses()) { const User *FU = U.getUser(); if (isa<BlockAddress>(FU)) @@ -1607,6 +1610,20 @@ bool Function::hasAddressTaken(const User **PutOffender, continue; } } + if (IgnoreLLVMUsed && !FU->user_empty()) { + const User *FUU = FU; + if (isa<BitCastOperator>(FU) && FU->hasOneUse() && + !FU->user_begin()->user_empty()) + FUU = *FU->user_begin(); + if (llvm::all_of(FUU->users(), [](const User *U) { + if (const auto *GV = dyn_cast<GlobalVariable>(U)) + return GV->hasName() && + (GV->getName().equals("llvm.compiler.used") || + GV->getName().equals("llvm.used")); + return false; + })) + continue; + } if (PutOffender) *PutOffender = FU; return true; |