struct AANoUnwindImpl : AANoUnwind {
AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (hasAttr({Attribute::NoUnwind}))
- indicateOptimisticFixpoint();
- }
-
const std::string getAsStr() const override {
return getAssumed() ? "nounwind" : "may-unwind";
}
void initialize(Attributor &A) override {
AANoUnwindImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
ReturnedValues.clear();
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition()) {
+ if (!F) {
indicatePessimisticFixpoint();
return;
}
return;
}
}
+
+ if (!F->hasExactDefinition())
+ indicatePessimisticFixpoint();
}
/// See AbstractAttribute::manifest(...).
struct AANoSyncImpl : AANoSync {
AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (hasAttr({Attribute::NoSync}))
- indicateOptimisticFixpoint();
- }
-
const std::string getAsStr() const override {
return getAssumed() ? "nosync" : "may-sync";
}
void initialize(Attributor &A) override {
AANoSyncImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
struct AANoFreeImpl : public AANoFree {
AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (hasAttr({Attribute::NoFree}))
- indicateOptimisticFixpoint();
- }
-
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
auto CheckForNoFree = [&](Instruction &I) {
void initialize(Attributor &A) override {
AANoFreeImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
void initialize(Attributor &A) override {
if (hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
indicateOptimisticFixpoint();
+ else
+ AANonNull::initialize(A);
}
/// See AbstractAttribute::getAsStr().
struct AANoRecurseImpl : public AANoRecurse {
AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (hasAttr({getAttrKind()})) {
- indicateOptimisticFixpoint();
- return;
- }
- }
-
/// See AbstractAttribute::getAsStr()
const std::string getAsStr() const override {
return getAssumed() ? "norecurse" : "may-recurse";
void initialize(Attributor &A) override {
AANoRecurseImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
- if (hasAttr({Attribute::WillReturn})) {
- indicateOptimisticFixpoint();
- return;
- }
+ AAWillReturn::initialize(A);
Function *F = getAssociatedFunction();
if (containsPossiblyEndlessLoop(F))
void initialize(Attributor &A) override {
AAWillReturnImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
struct AANoAliasImpl : AANoAlias {
AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (hasAttr({Attribute::NoAlias}))
- indicateOptimisticFixpoint();
- }
-
const std::string getAsStr() const override {
return getAssumed() ? "noalias" : "may-alias";
}
void initialize(Attributor &A) override {
AANoAliasImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
takeKnownDerefBytesMaximum(Attr.getValueAsInt());
NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
+
+ const IRPosition &IRP = this->getIRPosition();
+ bool IsFnInterface = IRP.isFnInterfaceKind();
+ const Function *FnScope = IRP.getAnchorScope();
+ if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
+ indicatePessimisticFixpoint();
}
/// See AbstractAttribute::getState()
void initialize(Attributor &A) override {
AADereferenceableImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
void initialize(Attributor &A) override {
AAAlignImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
return getAssumed() ? "noreturn" : "may-return";
}
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- if (hasAttr({getAttrKind()}))
- indicateOptimisticFixpoint();
- }
-
/// See AbstractAttribute::updateImpl(Attributor &A).
virtual ChangeStatus updateImpl(Attributor &A) override {
auto CheckForNoReturn = [](Instruction &) { return false; };
void initialize(Attributor &A) override {
AANoReturnImpl::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || !F->hasExactDefinition())
+ if (!F)
indicatePessimisticFixpoint();
}
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
- if (hasAttr(Attribute::NoCapture)) {
- indicateOptimisticFixpoint();
- return;
- }
+ AANoCapture::initialize(A);
const IRPosition &IRP = getIRPosition();
const Function *F =
// Check what state the associated function can actually capture.
if (F)
determineFunctionCaptureCapabilities(*F, *this);
-
- if (!F || !F->hasExactDefinition())
+ else
indicatePessimisticFixpoint();
}
}
CallSite CS(U.getUser());
- if (!CS || !CS.isCallee(&U) || !CS.getCaller()->hasExactDefinition()) {
+ if (!CS || !CS.isCallee(&U)) {
if (!RequireAllCallSites)
continue;
// Since we need to provide return instructions we have to have an exact
// definition.
const Function *AssociatedFunction = IRP.getAssociatedFunction();
- if (!AssociatedFunction || !AssociatedFunction->hasExactDefinition())
+ if (!AssociatedFunction)
return false;
// If this is a call site query we use the call site specific return values
const IRPosition &IRP = QueryingAA.getIRPosition();
const Function *AssociatedFunction = IRP.getAssociatedFunction();
- if (!AssociatedFunction || !AssociatedFunction->hasExactDefinition())
+ if (!AssociatedFunction)
return false;
// TODO: use the function scope once we have call site AAReturnedValues.
const IRPosition &IRP = QueryingAA.getIRPosition();
// Since we need to provide instructions we have to have an exact definition.
const Function *AssociatedFunction = IRP.getAssociatedFunction();
- if (!AssociatedFunction || !AssociatedFunction->hasExactDefinition())
+ if (!AssociatedFunction)
return false;
// TODO: use the function scope once we have call site AAReturnedValues.
Attributor A(InfoCache, DepRecInterval);
for (Function &F : M) {
- // TODO: Not all attributes require an exact definition. Find a way to
- // enable deduction for some but not all attributes in case the
- // definition might be changed at runtime, see also
- // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
- // TODO: We could always determine abstract attributes and if sufficient
- // information was found we could duplicate the functions that do not
- // have an exact definition.
- if (!F.hasExactDefinition()) {
+ if (F.hasExactDefinition())
+ NumFnWithExactDefinition++;
+ else
NumFnWithoutExactDefinition++;
- continue;
- }
// For now we ignore naked and optnone functions.
if (F.hasFnAttribute(Attribute::Naked) ||
F.hasFnAttribute(Attribute::OptimizeNone))
continue;
- NumFnWithExactDefinition++;
-
// Populate the Attributor with abstract attribute opportunities in the
// function and the information cache with IR information.
A.identifyDefaultAbstractAttributes(F);