[FunctionAttrs] Separate another chunk of the logic for functionattrs
authorChandler Carruth <chandlerc@gmail.com>
Fri, 30 Oct 2015 16:48:08 +0000 (16:48 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Fri, 30 Oct 2015 16:48:08 +0000 (16:48 +0000)
from its pass harness by providing a lambda to query for AA results.

This allows the legacy pass to easily provide a lambda that uses the
special helpers to construct function AA results from a legacy CGSCC
pass. With the new pass manager (the next patch) the lambda just
directly wraps the intuitive query API.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251715 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/FunctionAttrs.cpp

index 80883f766f9222322d95245b59ef9a3c85d6f2d7..2928cb0bc73454d2ff907a42cbadfa7f7e3cd023 100644 (file)
@@ -74,7 +74,6 @@ struct FunctionAttrs : public CallGraphSCCPass {
 private:
   TargetLibraryInfo *TLI;
 
-  bool AddReadAttrs(const SCCNodeSet &SCCNodes);
   bool annotateLibraryCalls(const CallGraphSCC &SCC);
 };
 }
@@ -205,18 +204,14 @@ static MemoryAccessKind checkFunctionMemoryAccess(Function &F, AAResults &AAR,
 }
 
 /// Deduce readonly/readnone attributes for the SCC.
-bool FunctionAttrs::AddReadAttrs(const SCCNodeSet &SCCNodes) {
+template <typename AARGetterT>
+static bool addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT AARGetter) {
   // 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 (Function *F : SCCNodes) {
-    // We need to manually construct BasicAA directly in order to disable its
-    // use of other function analyses.
-    BasicAAResult BAR(createLegacyPMBasicAAResult(*this, *F));
-
-    // Construct our own AA results for this function. We do this manually to
-    // work around the limitations of the legacy pass manager.
-    AAResults AAR(createLegacyPMAAResults(*this, *F, BAR));
+    // Call the callable parameter to look up AA results for this function.
+    AAResults &AAR = AARGetter(*F);
 
     switch (checkFunctionMemoryAccess(*F, AAR, SCCNodes)) {
     case MAK_MayWrite:
@@ -1777,6 +1772,17 @@ bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
   // Annotate declarations for which we have special knowledge.
   bool Changed = annotateLibraryCalls(SCC);
 
+  // We compute dedicated AA results for each function in the SCC as needed. We
+  // use a lambda referencing external objects so that they live long enough to
+  // be queried, but we re-use them each time.
+  Optional<BasicAAResult> BAR;
+  Optional<AAResults> AAR;
+  auto AARGetter = [&](Function &F) -> AAResults & {
+    BAR.emplace(createLegacyPMBasicAAResult(*this, F));
+    AAR.emplace(createLegacyPMAAResults(*this, F, *BAR));
+    return *AAR;
+  };
+
   // Fill SCCNodes with the elements of the SCC. Used for quickly looking up
   // whether a given CallGraphNode is in this SCC. Also track whether there are
   // any external or opt-none nodes that will prevent us from optimizing any
@@ -1795,7 +1801,7 @@ bool FunctionAttrs::runOnSCC(CallGraphSCC &SCC) {
     SCCNodes.insert(F);
   }
 
-  Changed |= AddReadAttrs(SCCNodes);
+  Changed |= addReadAttrs(SCCNodes, AARGetter);
   Changed |= addArgumentAttrs(SCCNodes);
 
   // If we have no external nodes participating in the SCC, we can infer some