#include "llvm/Transforms/Utils/CodeMoverUtils.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/DependenceAnalysis.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Dominators.h"
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(HasDependences,
"Cannot move across instructions that has memory dependences");
STATISTIC(MayThrowException, "Cannot move across instructions that may throw");
STATISTIC(NotControlFlowEquivalent,
"Instructions are not control flow equivalent");
STATISTIC(NotMovedPHINode, "Movement of PHINodes are not supported");
STATISTIC(NotMovedTerminator, "Movement of Terminator are not supported");
namespace {
ControlCondition;
#ifndef NDEBUG
raw_ostream &operator<<(raw_ostream &OS, const ControlCondition &C) {
OS << "[" << *C.getPointer() << ", " << (C.getInt() ? "true" : "false")
<< "]";
return OS;
}
#endif
class ControlConditions { … };
}
static bool domTreeLevelBefore(DominatorTree *DT, const Instruction *InstA,
const Instruction *InstB) { … }
const std::optional<ControlConditions>
ControlConditions::collectControlConditions(const BasicBlock &BB,
const BasicBlock &Dominator,
const DominatorTree &DT,
const PostDominatorTree &PDT,
unsigned MaxLookup) { … }
bool ControlConditions::addControlCondition(ControlCondition C) { … }
bool ControlConditions::isEquivalent(const ControlConditions &Other) const { … }
bool ControlConditions::isEquivalent(const ControlCondition &C1,
const ControlCondition &C2) { … }
bool ControlConditions::isEquivalent(const Value &V1, const Value &V2) { … }
bool ControlConditions::isInverse(const Value &V1, const Value &V2) { … }
bool llvm::isControlFlowEquivalent(const Instruction &I0, const Instruction &I1,
const DominatorTree &DT,
const PostDominatorTree &PDT) { … }
bool llvm::isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1,
const DominatorTree &DT,
const PostDominatorTree &PDT) { … }
static bool reportInvalidCandidate(const Instruction &I,
llvm::Statistic &Stat) { … }
static void
collectInstructionsInBetween(Instruction &StartInst, const Instruction &EndInst,
SmallPtrSetImpl<Instruction *> &InBetweenInsts) { … }
bool llvm::isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
DominatorTree &DT, const PostDominatorTree *PDT,
DependenceInfo *DI, bool CheckForEntireBlock) { … }
bool llvm::isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint,
DominatorTree &DT, const PostDominatorTree *PDT,
DependenceInfo *DI) { … }
void llvm::moveInstructionsToTheBeginning(BasicBlock &FromBB, BasicBlock &ToBB,
DominatorTree &DT,
const PostDominatorTree &PDT,
DependenceInfo &DI) { … }
void llvm::moveInstructionsToTheEnd(BasicBlock &FromBB, BasicBlock &ToBB,
DominatorTree &DT,
const PostDominatorTree &PDT,
DependenceInfo &DI) { … }
bool llvm::nonStrictlyPostDominate(const BasicBlock *ThisBlock,
const BasicBlock *OtherBlock,
const DominatorTree *DT,
const PostDominatorTree *PDT) { … }
bool llvm::isReachedBefore(const Instruction *I0, const Instruction *I1,
const DominatorTree *DT,
const PostDominatorTree *PDT) { … }