X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FFunctionAttrs.cpp;h=3ea54687365c1fb44c6a85eccdc60ad33e70079b;hp=931a54e09f680a854e13681ea7a44a2c5bec6d16;hb=28b6c23c41301dfdbd55a998583503498d984a3f;hpb=10b4880de3a57e384167506648092b5bca806582 diff --git a/lib/Transforms/IPO/FunctionAttrs.cpp b/lib/Transforms/IPO/FunctionAttrs.cpp index 931a54e09f6..3ea54687365 100644 --- a/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/lib/Transforms/IPO/FunctionAttrs.cpp @@ -58,82 +58,8 @@ struct FunctionAttrs : public CallGraphSCCPass { 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 &) const; - - // AddNoAliasAttrs - Deduce noalias attributes for the SCC. - bool AddNoAliasAttrs(const CallGraphSCC &SCC); - - /// \brief Does this function return null? - bool ReturnsNonNull(Function *F, SmallPtrSet &, - bool &Speculative) const; - - /// \brief Deduce nonnull attributes for the SCC. - bool AddNonNullAttrs(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(); @@ -143,6 +69,15 @@ struct FunctionAttrs : public CallGraphSCCPass { private: TargetLibraryInfo *TLI; + + bool AddReadAttrs(const CallGraphSCC &SCC); + bool AddArgumentAttrs(const CallGraphSCC &SCC); + bool IsFunctionMallocLike(Function *F, SmallPtrSet &) const; + bool AddNoAliasAttrs(const CallGraphSCC &SCC); + bool ReturnsNonNull(Function *F, SmallPtrSet &, + bool &Speculative) const; + bool AddNonNullAttrs(const CallGraphSCC &SCC); + bool annotateLibraryCalls(const CallGraphSCC &SCC); }; } @@ -157,7 +92,7 @@ INITIALIZE_PASS_END(FunctionAttrs, "functionattrs", Pass *llvm::createFunctionAttrsPass() { return new FunctionAttrs(); } -/// AddReadAttrs - Deduce readonly/readnone attributes for the SCC. +/// Deduce readonly/readnone attributes for the SCC. bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) { SmallPtrSet SCCNodes; @@ -316,9 +251,9 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) { } 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. +/// 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 Uses; @@ -356,9 +291,9 @@ public: } }; -// 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. +/// 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 &SCCNodes) : Captured(false), SCCNodes(SCCNodes) {} @@ -430,7 +365,7 @@ struct GraphTraits : public GraphTraits { }; } -// Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone. +/// Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone. static Attribute::AttrKind determinePointerReadAttrs(Argument *A, const SmallPtrSet &SCCNodes) { @@ -535,7 +470,7 @@ determinePointerReadAttrs(Argument *A, return IsRead ? Attribute::ReadOnly : Attribute::ReadNone; } -/// AddArgumentAttrs - Deduce nocapture attributes for the SCC. +/// Deduce nocapture attributes for the SCC. bool FunctionAttrs::AddArgumentAttrs(const CallGraphSCC &SCC) { bool Changed = false; @@ -745,8 +680,10 @@ bool FunctionAttrs::AddArgumentAttrs(const CallGraphSCC &SCC) { 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. +/// Tests whether a function is "malloc-like". +/// +/// 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 &SCCNodes) const { SmallSetVector FlowsToReturn; @@ -810,7 +747,7 @@ bool FunctionAttrs::IsFunctionMallocLike( return true; } -/// AddNoAliasAttrs - Deduce noalias attributes for the SCC. +/// Deduce noalias attributes for the SCC. bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) { SmallPtrSet SCCNodes; @@ -860,6 +797,7 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) { return MadeChange; } +/// Tests whether this function is known to not return null. bool FunctionAttrs::ReturnsNonNull(Function *F, SmallPtrSet &SCCNodes, bool &Speculative) const { @@ -924,6 +862,7 @@ bool FunctionAttrs::ReturnsNonNull(Function *F, return true; } +/// Deduce nonnull attributes for the SCC. bool FunctionAttrs::AddNonNullAttrs(const CallGraphSCC &SCC) { SmallPtrSet SCCNodes; @@ -997,16 +936,59 @@ bool FunctionAttrs::AddNonNullAttrs(const CallGraphSCC &SCC) { 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) { +static void setDoesNotAccessMemory(Function &F) { + if (!F.doesNotAccessMemory()) { + F.setDoesNotAccessMemory(); + ++NumAnnotated; + } +} + +static void setOnlyReadsMemory(Function &F) { + if (!F.onlyReadsMemory()) { + F.setOnlyReadsMemory(); + ++NumAnnotated; + } +} + +static void setDoesNotThrow(Function &F) { + if (!F.doesNotThrow()) { + F.setDoesNotThrow(); + ++NumAnnotated; + } +} + +static void setDoesNotCapture(Function &F, unsigned n) { + if (!F.doesNotCapture(n)) { + F.setDoesNotCapture(n); + ++NumAnnotated; + } +} + +static void setOnlyReadsMemory(Function &F, unsigned n) { + if (!F.onlyReadsMemory(n)) { + F.setOnlyReadsMemory(n); + ++NumAnnotated; + } +} + +static void setDoesNotAlias(Function &F, unsigned n) { + if (!F.doesNotAlias(n)) { + F.setDoesNotAlias(n); + ++NumAnnotated; + } +} + +/// Analyze the name and prototype of the given function and set any applicable +/// attributes. +/// +/// Returns true if any attributes were set and false otherwise. +static bool inferPrototypeAttributes(Function &F, const TargetLibraryInfo &TLI) { if (F.hasFnAttribute(Attribute::OptimizeNone)) return false; FunctionType *FTy = F.getFunctionType(); LibFunc::Func TheLibFunc; - if (!(TLI->getLibFunc(F.getName(), TheLibFunc) && TLI->has(TheLibFunc))) + if (!(TLI.getLibFunc(F.getName(), TheLibFunc) && TLI.has(TheLibFunc))) return false; switch (TheLibFunc) { @@ -1799,8 +1781,7 @@ bool FunctionAttrs::inferPrototypeAttributes(Function &F) { return true; } -/// annotateLibraryCalls - Adds attributes to well-known standard library -/// call declarations. +/// Adds attributes to well-known standard library call declarations. bool FunctionAttrs::annotateLibraryCalls(const CallGraphSCC &SCC) { bool MadeChange = false; @@ -1810,7 +1791,7 @@ bool FunctionAttrs::annotateLibraryCalls(const CallGraphSCC &SCC) { Function *F = (*I)->getFunction(); if (F && F->isDeclaration()) - MadeChange |= inferPrototypeAttributes(*F); + MadeChange |= inferPrototypeAttributes(*F, *TLI); } return MadeChange;