IRP.isAnyCallSitePosition())
return false;
+ // Check if we require a calles but we can't see all.
+ if (AAType::requiresCallersForArgOrFunction())
+ if (IRP.getPositionKind() == IRPosition::IRP_FUNCTION ||
+ IRP.getPositionKind() == IRPosition::IRP_ARGUMENT)
+ if (!AssociatedFn->hasLocalLinkage())
+ return false;
+
if (!AAType::isValidIRPositionForUpdate(*this, IRP))
return false;
/// a call site positon. Default is optimistic to minimize AAs.
static bool requiresCalleeForCallBase() { return true; }
+ /// Return true if this AA requires all callees for an argument or function
+ /// positon.
+ static bool requiresCallersForArgOrFunction() { return false; }
+
/// Return false if an AA should not be created for \p IRP.
static bool isValidIRPositionForInit(Attributor &A, const IRPosition &IRP) {
return true;
/// See AbstractAttribute::requiresCalleeForCallBase
static bool requiresCalleeForCallBase() { return false; }
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// Return true if we assume that the underlying value is alias.
bool isAssumedNoAlias() const { return getAssumed(); }
/// Returns true if pointer privatization is known to be possible.
bool isKnownPrivatizablePtr() const { return getKnown(); }
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// Return the type we can choose for a private copy of the underlying
/// value. std::nullopt means it is not clear yet, nullptr means there is
/// none.
return AbstractAttribute::isValidIRPositionForInit(A, IRP);
}
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// See AbstractAttribute::getState(...).
IntegerRangeState &getState() override { return *this; }
const IntegerRangeState &getState() const override { return *this; }
return AbstractAttribute::isValidIRPositionForInit(A, IRP);
}
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// See AbstractAttribute::getState(...).
PotentialConstantIntValuesState &getState() override { return *this; }
const PotentialConstantIntValuesState &getState() const override {
using Base = StateWrapper<PotentialLLVMValuesState, AbstractAttribute>;
AAPotentialValues(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// See AbstractAttribute::getState(...).
PotentialLLVMValuesState &getState() override { return *this; }
const PotentialLLVMValuesState &getState() const override { return *this; }
return AbstractAttribute::isValidIRPositionForInit(A, IRP);
}
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// Create an abstract attribute biew for the position \p IRP.
static AAUnderlyingObjects &createForPosition(const IRPosition &IRP,
Attributor &A);
return AbstractAttribute::isValidIRPositionForInit(A, IRP);
}
+ /// See AbstractAttribute::requiresCallersForArgOrFunction
+ static bool requiresCallersForArgOrFunction() { return true; }
+
/// Return the address space of the associated value. \p NoAddressSpace is
/// returned if the associated value is dead. This functions is not supposed
/// to be called if the AA is invalid.
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %2 = load i32, ptr %0, align 4' at position {flt: [@-1]} with state set-state(< { %2 = load i32, ptr %0, align 4[3], } >)
; GRAPH-EMPTY:
-; GRAPH-NEXT: [AAUnderlyingObjects] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state UnderlyingObjects inter #1 objs, intra #1 objs
-; GRAPH-EMPTY:
-; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state set-state(< {ptr %0[3], } >)
+; GRAPH-NEXT: [AAUnderlyingObjects] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state UnderlyingObjects <invalid>
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAPotentialValues] for CtxI <<null inst>> at position {flt: [@-1]} with state set-state(< {i32 0[3], } >)
; GRAPH-EMPTY:
; GRAPH-EMPTY:
; GRAPH-NEXT: [AAUndefinedBehavior] for CtxI ' %2 = load i32, ptr %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state undefined-behavior
; GRAPH-EMPTY:
+; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state set-state(< {ptr %0[3], } >)
+; GRAPH-EMPTY:
; GRAPH-NEXT: [AAIsDead] for CtxI ' %6 = call ptr @checkAndAdvance(ptr %5)' at position {flt: [@-1]} with state assumed-live
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %6 = call ptr @checkAndAdvance(ptr %5)' at position {cs: [@-1]} with state nounwind
; GRAPH-EMPTY:
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %6 = call ptr @checkAndAdvance(ptr %5)' at position {cs_arg: [@0]} with state unknown-dereferenceable
; GRAPH-EMPTY:
-; GRAPH-NEXT: [AANoAlias] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state may-alias
-; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoFree] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state nofree
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %6 = call ptr @checkAndAdvance(ptr %5)' at position {cs_arg: [@0]} with state nofree
; GRAPH-EMPTY:
; GRAPH-EMPTY:
; GRAPH-NEXT: [AANoFree] for CtxI ' %6 = call ptr @checkAndAdvance(ptr %5)' at position {cs_arg: [@0]} with state nofree
; GRAPH-EMPTY:
-; GRAPH-NEXT: [AAAddressSpace] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state addrspace(0)
+; GRAPH-NEXT: [AAAddressSpace] for CtxI ' %2 = load i32, ptr %0, align 4' at position {arg: [@0]} with state addrspace(<invalid>)
; GRAPH-EMPTY:
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, ptr %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
; DOT-DAG: Node[[Node69:0x[a-z0-9]+]] [shape=record,label="{[AAPrivatizablePtr]
; DOT-DAG: Node[[Node70:0x[a-z0-9]+]] [shape=record,label="{[AAAssumptionInfo]
; DOT-DAG: Node[[Node71:0x[a-z0-9]+]] [shape=record,label="{[AANoAlias]
-; DOT-DAG: Node[[Node72:0x[a-z0-9]+]] [shape=record,label="{[AANoAlias]
; DOT-DAG: Node[[Node73:0x[a-z0-9]+]] [shape=record,label="{[AANoFree]
; DOT-DAG: Node[[Node75:0x[a-z0-9]+]] [shape=record,label="{[AAAddressSpace]
; DOT-DAG: Node[[Node74:0x[a-z0-9]+]] [shape=record,label="{[AADereferenceable]