//===- 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.  It does the
// same with function arguments independently, marking them readonly/
// readnone/nocapture.  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.
//
//===----------------------------------------------------------------------===//

#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/InstIterator.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
using namespace llvm;

#define DEBUG_TYPE "functionattrs"

STATISTIC(NumReadNone, "Number of functions marked readnone");
STATISTIC(NumReadOnly, "Number of functions marked readonly");
STATISTIC(NumNoCapture, "Number of arguments marked nocapture");
STATISTIC(NumReadNoneArg, "Number of arguments marked readnone");
STATISTIC(NumReadOnlyArg, "Number of arguments marked readonly");
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(nullptr) {
      initializeFunctionAttrsPass(*PassRegistry::getPassRegistry());
    }

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

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

    // AddArgumentAttrs - Deduce nocapture attributes for the SCC.
    bool AddArgumentAttrs(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 setOnlyReadsMemory(Function &F, unsigned n) {
      if (!F.onlyReadsMemory(n)) {
        F.setOnlyReadsMemory(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);

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.setPreservesCFG();
      AU.addRequired<AliasAnalysis>();
      AU.addRequired<TargetLibraryInfoWrapperPass>();
      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(AliasAnalysis)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
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 || F->hasFnAttribute(Attribute::OptimizeNone))
      // External node or node we don't want to optimize - assume it may write
      // memory and give up.
      return false;

    FunctionModRefBehavior MRB = AA->getModRefBehavior(F);
    if (MRB == FMRB_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;
        FunctionModRefBehavior 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()) {
                AAMDNodes AAInfo;
                I->getAAMetadata(AAInfo);

                MemoryLocation Loc(Arg, MemoryLocation::UnknownSize, AAInfo);
                if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) {
                  if (MRB & MRI_Mod)
                    // Writes non-local memory.  Give up.
                    return false;
                  if (MRB & MRI_Ref)
                    // Ok, it reads non-local memory.
                    ReadsMemory = true;
                }
              }
            }
          continue;
        }
        // The call could access any memory. If that includes writes, give up.
        if (MRB & MRI_Mod)
          return false;
        // If it reads, note it.
        if (MRB & MRI_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()) {
          MemoryLocation Loc = MemoryLocation::get(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()) {
          MemoryLocation Loc = MemoryLocation::get(SI);
          if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true))
            continue;
        }
      } else if (VAArgInst *VI = dyn_cast<VAArgInst>(I)) {
        // Ignore vaargs on local memory.
        MemoryLocation Loc = MemoryLocation::get(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 = nullptr; }

    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() override { Captured = true; }

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

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

      bool Found = false;
      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);
          Found = true;
          break;
        }
      }
      assert(Found && "Capturing call-site captured nothing?");
      (void)Found;
      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();
    }
  };
}

// Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
static Attribute::AttrKind
determinePointerReadAttrs(Argument *A,
                          const SmallPtrSet<Argument*, 8> &SCCNodes) {
                                                       
  SmallVector<Use*, 32> Worklist;
  SmallSet<Use*, 32> Visited;

  // inalloca arguments are always clobbered by the call.
  if (A->hasInAllocaAttr())
    return Attribute::None;

  bool IsRead = false;
  // We don't need to track IsWritten. If A is written to, return immediately.

  for (Use &U : A->uses()) {
    Visited.insert(&U);
    Worklist.push_back(&U);
  }

  while (!Worklist.empty()) {
    Use *U = Worklist.pop_back_val();
    Instruction *I = cast<Instruction>(U->getUser());
    Value *V = U->get();

    switch (I->getOpcode()) {
    case Instruction::BitCast:
    case Instruction::GetElementPtr:
    case Instruction::PHI:
    case Instruction::Select:
    case Instruction::AddrSpaceCast:
      // The original value is not read/written via this if the new value isn't.
      for (Use &UU : I->uses())
        if (Visited.insert(&UU).second)
          Worklist.push_back(&UU);
      break;

    case Instruction::Call:
    case Instruction::Invoke: {
      bool Captures = true;

      if (I->getType()->isVoidTy())
        Captures = false;

      auto AddUsersToWorklistIfCapturing = [&] {
        if (Captures)
          for (Use &UU : I->uses())
            if (Visited.insert(&UU).second)
              Worklist.push_back(&UU);
      };

      CallSite CS(I);
      if (CS.doesNotAccessMemory()) {
        AddUsersToWorklistIfCapturing();
        continue;
      }

      Function *F = CS.getCalledFunction();
      if (!F) {
        if (CS.onlyReadsMemory()) {
          IsRead = true;
          AddUsersToWorklistIfCapturing();
          continue;
        }
        return Attribute::None;
      }

      Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
      CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
      for (CallSite::arg_iterator A = B; A != E; ++A, ++AI) {
        if (A->get() == V) {
          if (AI == AE) {
            assert(F->isVarArg() &&
                   "More params than args in non-varargs call.");
            return Attribute::None;
          }
          Captures &= !CS.doesNotCapture(A - B);
          if (SCCNodes.count(AI))
            continue;
          if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(A - B))
            return Attribute::None;
          if (!CS.doesNotAccessMemory(A - B))
            IsRead = true;
        }
      }
      AddUsersToWorklistIfCapturing();
      break;
    }

    case Instruction::Load:
      IsRead = true;
      break;

    case Instruction::ICmp:
    case Instruction::Ret:
      break;

    default:
      return Attribute::None;
    }
  }

  return IsRead ? Attribute::ReadOnly : Attribute::ReadNone;
}

