//===- FunctionAttrs.cpp - Pass which marks functions attributes ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a simple interprocedural pass which walks the
// call-graph, looking for functions which do not access or only read
// non-local memory, and marking them readnone/readonly.  In addition,
// it marks function arguments (of pointer type) 'nocapture' if a call
// to the function does not create any copies of the pointer value that
// outlive the call.  This more or less means that the pointer is only
// dereferenced, and not returned from the function or stored in a global.
// Finally, well-known library call declarations are marked with all
// attributes that are consistent with the function's standard definition.
// This pass is implemented as a bottom-up traversal of the call-graph.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "functionattrs"
#include "llvm/Transforms/IPO.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/InstIterator.h"
#include "llvm/Target/TargetLibraryInfo.h"
using namespace llvm;

STATISTIC(NumReadNone, "Number of functions marked readnone");
STATISTIC(NumReadOnly, "Number of functions marked readonly");
STATISTIC(NumNoCapture, "Number of arguments marked nocapture");
STATISTIC(NumNoAlias, "Number of function returns marked noalias");
STATISTIC(NumAnnotated, "Number of attributes added to library functions");

namespace {
  struct FunctionAttrs : public CallGraphSCCPass {
    static char ID; // Pass identification, replacement for typeid
    FunctionAttrs() : CallGraphSCCPass(ID), AA(0) {
      initializeFunctionAttrsPass(*PassRegistry::getPassRegistry());
    }

    // runOnSCC - Analyze the SCC, performing the transformation if possible.
    bool runOnSCC(CallGraphSCC &SCC);

    // AddReadAttrs - Deduce readonly/readnone attributes for the SCC.
    bool AddReadAttrs(const CallGraphSCC &SCC);

    // AddNoCaptureAttrs - Deduce nocapture attributes for the SCC.
    bool AddNoCaptureAttrs(const CallGraphSCC &SCC);

    // IsFunctionMallocLike - Does this function allocate new memory?
    bool IsFunctionMallocLike(Function *F,
                              SmallPtrSet<Function*, 8> &) const;

    // AddNoAliasAttrs - Deduce noalias attributes for the SCC.
    bool AddNoAliasAttrs(const CallGraphSCC &SCC);

    // Utility methods used by inferPrototypeAttributes to add attributes
    // and maintain annotation statistics.

    void setDoesNotAccessMemory(Function &F) {
      if (!F.doesNotAccessMemory()) {
	F.setDoesNotAccessMemory();
	++NumAnnotated;
      }
    }

    void setOnlyReadsMemory(Function &F) {
      if (!F.onlyReadsMemory()) {
	F.setOnlyReadsMemory();
	++NumAnnotated;
      }
    }

    void setDoesNotThrow(Function &F) {
      if (!F.doesNotThrow()) {
	F.setDoesNotThrow();
	++NumAnnotated;
      }
    }

    void setDoesNotCapture(Function &F, unsigned n) {
      if (!F.doesNotCapture(n)) {
	F.setDoesNotCapture(n);
	++NumAnnotated;
      }
    }

    void setDoesNotAlias(Function &F, unsigned n) {
      if (!F.doesNotAlias(n)) {
	F.setDoesNotAlias(n);
	++NumAnnotated;
      }
    }

    // inferPrototypeAttributes - Analyze the name and prototype of the
    // given function and set any applicable attributes.  Returns true
    // if any attributes were set and false otherwise.
    bool inferPrototypeAttributes(Function &F);

    // annotateLibraryCalls - Adds attributes to well-known standard library
    // call declarations.
    bool annotateLibraryCalls(const CallGraphSCC &SCC);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesCFG();
      AU.addRequired<AliasAnalysis>();
      AU.addRequired<TargetLibraryInfo>();
      CallGraphSCCPass::getAnalysisUsage(AU);
    }

  private:
    AliasAnalysis *AA;
    TargetLibraryInfo *TLI;
  };
}

char FunctionAttrs::ID = 0;
INITIALIZE_PASS_BEGIN(FunctionAttrs, "functionattrs",
                "Deduce function attributes", false, false)
INITIALIZE_AG_DEPENDENCY(CallGraph)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
INITIALIZE_PASS_END(FunctionAttrs, "functionattrs",
                "Deduce function attributes", false, false)

Pass *llvm::createFunctionAttrsPass() { return new FunctionAttrs(); }


