Line data Source code
1 : //===- OrderedBasicBlock.cpp --------------------------------- -*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file implements the OrderedBasicBlock class. OrderedBasicBlock
11 : // maintains an interface where clients can query if one instruction comes
12 : // before another in a BasicBlock. Since BasicBlock currently lacks a reliable
13 : // way to query relative position between instructions one can use
14 : // OrderedBasicBlock to do such queries. OrderedBasicBlock is lazily built on a
15 : // source BasicBlock and maintains an internal Instruction -> Position map. A
16 : // OrderedBasicBlock instance should be discarded whenever the source
17 : // BasicBlock changes.
18 : //
19 : // It's currently used by the CaptureTracker in order to find relative
20 : // positions of a pair of instructions inside a BasicBlock.
21 : //
22 : //===----------------------------------------------------------------------===//
23 :
24 : #include "llvm/Analysis/OrderedBasicBlock.h"
25 : #include "llvm/IR/Instruction.h"
26 : using namespace llvm;
27 :
28 5066230 : OrderedBasicBlock::OrderedBasicBlock(const BasicBlock *BasicB)
29 5066230 : : NextInstPos(0), BB(BasicB) {
30 5066230 : LastInstFound = BB->end();
31 5066230 : }
32 :
33 : /// Given no cached results, find if \p A comes before \p B in \p BB.
34 : /// Cache and number out instruction while walking \p BB.
35 87574 : bool OrderedBasicBlock::comesBefore(const Instruction *A,
36 : const Instruction *B) {
37 87574 : const Instruction *Inst = nullptr;
38 : assert(!(LastInstFound == BB->end() && NextInstPos != 0) &&
39 : "Instruction supposed to be in NumberedInsts");
40 : assert(A->getParent() == BB && "Instruction supposed to be in the block!");
41 : assert(B->getParent() == BB && "Instruction supposed to be in the block!");
42 :
43 : // Start the search with the instruction found in the last lookup round.
44 87574 : auto II = BB->begin();
45 : auto IE = BB->end();
46 87574 : if (LastInstFound != IE)
47 : II = std::next(LastInstFound);
48 :
49 : // Number all instructions up to the point where we find 'A' or 'B'.
50 1266521 : for (; II != IE; ++II) {
51 1266521 : Inst = cast<Instruction>(II);
52 1266521 : NumberedInsts[Inst] = NextInstPos++;
53 1266521 : if (Inst == A || Inst == B)
54 : break;
55 : }
56 :
57 : assert(II != IE && "Instruction not found?");
58 : assert((Inst == A || Inst == B) && "Should find A or B");
59 87574 : LastInstFound = II;
60 87574 : return Inst != B;
61 : }
62 :
63 : /// Find out whether \p A dominates \p B, meaning whether \p A
64 : /// comes before \p B in \p BB. This is a simplification that considers
65 : /// cached instruction positions and ignores other basic blocks, being
66 : /// only relevant to compare relative instructions positions inside \p BB.
67 123869 : bool OrderedBasicBlock::dominates(const Instruction *A, const Instruction *B) {
68 : assert(A->getParent() == B->getParent() &&
69 : "Instructions must be in the same basic block!");
70 : assert(A->getParent() == BB && "Instructions must be in the tracked block!");
71 :
72 : // First we lookup the instructions. If they don't exist, lookup will give us
73 : // back ::end(). If they both exist, we compare the numbers. Otherwise, if NA
74 : // exists and NB doesn't, it means NA must come before NB because we would
75 : // have numbered NB as well if it didn't. The same is true for NB. If it
76 : // exists, but NA does not, NA must come after it. If neither exist, we need
77 : // to number the block and cache the results (by calling comesBefore).
78 123869 : auto NAI = NumberedInsts.find(A);
79 123869 : auto NBI = NumberedInsts.find(B);
80 123869 : if (NAI != NumberedInsts.end() && NBI != NumberedInsts.end())
81 8740 : return NAI->second < NBI->second;
82 115129 : if (NAI != NumberedInsts.end())
83 : return true;
84 108671 : if (NBI != NumberedInsts.end())
85 : return false;
86 :
87 87574 : return comesBefore(A, B);
88 : }
|