llvm.org GIT mirror llvm / 3a86455
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@341015 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 1 year, 22 days ago
17 changed file(s) with 393 addition(s) and 394 deletion(s). Raw diff Collapse all Expand all
0 //===-- InstructionPrecedenceTracking.h -------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Implements a class that is able to define some instructions as "special"
9 // (e.g. as having implicit control flow, or writing memory, or having another
10 // interesting property) and then efficiently answers queries of the types:
11 // 1. Are there any special instructions in the block of interest?
12 // 2. Return first of the special instructions in the given block;
13 // 3. Check if the given instruction is preceeded by the first special
14 // instruction in the same block.
15 // The class provides caching that allows to answer these queries quickly. The
16 // user must make sure that the cached data is invalidated properly whenever
17 // a content of some tracked block is changed.
18 //===----------------------------------------------------------------------===//
19
20 #ifndef LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
21 #define LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
22
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/Analysis/OrderedInstructions.h"
25
26 namespace llvm {
27
28 class InstructionPrecedenceTracking {
29 // Maps a block to the topmost special instruction in it.
30 DenseMap
31 FirstImplicitControlFlowInsts;
32 // Allows to answer queries about precedence of instructions within one block.
33 OrderedInstructions OI;
34 // Blocks for which we have the up-to-date cached information.
35 SmallPtrSet KnownBlocks;
36
37 // Fills information about the given block's special instructions.
38 void fill(const BasicBlock *BB);
39
40 protected:
41 InstructionPrecedenceTracking(DominatorTree *DT)
42 : OI(OrderedInstructions(DT)) {}
43
44 /// Returns the topmost special instruction from the block \p BB. Returns
45 /// nullptr if there is no special instructions in the block.
46 const Instruction *getFirstSpecialInstruction(const BasicBlock *BB);
47
48 /// Returns true iff at least one instruction from the basic block \p BB is
49 /// special.
50 bool hasSpecialInstructions(const BasicBlock *BB);
51
52 /// Returns true iff the first special instruction of \p Insn's block exists
53 /// and dominates \p Insn.
54 bool isPreceededBySpecialInstruction(const Instruction *Insn);
55
56 /// A predicate that defines whether or not the instruction \p Insn is
57 /// considered special and needs to be tracked. Implementing this method in
58 /// children classes allows to implement tracking of implicit control flow,
59 /// memory writing instructions or any other kinds of instructions we might
60 /// be interested in.
61 virtual bool isSpecialInstruction(const Instruction *Insn) const = 0;
62
63 virtual ~InstructionPrecedenceTracking() = default;
64
65 public:
66 /// Clears cached information about this particular block.
67 void invalidateBlock(const BasicBlock *BB);
68
69 /// Invalidates all information from this tracking.
70 void clear();
71 };
72
73 /// This class allows to keep track on instructions with implicit control flow.
74 /// These are instructions that may not pass execution to their successors. For
75 /// example, throwing calls and guards do not always do this. If we need to know
76 /// for sure that some instruction is guaranteed to execute if the given block
77 /// is reached, then we need to make sure that there is no implicit control flow
78 /// instruction (ICFI) preceeding it. For example, this check is required if we
79 /// perform PRE moving non-speculable instruction to other place.
80 class ImplicitControlFlowTracking : public InstructionPrecedenceTracking {
81 public:
82 ImplicitControlFlowTracking(DominatorTree *DT)
83 : InstructionPrecedenceTracking(DT) {}
84
85 /// Returns the topmost instruction with implicit control flow from the given
86 /// basic block. Returns nullptr if there is no such instructions in the block.
87 const Instruction *getFirstICFI(const BasicBlock *BB) {
88 return getFirstSpecialInstruction(BB);
89 }
90
91 /// Returns true if at least one instruction from the given basic block has
92 /// implicit control flow.
93 bool hasICF(const BasicBlock *BB) {
94 return hasSpecialInstructions(BB);
95 }
96
97 /// Returns true if the first ICFI of Insn's block exists and dominates Insn.
98 bool isDominatedByICFIFromSameBlock(const Instruction *Insn) {
99 return isPreceededBySpecialInstruction(Insn);
100 }
101
102 virtual bool isSpecialInstruction(const Instruction *Insn) const;
103 };
104
105 } // llvm
106
107 #endif // LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
0 //===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines an efficient way to check for dominance relation between 2
10 // instructions.
11 //
12 // This interface dispatches to appropriate dominance check given 2
13 // instructions, i.e. in case the instructions are in the same basic block,
14 // OrderedBasicBlock (with instruction numbering and caching) are used.
15 // Otherwise, dominator tree is used.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
20 #define LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
21
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/Analysis/OrderedBasicBlock.h"
24 #include "llvm/IR/Dominators.h"
25 #include "llvm/IR/Operator.h"
26
27 namespace llvm {
28
29 class OrderedInstructions {
30 /// Used to check dominance for instructions in same basic block.
31 mutable DenseMap>
32 OBBMap;
33
34 /// The dominator tree of the parent function.
35 DominatorTree *DT;
36
37 /// Return true if the first instruction comes before the second in the
38 /// same basic block. It will create an ordered basic block, if it does
39 /// not yet exist in OBBMap.
40 bool localDominates(const Instruction *, const Instruction *) const;
41
42 public:
43 /// Constructor.
44 OrderedInstructions(DominatorTree *DT) : DT(DT) {}
45
46 /// Return true if first instruction dominates the second.
47 bool dominates(const Instruction *, const Instruction *) const;
48
49 /// Return true if the first instruction comes before the second in the
50 /// dominator tree DFS traversal if they are in different basic blocks,
51 /// or if the first instruction comes before the second in the same basic
52 /// block.
53 bool dfsBefore(const Instruction *, const Instruction *) const;
54
55 /// Invalidate the OrderedBasicBlock cache when its basic block changes.
56 /// i.e. If an instruction is deleted or added to the basic block, the user
57 /// should call this function to invalidate the OrderedBasicBlock cache for
58 /// this basic block.
59 void invalidateBlock(const BasicBlock *BB) { OBBMap.erase(BB); }
60 };
61
62 } // end namespace llvm
63
64 #endif // LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
2121 #include "llvm/ADT/SetVector.h"
2222 #include "llvm/ADT/SmallVector.h"
2323 #include "llvm/Analysis/AliasAnalysis.h"
24 #include "llvm/Analysis/InstructionPrecedenceTracking.h"
2425 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
2526 #include "llvm/IR/Dominators.h"
2627 #include "llvm/IR/InstrTypes.h"
2728 #include "llvm/IR/PassManager.h"
2829 #include "llvm/Support/Allocator.h"
2930 #include "llvm/Support/Compiler.h"
30 #include "llvm/Transforms/Utils/InstructionPrecedenceTracking.h"
3131 #include
3232 #include
3333 #include
+0
-108
include/llvm/Transforms/Utils/InstructionPrecedenceTracking.h less more
None //===-- InstructionPrecedenceTracking.h -------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Implements a class that is able to define some instructions as "special"
9 // (e.g. as having implicit control flow, or writing memory, or having another
10 // interesting property) and then efficiently answers queries of the types:
11 // 1. Are there any special instructions in the block of interest?
12 // 2. Return first of the special instructions in the given block;
13 // 3. Check if the given instruction is preceeded by the first special
14 // instruction in the same block.
15 // The class provides caching that allows to answer these queries quickly. The
16 // user must make sure that the cached data is invalidated properly whenever
17 // a content of some tracked block is changed.
18 //===----------------------------------------------------------------------===//
19
20 #ifndef LLVM_TRANSFORMS_UTILS_INSTRUCTIONPRECEDENCETRACKING_H
21 #define LLVM_TRANSFORMS_UTILS_INSTRUCTIONPRECEDENCETRACKING_H
22
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/Transforms/Utils/OrderedInstructions.h"
25
26 namespace llvm {
27
28 class InstructionPrecedenceTracking {
29 // Maps a block to the topmost special instruction in it.
30 DenseMap
31 FirstImplicitControlFlowInsts;
32 // Allows to answer queries about precedence of instructions within one block.
33 OrderedInstructions OI;
34 // Blocks for which we have the up-to-date cached information.
35 SmallPtrSet KnownBlocks;
36
37 // Fills information about the given block's special instructions.
38 void fill(const BasicBlock *BB);
39
40 protected:
41 InstructionPrecedenceTracking(DominatorTree *DT)
42 : OI(OrderedInstructions(DT)) {}
43
44 /// Returns the topmost special instruction from the block \p BB. Returns
45 /// nullptr if there is no special instructions in the block.
46 const Instruction *getFirstSpecialInstruction(const BasicBlock *BB);
47
48 /// Returns true iff at least one instruction from the basic block \p BB is
49 /// special.
50 bool hasSpecialInstructions(const BasicBlock *BB);
51
52 /// Returns true iff the first special instruction of \p Insn's block exists
53 /// and dominates \p Insn.
54 bool isPreceededBySpecialInstruction(const Instruction *Insn);
55
56 /// A predicate that defines whether or not the instruction \p Insn is
57 /// considered special and needs to be tracked. Implementing this method in
58 /// children classes allows to implement tracking of implicit control flow,
59 /// memory writing instructions or any other kinds of instructions we might
60 /// be interested in.
61 virtual bool isSpecialInstruction(const Instruction *Insn) const = 0;
62
63 virtual ~InstructionPrecedenceTracking() = default;
64
65 public:
66 /// Clears cached information about this particular block.
67 void invalidateBlock(const BasicBlock *BB);
68
69 /// Invalidates all information from this tracking.
70 void clear();
71 };
72
73 /// This class allows to keep track on instructions with implicit control flow.
74 /// These are instructions that may not pass execution to their successors. For
75 /// example, throwing calls and guards do not always do this. If we need to know
76 /// for sure that some instruction is guaranteed to execute if the given block
77 /// is reached, then we need to make sure that there is no implicit control flow
78 /// instruction (ICFI) preceeding it. For example, this check is required if we
79 /// perform PRE moving non-speculable instruction to other place.
80 class ImplicitControlFlowTracking : public InstructionPrecedenceTracking {
81 public:
82 ImplicitControlFlowTracking(DominatorTree *DT)
83 : InstructionPrecedenceTracking(DT) {}
84
85 /// Returns the topmost instruction with implicit control flow from the given
86 /// basic block. Returns nullptr if there is no such instructions in the block.
87 const Instruction *getFirstICFI(const BasicBlock *BB) {
88 return getFirstSpecialInstruction(BB);
89 }
90
91 /// Returns true if at least one instruction from the given basic block has
92 /// implicit control flow.
93 bool hasICF(const BasicBlock *BB) {
94 return hasSpecialInstructions(BB);
95 }
96
97 /// Returns true if the first ICFI of Insn's block exists and dominates Insn.
98 bool isDominatedByICFIFromSameBlock(const Instruction *Insn) {
99 return isPreceededBySpecialInstruction(Insn);
100 }
101
102 virtual bool isSpecialInstruction(const Instruction *Insn) const;
103 };
104
105 } // llvm
106
107 #endif // LLVM_TRANSFORMS_UTILS_INSTRUCTIONPRECEDENCETRACKING_H
+0
-65
include/llvm/Transforms/Utils/OrderedInstructions.h less more
None //===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines an efficient way to check for dominance relation between 2
10 // instructions.
11 //
12 // This interface dispatches to appropriate dominance check given 2
13 // instructions, i.e. in case the instructions are in the same basic block,
14 // OrderedBasicBlock (with instruction numbering and caching) are used.
15 // Otherwise, dominator tree is used.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #ifndef LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
20 #define LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
21
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/Analysis/OrderedBasicBlock.h"
24 #include "llvm/IR/Dominators.h"
25 #include "llvm/IR/Operator.h"
26
27 namespace llvm {
28
29 class OrderedInstructions {
30 /// Used to check dominance for instructions in same basic block.
31 mutable DenseMap>
32 OBBMap;
33
34 /// The dominator tree of the parent function.
35 DominatorTree *DT;
36
37 /// Return true if the first instruction comes before the second in the
38 /// same basic block. It will create an ordered basic block, if it does
39 /// not yet exist in OBBMap.
40 bool localDominates(const Instruction *, const Instruction *) const;
41
42 public:
43 /// Constructor.
44 OrderedInstructions(DominatorTree *DT) : DT(DT) {}
45
46 /// Return true if first instruction dominates the second.
47 bool dominates(const Instruction *, const Instruction *) const;
48
49 /// Return true if the first instruction comes before the second in the
50 /// dominator tree DFS traversal if they are in different basic blocks,
51 /// or if the first instruction comes before the second in the same basic
52 /// block.
53 bool dfsBefore(const Instruction *, const Instruction *) const;
54
55 /// Invalidate the OrderedBasicBlock cache when its basic block changes.
56 /// i.e. If an instruction is deleted or added to the basic block, the user
57 /// should call this function to invalidate the OrderedBasicBlock cache for
58 /// this basic block.
59 void invalidateBlock(const BasicBlock *BB) { OBBMap.erase(BB); }
60 };
61
62 } // end namespace llvm
63
64 #endif // LLVM_TRANSFORMS_UTILS_ORDEREDINSTRUCTIONS_H
5959 #include "llvm/ADT/ilist_node.h"
6060 #include "llvm/ADT/iterator.h"
6161 #include "llvm/Analysis/AssumptionCache.h"
62 #include "llvm/Analysis/OrderedInstructions.h"
6263 #include "llvm/IR/BasicBlock.h"
6364 #include "llvm/IR/Dominators.h"
6465 #include "llvm/IR/Instructions.h"
7576 #include "llvm/Support/Casting.h"
7677 #include "llvm/Support/Compiler.h"
7778 #include "llvm/Support/ErrorHandling.h"
78 #include "llvm/Transforms/Utils/OrderedInstructions.h"
7979 #include
8080 #include
8181 #include
3434 IndirectCallPromotionAnalysis.cpp
3535 InlineCost.cpp
3636 InstCount.cpp
37 InstructionPrecedenceTracking.cpp
3738 InstructionSimplify.cpp
3839 Interval.cpp
3940 IntervalPartition.cpp
6465 ObjCARCInstKind.cpp
6566 OptimizationRemarkEmitter.cpp
6667 OrderedBasicBlock.cpp
68 OrderedInstructions.cpp
6769 PHITransAddr.cpp
6870 PhiValues.cpp
6971 PostDominators.cpp
0 //===-- InstructionPrecedenceTracking.cpp -----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Implements a class that is able to define some instructions as "special"
9 // (e.g. as having implicit control flow, or writing memory, or having another
10 // interesting property) and then efficiently answers queries of the types:
11 // 1. Are there any special instructions in the block of interest?
12 // 2. Return first of the special instructions in the given block;
13 // 3. Check if the given instruction is preceeded by the first special
14 // instruction in the same block.
15 // The class provides caching that allows to answer these queries quickly. The
16 // user must make sure that the cached data is invalidated properly whenever
17 // a content of some tracked block is changed.
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/Analysis/InstructionPrecedenceTracking.h"
21 #include "llvm/Analysis/ValueTracking.h"
22
23 using namespace llvm;
24
25 const Instruction *InstructionPrecedenceTracking::getFirstSpecialInstruction(
26 const BasicBlock *BB) {
27 if (!KnownBlocks.count(BB))
28 fill(BB);
29 auto *FirstICF = FirstImplicitControlFlowInsts.lookup(BB);
30 assert((!FirstICF || FirstICF->getParent() == BB) && "Inconsistent cache!");
31 return FirstICF;
32 }
33
34 bool InstructionPrecedenceTracking::hasSpecialInstructions(
35 const BasicBlock *BB) {
36 return getFirstSpecialInstruction(BB) != nullptr;
37 }
38
39 bool InstructionPrecedenceTracking::isPreceededBySpecialInstruction(
40 const Instruction *Insn) {
41 const Instruction *MaybeFirstICF =
42 getFirstSpecialInstruction(Insn->getParent());
43 return MaybeFirstICF && OI.dominates(MaybeFirstICF, Insn);
44 }
45
46 void InstructionPrecedenceTracking::fill(const BasicBlock *BB) {
47 FirstImplicitControlFlowInsts.erase(BB);
48 for (auto &I : *BB)
49 if (isSpecialInstruction(&I)) {
50 FirstImplicitControlFlowInsts[BB] = &I;
51 break;
52 }
53
54 // Mark this block as having a known result.
55 KnownBlocks.insert(BB);
56 }
57
58 void InstructionPrecedenceTracking::invalidateBlock(const BasicBlock *BB) {
59 OI.invalidateBlock(BB);
60 FirstImplicitControlFlowInsts.erase(BB);
61 KnownBlocks.erase(BB);
62 }
63
64 void InstructionPrecedenceTracking::clear() {
65 for (auto It : FirstImplicitControlFlowInsts)
66 OI.invalidateBlock(It.first);
67 FirstImplicitControlFlowInsts.clear();
68 KnownBlocks.clear();
69 }
70
71 bool ImplicitControlFlowTracking::isSpecialInstruction(
72 const Instruction *Insn) const {
73 // If a block's instruction doesn't always pass the control to its successor
74 // instruction, mark the block as having implicit control flow. We use them
75 // to avoid wrong assumptions of sort "if A is executed and B post-dominates
76 // A, then B is also executed". This is not true is there is an implicit
77 // control flow instruction (e.g. a guard) between them.
78 //
79 // TODO: Currently, isGuaranteedToTransferExecutionToSuccessor returns false
80 // for volatile stores and loads because they can trap. The discussion on
81 // whether or not it is correct is still ongoing. We might want to get rid
82 // of this logic in the future. Anyways, trapping instructions shouldn't
83 // introduce implicit control flow, so we explicitly allow them here. This
84 // must be removed once isGuaranteedToTransferExecutionToSuccessor is fixed.
85 if (isGuaranteedToTransferExecutionToSuccessor(Insn))
86 return false;
87 if (isa(Insn)) {
88 assert(cast(Insn)->isVolatile() &&
89 "Non-volatile load should transfer execution to successor!");
90 return false;
91 }
92 if (isa(Insn)) {
93 assert(cast(Insn)->isVolatile() &&
94 "Non-volatile store should transfer execution to successor!");
95 return false;
96 }
97 return true;
98 }
0 //===-- OrderedInstructions.cpp - Instruction dominance function ---------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines utility to check dominance relation of 2 instructions.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Analysis/OrderedInstructions.h"
14 using namespace llvm;
15
16 bool OrderedInstructions::localDominates(const Instruction *InstA,
17 const Instruction *InstB) const {
18 assert(InstA->getParent() == InstB->getParent() &&
19 "Instructions must be in the same basic block");
20
21 const BasicBlock *IBB = InstA->getParent();
22 auto OBB = OBBMap.find(IBB);
23 if (OBB == OBBMap.end())
24 OBB = OBBMap.insert({IBB, make_unique(IBB)}).first;
25 return OBB->second->dominates(InstA, InstB);
26 }
27
28 /// Given 2 instructions, use OrderedBasicBlock to check for dominance relation
29 /// if the instructions are in the same basic block, Otherwise, use dominator
30 /// tree.
31 bool OrderedInstructions::dominates(const Instruction *InstA,
32 const Instruction *InstB) const {
33 // Use ordered basic block to do dominance check in case the 2 instructions
34 // are in the same basic block.
35 if (InstA->getParent() == InstB->getParent())
36 return localDominates(InstA, InstB);
37 return DT->dominates(InstA->getParent(), InstB->getParent());
38 }
39
40 bool OrderedInstructions::dfsBefore(const Instruction *InstA,
41 const Instruction *InstB) const {
42 // Use ordered basic block in case the 2 instructions are in the same basic
43 // block.
44 if (InstA->getParent() == InstB->getParent())
45 return localDominates(InstA, InstB);
46
47 DomTreeNode *DA = DT->getNode(InstA->getParent());
48 DomTreeNode *DB = DT->getNode(InstB->getParent());
49 return DA->getDFSNumIn() < DB->getDFSNumIn();
50 }
2121 InlineFunction.cpp
2222 ImportedFunctionsInliningStatistics.cpp
2323 InstructionNamer.cpp
24 InstructionPrecedenceTracking.cpp
2524 IntegerDivision.cpp
2625 LCSSA.cpp
2726 LibCallsShrinkWrap.cpp
4140 MetaRenamer.cpp
4241 ModuleUtils.cpp
4342 NameAnonGlobals.cpp
44 OrderedInstructions.cpp
4543 PredicateInfo.cpp
4644 PromoteMemoryToRegister.cpp
4745 StripGCRelocates.cpp
+0
-99
lib/Transforms/Utils/InstructionPrecedenceTracking.cpp less more
None //===-- InstructionPrecedenceTracking.cpp -----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // Implements a class that is able to define some instructions as "special"
9 // (e.g. as having implicit control flow, or writing memory, or having another
10 // interesting property) and then efficiently answers queries of the types:
11 // 1. Are there any special instructions in the block of interest?
12 // 2. Return first of the special instructions in the given block;
13 // 3. Check if the given instruction is preceeded by the first special
14 // instruction in the same block.
15 // The class provides caching that allows to answer these queries quickly. The
16 // user must make sure that the cached data is invalidated properly whenever
17 // a content of some tracked block is changed.
18 //===----------------------------------------------------------------------===//
19
20 #include "llvm/Analysis/ValueTracking.h"
21 #include "llvm/Transforms/Utils/InstructionPrecedenceTracking.h"
22
23 using namespace llvm;
24
25 const Instruction *InstructionPrecedenceTracking::getFirstSpecialInstruction(
26 const BasicBlock *BB) {
27 if (!KnownBlocks.count(BB))
28 fill(BB);
29 auto *FirstICF = FirstImplicitControlFlowInsts.lookup(BB);
30 assert((!FirstICF || FirstICF->getParent() == BB) && "Inconsistent cache!");
31 return FirstICF;
32 }
33
34 bool InstructionPrecedenceTracking::hasSpecialInstructions(
35 const BasicBlock *BB) {
36 return getFirstSpecialInstruction(BB) != nullptr;
37 }
38
39 bool InstructionPrecedenceTracking::isPreceededBySpecialInstruction(
40 const Instruction *Insn) {
41 const Instruction *MaybeFirstICF =
42 getFirstSpecialInstruction(Insn->getParent());
43 return MaybeFirstICF && OI.dominates(MaybeFirstICF, Insn);
44 }
45
46 void InstructionPrecedenceTracking::fill(const BasicBlock *BB) {
47 FirstImplicitControlFlowInsts.erase(BB);
48 for (auto &I : *BB)
49 if (isSpecialInstruction(&I)) {
50 FirstImplicitControlFlowInsts[BB] = &I;
51 break;
52 }
53
54 // Mark this block as having a known result.
55 KnownBlocks.insert(BB);
56 }
57
58 void InstructionPrecedenceTracking::invalidateBlock(const BasicBlock *BB) {
59 OI.invalidateBlock(BB);
60 FirstImplicitControlFlowInsts.erase(BB);
61 KnownBlocks.erase(BB);
62 }
63
64 void InstructionPrecedenceTracking::clear() {
65 for (auto It : FirstImplicitControlFlowInsts)
66 OI.invalidateBlock(It.first);
67 FirstImplicitControlFlowInsts.clear();
68 KnownBlocks.clear();
69 }
70
71 bool ImplicitControlFlowTracking::isSpecialInstruction(
72 const Instruction *Insn) const {
73 // If a block's instruction doesn't always pass the control to its successor
74 // instruction, mark the block as having implicit control flow. We use them
75 // to avoid wrong assumptions of sort "if A is executed and B post-dominates
76 // A, then B is also executed". This is not true is there is an implicit
77 // control flow instruction (e.g. a guard) between them.
78 //
79 // TODO: Currently, isGuaranteedToTransferExecutionToSuccessor returns false
80 // for volatile stores and loads because they can trap. The discussion on
81 // whether or not it is correct is still ongoing. We might want to get rid
82 // of this logic in the future. Anyways, trapping instructions shouldn't
83 // introduce implicit control flow, so we explicitly allow them here. This
84 // must be removed once isGuaranteedToTransferExecutionToSuccessor is fixed.
85 if (isGuaranteedToTransferExecutionToSuccessor(Insn))
86 return false;
87 if (isa(Insn)) {
88 assert(cast(Insn)->isVolatile() &&
89 "Non-volatile load should transfer execution to successor!");
90 return false;
91 }
92 if (isa(Insn)) {
93 assert(cast(Insn)->isVolatile() &&
94 "Non-volatile store should transfer execution to successor!");
95 return false;
96 }
97 return true;
98 }
+0
-51
lib/Transforms/Utils/OrderedInstructions.cpp less more
None //===-- OrderedInstructions.cpp - Instruction dominance function ---------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines utility to check dominance relation of 2 instructions.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Transforms/Utils/OrderedInstructions.h"
14 using namespace llvm;
15
16 bool OrderedInstructions::localDominates(const Instruction *InstA,
17 const Instruction *InstB) const {
18 assert(InstA->getParent() == InstB->getParent() &&
19 "Instructions must be in the same basic block");
20
21 const BasicBlock *IBB = InstA->getParent();
22 auto OBB = OBBMap.find(IBB);
23 if (OBB == OBBMap.end())
24 OBB = OBBMap.insert({IBB, make_unique(IBB)}).first;
25 return OBB->second->dominates(InstA, InstB);
26 }
27
28 /// Given 2 instructions, use OrderedBasicBlock to check for dominance relation
29 /// if the instructions are in the same basic block, Otherwise, use dominator
30 /// tree.
31 bool OrderedInstructions::dominates(const Instruction *InstA,
32 const Instruction *InstB) const {
33 // Use ordered basic block to do dominance check in case the 2 instructions
34 // are in the same basic block.
35 if (InstA->getParent() == InstB->getParent())
36 return localDominates(InstA, InstB);
37 return DT->dominates(InstA->getParent(), InstB->getParent());
38 }
39
40 bool OrderedInstructions::dfsBefore(const Instruction *InstA,
41 const Instruction *InstB) const {
42 // Use ordered basic block in case the 2 instructions are in the same basic
43 // block.
44 if (InstA->getParent() == InstB->getParent())
45 return localDominates(InstA, InstB);
46
47 DomTreeNode *DA = DT->getNode(InstA->getParent());
48 DomTreeNode *DB = DT->getNode(InstB->getParent());
49 return DA->getDFSNumIn() < DB->getDFSNumIn();
50 }
3434 #include "llvm/Support/DebugCounter.h"
3535 #include "llvm/Support/FormattedStream.h"
3636 #include "llvm/Transforms/Utils.h"
37 #include "llvm/Transforms/Utils/OrderedInstructions.h"
3837 #include
3938 #define DEBUG_TYPE "predicateinfo"
4039 using namespace llvm;
1919 MemoryBuiltinsTest.cpp
2020 MemorySSA.cpp
2121 OrderedBasicBlockTest.cpp
22 OrderedInstructions.cpp
2223 PhiValuesTest.cpp
2324 ProfileSummaryInfoTest.cpp
2425 ScalarEvolutionTest.cpp
0 //===- OrderedInstructions.cpp - Unit tests for OrderedInstructions ------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Analysis/OrderedInstructions.h"
10 #include "llvm/IR/BasicBlock.h"
11 #include "llvm/IR/Dominators.h"
12 #include "llvm/IR/IRBuilder.h"
13 #include "llvm/IR/Instructions.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Module.h"
16 #include "gtest/gtest.h"
17
18 using namespace llvm;
19
20 /// Check intra-basicblock and inter-basicblock dominance using
21 /// OrderedInstruction.
22 TEST(OrderedInstructionsTest, DominanceTest) {
23 LLVMContext Ctx;
24 Module M("test", Ctx);
25 IRBuilder<> B(Ctx);
26 FunctionType *FTy =
27 FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
28 Function *F = cast(M.getOrInsertFunction("f", FTy));
29
30 // Create the function as follow and check for dominance relation.
31 //
32 // test():
33 // bbx:
34 // loadx;
35 // loady;
36 // bby:
37 // loadz;
38 // return;
39 //
40 // More specifically, check for loadx -> (dominates) loady,
41 // loady -> loadx and loady -> loadz.
42 //
43 // Create BBX with 2 loads.
44 BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
45 B.SetInsertPoint(BBX);
46 Argument *PointerArg = &*F->arg_begin();
47 LoadInst *LoadInstX = B.CreateLoad(PointerArg);
48 LoadInst *LoadInstY = B.CreateLoad(PointerArg);
49
50 // Create BBY with 1 load.
51 BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
52 B.SetInsertPoint(BBY);
53 LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
54 B.CreateRet(LoadInstZ);
55 std::unique_ptr DT(new DominatorTree(*F));
56 OrderedInstructions OI(&*DT);
57
58 // Intra-BB dominance test.
59 EXPECT_TRUE(OI.dominates(LoadInstX, LoadInstY));
60 EXPECT_FALSE(OI.dominates(LoadInstY, LoadInstX));
61
62 // Inter-BB dominance test.
63 EXPECT_TRUE(OI.dominates(LoadInstY, LoadInstZ));
64 }
1313 FunctionComparator.cpp
1414 IntegerDivision.cpp
1515 Local.cpp
16 OrderedInstructions.cpp
1716 SSAUpdaterBulk.cpp
1817 ValueMapperTest.cpp
1918 )
+0
-65
unittests/Transforms/Utils/OrderedInstructions.cpp less more
None //===- OrderedInstructions.cpp - Unit tests for OrderedInstructions ------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Transforms/Utils/OrderedInstructions.h"
10 #include "llvm/IR/BasicBlock.h"
11 #include "llvm/IR/Dominators.h"
12 #include "llvm/IR/IRBuilder.h"
13 #include "llvm/IR/Instructions.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Module.h"
16 #include "gtest/gtest.h"
17
18 using namespace llvm;
19
20 /// Check intra-basicblock and inter-basicblock dominance using
21 /// OrderedInstruction.
22 TEST(OrderedInstructionsTest, DominanceTest) {
23 LLVMContext Ctx;
24 Module M("test", Ctx);
25 IRBuilder<> B(Ctx);
26 FunctionType *FTy =
27 FunctionType::get(Type::getVoidTy(Ctx), {B.getInt8PtrTy()}, false);
28 Function *F = cast(M.getOrInsertFunction("f", FTy));
29
30 // Create the function as follow and check for dominance relation.
31 //
32 // test():
33 // bbx:
34 // loadx;
35 // loady;
36 // bby:
37 // loadz;
38 // return;
39 //
40 // More specifically, check for loadx -> (dominates) loady,
41 // loady -> loadx and loady -> loadz.
42 //
43 // Create BBX with 2 loads.
44 BasicBlock *BBX = BasicBlock::Create(Ctx, "bbx", F);
45 B.SetInsertPoint(BBX);
46 Argument *PointerArg = &*F->arg_begin();
47 LoadInst *LoadInstX = B.CreateLoad(PointerArg);
48 LoadInst *LoadInstY = B.CreateLoad(PointerArg);
49
50 // Create BBY with 1 load.
51 BasicBlock *BBY = BasicBlock::Create(Ctx, "bby", F);
52 B.SetInsertPoint(BBY);
53 LoadInst *LoadInstZ = B.CreateLoad(PointerArg);
54 B.CreateRet(LoadInstZ);
55 std::unique_ptr DT(new DominatorTree(*F));
56 OrderedInstructions OI(&*DT);
57
58 // Intra-BB dominance test.
59 EXPECT_TRUE(OI.dominates(LoadInstX, LoadInstY));
60 EXPECT_FALSE(OI.dominates(LoadInstY, LoadInstX));
61
62 // Inter-BB dominance test.
63 EXPECT_TRUE(OI.dominates(LoadInstY, LoadInstZ));
64 }