31#define DEBUG_TYPE "flattencfg"
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))
432 if (FirstEntryBlock == SecondEntryBlock)
436 bool InvertCond2 =
false;
438 if (IfFalse1 == FirstEntryBlock) {
441 CombineOp = BinaryOperator::Or;
442 if (IfFalse2 != SecondEntryBlock) {
443 if (IfTrue2 != SecondEntryBlock)
450 if (!CompareIfRegionBlock(IfTrue1, IfTrue2, SecondEntryBlock))
452 }
else if (IfTrue1 == FirstEntryBlock) {
455 CombineOp = BinaryOperator::And;
456 if (IfTrue2 != SecondEntryBlock) {
457 if (IfFalse2 != SecondEntryBlock)
464 if (!CompareIfRegionBlock(IfFalse1, IfFalse2, SecondEntryBlock))
483 FirstEntryBlock->
splice(FirstEntryBlock->
end(), SecondEntryBlock);
494 Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt);
498 for (
PHINode &Phi : Succ->phis()) {
499 for (
unsigned i = 0, e =
Phi.getNumIncomingValues(); i != e; ++i) {
500 if (
Phi.getIncomingBlock(i) == SecondEntryBlock)
501 Phi.setIncomingBlock(i, FirstEntryBlock);
507 if (IfTrue1 != FirstEntryBlock) {
513 if (IfFalse1 != FirstEntryBlock) {
521 LLVM_DEBUG(
dbgs() <<
"If conditions merged into:\n" << *FirstEntryBlock);
531 if (FlattenParallelAndOr(BB, Builder) || MergeIfRegion(BB, Builder))
540 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
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const BasicBlock * getParent() const
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.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
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.
self_iterator getIterator()
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
NodeAddr< PhiNode * > Phi
This is an optimization pass for GlobalISel generic memory operations.
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.
auto successors(const MachineBasicBlock *BB)
Interval::pred_iterator pred_end(Interval *I)
void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
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.