[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