/// AddReadAttrs - Deduce readonly/readnone attributes for the SCC.
bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
  SmallPtrSet<Function*, 8> SCCNodes;

  // Fill SCCNodes with the elements of the SCC.  Used for quickly
  // looking up whether a given CallGraphNode is in this SCC.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I)
    SCCNodes.insert((*I)->getFunction());

  // Check if any of the functions in the SCC read or write memory.  If they
  // write memory then they can't be marked readnone or readonly.
  bool ReadsMemory = false;
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();

    if (F == 0)
      // External node - may write memory.  Just give up.
      return false;

    AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F);
    if (MRB == AliasAnalysis::DoesNotAccessMemory)
      // Already perfect!
      continue;

    // Definitions with weak linkage may be overridden at linktime with
    // something that writes memory, so treat them like declarations.
    if (F->isDeclaration() || F->mayBeOverridden()) {
      if (!AliasAnalysis::onlyReadsMemory(MRB))
        // May write memory.  Just give up.
        return false;

      ReadsMemory = true;
      continue;
    }

    // Scan the function body for instructions that may read or write memory.
    for (inst_iterator II = inst_begin(F), E = inst_end(F); II != E; ++II) {
      Instruction *I = &*II;

      // Some instructions can be ignored even if they read or write memory.
      // Detect these now, skipping to the next instruction if one is found.
      CallSite CS(cast<Value>(I));
      if (CS) {
        // Ignore calls to functions in the same SCC.
        if (CS.getCalledFunction() && SCCNodes.count(CS.getCalledFunction()))
          continue;
        AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(CS);
        // If the call doesn't access arbitrary memory, we may be able to
        // figure out something.
        if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
          // If the call does access argument pointees, check each argument.
          if (AliasAnalysis::doesAccessArgPointees(MRB))
            // Check whether all pointer arguments point to local memory, and
            // ignore calls that only access local memory.
            for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
                 CI != CE; ++CI) {
              Value *Arg = *CI;
              if (Arg->getType()->isPointerTy()) {
                AliasAnalysis::Location Loc(Arg,
                                            AliasAnalysis::UnknownSize,
                                            I->getMetadata(LLVMContext::MD_tbaa));
                if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) {
                  if (MRB & AliasAnalysis::Mod)
                    // Writes non-local memory.  Give up.
                    return false;
                  if (MRB & AliasAnalysis::Ref)
                    // Ok, it reads non-local memory.
                    ReadsMemory = true;
                }
              }
            }
          continue;
        }
        // The call could access any memory. If that includes writes, give up.
        if (MRB & AliasAnalysis::Mod)
          return false;
        // If it reads, note it.
        if (MRB & AliasAnalysis::Ref)
          ReadsMemory = true;
        continue;
      } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
        // Ignore non-volatile loads from local memory. (Atomic is okay here.)
        if (!LI->isVolatile()) {
          AliasAnalysis::Location Loc = AA->getLocation(LI);
          if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true))
            continue;
        }
      } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
        // Ignore non-volatile stores to local memory. (Atomic is okay here.)
        if (!SI->isVolatile()) {
          AliasAnalysis::Location Loc = AA->getLocation(SI);
          if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true))
            continue;
        }
      } else if (VAArgInst *VI = dyn_cast<VAArgInst>(I)) {
        // Ignore vaargs on local memory.
        AliasAnalysis::Location Loc = AA->getLocation(VI);
        if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true))
          continue;
      }

      // Any remaining instructions need to be taken seriously!  Check if they
      // read or write memory.
      if (I->mayWriteToMemory())
        // Writes memory.  Just give up.
        return false;

      // If this instruction may read memory, remember that.
      ReadsMemory |= I->mayReadFromMemory();
    }
  }

  // Success!  Functions in this SCC do not access memory, or only read memory.
  // Give them the appropriate attribute.
  bool MadeChange = false;
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();

    if (F->doesNotAccessMemory())
      // Already perfect!
      continue;

    if (F->onlyReadsMemory() && ReadsMemory)
      // No change.
      continue;

    MadeChange = true;

    // Clear out any existing attributes.
    AttrBuilder B;
    B.addAttribute(Attribute::ReadOnly)
      .addAttribute(Attribute::ReadNone);
    F->removeAttributes(AttributeSet::FunctionIndex,
                        AttributeSet::get(F->getContext(),
                                          AttributeSet::FunctionIndex, B));

    // Add in the new attribute.
    F->addAttribute(AttributeSet::FunctionIndex,
                    ReadsMemory ? Attribute::ReadOnly : Attribute::ReadNone);

    if (ReadsMemory)
      ++NumReadOnly;
    else
      ++NumReadNone;
  }

  return MadeChange;
}

