31#define DEBUG_TYPE "flatten-cfg"
149 BranchInst *PBI = dyn_cast<BranchInst>(Pred->getTerminator());
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;
253 auto *CI = dyn_cast<CmpInst>(BI->getCondition());
260 CI->setPredicate(ICmpInst::getInversePredicate(Predicate));
261 BI->swapSuccessors();
273 PHI = dyn_cast<PHINode>(PS2->
begin());
280 bool Iteration =
true;
288 FirstCondBlock->
splice(FirstCondBlock->
end(), CB);
303 if (CB == LastCondBlock)
311 LLVM_DEBUG(
dbgs() <<
"Use parallel and/or in:\n" << *FirstCondBlock);
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->isNoAlias(&*iter1, &*BI))
411 if (isa<PHINode>(BB->
front()))
436 if (FirstEntryBlock == SecondEntryBlock)
440 bool InvertCond2 =
false;
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);
525 if (FlattenParallelAndOr(BB, Builder) || MergeIfRegion(BB, Builder))
534 return FlattenCFGOpt(AA).run(BB);
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
const Instruction & front() const
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const Function * getParent() const
Return the enclosing method, or null if none.
SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
InstListType::iterator iterator
Instruction iterators...
LLVMContext & getContext() const
Get the context in which this basic block lives.
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.
const Instruction & back() const
Conditional or Unconditional Branch instruction.
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 * CreateOr(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.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
An instruction for storing to memory.
This function has undefined behavior.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
LLVM Value Representation.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
This is an optimization pass for GlobalISel generic memory operations.
pred_iterator pred_end(BasicBlock *BB)
bool FlattenCFG(BasicBlock *BB, AAResults *AA=nullptr)
This function is used to flatten a CFG.
BranchInst * GetIfCondition(BasicBlock *BB, BasicBlock *&IfTrue, BasicBlock *&IfFalse)
Check whether BB is the merge point of a if-region.
pred_iterator pred_begin(BasicBlock *BB)
void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.