]> granicus.if.org Git - clang/commitdiff
Add alternate version of LiveVariables analysis that does not kill liveness at assign...
authorTom Care <tom.care@uqconnect.edu.au>
Fri, 27 Aug 2010 22:30:10 +0000 (22:30 +0000)
committerTom Care <tom.care@uqconnect.edu.au>
Fri, 27 Aug 2010 22:30:10 +0000 (22:30 +0000)
- Added killAtAssign flag to LiveVariables
- Added relaxed LiveVariables to AnalysisContext with an accessor

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

include/clang/Analysis/Analyses/LiveVariables.h
include/clang/Analysis/AnalysisContext.h
lib/Analysis/AnalysisContext.cpp
lib/Analysis/LiveVariables.cpp

index 44ab080acbf376dcbc8cc272a1ec70db963f31ca..237fe14aed4f4d9cb00bff310b71fe3721c3ef56 100644 (file)
@@ -41,8 +41,9 @@ struct LiveVariables_ValueTypes {
     ObserverTy* Observer;
     ValTy AlwaysLive;
     AnalysisContext *AC;
+    bool killAtAssign;
 
-    AnalysisDataTy() : Observer(NULL), AC(NULL) {}
+    AnalysisDataTy() : Observer(NULL), AC(NULL), killAtAssign(true) {}
   };
 
   //===-----------------------------------------------------===//
@@ -68,7 +69,7 @@ class LiveVariables : public DataflowValues<LiveVariables_ValueTypes,
 public:
   typedef LiveVariables_ValueTypes::ObserverTy ObserverTy;
 
-  LiveVariables(AnalysisContext &AC);
+  LiveVariables(AnalysisContext &AC, bool killAtAssign = true);
 
   /// IsLive - Return true if a variable is live at the end of a
   /// specified block.
index 6091db4be923ef6edf757721493f579feb4f7ade..7d4d25f8b0d847fe9fe1671a80412226f74e83c9 100644 (file)
@@ -49,6 +49,7 @@ class AnalysisContext {
   CFG *cfg, *completeCFG;
   bool builtCFG, builtCompleteCFG;
   LiveVariables *liveness;
+  LiveVariables *relaxedLiveness;
   ParentMap *PM;
   PseudoConstantAnalysis *PCA;
   llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
@@ -61,7 +62,7 @@ public:
                   bool addehedges = false)
     : D(d), TU(tu), cfg(0), completeCFG(0),
       builtCFG(false), builtCompleteCFG(false),
-      liveness(0), PM(0), PCA(0),
+      liveness(0), relaxedLiveness(0), PM(0), PCA(0),
       ReferencedBlockVars(0), UseUnoptimizedCFG(useUnoptimizedCFG),
       AddEHEdges(addehedges) {}
 
@@ -89,6 +90,7 @@ public:
   ParentMap &getParentMap();
   PseudoConstantAnalysis *getPseudoConstantAnalysis();
   LiveVariables *getLiveVariables();
+  LiveVariables *getRelaxedLiveVariables();
 
   typedef const VarDecl * const * referenced_decls_iterator;
 
index 2c337f07c3c9c4786318693d545158ff28d9aee4..884cbc65f4b89664a660a0375b241c491e7edef7 100644 (file)
@@ -104,6 +104,20 @@ LiveVariables *AnalysisContext::getLiveVariables() {
   return liveness;
 }
 
+LiveVariables *AnalysisContext::getRelaxedLiveVariables() {
+  if (!relaxedLiveness) {
+    CFG *c = getCFG();
+    if (!c)
+      return 0;
+
+    relaxedLiveness = new LiveVariables(*this, false);
+    relaxedLiveness->runOnCFG(*c);
+    relaxedLiveness->runOnAllBlocks(*c, 0, true);
+  }
+
+  return relaxedLiveness;
+}
+
 AnalysisContext *AnalysisContextManager::getContext(const Decl *D,
                                                     idx::TranslationUnit *TU) {
   AnalysisContext *&AC = Contexts[D];
index 3011fd0dee44fa761a5fd63cb86d194e628a6698..47b2e3d6040f1648ca872b4c0440865550435fa0 100644 (file)
@@ -77,12 +77,13 @@ public:
 };
 } // end anonymous namespace
 
-LiveVariables::LiveVariables(AnalysisContext &AC) {  
+LiveVariables::LiveVariables(AnalysisContext &AC, bool killAtAssign) {
   // Register all referenced VarDecls.
   CFG &cfg = *AC.getCFG();
   getAnalysisData().setCFG(cfg);
   getAnalysisData().setContext(AC.getASTContext());
   getAnalysisData().AC = &AC;
+  getAnalysisData().killAtAssign = killAtAssign;
 
   RegisterDecls R(getAnalysisData());
   cfg.VisitBlockStmts(R);
@@ -260,12 +261,13 @@ void TransferFuncs::VisitAssign(BinaryOperator* B) {
     if (DR->getDecl()->getType()->isReferenceType()) {
       VisitDeclRefExpr(DR);
     } else {
-      // Update liveness inforamtion.
-      unsigned bit = AD.getIdx(DR->getDecl());
-      LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
-
-      if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+      if (AD.killAtAssign) {
+        // Update liveness inforamtion.
+        unsigned bit = AD.getIdx(DR->getDecl());
+        LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
 
+        if (AD.Observer) { AD.Observer->ObserverKill(DR); }
+      }
       // Handle things like +=, etc., which also generate "uses"
       // of a variable.  Do this just by visiting the subexpression.
       if (B->getOpcode() != BO_Assign)