/// AddArgumentAttrs - Deduce nocapture attributes for the SCC.
bool FunctionAttrs::AddArgumentAttrs(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() &&
        !F->hasFnAttribute(Attribute::OptimizeNone))
      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 || F->hasFnAttribute(Attribute::OptimizeNone))
      // External node or function we're trying not to optimize - 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()) 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;
}

/// 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:
        case Instruction::AddrSpaceCast:
          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 (Value *IncValue : PN->incoming_values())
            FlowsToReturn.insert(IncValue);
          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 || F->hasFnAttribute(Attribute::OptimizeNone))
      // External node or node we don't want to optimize - 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) {
  if (F.hasFnAttribute(Attribute::OptimizeNone))
    return false;

  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::strtol:
  case LibFunc::strtod:
  case LibFunc::strtof:
  case LibFunc::strtoul:
  case LibFunc::strtoll:
  case LibFunc::strtold:
  case LibFunc::strtoull:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::strcpy:
  case LibFunc::stpcpy:
  case LibFunc::strcat:
  case LibFunc::strncat:
  case LibFunc::strncpy:
  case LibFunc::stpncpy:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 2);
    break;
  case LibFunc::strcmp: //0,1
    case LibFunc::strspn: // 0,1
    case LibFunc::strncmp: // 0,1
    case LibFunc::strcspn: //0,1
    case LibFunc::strcoll: //0,1
    case LibFunc::strcasecmp:  // 0,1
    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);
    setOnlyReadsMemory(F, 2);
    break;
  case LibFunc::scanf:
    if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(F, 1);
    break;
  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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::stat:
  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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::sscanf:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(F, 2);
    break;
  case LibFunc::sprintf:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 2);
    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);
    setOnlyReadsMemory(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:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::memcpy:
  case LibFunc::memccpy:
  case LibFunc::memmove:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 2);
    break;
  case LibFunc::memalign:
    if (!FTy->getReturnType()->isPointerTy())
      return false;
    setDoesNotAlias(F, 0);
    break;
  case LibFunc::mkdir:
    if (FTy->getNumParams() == 0 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(F, 1);
    break;
  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::rewind:
    if (FTy->getNumParams() < 1 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::rmdir:
  case LibFunc::remove:
  case LibFunc::realpath:
    if (FTy->getNumParams() < 1 ||
        !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::rename:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(F, 2);
    break;
  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);
    setOnlyReadsMemory(F, 1);
    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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    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:
    if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(F, 1);
    break;
  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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    break;
  case LibFunc::fread:
    if (FTy->getNumParams() != 4 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(3)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 4);
    break;
  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);
    break;
  case LibFunc::fputs:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::fscanf:
  case LibFunc::fprintf:
    if (FTy->getNumParams() < 2 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 2);
    break;
  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);
    setOnlyReadsMemory(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:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    break;
  case LibFunc::unlink:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::unsetenv:
    if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::pread:
    if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
      return false;
    // May throw; "pread" is a valid pthread cancellation point.
    setDoesNotCapture(F, 2);
    break;
  case LibFunc::pwrite:
    if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
      return false;
    // May throw; "pwrite" is a valid pthread cancellation point.
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::vsscanf:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(1)->isPointerTy() ||
        !FTy->getParamType(2)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(F, 2);
    break;
  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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::lchown:
    if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::dunder_strtok_r:
    if (FTy->getNumParams() != 3 ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::stat64:
  case LibFunc::lstat64:
  case LibFunc::statvfs64:
    if (FTy->getNumParams() < 1 ||
        !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    setOnlyReadsMemory(F, 1);
    break;
  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);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    setOnlyReadsMemory(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);
    setOnlyReadsMemory(F, 1);
    break;
  case LibFunc::gettimeofday:
    if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
        !FTy->getParamType(1)->isPointerTy())
      return false;
    // Currently some platforms have the restrict keyword on the arguments to
    // gettimeofday. To be conservative, do not add noalias to gettimeofday's
    // arguments.
    setDoesNotThrow(F);
    setDoesNotCapture(F, 1);
    setDoesNotCapture(F, 2);
    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 && F->isDeclaration())
      MadeChange |= inferPrototypeAttributes(*F);
  }

  return MadeChange;
}

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

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