31#define DEBUG_TYPE "flatten-cfg"
148 for (BasicBlock *Pred : Preds) {
155 BasicBlock *PP = Pred->getSinglePredecessor();
163 if (UnCondBlock || !PP || !Preds.contains(PP) ||
164 Pred->hasAddressTaken())
179 if (PP && Preds.count(PP)) {
183 if (Pred->hasAddressTaken())
199 FirstCondBlock = Pred;
207 int CIdx = (PS1 == BB) ? 0 : 1;
211 else if (CIdx != Idx)
216 if (!Preds.contains(PS)) {
218 LastCondBlock = Pred;
224 LastCondBlock = Pred;
229 if (!FirstCondBlock || !LastCondBlock || (FirstCondBlock == LastCondBlock))
249 bool EverChanged =
false;
250 for (; CurrBlock != FirstCondBlock;
260 CI->setPredicate(ICmpInst::getInversePredicate(Predicate));
261 BI->swapSuccessors();
280 bool Iteration =
true;
281 IRBuilder<>::InsertPointGuard Guard(Builder);
288 FirstCondBlock->
splice(FirstCondBlock->
end(), CB);
303 if (CB == LastCondBlock)
311 LLVM_DEBUG(
dbgs() <<
"Use parallel and/or in:\n" << *FirstCondBlock);
320bool FlattenCFGOpt::CompareIfRegionBlock(BasicBlock *Block1, BasicBlock *Block2,
339 if (!iter1->isIdenticalTo(&*iter2))
344 if (iter1->mayHaveSideEffects()) {
347 if (!SI ||
SI->isVolatile())
353 if (iter1->mayReadFromMemory())
356 if (iter1->mayWriteToMemory()) {
358 if (BI->mayReadFromMemory() || BI->mayWriteToMemory()) {
360 if (!AA || AA->
getModRefInfo(&*iter1, &*BI) != ModRefInfo::NoModRef)
409bool FlattenCFGOpt::MergeIfRegion(BasicBlock *BB,
IRBuilder<> &Builder) {
427 BranchInst *DomBI1 =
GetIfCondition(SecondEntryBlock, IfTrue1, IfFalse1);
436 if (FirstEntryBlock == SecondEntryBlock)
440 bool InvertCond2 =
false;
441 BinaryOperator::BinaryOps CombineOp;
442 if (IfFalse1 == FirstEntryBlock) {
445 CombineOp = BinaryOperator::Or;
446 if (IfFalse2 != SecondEntryBlock) {
447 if (IfTrue2 != SecondEntryBlock)
454 if (!CompareIfRegionBlock(IfTrue1, IfTrue2, SecondEntryBlock))
456 }
else if (IfTrue1 == FirstEntryBlock) {
459 CombineOp = BinaryOperator::And;
460 if (IfTrue2 != SecondEntryBlock) {
461 if (IfFalse2 != SecondEntryBlock)
468 if (!CompareIfRegionBlock(IfFalse1, IfFalse2, SecondEntryBlock))
487 FirstEntryBlock->
splice(FirstEntryBlock->
end(), SecondEntryBlock);
501 if (IfTrue1 != FirstEntryBlock) {
507 if (IfFalse1 != FirstEntryBlock) {
515 LLVM_DEBUG(
dbgs() <<
"If conditions merged into:\n" << *FirstEntryBlock);
519bool FlattenCFGOpt::run(BasicBlock *BB) {
525 if (FlattenParallelAndOr(BB, Builder) || MergeIfRegion(BB, Builder))
534 return FlattenCFGOpt(
AA).run(BB);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file defines the SmallPtrSet class.
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
Check whether or not an instruction may read or write the optionally specified memory location.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & back() const
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Instruction & front() const
LLVM_ABI SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
LLVM_ABI void dropAllReferences()
Cause all subinstructions to "let go" of all the references that said subinstructions are maintaining...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void splice(BasicBlock::iterator ToIt, BasicBlock *FromBB)
Transfer all instructions from FromBB to this basic block at ToIt.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Value * getCondition() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
BasicBlock::iterator GetInsertPoint() const
BasicBlock * GetInsertBlock() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI bool FlattenCFG(BasicBlock *BB, AAResults *AA=nullptr)
This function is used to flatten a CFG.
LLVM_ABI BranchInst * GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue, BasicBlock *&IfFalse)
Check whether BB is the merge point of a if-region.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr from_range_t from_range
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
LLVM_ABI void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.