forked from OSchip/llvm-project
[llvm][NFC][CallSite] Remove CallSite from FunctionAttrs
Reviewers: dblaikie, craig.topper Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78584
This commit is contained in:
parent
d892eec710
commit
9ee02aef62
|
@ -33,7 +33,6 @@
|
||||||
#include "llvm/IR/Argument.h"
|
#include "llvm/IR/Argument.h"
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/IR/BasicBlock.h"
|
#include "llvm/IR/BasicBlock.h"
|
||||||
#include "llvm/IR/CallSite.h"
|
|
||||||
#include "llvm/IR/Constant.h"
|
#include "llvm/IR/Constant.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/Function.h"
|
#include "llvm/IR/Function.h"
|
||||||
|
@ -160,8 +159,7 @@ static MemoryAccessKind checkFunctionMemoryAccess(Function &F, bool ThisBody,
|
||||||
|
|
||||||
// Check whether all pointer arguments point to local memory, and
|
// Check whether all pointer arguments point to local memory, and
|
||||||
// ignore calls that only access local memory.
|
// ignore calls that only access local memory.
|
||||||
for (CallSite::arg_iterator CI = Call->arg_begin(), CE = Call->arg_end();
|
for (auto CI = Call->arg_begin(), CE = Call->arg_end(); CI != CE; ++CI) {
|
||||||
CI != CE; ++CI) {
|
|
||||||
Value *Arg = *CI;
|
Value *Arg = *CI;
|
||||||
if (!Arg->getType()->isPtrOrPtrVectorTy())
|
if (!Arg->getType()->isPtrOrPtrVectorTy())
|
||||||
continue;
|
continue;
|
||||||
|
@ -362,13 +360,13 @@ struct ArgumentUsesTracker : public CaptureTracker {
|
||||||
void tooManyUses() override { Captured = true; }
|
void tooManyUses() override { Captured = true; }
|
||||||
|
|
||||||
bool captured(const Use *U) override {
|
bool captured(const Use *U) override {
|
||||||
CallSite CS(U->getUser());
|
CallBase *CB = dyn_cast<CallBase>(U->getUser());
|
||||||
if (!CS.getInstruction()) {
|
if (!CB) {
|
||||||
Captured = true;
|
Captured = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Function *F = CS.getCalledFunction();
|
Function *F = CB->getCalledFunction();
|
||||||
if (!F || !F->hasExactDefinition() || !SCCNodes.count(F)) {
|
if (!F || !F->hasExactDefinition() || !SCCNodes.count(F)) {
|
||||||
Captured = true;
|
Captured = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -379,14 +377,14 @@ struct ArgumentUsesTracker : public CaptureTracker {
|
||||||
// these.
|
// these.
|
||||||
|
|
||||||
unsigned UseIndex =
|
unsigned UseIndex =
|
||||||
std::distance(const_cast<const Use *>(CS.arg_begin()), U);
|
std::distance(const_cast<const Use *>(CB->arg_begin()), U);
|
||||||
|
|
||||||
assert(UseIndex < CS.data_operands_size() &&
|
assert(UseIndex < CB->data_operands_size() &&
|
||||||
"Indirect function calls should have been filtered above!");
|
"Indirect function calls should have been filtered above!");
|
||||||
|
|
||||||
if (UseIndex >= CS.getNumArgOperands()) {
|
if (UseIndex >= CB->getNumArgOperands()) {
|
||||||
// Data operand, but not a argument operand -- must be a bundle operand
|
// Data operand, but not a argument operand -- must be a bundle operand
|
||||||
assert(CS.hasOperandBundles() && "Must be!");
|
assert(CB->hasOperandBundles() && "Must be!");
|
||||||
|
|
||||||
// CaptureTracking told us that we're being captured by an operand bundle
|
// CaptureTracking told us that we're being captured by an operand bundle
|
||||||
// use. In this case it does not matter if the callee is within our SCC
|
// use. In this case it does not matter if the callee is within our SCC
|
||||||
|
@ -490,15 +488,15 @@ determinePointerReadAttrs(Argument *A,
|
||||||
Worklist.push_back(&UU);
|
Worklist.push_back(&UU);
|
||||||
};
|
};
|
||||||
|
|
||||||
CallSite CS(I);
|
CallBase &CB = cast<CallBase>(*I);
|
||||||
if (CS.doesNotAccessMemory()) {
|
if (CB.doesNotAccessMemory()) {
|
||||||
AddUsersToWorklistIfCapturing();
|
AddUsersToWorklistIfCapturing();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Function *F = CS.getCalledFunction();
|
Function *F = CB.getCalledFunction();
|
||||||
if (!F) {
|
if (!F) {
|
||||||
if (CS.onlyReadsMemory()) {
|
if (CB.onlyReadsMemory()) {
|
||||||
IsRead = true;
|
IsRead = true;
|
||||||
AddUsersToWorklistIfCapturing();
|
AddUsersToWorklistIfCapturing();
|
||||||
continue;
|
continue;
|
||||||
|
@ -510,23 +508,23 @@ determinePointerReadAttrs(Argument *A,
|
||||||
// operands. This means there is no need to adjust UseIndex to account
|
// operands. This means there is no need to adjust UseIndex to account
|
||||||
// for these.
|
// for these.
|
||||||
|
|
||||||
unsigned UseIndex = std::distance(CS.arg_begin(), U);
|
unsigned UseIndex = std::distance(CB.arg_begin(), U);
|
||||||
|
|
||||||
// U cannot be the callee operand use: since we're exploring the
|
// U cannot be the callee operand use: since we're exploring the
|
||||||
// transitive uses of an Argument, having such a use be a callee would
|
// transitive uses of an Argument, having such a use be a callee would
|
||||||
// imply the CallSite is an indirect call or invoke; and we'd take the
|
// imply the call site is an indirect call or invoke; and we'd take the
|
||||||
// early exit above.
|
// early exit above.
|
||||||
assert(UseIndex < CS.data_operands_size() &&
|
assert(UseIndex < CB.data_operands_size() &&
|
||||||
"Data operand use expected!");
|
"Data operand use expected!");
|
||||||
|
|
||||||
bool IsOperandBundleUse = UseIndex >= CS.getNumArgOperands();
|
bool IsOperandBundleUse = UseIndex >= CB.getNumArgOperands();
|
||||||
|
|
||||||
if (UseIndex >= F->arg_size() && !IsOperandBundleUse) {
|
if (UseIndex >= F->arg_size() && !IsOperandBundleUse) {
|
||||||
assert(F->isVarArg() && "More params than args in non-varargs call");
|
assert(F->isVarArg() && "More params than args in non-varargs call");
|
||||||
return Attribute::None;
|
return Attribute::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Captures &= !CS.doesNotCapture(UseIndex);
|
Captures &= !CB.doesNotCapture(UseIndex);
|
||||||
|
|
||||||
// Since the optimizer (by design) cannot see the data flow corresponding
|
// Since the optimizer (by design) cannot see the data flow corresponding
|
||||||
// to a operand bundle use, these cannot participate in the optimistic SCC
|
// to a operand bundle use, these cannot participate in the optimistic SCC
|
||||||
|
@ -535,12 +533,12 @@ determinePointerReadAttrs(Argument *A,
|
||||||
if (IsOperandBundleUse ||
|
if (IsOperandBundleUse ||
|
||||||
!SCCNodes.count(&*std::next(F->arg_begin(), UseIndex))) {
|
!SCCNodes.count(&*std::next(F->arg_begin(), UseIndex))) {
|
||||||
|
|
||||||
// The accessors used on CallSite here do the right thing for calls and
|
// The accessors used on call site here do the right thing for calls and
|
||||||
// invokes with operand bundles.
|
// invokes with operand bundles.
|
||||||
|
|
||||||
if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(UseIndex))
|
if (!CB.onlyReadsMemory() && !CB.onlyReadsMemory(UseIndex))
|
||||||
return Attribute::None;
|
return Attribute::None;
|
||||||
if (!CS.doesNotAccessMemory(UseIndex))
|
if (!CB.doesNotAccessMemory(UseIndex))
|
||||||
IsRead = true;
|
IsRead = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,8 +636,8 @@ static bool addArgumentAttrsFromCallsites(Function &F) {
|
||||||
// callsite.
|
// callsite.
|
||||||
BasicBlock &Entry = F.getEntryBlock();
|
BasicBlock &Entry = F.getEntryBlock();
|
||||||
for (Instruction &I : Entry) {
|
for (Instruction &I : Entry) {
|
||||||
if (auto CS = CallSite(&I)) {
|
if (auto *CB = dyn_cast<CallBase>(&I)) {
|
||||||
if (auto *CalledFunc = CS.getCalledFunction()) {
|
if (auto *CalledFunc = CB->getCalledFunction()) {
|
||||||
for (auto &CSArg : CalledFunc->args()) {
|
for (auto &CSArg : CalledFunc->args()) {
|
||||||
if (!CSArg.hasNonNullAttr())
|
if (!CSArg.hasNonNullAttr())
|
||||||
continue;
|
continue;
|
||||||
|
@ -647,7 +645,7 @@ static bool addArgumentAttrsFromCallsites(Function &F) {
|
||||||
// If the non-null callsite argument operand is an argument to 'F'
|
// If the non-null callsite argument operand is an argument to 'F'
|
||||||
// (the caller) and the call is guaranteed to execute, then the value
|
// (the caller) and the call is guaranteed to execute, then the value
|
||||||
// must be non-null throughout 'F'.
|
// must be non-null throughout 'F'.
|
||||||
auto *FArg = dyn_cast<Argument>(CS.getArgOperand(CSArg.getArgNo()));
|
auto *FArg = dyn_cast<Argument>(CB->getArgOperand(CSArg.getArgNo()));
|
||||||
if (FArg && !FArg->hasNonNullAttr()) {
|
if (FArg && !FArg->hasNonNullAttr()) {
|
||||||
FArg->addAttr(Attribute::NonNull);
|
FArg->addAttr(Attribute::NonNull);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
@ -904,10 +902,10 @@ static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes) {
|
||||||
break;
|
break;
|
||||||
case Instruction::Call:
|
case Instruction::Call:
|
||||||
case Instruction::Invoke: {
|
case Instruction::Invoke: {
|
||||||
CallSite CS(RVI);
|
CallBase &CB = cast<CallBase>(*RVI);
|
||||||
if (CS.hasRetAttr(Attribute::NoAlias))
|
if (CB.hasRetAttr(Attribute::NoAlias))
|
||||||
break;
|
break;
|
||||||
if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction()))
|
if (CB.getCalledFunction() && SCCNodes.count(CB.getCalledFunction()))
|
||||||
break;
|
break;
|
||||||
LLVM_FALLTHROUGH;
|
LLVM_FALLTHROUGH;
|
||||||
}
|
}
|
||||||
|
@ -1013,8 +1011,8 @@ static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes,
|
||||||
}
|
}
|
||||||
case Instruction::Call:
|
case Instruction::Call:
|
||||||
case Instruction::Invoke: {
|
case Instruction::Invoke: {
|
||||||
CallSite CS(RVI);
|
CallBase &CB = cast<CallBase>(*RVI);
|
||||||
Function *Callee = CS.getCalledFunction();
|
Function *Callee = CB.getCalledFunction();
|
||||||
// A call to a node within the SCC is assumed to return null until
|
// A call to a node within the SCC is assumed to return null until
|
||||||
// proven otherwise
|
// proven otherwise
|
||||||
if (Callee && SCCNodes.count(Callee)) {
|
if (Callee && SCCNodes.count(Callee)) {
|
||||||
|
@ -1223,10 +1221,11 @@ bool AttributeInferer::run(const SCCNodeSet &SCCNodes) {
|
||||||
/// Helper for non-Convergent inference predicate InstrBreaksAttribute.
|
/// Helper for non-Convergent inference predicate InstrBreaksAttribute.
|
||||||
static bool InstrBreaksNonConvergent(Instruction &I,
|
static bool InstrBreaksNonConvergent(Instruction &I,
|
||||||
const SCCNodeSet &SCCNodes) {
|
const SCCNodeSet &SCCNodes) {
|
||||||
const CallSite CS(&I);
|
const CallBase *CB = dyn_cast<CallBase>(&I);
|
||||||
// Breaks non-convergent assumption if CS is a convergent call to a function
|
// Breaks non-convergent assumption if CS is a convergent call to a function
|
||||||
// not in the SCC.
|
// not in the SCC.
|
||||||
return CS && CS.isConvergent() && SCCNodes.count(CS.getCalledFunction()) == 0;
|
return CB && CB->isConvergent() &&
|
||||||
|
SCCNodes.count(CB->getCalledFunction()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper for NoUnwind inference predicate InstrBreaksAttribute.
|
/// Helper for NoUnwind inference predicate InstrBreaksAttribute.
|
||||||
|
@ -1247,11 +1246,11 @@ static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes) {
|
||||||
|
|
||||||
/// Helper for NoFree inference predicate InstrBreaksAttribute.
|
/// Helper for NoFree inference predicate InstrBreaksAttribute.
|
||||||
static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
|
static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
|
||||||
CallSite CS(&I);
|
CallBase *CB = dyn_cast<CallBase>(&I);
|
||||||
if (!CS)
|
if (!CB)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Function *Callee = CS.getCalledFunction();
|
Function *Callee = CB->getCalledFunction();
|
||||||
if (!Callee)
|
if (!Callee)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1368,8 +1367,8 @@ static bool addNoRecurseAttrs(const SCCNodeSet &SCCNodes) {
|
||||||
// marked norecurse, so any called from F to F will not be marked norecurse.
|
// marked norecurse, so any called from F to F will not be marked norecurse.
|
||||||
for (auto &BB : *F)
|
for (auto &BB : *F)
|
||||||
for (auto &I : BB.instructionsWithoutDebug())
|
for (auto &I : BB.instructionsWithoutDebug())
|
||||||
if (auto CS = CallSite(&I)) {
|
if (auto *CB = dyn_cast<CallBase>(&I)) {
|
||||||
Function *Callee = CS.getCalledFunction();
|
Function *Callee = CB->getCalledFunction();
|
||||||
if (!Callee || Callee == F || !Callee->doesNotRecurse())
|
if (!Callee || Callee == F || !Callee->doesNotRecurse())
|
||||||
// Function calls a potentially recursive function.
|
// Function calls a potentially recursive function.
|
||||||
return false;
|
return false;
|
||||||
|
@ -1439,8 +1438,8 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
|
||||||
// function.
|
// function.
|
||||||
if (!HasUnknownCall)
|
if (!HasUnknownCall)
|
||||||
for (Instruction &I : instructions(F))
|
for (Instruction &I : instructions(F))
|
||||||
if (auto CS = CallSite(&I))
|
if (auto *CB = dyn_cast<CallBase>(&I))
|
||||||
if (!CS.getCalledFunction()) {
|
if (!CB->getCalledFunction()) {
|
||||||
HasUnknownCall = true;
|
HasUnknownCall = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1575,8 +1574,8 @@ static bool addNoRecurseAttrsTopDown(Function &F) {
|
||||||
auto *I = dyn_cast<Instruction>(U);
|
auto *I = dyn_cast<Instruction>(U);
|
||||||
if (!I)
|
if (!I)
|
||||||
return false;
|
return false;
|
||||||
CallSite CS(I);
|
CallBase *CB = dyn_cast<CallBase>(I);
|
||||||
if (!CS || !CS.getParent()->getParent()->doesNotRecurse())
|
if (!CB || !CB->getParent()->getParent()->doesNotRecurse())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return setDoesNotRecurse(F);
|
return setDoesNotRecurse(F);
|
||||||
|
|
Loading…
Reference in New Issue