From ee504358f21d93e7cc04d65bcc489f2b23bd87a4 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Tue, 18 Jul 2023 23:27:16 -0700 Subject: [PATCH] [Attributor][NFCI] Avoid updating AAs that depend on missing callees --- llvm/include/llvm/Transforms/IPO/Attributor.h | 32 +++++++++++++++++++++++++++ llvm/test/Transforms/Attributor/depgraph.ll | 11 ++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 9e411fe..1da00ac 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1706,6 +1706,13 @@ struct Attributor { 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; @@ -3236,6 +3243,10 @@ struct AbstractAttribute : public IRPosition, public AADepGraphNode { /// 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; @@ -3743,6 +3754,9 @@ struct AANoAlias /// 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(); } @@ -4462,6 +4476,9 @@ struct AAPrivatizablePtr /// 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. @@ -4758,6 +4775,9 @@ struct AAValueConstantRange 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; } @@ -5027,6 +5047,9 @@ struct AAPotentialConstantValues 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 { @@ -5080,6 +5103,9 @@ struct AAPotentialValues using Base = StateWrapper; 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; } @@ -5957,6 +5983,9 @@ struct AAUnderlyingObjects : AbstractAttribute { 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); @@ -5997,6 +6026,9 @@ struct AAAddressSpace : public StateWrapper { 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. diff --git a/llvm/test/Transforms/Attributor/depgraph.ll b/llvm/test/Transforms/Attributor/depgraph.ll index 4de58c95..73f6e2e 100644 --- a/llvm/test/Transforms/Attributor/depgraph.ll +++ b/llvm/test/Transforms/Attributor/depgraph.ll @@ -57,9 +57,7 @@ define ptr @checkAndAdvance(ptr align 16 %0) { ; 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 ; GRAPH-EMPTY: ; GRAPH-NEXT: [AAPotentialValues] for CtxI <> at position {flt: [@-1]} with state set-state(< {i32 0[3], } >) ; GRAPH-EMPTY: @@ -71,6 +69,8 @@ define ptr @checkAndAdvance(ptr align 16 %0) { ; 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 @@ -218,8 +218,6 @@ define ptr @checkAndAdvance(ptr align 16 %0) { ; 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: @@ -233,7 +231,7 @@ define ptr @checkAndAdvance(ptr align 16 %0) { ; 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() ; GRAPH-EMPTY: ; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, ptr %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable @@ -310,7 +308,6 @@ define ptr @checkAndAdvance(ptr align 16 %0) { ; 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] -- 2.7.4