Skip to content

Commit

Permalink
[Attributor] Use AAValueSimplify to simplify returned values
Browse files Browse the repository at this point in the history
We should use AAValueSimplify for all value simplification, however
there was some leftover logic that predates AAValueSimplify in
AAReturnedValues. This remove the AAReturnedValues part and provides a
replacement by making AAValueSimplifyReturned strong enough to handle
all previously covered cases. Further, this improve
AAValueSimplifyCallSiteReturned to handle returned arguments.

AAReturnedValues is now much easier and the collected returned
values/instructions are now from the associated function only, making it
much more sane. We also do not have the brittle logic anymore that looks
for unresolved calls. Instead, we use AAValueSimplify to handle
recursion.

Useful code has been split into helper functions, e.g., an Attributor
interface to get a simplified value.

Differential Revision: https://reviews.llvm.org/D103860
  • Loading branch information
jdoerfert committed Jul 10, 2021
1 parent 93a279a commit 374e573
Show file tree
Hide file tree
Showing 38 changed files with 852 additions and 1,102 deletions.
13 changes: 12 additions & 1 deletion llvm/include/llvm/Transforms/IPO/Attributor.h
Expand Up @@ -1481,6 +1481,12 @@ struct Attributor {
bool &UsedAssumedInformation) {
return getAssumedSimplified(IRP, &AA, UsedAssumedInformation);
}
Optional<Value *> getAssumedSimplified(const Value &V,
const AbstractAttribute &AA,
bool &UsedAssumedInformation) {
return getAssumedSimplified(IRPosition::value(V), AA,
UsedAssumedInformation);
}

/// Register \p CB as a simplification callback.
/// `Attributor::getAssumedSimplified` will use these callbacks before
Expand All @@ -1507,6 +1513,12 @@ struct Attributor {
bool &UsedAssumedInformation);

public:
/// Translate \p V from the callee context into the call site context.
Optional<Value *>
translateArgumentToCallSiteContent(Optional<Value *> V, CallBase &CB,
const AbstractAttribute &AA,
bool &UsedAssumedInformation);

/// Return true if \p AA (or its context instruction) is assumed dead.
///
/// If \p LivenessAA is not provided it is queried.
Expand Down Expand Up @@ -2654,7 +2666,6 @@ struct AAReturnedValues
virtual llvm::iterator_range<const_iterator> returned_values() const = 0;

virtual size_t getNumReturnValues() const = 0;
virtual const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const = 0;

/// Create an abstract attribute view for the position \p IRP.
static AAReturnedValues &createForPosition(const IRPosition &IRP,
Expand Down
29 changes: 24 additions & 5 deletions llvm/lib/Transforms/IPO/Attributor.cpp
Expand Up @@ -26,6 +26,7 @@
#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/IRBuilder.h"
Expand Down Expand Up @@ -670,6 +671,21 @@ Attributor::getAssumedSimplified(const IRPosition &IRP,
return const_cast<Value *>(&IRP.getAssociatedValue());
}

Optional<Value *> Attributor::translateArgumentToCallSiteContent(
Optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
bool &UsedAssumedInformation) {
if (!V.hasValue())
return V;
if (*V == nullptr || isa<Constant>(*V))
return V;
if (auto *Arg = dyn_cast<Argument>(*V))
if (!Arg->hasPointeeInMemoryValueAttr())
return getAssumedSimplified(
IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
UsedAssumedInformation);
return nullptr;
}

Attributor::~Attributor() {
// The abstract attributes are allocated via the BumpPtrAllocator Allocator,
// thus we cannot delete them. We can, and want to, destruct them though.
Expand Down Expand Up @@ -1365,11 +1381,17 @@ ChangeStatus Attributor::cleanupIR() {

// Do not replace uses in returns if the value is a must-tail call we will
// not delete.
if (isa<ReturnInst>(U->getUser()))
if (auto *RI = dyn_cast<ReturnInst>(U->getUser())) {
if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
if (CI->isMustTailCall() &&
(!ToBeDeletedInsts.count(CI) || !isRunOn(*CI->getCaller())))
return;
// If we rewrite a return and the new value is not an argument, strip the
// `returned` attribute as it is wrong now.
if (!isa<Argument>(NewV))
for (auto &Arg : RI->getFunction()->args())
Arg.removeAttr(Attribute::Returned);
}

// Do not perform call graph altering changes outside the SCC.
if (auto *CB = dyn_cast<CallBase>(U->getUser()))
Expand Down Expand Up @@ -2292,10 +2314,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {

IRPosition CBRetPos = IRPosition::callsite_returned(CB);

// Call site return integer values might be limited by a constant range.
if (Callee->getReturnType()->isIntegerTy())
getOrCreateAAFor<AAValueConstantRange>(CBRetPos);
getOrCreateAAFor<AAValueSimplify>(CBRetPos);
}

for (int I = 0, E = CB.getNumArgOperands(); I < E; ++I) {
Expand Down

0 comments on commit 374e573

Please sign in to comment.