[llvm] r344601 - [NFC] Introduce ICFLoopSafetyInfo

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 16 02:58:09 PDT 2018


Author: mkazantsev
Date: Tue Oct 16 02:58:09 2018
New Revision: 344601

URL: http://llvm.org/viewvc/llvm-project?rev=344601&view=rev
Log:
[NFC] Introduce ICFLoopSafetyInfo

This is an alternative implementation of LoopSafetyInfo that uses the implicit
control flow tracking to give precise answers on queries "whether or not this
block contains throwing instructions". This rules out false-positive answers on
LoopSafetyInfo's queries.

This patch only introduces the new implementation. It is not currently used in
any pass. The enabling patches will go separately, through review.

The plan is to completely replace all uses of LoopSafetyInfo with
ICFLoopSafetyInfo in the future, but to avoid introducing functional problems,
we will do it pass by pass.

Modified:
    llvm/trunk/include/llvm/Analysis/MustExecute.h
    llvm/trunk/lib/Analysis/MustExecute.cpp

Modified: llvm/trunk/include/llvm/Analysis/MustExecute.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MustExecute.h?rev=344601&r1=344600&r2=344601&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MustExecute.h (original)
+++ llvm/trunk/include/llvm/Analysis/MustExecute.h Tue Oct 16 02:58:09 2018
@@ -19,6 +19,7 @@
 
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/Analysis/EHPersonalities.h"
+#include "llvm/Analysis/InstructionPrecedenceTracking.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Dominators.h"
@@ -122,6 +123,37 @@ public:
   virtual ~SimpleLoopSafetyInfo() {};
 };
 
+/// This implementation of LoopSafetyInfo use ImplicitControlFlowTracking to
+/// give precise answers on "may throw" queries. This implementation uses cache
+/// that should be invalidated by calling the method dropCachedInfo whenever we
+/// modify a basic block's contents by adding or removing instructions.
+class ICFLoopSafetyInfo: public LoopSafetyInfo {
+  bool MayThrow = false;       // The current loop contains an instruction which
+                               // may throw.
+  // Contains information about implicit control flow in this loop's blocks.
+  mutable ImplicitControlFlowTracking ICF;
+
+public:
+  virtual bool blockMayThrow(const BasicBlock *BB) const;
+
+  virtual bool anyBlockMayThrow() const;
+
+  virtual void computeLoopSafetyInfo(const Loop *CurLoop);
+
+  virtual bool isGuaranteedToExecute(const Instruction &Inst,
+                                     const DominatorTree *DT,
+                                     const Loop *CurLoop) const;
+
+  /// Drops cached information regarding the implicit control flow in block
+  /// \p BB. It should be called for every block in which we add or remove any
+  /// instructions  to a block before we make queries to it.
+  void dropCachedInfo(const BasicBlock *BB);
+
+  ICFLoopSafetyInfo(DominatorTree *DT) : LoopSafetyInfo(), ICF(DT) {};
+
+  virtual ~ICFLoopSafetyInfo() {};
+};
+
 }
 
 #endif

Modified: llvm/trunk/lib/Analysis/MustExecute.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MustExecute.cpp?rev=344601&r1=344600&r2=344601&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MustExecute.cpp (original)
+++ llvm/trunk/lib/Analysis/MustExecute.cpp Tue Oct 16 02:58:09 2018
@@ -61,6 +61,31 @@ void SimpleLoopSafetyInfo::computeLoopSa
   computeBlockColors(CurLoop);
 }
 
+bool ICFLoopSafetyInfo::blockMayThrow(const BasicBlock *BB) const {
+  return ICF.hasICF(BB);
+}
+
+bool ICFLoopSafetyInfo::anyBlockMayThrow() const {
+  return MayThrow;
+}
+
+void ICFLoopSafetyInfo::computeLoopSafetyInfo(const Loop *CurLoop) {
+  assert(CurLoop != nullptr && "CurLoop can't be null");
+  ICF.clear();
+  MayThrow = false;
+  // Figure out the fact that at least one block may throw.
+  for (auto &BB : CurLoop->blocks())
+    if (ICF.hasICF(&*BB)) {
+      MayThrow = true;
+      break;
+    }
+  computeBlockColors(CurLoop);
+}
+
+void ICFLoopSafetyInfo::dropCachedInfo(const BasicBlock *BB) {
+  ICF.invalidateBlock(BB);
+}
+
 void LoopSafetyInfo::computeBlockColors(const Loop *CurLoop) {
   // Compute funclet colors if we might sink/hoist in a function with a funclet
   // personality routine.
@@ -215,6 +240,12 @@ bool SimpleLoopSafetyInfo::isGuaranteedT
   return allLoopPathsLeadToBlock(CurLoop, Inst.getParent(), DT);
 }
 
+bool ICFLoopSafetyInfo::isGuaranteedToExecute(const Instruction &Inst,
+                                              const DominatorTree *DT,
+                                              const Loop *CurLoop) const {
+  return !ICF.isDominatedByICFIFromSameBlock(&Inst) &&
+         allLoopPathsLeadToBlock(CurLoop, Inst.getParent(), DT);
+}
 
 namespace {
   struct MustExecutePrinter : public FunctionPass {




More information about the llvm-commits mailing list