/// RemoveDeadArgumentsFromCallers - Checks if the given function has any 
/// arguments that are unused, and changes the caller parameters to be undefined
/// instead.
bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
{
  if (Fn.isDeclaration() || Fn.mayBeOverridden())
    return false;

  // Functions with local linkage should already have been handled, except the
  // fragile (variadic) ones which we can improve here.
  if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
    return false;

  // If a function seen at compile time is not necessarily the one linked to
  // the binary being built, it is illegal to change the actual arguments
  // passed to it. These functions can be captured by isWeakForLinker().
  // *NOTE* that mayBeOverridden() is insufficient for this purpose as it
  // doesn't include linkage types like AvailableExternallyLinkage and
  // LinkOnceODRLinkage. Take link_odr* as an example, it indicates a set of
  // *EQUIVALENT* globals that can be merged at link-time. However, the
  // semantic of *EQUIVALENT*-functions includes parameters. Changing
  // parameters breaks this assumption.
  //
  if (Fn.isWeakForLinker())
    return false;

  if (Fn.use_empty())
    return false;

  SmallVector<unsigned, 8> UnusedArgs;
  for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); 
       I != E; ++I) {
    Argument *Arg = I;

    if (Arg->use_empty() && !Arg->hasByValOrInAllocaAttr())
      UnusedArgs.push_back(Arg->getArgNo());
  }

  if (UnusedArgs.empty())
    return false;

  bool Changed = false;

  for (Use &U : Fn.uses()) {
    CallSite CS(U.getUser());
    if (!CS || !CS.isCallee(&U))
      continue;

    // Now go through all unused args and replace them with "undef".
    for (unsigned I = 0, E = UnusedArgs.size(); I != E; ++I) {
      unsigned ArgNo = UnusedArgs[I];

      Value *Arg = CS.getArgument(ArgNo);
      CS.setArgument(ArgNo, UndefValue::get(Arg->getType()));
      ++NumArgumentsReplacedWithUndef;
      Changed = true;
    }
  }

  return Changed;
}
/// RemoveDeadArgumentsFromCallers - Checks if the given function has any 
/// arguments that are unused, and changes the caller parameters to be undefined
/// instead.
bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
{
  if (Fn.isDeclaration() || Fn.mayBeOverridden())
    return false;

  // Functions with local linkage should already have been handled, except the
  // fragile (variadic) ones which we can improve here.
  if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
    return false;

  if (Fn.use_empty())
    return false;

  SmallVector<unsigned, 8> UnusedArgs;
  for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(); 
       I != E; ++I) {
    Argument *Arg = I;

    if (Arg->use_empty() && !Arg->hasByValAttr())
      UnusedArgs.push_back(Arg->getArgNo());
  }

  if (UnusedArgs.empty())
    return false;

  bool Changed = false;

  for (Function::use_iterator I = Fn.use_begin(), E = Fn.use_end(); 
       I != E; ++I) {
    CallSite CS(*I);
    if (!CS || !CS.isCallee(I))
      continue;

    // Now go through all unused args and replace them with "undef".
    for (unsigned I = 0, E = UnusedArgs.size(); I != E; ++I) {
      unsigned ArgNo = UnusedArgs[I];

      Value *Arg = CS.getArgument(ArgNo);
      CS.setArgument(ArgNo, UndefValue::get(Arg->getType()));
      ++NumArgumentsReplacedWithUndef;
      Changed = true;
    }
  }

  return Changed;
}
/// PromoteArguments - This method checks the specified function to see if there
/// are any promotable arguments and if it is safe to promote the function (for
/// example, all callers are direct).  If safe to promote some arguments, it
/// calls the DoPromotion method.
///
CallGraphNode *ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
  Function *F = CGN->getFunction();

  // Make sure that it is local to this module.
  if (!F || !F->hasLocalLinkage()) return nullptr;

  // Don't promote arguments for variadic functions. Adding, removing, or
  // changing non-pack parameters can change the classification of pack
  // parameters. Frontends encode that classification at the call site in the
  // IR, while in the callee the classification is determined dynamically based
  // on the number of registers consumed so far.
  if (F->isVarArg()) return nullptr;

  // First check: see if there are any pointer arguments!  If not, quick exit.
  SmallVector<Argument*, 16> PointerArgs;
  for (Argument &I : F->args())
    if (I.getType()->isPointerTy())
      PointerArgs.push_back(&I);
  if (PointerArgs.empty()) return nullptr;

  // Second check: make sure that all callers are direct callers.  We can't
  // transform functions that have indirect callers.  Also see if the function
  // is self-recursive.
  bool isSelfRecursive = false;
  for (Use &U : F->uses()) {
    CallSite CS(U.getUser());
    // Must be a direct call.
    if (CS.getInstruction() == nullptr || !CS.isCallee(&U)) return nullptr;
    
    if (CS.getInstruction()->getParent()->getParent() == F)
      isSelfRecursive = true;
  }
  
  const DataLayout &DL = F->getParent()->getDataLayout();

  // We need to manually construct BasicAA directly in order to disable its use
  // of other function analyses.
  BasicAAResult BAR(createLegacyPMBasicAAResult(*this, *F));

  // Construct our own AA results for this function. We do this manually to
  // work around the limitations of the legacy pass manager.
  AAResults AAR(createLegacyPMAAResults(*this, *F, BAR));

  // Check to see which arguments are promotable.  If an argument is promotable,
  // add it to ArgsToPromote.
  SmallPtrSet<Argument*, 8> ArgsToPromote;
  SmallPtrSet<Argument*, 8> ByValArgsToTransform;
  for (unsigned i = 0, e = PointerArgs.size(); i != e; ++i) {
    Argument *PtrArg = PointerArgs[i];
    Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType();

    // Replace sret attribute with noalias. This reduces register pressure by
    // avoiding a register copy.
    if (PtrArg->hasStructRetAttr()) {
      unsigned ArgNo = PtrArg->getArgNo();
      F->setAttributes(
          F->getAttributes()
              .removeAttribute(F->getContext(), ArgNo + 1, Attribute::StructRet)
              .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias));
      for (Use &U : F->uses()) {
        CallSite CS(U.getUser());
        CS.setAttributes(
            CS.getAttributes()
                .removeAttribute(F->getContext(), ArgNo + 1,
                                 Attribute::StructRet)
                .addAttribute(F->getContext(), ArgNo + 1, Attribute::NoAlias));
      }
    }

    // If this is a byval argument, and if the aggregate type is small, just
    // pass the elements, which is always safe, if the passed value is densely
    // packed or if we can prove the padding bytes are never accessed. This does
    // not apply to inalloca.
    bool isSafeToPromote =
        PtrArg->hasByValAttr() &&
        (isDenselyPacked(AgTy, DL) || !canPaddingBeAccessed(PtrArg));
    if (isSafeToPromote) {
      if (StructType *STy = dyn_cast<StructType>(AgTy)) {
        if (maxElements > 0 && STy->getNumElements() > maxElements) {
          DEBUG(dbgs() << "argpromotion disable promoting argument '"
                << PtrArg->getName() << "' because it would require adding more"
                << " than " << maxElements << " arguments to the function.\n");
          continue;
        }
        
        // If all the elements are single-value types, we can promote it.
        bool AllSimple = true;
        for (const auto *EltTy : STy->elements()) {
          if (!EltTy->isSingleValueType()) {
            AllSimple = false;
            break;
          }
        }

        // Safe to transform, don't even bother trying to "promote" it.
        // Passing the elements as a scalar will allow sroa to hack on
        // the new alloca we introduce.
        if (AllSimple) {
          ByValArgsToTransform.insert(PtrArg);
          continue;
        }
      }
    }

    // If the argument is a recursive type and we're in a recursive
    // function, we could end up infinitely peeling the function argument.
    if (isSelfRecursive) {
      if (StructType *STy = dyn_cast<StructType>(AgTy)) {
        bool RecursiveType = false;
        for (const auto *EltTy : STy->elements()) {
          if (EltTy == PtrArg->getType()) {
            RecursiveType = true;
            break;
          }
        }
        if (RecursiveType)
          continue;
      }
    }
    
    // Otherwise, see if we can promote the pointer to its value.
    if (isSafeToPromoteArgument(PtrArg, PtrArg->hasByValOrInAllocaAttr(), AAR))
      ArgsToPromote.insert(PtrArg);
  }

  // No promotable pointer arguments.
  if (ArgsToPromote.empty() && ByValArgsToTransform.empty()) 
    return nullptr;

  return DoPromotion(F, ArgsToPromote, ByValArgsToTransform);
}
Exemple #4
0
/// Deduce nocapture attributes for the SCC.
static bool addArgumentAttrs(const SCCNodeSet &SCCNodes) {
    bool Changed = false;

    ArgumentGraph AG;

    AttrBuilder B;
    B.addAttribute(Attribute::NoCapture);

    // Check each function in turn, determining which pointer arguments are not
    // captured.
    for (Function *F : SCCNodes) {
        // Definitions with weak linkage may be overridden at linktime with
        // something that captures pointers, so treat them like declarations.
        if (F->isDeclaration() || F->mayBeOverridden())
            continue;

        // Functions that are readonly (or readnone) and nounwind and don't return
        // a value can't capture arguments. Don't analyze them.
        if (F->onlyReadsMemory() && F->doesNotThrow() &&
                F->getReturnType()->isVoidTy()) {
            for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E;
                    ++A) {
                if (A->getType()->isPointerTy() && !A->hasNoCaptureAttr()) {
                    A->addAttr(AttributeSet::get(F->getContext(), A->getArgNo() + 1, B));
                    ++NumNoCapture;
                    Changed = true;
                }
            }
            continue;
        }

        for (Function::arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E;
                ++A) {
            if (!A->getType()->isPointerTy())
                continue;
            bool HasNonLocalUses = false;
            if (!A->hasNoCaptureAttr()) {
                ArgumentUsesTracker Tracker(SCCNodes);
                PointerMayBeCaptured(&*A, &Tracker);
                if (!Tracker.Captured) {
                    if (Tracker.Uses.empty()) {
                        // If it's trivially not captured, mark it nocapture now.
                        A->addAttr(
                            AttributeSet::get(F->getContext(), A->getArgNo() + 1, B));
                        ++NumNoCapture;
                        Changed = true;
                    } else {
                        // If it's not trivially captured and not trivially not captured,
                        // then it must be calling into another function in our SCC. Save
                        // its particulars for Argument-SCC analysis later.
                        ArgumentGraphNode *Node = AG[&*A];
                        for (SmallVectorImpl<Argument *>::iterator
                                UI = Tracker.Uses.begin(),
                                UE = Tracker.Uses.end();
                                UI != UE; ++UI) {
                            Node->Uses.push_back(AG[*UI]);
                            if (*UI != A)
                                HasNonLocalUses = true;
                        }
                    }
                }
                // Otherwise, it's captured. Don't bother doing SCC analysis on it.
            }
            if (!HasNonLocalUses && !A->onlyReadsMemory()) {
                // Can we determine that it's readonly/readnone without doing an SCC?
                // Note that we don't allow any calls at all here, or else our result
                // will be dependent on the iteration order through the functions in the
                // SCC.
                SmallPtrSet<Argument *, 8> Self;
                Self.insert(&*A);
                Attribute::AttrKind R = determinePointerReadAttrs(&*A, Self);
                if (R != Attribute::None) {
                    AttrBuilder B;
                    B.addAttribute(R);
                    A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
                    Changed = true;
                    R == Attribute::ReadOnly ? ++NumReadOnlyArg : ++NumReadNoneArg;
                }
            }
        }
    }

    // The graph we've collected is partial because we stopped scanning for
    // argument uses once we solved the argument trivially. These partial nodes
    // show up as ArgumentGraphNode objects with an empty Uses list, and for
    // these nodes the final decision about whether they capture has already been
    // made.  If the definition doesn't have a 'nocapture' attribute by now, it
    // captures.

    for (scc_iterator<ArgumentGraph *> I = scc_begin(&AG); !I.isAtEnd(); ++I) {
        const std::vector<ArgumentGraphNode *> &ArgumentSCC = *I;
        if (ArgumentSCC.size() == 1) {
            if (!ArgumentSCC[0]->Definition)
                continue; // synthetic root node

            // eg. "void f(int* x) { if (...) f(x); }"
            if (ArgumentSCC[0]->Uses.size() == 1 &&
                    ArgumentSCC[0]->Uses[0] == ArgumentSCC[0]) {
                Argument *A = ArgumentSCC[0]->Definition;
                A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
                ++NumNoCapture;
                Changed = true;
            }
            continue;
        }

        bool SCCCaptured = false;
        for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end();
                I != E && !SCCCaptured; ++I) {
            ArgumentGraphNode *Node = *I;
            if (Node->Uses.empty()) {
                if (!Node->Definition->hasNoCaptureAttr())
                    SCCCaptured = true;
            }
        }
        if (SCCCaptured)
            continue;

        SmallPtrSet<Argument *, 8> ArgumentSCCNodes;
        // Fill ArgumentSCCNodes with the elements of the ArgumentSCC.  Used for
        // quickly looking up whether a given Argument is in this ArgumentSCC.
        for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end(); I != E; ++I) {
            ArgumentSCCNodes.insert((*I)->Definition);
        }

        for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end();
                I != E && !SCCCaptured; ++I) {
            ArgumentGraphNode *N = *I;
            for (SmallVectorImpl<ArgumentGraphNode *>::iterator UI = N->Uses.begin(),
                    UE = N->Uses.end();
                    UI != UE; ++UI) {
                Argument *A = (*UI)->Definition;
                if (A->hasNoCaptureAttr() || ArgumentSCCNodes.count(A))
                    continue;
                SCCCaptured = true;
                break;
            }
        }
        if (SCCCaptured)
            continue;

        for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
            Argument *A = ArgumentSCC[i]->Definition;
            A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
            ++NumNoCapture;
            Changed = true;
        }

        // We also want to compute readonly/readnone. With a small number of false
        // negatives, we can assume that any pointer which is captured isn't going
        // to be provably readonly or readnone, since by definition we can't
        // analyze all uses of a captured pointer.
        //
        // The false negatives happen when the pointer is captured by a function
        // that promises readonly/readnone behaviour on the pointer, then the
        // pointer's lifetime ends before anything that writes to arbitrary memory.
        // Also, a readonly/readnone pointer may be returned, but returning a
        // pointer is capturing it.

        Attribute::AttrKind ReadAttr = Attribute::ReadNone;
        for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
            Argument *A = ArgumentSCC[i]->Definition;
            Attribute::AttrKind K = determinePointerReadAttrs(A, ArgumentSCCNodes);
            if (K == Attribute::ReadNone)
                continue;
            if (K == Attribute::ReadOnly) {
                ReadAttr = Attribute::ReadOnly;
                continue;
            }
            ReadAttr = K;
            break;
        }

        if (ReadAttr != Attribute::None) {
            AttrBuilder B, R;
            B.addAttribute(ReadAttr);
            R.addAttribute(Attribute::ReadOnly).addAttribute(Attribute::ReadNone);
            for (unsigned i = 0, e = ArgumentSCC.size(); i != e; ++i) {
                Argument *A = ArgumentSCC[i]->Definition;
                // Clear out existing readonly/readnone attributes
                A->removeAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, R));
                A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B));
                ReadAttr == Attribute::ReadOnly ? ++NumReadOnlyArg : ++NumReadNoneArg;
                Changed = true;
            }
        }
    }

    return Changed;
}