namespace {
  // For a given pointer Argument, this retains a list of Arguments of functions
  // in the same SCC that the pointer data flows into. We use this to build an
  // SCC of the arguments.
  struct ArgumentGraphNode {
    Argument *Definition;
    SmallVector<ArgumentGraphNode*, 4> Uses;
  };

  class ArgumentGraph {
    // We store pointers to ArgumentGraphNode objects, so it's important that
    // that they not move around upon insert.
    typedef std::map<Argument*, ArgumentGraphNode> ArgumentMapTy;

    ArgumentMapTy ArgumentMap;

    // There is no root node for the argument graph, in fact:
    //   void f(int *x, int *y) { if (...) f(x, y); }
    // is an example where the graph is disconnected. The SCCIterator requires a
    // single entry point, so we maintain a fake ("synthetic") root node that
    // uses every node. Because the graph is directed and nothing points into
    // the root, it will not participate in any SCCs (except for its own).
    ArgumentGraphNode SyntheticRoot;

  public:
    ArgumentGraph() { SyntheticRoot.Definition = 0; }

    typedef SmallVectorImpl<ArgumentGraphNode*>::iterator iterator;

    iterator begin() { return SyntheticRoot.Uses.begin(); }
    iterator end() { return SyntheticRoot.Uses.end(); }
    ArgumentGraphNode *getEntryNode() { return &SyntheticRoot; }

    ArgumentGraphNode *operator[](Argument *A) {
      ArgumentGraphNode &Node = ArgumentMap[A];
      Node.Definition = A;
      SyntheticRoot.Uses.push_back(&Node);
      return &Node;
    }
  };

  // This tracker checks whether callees are in the SCC, and if so it does not
  // consider that a capture, instead adding it to the "Uses" list and
  // continuing with the analysis.
  struct ArgumentUsesTracker : public CaptureTracker {
    ArgumentUsesTracker(const SmallPtrSet<Function*, 8> &SCCNodes)
      : Captured(false), SCCNodes(SCCNodes) {}

    void tooManyUses() { Captured = true; }

    bool captured(Use *U) {
      CallSite CS(U->getUser());
      if (!CS.getInstruction()) { Captured = true; return true; }

      Function *F = CS.getCalledFunction();
      if (!F || !SCCNodes.count(F)) { Captured = true; return true; }

      Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
      for (CallSite::arg_iterator PI = CS.arg_begin(), PE = CS.arg_end();
           PI != PE; ++PI, ++AI) {
        if (AI == AE) {
          assert(F->isVarArg() && "More params than args in non-varargs call");
          Captured = true;
          return true;
        }
        if (PI == U) {
          Uses.push_back(AI);
          break;
        }
      }
      assert(!Uses.empty() && "Capturing call-site captured nothing?");
      return false;
    }

    bool Captured;  // True only if certainly captured (used outside our SCC).
    SmallVector<Argument*, 4> Uses;  // Uses within our SCC.

    const SmallPtrSet<Function*, 8> &SCCNodes;
  };
}

namespace llvm {
  template<> struct GraphTraits<ArgumentGraphNode*> {
    typedef ArgumentGraphNode NodeType;
    typedef SmallVectorImpl<ArgumentGraphNode*>::iterator ChildIteratorType;

    static inline NodeType *getEntryNode(NodeType *A) { return A; }
    static inline ChildIteratorType child_begin(NodeType *N) {
      return N->Uses.begin();
    }
    static inline ChildIteratorType child_end(NodeType *N) {
      return N->Uses.end();
    }
  };
  template<> struct GraphTraits<ArgumentGraph*>
    : public GraphTraits<ArgumentGraphNode*> {
    static NodeType *getEntryNode(ArgumentGraph *AG) {
      return AG->getEntryNode();
    }
    static ChildIteratorType nodes_begin(ArgumentGraph *AG) {
      return AG->begin();
    }
    static ChildIteratorType nodes_end(ArgumentGraph *AG) {
      return AG->end();
    }
  };
}

