[llvm] r341015 - [NFC] Move OrderedInstructions and InstructionPrecedenceTracking to Analysis

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 29 21:49:03 PDT 2018


Author: mkazantsev
Date: Wed Aug 29 21:49:03 2018
New Revision: 341015

URL: http://llvm.org/viewvc/llvm-project?rev=341015&view=rev
Log:
[NFC] Move OrderedInstructions and InstructionPrecedenceTracking to Analysis

These classes don't make any changes to IR and have no reason to be in
Transform/Utils. This patch moves them to Analysis folder. This will allow
us reusing these classes in some analyzes, like MustExecute.

Added:
    llvm/trunk/include/llvm/Analysis/InstructionPrecedenceTracking.h
    llvm/trunk/include/llvm/Analysis/OrderedInstructions.h
    llvm/trunk/lib/Analysis/InstructionPrecedenceTracking.cpp
    llvm/trunk/lib/Analysis/OrderedInstructions.cpp
    llvm/trunk/unittests/Analysis/OrderedInstructions.cpp
Removed:
    llvm/trunk/include/llvm/Transforms/Utils/InstructionPrecedenceTracking.h
    llvm/trunk/include/llvm/Transforms/Utils/OrderedInstructions.h
    llvm/trunk/lib/Transforms/Utils/InstructionPrecedenceTracking.cpp
    llvm/trunk/lib/Transforms/Utils/OrderedInstructions.cpp
    llvm/trunk/unittests/Transforms/Utils/OrderedInstructions.cpp
Modified:
    llvm/trunk/include/llvm/Transforms/Scalar/GVN.h
    llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h
    llvm/trunk/lib/Analysis/CMakeLists.txt
    llvm/trunk/lib/Transforms/Utils/CMakeLists.txt
    llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp
    llvm/trunk/unittests/Analysis/CMakeLists.txt
    llvm/trunk/unittests/Transforms/Utils/CMakeLists.txt

Added: llvm/trunk/include/llvm/Analysis/InstructionPrecedenceTracking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionPrecedenceTracking.h?rev=341015&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Analysis/InstructionPrecedenceTracking.h (added)
+++ llvm/trunk/include/llvm/Analysis/InstructionPrecedenceTracking.h Wed Aug 29 21:49:03 2018
@@ -0,0 +1,108 @@
+//===-- InstructionPrecedenceTracking.h -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Implements a class that is able to define some instructions as "special"
+// (e.g. as having implicit control flow, or writing memory, or having another
+// interesting property) and then efficiently answers queries of the types:
+// 1. Are there any special instructions in the block of interest?
+// 2. Return first of the special instructions in the given block;
+// 3. Check if the given instruction is preceeded by the first special
+//    instruction in the same block.
+// The class provides caching that allows to answer these queries quickly. The
+// user must make sure that the cached data is invalidated properly whenever
+// a content of some tracked block is changed.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
+#define LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
+
+#include "llvm/IR/Dominators.h"
+#include "llvm/Analysis/OrderedInstructions.h"
+
+namespace llvm {
+
+class InstructionPrecedenceTracking {
+  // Maps a block to the topmost special instruction in it.
+  DenseMap<const BasicBlock *, const Instruction *>
+      FirstImplicitControlFlowInsts;
+  // Allows to answer queries about precedence of instructions within one block.
+  OrderedInstructions OI;
+  // Blocks for which we have the up-to-date cached information.
+  SmallPtrSet<const BasicBlock *, 8> KnownBlocks;
+
+  // Fills information about the given block's special instructions.
+  void fill(const BasicBlock *BB);
+
+protected:
+  InstructionPrecedenceTracking(DominatorTree *DT)
+      : OI(OrderedInstructions(DT)) {}
+
+  /// Returns the topmost special instruction from the block \p BB. Returns
+  /// nullptr if there is no special instructions in the block.
+  const Instruction *getFirstSpecialInstruction(const BasicBlock *BB);
+
+  /// Returns true iff at least one instruction from the basic block \p BB is
+  /// special.
+  bool hasSpecialInstructions(const BasicBlock *BB);
+
+  /// Returns true iff the first special instruction of \p Insn's block exists
+  /// and dominates \p Insn.
+  bool isPreceededBySpecialInstruction(const Instruction *Insn);
+
+  /// A predicate that defines whether or not the instruction \p Insn is
+  /// considered special and needs to be tracked. Implementing this method in
+  /// children classes allows to implement tracking of implicit control flow,
+  /// memory writing instructions or any other kinds of instructions we might
+  /// be interested in.
+  virtual bool isSpecialInstruction(const Instruction *Insn) const = 0;
+
+  virtual ~InstructionPrecedenceTracking() = default;
+
+public:
+  /// Clears cached information about this particular block.
+  void invalidateBlock(const BasicBlock *BB);
+
+  /// Invalidates all information from this tracking.
+  void clear();
+};
+
+/// This class allows to keep track on instructions with implicit control flow.
+/// These are instructions that may not pass execution to their successors. For
+/// example, throwing calls and guards do not always do this. If we need to know
+/// for sure that some instruction is guaranteed to execute if the given block
+/// is reached, then we need to make sure that there is no implicit control flow
+/// instruction (ICFI) preceeding it. For example, this check is required if we
+/// perform PRE moving non-speculable instruction to other place.
+class ImplicitControlFlowTracking : public InstructionPrecedenceTracking {
+public:
+  ImplicitControlFlowTracking(DominatorTree *DT)
+      : InstructionPrecedenceTracking(DT) {}
+
+  /// Returns the topmost instruction with implicit control flow from the given
+  /// basic block. Returns nullptr if there is no such instructions in the block.
+  const Instruction *getFirstICFI(const BasicBlock *BB) {
+    return getFirstSpecialInstruction(BB);
+  }
+
+  /// Returns true if at least one instruction from the given basic block has
+  /// implicit control flow.
+  bool hasICF(const BasicBlock *BB) {
+    return hasSpecialInstructions(BB);
+  }
+
+  /// Returns true if the first ICFI of Insn's block exists and dominates Insn.
+  bool isDominatedByICFIFromSameBlock(const Instruction *Insn) {
+    return isPreceededBySpecialInstruction(Insn);
+  }
+
+  virtual bool isSpecialInstruction(const Instruction *Insn) const;
+};
+
+} // llvm
+
+#endif // LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H

