1 //===- Transform/Utils/CodeMoverUtils.h - CodeMover Utils -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This family of functions determine movements are safe on basic blocks, and 10 // instructions contained within a function. 11 // 12 // Please note that this is work in progress, and the functionality is not 13 // ready for broader production use. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_TRANSFORMS_UTILS_CODEMOVERUTILS_H 18 #define LLVM_TRANSFORMS_UTILS_CODEMOVERUTILS_H 19 20 namespace llvm { 21 22 class BasicBlock; 23 class DependenceInfo; 24 class DominatorTree; 25 class Instruction; 26 class PostDominatorTree; 27 28 /// Return true if \p I0 and \p I1 are control flow equivalent. 29 /// Two instructions are control flow equivalent if their basic blocks are 30 /// control flow equivalent. 31 bool isControlFlowEquivalent(const Instruction &I0, const Instruction &I1, 32 const DominatorTree &DT, 33 const PostDominatorTree &PDT); 34 35 /// Return true if \p BB0 and \p BB1 are control flow equivalent. 36 /// Two basic blocks are control flow equivalent if when one executes, the other 37 /// is guaranteed to execute. 38 bool isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1, 39 const DominatorTree &DT, 40 const PostDominatorTree &PDT); 41 42 /// Return true if \p I can be safely moved before \p InsertPoint. 43 bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint, 44 DominatorTree &DT, 45 const PostDominatorTree *PDT = nullptr, 46 DependenceInfo *DI = nullptr, 47 bool CheckForEntireBlock = false); 48 49 /// Return true if all instructions (except the terminator) in \p BB can be 50 /// safely moved before \p InsertPoint. 51 bool isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint, 52 DominatorTree &DT, 53 const PostDominatorTree *PDT = nullptr, 54 DependenceInfo *DI = nullptr); 55 56 /// Move instructions, in an order-preserving manner, from \p FromBB to the 57 /// beginning of \p ToBB when proven safe. 58 void moveInstructionsToTheBeginning(BasicBlock &FromBB, BasicBlock &ToBB, 59 DominatorTree &DT, 60 const PostDominatorTree &PDT, 61 DependenceInfo &DI); 62 63 /// Move instructions, in an order-preserving manner, from \p FromBB to the end 64 /// of \p ToBB when proven safe. 65 void moveInstructionsToTheEnd(BasicBlock &FromBB, BasicBlock &ToBB, 66 DominatorTree &DT, const PostDominatorTree &PDT, 67 DependenceInfo &DI); 68 69 /// In case that two BBs \p ThisBlock and \p OtherBlock are control flow 70 /// equivalent but they do not strictly dominate and post-dominate each 71 /// other, we determine if \p ThisBlock is reached after \p OtherBlock 72 /// in the control flow. 73 bool nonStrictlyPostDominate(const BasicBlock *ThisBlock, 74 const BasicBlock *OtherBlock, 75 const DominatorTree *DT, 76 const PostDominatorTree *PDT); 77 78 // Check if I0 is reached before I1 in the control flow. 79 bool isReachedBefore(const Instruction *I0, const Instruction *I1, 80 const DominatorTree *DT, const PostDominatorTree *PDT); 81 82 } // end namespace llvm 83 84 #endif // LLVM_TRANSFORMS_UTILS_CODEMOVERUTILS_H 85