/// AddNoCaptureAttrs - Deduce nocapture attributes for the SCC.
bool FunctionAttrs::AddNoCaptureAttrs(const CallGraphSCC &SCC) {
  bool Changed = false;

  SmallPtrSet<Function*, 8> SCCNodes;

  // Fill SCCNodes with the elements of the SCC.  Used for quickly
  // looking up whether a given CallGraphNode is in this SCC.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();
    if (F && !F->isDeclaration() && !F->mayBeOverridden())
      SCCNodes.insert(F);
  }

  ArgumentGraph AG;

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

  // Check each function in turn, determining which pointer arguments are not
  // captured.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();

    if (F == 0)
      // External node - only a problem for arguments that we pass to it.
      continue;

    // 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() && !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]);
          }
        }
        // Otherwise, it's captured. Don't bother doing SCC analysis on it.
      }
  }

  // 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), E = scc_end(&AG);
       I != E; ++I) {
    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]) {
        ArgumentSCC[0]->
          Definition->
          addAttr(AttributeSet::get(ArgumentSCC[0]->Definition->getContext(),
                                    ArgumentSCC[0]->Definition->getArgNo() + 1,
                                    B));
        ++NumNoCapture;
        Changed = true;
      }
      continue;
    }

    bool SCCCaptured = false;
    for (std::vector<ArgumentGraphNode*>::iterator 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 (std::vector<ArgumentGraphNode*>::iterator I = ArgumentSCC.begin(),
           E = ArgumentSCC.end(); I != E; ++I) {
      ArgumentSCCNodes.insert((*I)->Definition);
    }

    for (std::vector<ArgumentGraphNode*>::iterator 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;
    }
  }

  return Changed;
}

/// IsFunctionMallocLike - A function is malloc-like if it returns either null
/// or a pointer that doesn't alias any other pointer visible to the caller.
bool FunctionAttrs::IsFunctionMallocLike(Function *F,
                              SmallPtrSet<Function*, 8> &SCCNodes) const {
  SmallSetVector<Value *, 8> FlowsToReturn;
  for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
    if (ReturnInst *Ret = dyn_cast<ReturnInst>(I->getTerminator()))
      FlowsToReturn.insert(Ret->getReturnValue());

  for (unsigned i = 0; i != FlowsToReturn.size(); ++i) {
    Value *RetVal = FlowsToReturn[i];

    if (Constant *C = dyn_cast<Constant>(RetVal)) {
      if (!C->isNullValue() && !isa<UndefValue>(C))
        return false;

      continue;
    }

    if (isa<Argument>(RetVal))
      return false;

    if (Instruction *RVI = dyn_cast<Instruction>(RetVal))
      switch (RVI->getOpcode()) {
        // Extend the analysis by looking upwards.
        case Instruction::BitCast:
        case Instruction::GetElementPtr:
          FlowsToReturn.insert(RVI->getOperand(0));
          continue;
        case Instruction::Select: {
          SelectInst *SI = cast<SelectInst>(RVI);
          FlowsToReturn.insert(SI->getTrueValue());
          FlowsToReturn.insert(SI->getFalseValue());
          continue;
        }
        case Instruction::PHI: {
          PHINode *PN = cast<PHINode>(RVI);
          for (int i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
            FlowsToReturn.insert(PN->getIncomingValue(i));
          continue;
        }

        // Check whether the pointer came from an allocation.
        case Instruction::Alloca:
          break;
        case Instruction::Call:
        case Instruction::Invoke: {
          CallSite CS(RVI);
          if (CS.paramHasAttr(0, Attribute::NoAlias))
            break;
          if (CS.getCalledFunction() &&
              SCCNodes.count(CS.getCalledFunction()))
            break;
        } // fall-through
        default:
          return false;  // Did not come from an allocation.
      }

    if (PointerMayBeCaptured(RetVal, false, /*StoreCaptures=*/false))
      return false;
  }

  return true;
}

/// AddNoAliasAttrs - Deduce noalias attributes for the SCC.
bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
  SmallPtrSet<Function*, 8> SCCNodes;

  // Fill SCCNodes with the elements of the SCC.  Used for quickly
  // looking up whether a given CallGraphNode is in this SCC.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I)
    SCCNodes.insert((*I)->getFunction());

  // Check each function in turn, determining which functions return noalias
  // pointers.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();

    if (F == 0)
      // External node - skip it;
      return false;

    // Already noalias.
    if (F->doesNotAlias(0))
      continue;

    // Definitions with weak linkage may be overridden at linktime, so
    // treat them like declarations.
    if (F->isDeclaration() || F->mayBeOverridden())
      return false;

    // We annotate noalias return values, which are only applicable to 
    // pointer types.
    if (!F->getReturnType()->isPointerTy())
      continue;

    if (!IsFunctionMallocLike(F, SCCNodes))
      return false;
  }

  bool MadeChange = false;
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();
    if (F->doesNotAlias(0) || !F->getReturnType()->isPointerTy())
      continue;

    F->setDoesNotAlias(0);
    ++NumNoAlias;
    MadeChange = true;
  }

  return MadeChange;
}