Added: llvm/trunk/include/llvm/Analysis/OrderedInstructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/OrderedInstructions.h?rev=341015&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Analysis/OrderedInstructions.h (added)
+++ llvm/trunk/include/llvm/Analysis/OrderedInstructions.h Wed Aug 29 21:49:03 2018
@@ -0,0 +1,65 @@
+//===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an efficient way to check for dominance relation between 2
+// instructions.
+//
+// This interface dispatches to appropriate dominance check given 2
+// instructions, i.e. in case the instructions are in the same basic block,
+// OrderedBasicBlock (with instruction numbering and caching) are used.
+// Otherwise, dominator tree is used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
+#define LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/OrderedBasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Operator.h"
+
+namespace llvm {
+
+class OrderedInstructions {
+  /// Used to check dominance for instructions in same basic block.
+  mutable DenseMap<const BasicBlock *, std::unique_ptr<OrderedBasicBlock>>
+      OBBMap;
+
+  /// The dominator tree of the parent function.
+  DominatorTree *DT;
+
+  /// Return true if the first instruction comes before the second in the
+  /// same basic block. It will create an ordered basic block, if it does
+  /// not yet exist in OBBMap.
+  bool localDominates(const Instruction *, const Instruction *) const;
+
+public:
+  /// Constructor.
+  OrderedInstructions(DominatorTree *DT) : DT(DT) {}
+
+  /// Return true if first instruction dominates the second.
+  bool dominates(const Instruction *, const Instruction *) const;
+
+  /// Return true if the first instruction comes before the second in the
+  /// dominator tree DFS traversal if they are in different basic blocks,
+  /// or if the first instruction comes before the second in the same basic
+  /// block.
+  bool dfsBefore(const Instruction *, const Instruction *) const;
+
+  /// Invalidate the OrderedBasicBlock cache when its basic block changes.
+  /// i.e. If an instruction is deleted or added to the basic block, the user
+  /// should call this function to invalidate the OrderedBasicBlock cache for
+  /// this basic block.
+  void invalidateBlock(const BasicBlock *BB) { OBBMap.erase(BB); }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H

Modified: llvm/trunk/include/llvm/Transforms/Scalar/GVN.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/GVN.h?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/GVN.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar/GVN.h Wed Aug 29 21:49:03 2018
@@ -22,13 +22,13 @@
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/InstructionPrecedenceTracking.h"
 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Compiler.h"
-#include "llvm/Transforms/Utils/InstructionPrecedenceTracking.h"
 #include <cstdint>
 #include <utility>
 #include <vector>

Removed: llvm/trunk/include/llvm/Transforms/Utils/InstructionPrecedenceTracking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/InstructionPrecedenceTracking.h?rev=341014&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/InstructionPrecedenceTracking.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/InstructionPrecedenceTracking.h (removed)
@@ -1,108 +0,0 @@
-//===-- InstructionPrecedenceTracking.h -------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Implements a class that is able to define some instructions as "special"
-// (e.g. as having implicit control flow, or writing memory, or having another
-// interesting property) and then efficiently answers queries of the types:
-// 1. Are there any special instructions in the block of interest?
-// 2. Return first of the special instructions in the given block;
-// 3. Check if the given instruction is preceeded by the first special
-//    instruction in the same block.
-// The class provides caching that allows to answer these queries quickly. The
-// user must make sure that the cached data is invalidated properly whenever
-// a content of some tracked block is changed.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_INSTRUCTIONPRECEDENCETRACKING_H
-#define LLVM_TRANSFORMS_UTILS_INSTRUCTIONPRECEDENCETRACKING_H
-
-#include "llvm/IR/Dominators.h"
-#include "llvm/Transforms/Utils/OrderedInstructions.h"
-
-namespace llvm {
-
-class InstructionPrecedenceTracking {
-  // Maps a block to the topmost special instruction in it.
-  DenseMap<const BasicBlock *, const Instruction *>
-      FirstImplicitControlFlowInsts;
-  // Allows to answer queries about precedence of instructions within one block.
-  OrderedInstructions OI;
-  // Blocks for which we have the up-to-date cached information.
-  SmallPtrSet<const BasicBlock *, 8> KnownBlocks;
-
-  // Fills information about the given block's special instructions.
-  void fill(const BasicBlock *BB);
-
-protected:
-  InstructionPrecedenceTracking(DominatorTree *DT)
-      : OI(OrderedInstructions(DT)) {}
-
-  /// Returns the topmost special instruction from the block \p BB. Returns
-  /// nullptr if there is no special instructions in the block.
-  const Instruction *getFirstSpecialInstruction(const BasicBlock *BB);
-
-  /// Returns true iff at least one instruction from the basic block \p BB is
-  /// special.
-  bool hasSpecialInstructions(const BasicBlock *BB);
-
-  /// Returns true iff the first special instruction of \p Insn's block exists
-  /// and dominates \p Insn.
-  bool isPreceededBySpecialInstruction(const Instruction *Insn);
-
-  /// A predicate that defines whether or not the instruction \p Insn is
-  /// considered special and needs to be tracked. Implementing this method in
-  /// children classes allows to implement tracking of implicit control flow,
-  /// memory writing instructions or any other kinds of instructions we might
-  /// be interested in.
-  virtual bool isSpecialInstruction(const Instruction *Insn) const = 0;
-
-  virtual ~InstructionPrecedenceTracking() = default;
-
-public:
-  /// Clears cached information about this particular block.
-  void invalidateBlock(const BasicBlock *BB);
-
-  /// Invalidates all information from this tracking.
-  void clear();
-};
-
-/// This class allows to keep track on instructions with implicit control flow.
-/// These are instructions that may not pass execution to their successors. For
-/// example, throwing calls and guards do not always do this. If we need to know
-/// for sure that some instruction is guaranteed to execute if the given block
-/// is reached, then we need to make sure that there is no implicit control flow
-/// instruction (ICFI) preceeding it. For example, this check is required if we
-/// perform PRE moving non-speculable instruction to other place.
-class ImplicitControlFlowTracking : public InstructionPrecedenceTracking {
-public:
-  ImplicitControlFlowTracking(DominatorTree *DT)
-      : InstructionPrecedenceTracking(DT) {}
-
-  /// Returns the topmost instruction with implicit control flow from the given
-  /// basic block. Returns nullptr if there is no such instructions in the block.
-  const Instruction *getFirstICFI(const BasicBlock *BB) {
-    return getFirstSpecialInstruction(BB);
-  }
-
-  /// Returns true if at least one instruction from the given basic block has
-  /// implicit control flow.
-  bool hasICF(const BasicBlock *BB) {
-    return hasSpecialInstructions(BB);
-  }
-
-  /// Returns true if the first ICFI of Insn's block exists and dominates Insn.
-  bool isDominatedByICFIFromSameBlock(const Instruction *Insn) {
-    return isPreceededBySpecialInstruction(Insn);
-  }
-
-  virtual bool isSpecialInstruction(const Instruction *Insn) const;
-};
-
-} // llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_INSTRUCTIONPRECEDENCETRACKING_H

Removed: llvm/trunk/include/llvm/Transforms/Utils/OrderedInstructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/OrderedInstructions.h?rev=341014&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/OrderedInstructions.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/OrderedInstructions.h (removed)
@@ -1,65 +0,0 @@
-//===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines an efficient way to check for dominance relation between 2
-// instructions.
-//
-// This interface dispatches to appropriate dominance check given 2
-// instructions, i.e. in case the instructions are in the same basic block,
-// OrderedBasicBlock (with instruction numbering and caching) are used.
-// Otherwise, dominator tree is used.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
-#define LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Analysis/OrderedBasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Operator.h"
-
-namespace llvm {
-
-class OrderedInstructions {
-  /// Used to check dominance for instructions in same basic block.
-  mutable DenseMap<const BasicBlock *, std::unique_ptr<OrderedBasicBlock>>
-      OBBMap;
-
-  /// The dominator tree of the parent function.
-  DominatorTree *DT;
-
-  /// Return true if the first instruction comes before the second in the
-  /// same basic block. It will create an ordered basic block, if it does
-  /// not yet exist in OBBMap.
-  bool localDominates(const Instruction *, const Instruction *) const;
-
-public:
-  /// Constructor.
-  OrderedInstructions(DominatorTree *DT) : DT(DT) {}
-
-  /// Return true if first instruction dominates the second.
-  bool dominates(const Instruction *, const Instruction *) const;
-
-  /// Return true if the first instruction comes before the second in the
-  /// dominator tree DFS traversal if they are in different basic blocks,
-  /// or if the first instruction comes before the second in the same basic
-  /// block.
-  bool dfsBefore(const Instruction *, const Instruction *) const;
-
-  /// Invalidate the OrderedBasicBlock cache when its basic block changes.
-  /// i.e. If an instruction is deleted or added to the basic block, the user
-  /// should call this function to invalidate the OrderedBasicBlock cache for
-  /// this basic block.
-  void invalidateBlock(const BasicBlock *BB) { OBBMap.erase(BB); }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H

Modified: llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/PredicateInfo.h Wed Aug 29 21:49:03 2018
@@ -60,6 +60,7 @@
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/OrderedInstructions.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Instructions.h"
@@ -76,7 +77,6 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Transforms/Utils/OrderedInstructions.h"
 #include <algorithm>
 #include <cassert>
 #include <cstddef>

Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Wed Aug 29 21:49:03 2018
@@ -35,6 +35,7 @@ add_llvm_library(LLVMAnalysis
   IndirectCallPromotionAnalysis.cpp
   InlineCost.cpp
   InstCount.cpp
+  InstructionPrecedenceTracking.cpp
   InstructionSimplify.cpp
   Interval.cpp
   IntervalPartition.cpp
@@ -65,6 +66,7 @@ add_llvm_library(LLVMAnalysis
   ObjCARCInstKind.cpp
   OptimizationRemarkEmitter.cpp
   OrderedBasicBlock.cpp
+  OrderedInstructions.cpp
   PHITransAddr.cpp
   PhiValues.cpp
   PostDominators.cpp

Added: llvm/trunk/lib/Analysis/InstructionPrecedenceTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionPrecedenceTracking.cpp?rev=341015&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionPrecedenceTracking.cpp (added)
+++ llvm/trunk/lib/Analysis/InstructionPrecedenceTracking.cpp Wed Aug 29 21:49:03 2018
@@ -0,0 +1,99 @@
+//===-- InstructionPrecedenceTracking.cpp -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Implements a class that is able to define some instructions as "special"
+// (e.g. as having implicit control flow, or writing memory, or having another
+// interesting property) and then efficiently answers queries of the types:
+// 1. Are there any special instructions in the block of interest?
+// 2. Return first of the special instructions in the given block;
+// 3. Check if the given instruction is preceeded by the first special
+//    instruction in the same block.
+// The class provides caching that allows to answer these queries quickly. The
+// user must make sure that the cached data is invalidated properly whenever
+// a content of some tracked block is changed.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/InstructionPrecedenceTracking.h"
+#include "llvm/Analysis/ValueTracking.h"
+
+using namespace llvm;
+
+const Instruction *InstructionPrecedenceTracking::getFirstSpecialInstruction(
+    const BasicBlock *BB) {
+  if (!KnownBlocks.count(BB))
+    fill(BB);
+  auto *FirstICF = FirstImplicitControlFlowInsts.lookup(BB);
+  assert((!FirstICF || FirstICF->getParent() == BB) && "Inconsistent cache!");
+  return FirstICF;
+}
+
+bool InstructionPrecedenceTracking::hasSpecialInstructions(
+    const BasicBlock *BB) {
+  return getFirstSpecialInstruction(BB) != nullptr;
+}
+
+bool InstructionPrecedenceTracking::isPreceededBySpecialInstruction(
+    const Instruction *Insn) {
+  const Instruction *MaybeFirstICF =
+      getFirstSpecialInstruction(Insn->getParent());
+  return MaybeFirstICF && OI.dominates(MaybeFirstICF, Insn);
+}
+
+void InstructionPrecedenceTracking::fill(const BasicBlock *BB) {
+  FirstImplicitControlFlowInsts.erase(BB);
+  for (auto &I : *BB)
+    if (isSpecialInstruction(&I)) {
+      FirstImplicitControlFlowInsts[BB] = &I;
+      break;
+    }
+
+  // Mark this block as having a known result.
+  KnownBlocks.insert(BB);
+}
+
+void InstructionPrecedenceTracking::invalidateBlock(const BasicBlock *BB) {
+  OI.invalidateBlock(BB);
+  FirstImplicitControlFlowInsts.erase(BB);
+  KnownBlocks.erase(BB);
+}
+
+void InstructionPrecedenceTracking::clear() {
+  for (auto It : FirstImplicitControlFlowInsts)
+    OI.invalidateBlock(It.first);
+  FirstImplicitControlFlowInsts.clear();
+  KnownBlocks.clear();
+}
+
+bool ImplicitControlFlowTracking::isSpecialInstruction(
+    const Instruction *Insn) const {
+  // If a block's instruction doesn't always pass the control to its successor
+  // instruction, mark the block as having implicit control flow. We use them
+  // to avoid wrong assumptions of sort "if A is executed and B post-dominates
+  // A, then B is also executed". This is not true is there is an implicit
+  // control flow instruction (e.g. a guard) between them.
+  //
+  // TODO: Currently, isGuaranteedToTransferExecutionToSuccessor returns false
+  // for volatile stores and loads because they can trap. The discussion on
+  // whether or not it is correct is still ongoing. We might want to get rid
+  // of this logic in the future. Anyways, trapping instructions shouldn't
+  // introduce implicit control flow, so we explicitly allow them here. This
+  // must be removed once isGuaranteedToTransferExecutionToSuccessor is fixed.
+  if (isGuaranteedToTransferExecutionToSuccessor(Insn))
+    return false;
+  if (isa<LoadInst>(Insn)) {
+    assert(cast<LoadInst>(Insn)->isVolatile() &&
+           "Non-volatile load should transfer execution to successor!");
+    return false;
+  }
+  if (isa<StoreInst>(Insn)) {
+    assert(cast<StoreInst>(Insn)->isVolatile() &&
+           "Non-volatile store should transfer execution to successor!");
+    return false;
+  }
+  return true;
+}

Added: llvm/trunk/lib/Analysis/OrderedInstructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/OrderedInstructions.cpp?rev=341015&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/OrderedInstructions.cpp (added)
+++ llvm/trunk/lib/Analysis/OrderedInstructions.cpp Wed Aug 29 21:49:03 2018
@@ -0,0 +1,51 @@
+//===-- OrderedInstructions.cpp - Instruction dominance function ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines utility to check dominance relation of 2 instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/OrderedInstructions.h"
+using namespace llvm;
+
+bool OrderedInstructions::localDominates(const Instruction *InstA,
+                                         const Instruction *InstB) const {
+  assert(InstA->getParent() == InstB->getParent() &&
+         "Instructions must be in the same basic block");
+
+  const BasicBlock *IBB = InstA->getParent();
+  auto OBB = OBBMap.find(IBB);
+  if (OBB == OBBMap.end())
+    OBB = OBBMap.insert({IBB, make_unique<OrderedBasicBlock>(IBB)}).first;
+  return OBB->second->dominates(InstA, InstB);
+}
+
+/// Given 2 instructions, use OrderedBasicBlock to check for dominance relation
+/// if the instructions are in the same basic block, Otherwise, use dominator
+/// tree.
+bool OrderedInstructions::dominates(const Instruction *InstA,
+                                    const Instruction *InstB) const {
+  // Use ordered basic block to do dominance check in case the 2 instructions
+  // are in the same basic block.
+  if (InstA->getParent() == InstB->getParent())
+    return localDominates(InstA, InstB);
+  return DT->dominates(InstA->getParent(), InstB->getParent());
+}
+
+bool OrderedInstructions::dfsBefore(const Instruction *InstA,
+                                    const Instruction *InstB) const {
+  // Use ordered basic block in case the 2 instructions are in the same basic
+  // block.
+  if (InstA->getParent() == InstB->getParent())
+    return localDominates(InstA, InstB);
+
+  DomTreeNode *DA = DT->getNode(InstA->getParent());
+  DomTreeNode *DB = DT->getNode(InstB->getParent());
+  return DA->getDFSNumIn() < DB->getDFSNumIn();
+}

Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Wed Aug 29 21:49:03 2018
@@ -22,7 +22,6 @@ add_llvm_library(LLVMTransformUtils
   InlineFunction.cpp
   ImportedFunctionsInliningStatistics.cpp
   InstructionNamer.cpp
-  InstructionPrecedenceTracking.cpp
   IntegerDivision.cpp
   LCSSA.cpp
   LibCallsShrinkWrap.cpp
@@ -42,7 +41,6 @@ add_llvm_library(LLVMTransformUtils
   MetaRenamer.cpp
   ModuleUtils.cpp
   NameAnonGlobals.cpp
-  OrderedInstructions.cpp
   PredicateInfo.cpp
   PromoteMemoryToRegister.cpp
   StripGCRelocates.cpp

Removed: llvm/trunk/lib/Transforms/Utils/InstructionPrecedenceTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InstructionPrecedenceTracking.cpp?rev=341014&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InstructionPrecedenceTracking.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InstructionPrecedenceTracking.cpp (removed)
@@ -1,99 +0,0 @@
-//===-- InstructionPrecedenceTracking.cpp -----------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Implements a class that is able to define some instructions as "special"
-// (e.g. as having implicit control flow, or writing memory, or having another
-// interesting property) and then efficiently answers queries of the types:
-// 1. Are there any special instructions in the block of interest?
-// 2. Return first of the special instructions in the given block;
-// 3. Check if the given instruction is preceeded by the first special
-//    instruction in the same block.
-// The class provides caching that allows to answer these queries quickly. The
-// user must make sure that the cached data is invalidated properly whenever
-// a content of some tracked block is changed.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Transforms/Utils/InstructionPrecedenceTracking.h"
-
-using namespace llvm;
-
-const Instruction *InstructionPrecedenceTracking::getFirstSpecialInstruction(
-    const BasicBlock *BB) {
-  if (!KnownBlocks.count(BB))
-    fill(BB);
-  auto *FirstICF = FirstImplicitControlFlowInsts.lookup(BB);
-  assert((!FirstICF || FirstICF->getParent() == BB) && "Inconsistent cache!");
-  return FirstICF;
-}
-
-bool InstructionPrecedenceTracking::hasSpecialInstructions(
-    const BasicBlock *BB) {
-  return getFirstSpecialInstruction(BB) != nullptr;
-}
-
-bool InstructionPrecedenceTracking::isPreceededBySpecialInstruction(
-    const Instruction *Insn) {
-  const Instruction *MaybeFirstICF =
-      getFirstSpecialInstruction(Insn->getParent());
-  return MaybeFirstICF && OI.dominates(MaybeFirstICF, Insn);
-}
-
-void InstructionPrecedenceTracking::fill(const BasicBlock *BB) {
-  FirstImplicitControlFlowInsts.erase(BB);
-  for (auto &I : *BB)
-    if (isSpecialInstruction(&I)) {
-      FirstImplicitControlFlowInsts[BB] = &I;
-      break;
-    }
-
-  // Mark this block as having a known result.
-  KnownBlocks.insert(BB);
-}
-
-void InstructionPrecedenceTracking::invalidateBlock(const BasicBlock *BB) {
-  OI.invalidateBlock(BB);
-  FirstImplicitControlFlowInsts.erase(BB);
-  KnownBlocks.erase(BB);
-}
-
-void InstructionPrecedenceTracking::clear() {
-  for (auto It : FirstImplicitControlFlowInsts)
-    OI.invalidateBlock(It.first);
-  FirstImplicitControlFlowInsts.clear();
-  KnownBlocks.clear();
-}
-
-bool ImplicitControlFlowTracking::isSpecialInstruction(
-    const Instruction *Insn) const {
-  // If a block's instruction doesn't always pass the control to its successor
-  // instruction, mark the block as having implicit control flow. We use them
-  // to avoid wrong assumptions of sort "if A is executed and B post-dominates
-  // A, then B is also executed". This is not true is there is an implicit
-  // control flow instruction (e.g. a guard) between them.
-  //
-  // TODO: Currently, isGuaranteedToTransferExecutionToSuccessor returns false
-  // for volatile stores and loads because they can trap. The discussion on
-  // whether or not it is correct is still ongoing. We might want to get rid
-  // of this logic in the future. Anyways, trapping instructions shouldn't
-  // introduce implicit control flow, so we explicitly allow them here. This
-  // must be removed once isGuaranteedToTransferExecutionToSuccessor is fixed.
-  if (isGuaranteedToTransferExecutionToSuccessor(Insn))
-    return false;
-  if (isa<LoadInst>(Insn)) {
-    assert(cast<LoadInst>(Insn)->isVolatile() &&
-           "Non-volatile load should transfer execution to successor!");
-    return false;
-  }
-  if (isa<StoreInst>(Insn)) {
-    assert(cast<StoreInst>(Insn)->isVolatile() &&
-           "Non-volatile store should transfer execution to successor!");
-    return false;
-  }
-  return true;
-}

Removed: llvm/trunk/lib/Transforms/Utils/OrderedInstructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/OrderedInstructions.cpp?rev=341014&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/OrderedInstructions.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/OrderedInstructions.cpp (removed)
@@ -1,51 +0,0 @@
-//===-- OrderedInstructions.cpp - Instruction dominance function ---------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines utility to check dominance relation of 2 instructions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Utils/OrderedInstructions.h"
-using namespace llvm;
-
-bool OrderedInstructions::localDominates(const Instruction *InstA,
-                                         const Instruction *InstB) const {
-  assert(InstA->getParent() == InstB->getParent() &&
-         "Instructions must be in the same basic block");
-
-  const BasicBlock *IBB = InstA->getParent();
-  auto OBB = OBBMap.find(IBB);
-  if (OBB == OBBMap.end())
-    OBB = OBBMap.insert({IBB, make_unique<OrderedBasicBlock>(IBB)}).first;
-  return OBB->second->dominates(InstA, InstB);
-}
-
-/// Given 2 instructions, use OrderedBasicBlock to check for dominance relation
-/// if the instructions are in the same basic block, Otherwise, use dominator
-/// tree.
-bool OrderedInstructions::dominates(const Instruction *InstA,
-                                    const Instruction *InstB) const {
-  // Use ordered basic block to do dominance check in case the 2 instructions
-  // are in the same basic block.
-  if (InstA->getParent() == InstB->getParent())
-    return localDominates(InstA, InstB);
-  return DT->dominates(InstA->getParent(), InstB->getParent());
-}
-
-bool OrderedInstructions::dfsBefore(const Instruction *InstA,
-                                    const Instruction *InstB) const {
-  // Use ordered basic block in case the 2 instructions are in the same basic
-  // block.
-  if (InstA->getParent() == InstB->getParent())
-    return localDominates(InstA, InstB);
-
-  DomTreeNode *DA = DT->getNode(InstA->getParent());
-  DomTreeNode *DB = DT->getNode(InstB->getParent());
-  return DA->getDFSNumIn() < DB->getDFSNumIn();
-}

Modified: llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/PredicateInfo.cpp Wed Aug 29 21:49:03 2018
@@ -35,7 +35,6 @@
 #include "llvm/Support/DebugCounter.h"
 #include "llvm/Support/FormattedStream.h"
 #include "llvm/Transforms/Utils.h"
-#include "llvm/Transforms/Utils/OrderedInstructions.h"
 #include <algorithm>
 #define DEBUG_TYPE "predicateinfo"
 using namespace llvm;

Modified: llvm/trunk/unittests/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/CMakeLists.txt?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/unittests/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Analysis/CMakeLists.txt Wed Aug 29 21:49:03 2018
@@ -20,6 +20,7 @@ add_llvm_unittest(AnalysisTests
   MemoryBuiltinsTest.cpp
   MemorySSA.cpp
   OrderedBasicBlockTest.cpp
+  OrderedInstructions.cpp
   PhiValuesTest.cpp
   ProfileSummaryInfoTest.cpp
   ScalarEvolutionTest.cpp

Added: llvm/trunk/unittests/Analysis/OrderedInstructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Analysis/OrderedInstructions.cpp?rev=341015&view=auto
==============================================================================
--- llvm/trunk/unittests/Analysis/OrderedInstructions.cpp (added)
+++ llvm/trunk/unittests/Analysis/OrderedInstructions.cpp Wed Aug 29 21:49:03 2018
@@ -0,0 +1,65 @@
+//===- OrderedInstructions.cpp - Unit tests for OrderedInstructions  ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/OrderedInstructions.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+/// Check intra-basicblock and inter-basicblock dominance using
+/// OrderedInstruction.
+TEST(OrderedInstructionsTest, DominanceTest) {
+  LLVMContext Ctx;
+  Module M("test", Ctx);
+  IRBuilder<> B(Ctx);
+  FunctionType *FTy =
+      FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
+  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
+
+  // Create the function as follow and check for dominance relation.
+  //
+  // test():
+  //  bbx:
+  //    loadx;
+  //    loady;
+  //  bby:
+  //    loadz;
+  //    return;
+  //
+  // More specifically, check for loadx -> (dominates) loady,
+  // loady -> loadx and loady -> loadz.
+  //
+  // Create BBX with 2 loads.
+  BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
+  B.SetInsertPoint(BBX);
+  Argument *PointerArg = &*F->arg_begin();
+  LoadInst *LoadInstX = B.CreateLoad(PointerArg);
+  LoadInst *LoadInstY = B.CreateLoad(PointerArg);
+
+  // Create BBY with 1 load.
+  BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
+  B.SetInsertPoint(BBY);
+  LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
+  B.CreateRet(LoadInstZ);
+  std::unique_ptr<DominatorTree> DT(new DominatorTree(*F));
+  OrderedInstructions OI(&*DT);
+
+  // Intra-BB dominance test.
+  EXPECT_TRUE(OI.dominates(LoadInstX, LoadInstY));
+  EXPECT_FALSE(OI.dominates(LoadInstY, LoadInstX));
+
+  // Inter-BB dominance test.
+  EXPECT_TRUE(OI.dominates(LoadInstY, LoadInstZ));
+}

Modified: llvm/trunk/unittests/Transforms/Utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/CMakeLists.txt?rev=341015&r1=341014&r2=341015&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/CMakeLists.txt (original)
+++ llvm/trunk/unittests/Transforms/Utils/CMakeLists.txt Wed Aug 29 21:49:03 2018
@@ -14,7 +14,6 @@ add_llvm_unittest(UtilsTests
   FunctionComparator.cpp
   IntegerDivision.cpp
   Local.cpp
-  OrderedInstructions.cpp
   SSAUpdaterBulk.cpp
   ValueMapperTest.cpp
   )

Removed: llvm/trunk/unittests/Transforms/Utils/OrderedInstructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/OrderedInstructions.cpp?rev=341014&view=auto
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/OrderedInstructions.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/OrderedInstructions.cpp (removed)
@@ -1,65 +0,0 @@
-//===- OrderedInstructions.cpp - Unit tests for OrderedInstructions  ------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Utils/OrderedInstructions.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-/// Check intra-basicblock and inter-basicblock dominance using
-/// OrderedInstruction.
-TEST(OrderedInstructionsTest, DominanceTest) {
-  LLVMContext Ctx;
-  Module M("test", Ctx);
-  IRBuilder<> B(Ctx);
-  FunctionType *FTy =
-      FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
-  Function *F = cast<Function>(M.getOrInsertFunction("f", FTy));
-
-  // Create the function as follow and check for dominance relation.
-  //
-  // test():
-  //  bbx:
-  //    loadx;
-  //    loady;
-  //  bby:
-  //    loadz;
-  //    return;
-  //
-  // More specifically, check for loadx -> (dominates) loady,
-  // loady -> loadx and loady -> loadz.
-  //
-  // Create BBX with 2 loads.
-  BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
-  B.SetInsertPoint(BBX);
-  Argument *PointerArg = &*F->arg_begin();
-  LoadInst *LoadInstX = B.CreateLoad(PointerArg);
-  LoadInst *LoadInstY = B.CreateLoad(PointerArg);
-
-  // Create BBY with 1 load.
-  BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
-  B.SetInsertPoint(BBY);
-  LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
-  B.CreateRet(LoadInstZ);
-  std::unique_ptr<DominatorTree> DT(new DominatorTree(*F));
-  OrderedInstructions OI(&*DT);
-
-  // Intra-BB dominance test.
-  EXPECT_TRUE(OI.dominates(LoadInstX, LoadInstY));
-  EXPECT_FALSE(OI.dominates(LoadInstY, LoadInstX));
-
-  // Inter-BB dominance test.
-  EXPECT_TRUE(OI.dominates(LoadInstY, LoadInstZ));
-}




More information about the llvm-commits mailing list