/// inferPrototypeAttributes - Analyze the name and prototype of the
/// given function and set any applicable attributes.  Returns true
/// if any attributes were set and false otherwise.
bool FunctionAttrs::inferPrototypeAttributes(Function &F) {
  FunctionType *FTy = F.getFunctionType();
  LibFunc::Func TheLibFunc;
  if (!(TLI->getLibFunc(F.getName(), TheLibFunc) && TLI->has(TheLibFunc)))
    return false;

  switch (TheLibFunc) {
  case LibFunc::strlen:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setOnlyReadsMemory(F);
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::strchr:
  case LibFunc::strrchr:
    if (FTy->getNumParams() != 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isIntegerTy())
      return false;
    setOnlyReadsMemory(F);
    setDoesNotThrow(F);
    break;
  case LibFunc::strcpy:
  case LibFunc::stpcpy:
  case LibFunc::strcat:
  case LibFunc::strtol:
  case LibFunc::strtod:
  case LibFunc::strtof:
  case LibFunc::strtoul:
  case LibFunc::strtoll:
  case LibFunc::strtold:
  case LibFunc::strncat:
  case LibFunc::strncpy:
  case LibFunc::stpncpy:
  case LibFunc::strtoull:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::strxfrm:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::strcmp:
  case LibFunc::strspn:
  case LibFunc::strncmp:
  case LibFunc::strcspn:
  case LibFunc::strcoll:
  case LibFunc::strcasecmp:
  case LibFunc::strncasecmp:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setOnlyReadsMemory(F);
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::strstr:
  case LibFunc::strpbrk:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setOnlyReadsMemory(F);
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::strtok:
  case LibFunc::strtok_r:
    if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::scanf:
  case LibFunc::setbuf:
  case LibFunc::setvbuf:
    if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::strdup:
  case LibFunc::strndup:
    if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::stat:
  case LibFunc::sscanf:
  case LibFunc::sprintf:
  case LibFunc::statvfs:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::snprintf:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(2)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 3);
    break;
  case LibFunc::setitimer:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(1)->isPointerTy() ||
        !FTy->getParamType(2)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    setDoesNotCapture(F, 3);
    break;
  case LibFunc::system:
    if (FTy->getNumParams() != 1 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    // May throw; "system" is a valid pthread cancellation point.
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::malloc:
    if (FTy->getNumParams() != 1 ||
        !FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::memcmp:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setOnlyReadsMemory(F);
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::memchr:
  case LibFunc::memrchr:
    if (FTy->getNumParams() != 3)
      return false;
    setOnlyReadsMemory(F);
    setDoesNotThrow(F);
    break;
  case LibFunc::modf:
  case LibFunc::modff:
  case LibFunc::modfl:
  case LibFunc::memcpy:
  case LibFunc::memccpy:
  case LibFunc::memmove:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::memalign:
    if (!FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::mkdir:
  case LibFunc::mktime:
    if (FTy->getNumParams() == 0 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::realloc:
    if (FTy->getNumParams() != 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::read:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    // May throw; "read" is a valid pthread cancellation point.
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::rmdir:
  case LibFunc::rewind:
  case LibFunc::remove:
  case LibFunc::realpath:
    if (FTy->getNumParams() < 1 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::rename:
  case LibFunc::readlink:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::write:
    if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
      return false;
    // May throw; "write" is a valid pthread cancellation point.
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::bcopy:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::bcmp:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setOnlyReadsMemory(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::bzero:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::calloc:
    if (FTy->getNumParams() != 2 ||
        !FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::chmod:
  case LibFunc::chown:
  case LibFunc::ctermid:
  case LibFunc::clearerr:
  case LibFunc::closedir:
    if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::atoi:
  case LibFunc::atol:
  case LibFunc::atof:
  case LibFunc::atoll:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setOnlyReadsMemory(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::access:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::fopen:
    if (FTy->getNumParams() != 2 ||
        !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::fdopen:
    if (FTy->getNumParams() != 2 ||
        !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::feof:
  case LibFunc::free:
  case LibFunc::fseek:
  case LibFunc::ftell:
  case LibFunc::fgetc:
  case LibFunc::fseeko:
  case LibFunc::ftello:
  case LibFunc::fileno:
  case LibFunc::fflush:
  case LibFunc::fclose:
  case LibFunc::fsetpos:
  case LibFunc::flockfile:
  case LibFunc::funlockfile:
  case LibFunc::ftrylockfile:
    if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::ferror:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(F);
    break;
  case LibFunc::fputc:
  case LibFunc::fstat:
  case LibFunc::frexp:
  case LibFunc::frexpf:
  case LibFunc::frexpl:
  case LibFunc::fstatvfs:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::fgets:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(2)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 3);
  case LibFunc::fread:
  case LibFunc::fwrite:
    if (FTy->getNumParams() != 4 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(3)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 4);
  case LibFunc::fputs:
  case LibFunc::fscanf:
  case LibFunc::fprintf:
  case LibFunc::fgetpos:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::getc:
  case LibFunc::getlogin_r:
  case LibFunc::getc_unlocked:
    if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::getenv:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setOnlyReadsMemory(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::gets:
  case LibFunc::getchar:
    setDoesNotThrow(F);
    break;
  case LibFunc::getitimer:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::getpwnam:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::ungetc:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::uname:
  case LibFunc::unlink:
  case LibFunc::unsetenv:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::utime:
  case LibFunc::utimes:
    if (FTy->getNumParams() != 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::putc:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::puts:
  case LibFunc::printf:
  case LibFunc::perror:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::pread:
  case LibFunc::pwrite:
    if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
      return false;
    // May throw; these are valid pthread cancellation points.
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::putchar:
    setDoesNotThrow(F);
    break;
  case LibFunc::popen:
    if (FTy->getNumParams() != 2 ||
        !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::pclose:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::vscanf:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::vsscanf:
  case LibFunc::vfscanf:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(1)->isPointerTy() ||
        !FTy->getParamType(2)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::valloc:
    if (!FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::vprintf:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::vfprintf:
  case LibFunc::vsprintf:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::vsnprintf:
    if (FTy->getNumParams() != 4 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(2)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 3);
    break;
  case LibFunc::open:
    if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
      return false;
    // May throw; "open" is a valid pthread cancellation point.
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::opendir:
    if (FTy->getNumParams() != 1 ||
        !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::tmpfile:
    if (!FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::times:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::htonl:
  case LibFunc::htons:
  case LibFunc::ntohl:
  case LibFunc::ntohs:
    setDoesNotThrow(F);
    setDoesNotAccessMemory(F);
    break;
  case LibFunc::lstat:
    if (FTy->getNumParams() != 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::lchown:
    if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::qsort:
    if (FTy->getNumParams() != 4 || !FTy->getParamType(3)->isPointerTy())
      return false;
    // May throw; places call through function pointer.
    setDoesNotCapture(F, 4);
    break;
  case LibFunc::dunder_strdup:
  case LibFunc::dunder_strndup:
    if (FTy->getNumParams() < 1 ||
        !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::dunder_strtok_r:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::under_IO_getc:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::under_IO_putc:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::dunder_isoc99_scanf:
    if (FTy->getNumParams() < 1 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::stat64:
  case LibFunc::lstat64:
  case LibFunc::statvfs64:
  case LibFunc::dunder_isoc99_sscanf:
    if (FTy->getNumParams() < 1 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::fopen64:
    if (FTy->getNumParams() != 2 ||
        !FTy->getReturnType()->isPointerTy() ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::fseeko64:
  case LibFunc::ftello64:
    if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::tmpfile64:
    if (!FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::fstat64:
  case LibFunc::fstatvfs64:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::open64:
    if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
      return false;
    // May throw; "open" is a valid pthread cancellation point.
    setDoesNotCapture(F, 1);
    break;
  default:
    // Didn't mark any attributes.
    return false;
  }

  return true;
}

/// annotateLibraryCalls - Adds attributes to well-known standard library
/// call declarations.
bool FunctionAttrs::annotateLibraryCalls(const CallGraphSCC &SCC) {
  bool MadeChange = false;

  // Check each function in turn annotating well-known library function
  // declarations with attributes.
  for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
    Function *F = (*I)->getFunction();

    if (F != 0 && F->isDeclaration())
      MadeChange |= inferPrototypeAttributes(*F);
  }

  return MadeChange;
}

bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
  AA = &getAnalysis<AliasAnalysis>();
  TLI = &getAnalysis<TargetLibraryInfo>();

  bool Changed = annotateLibraryCalls(SCC);
  Changed |= AddReadAttrs(SCC);
  Changed |= AddNoCaptureAttrs(SCC);
  Changed |= AddNoAliasAttrs(SCC);
  return Changed;
}
