diff options
author | Devang Patel <dpatel@apple.com> | 2010-10-07 23:29:37 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2010-10-07 23:29:37 +0000 |
commit | d82e9e7d939bb4b4f4773e9853c061e14188f705 (patch) | |
tree | 8200536b4d4efdf5bb833c88ba2a42ec380f0433 | |
parent | 358cf1631a7e416745bd2cb428cef928969465b1 (diff) |
Remove LoopIndexSplit pass. It is neither maintained nor used by anyone.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116004 91177308-0d34-0410-b5e6-96231b3b80d8
43 files changed, 0 insertions, 3661 deletions
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 583536aa35..673f126660 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -124,7 +124,6 @@ void initializeLoaderPassPass(PassRegistry&); void initializeLoopDeletionPass(PassRegistry&); void initializeLoopDependenceAnalysisPass(PassRegistry&); void initializeLoopExtractorPass(PassRegistry&); -void initializeLoopIndexSplitPass(PassRegistry&); void initializeLoopInfoPass(PassRegistry&); void initializeLoopRotatePass(PassRegistry&); void initializeLoopSimplifyPass(PassRegistry&); diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index e0bde99097..7af4465b40 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -90,7 +90,6 @@ namespace { (void) llvm::createLoopUnrollPass(); (void) llvm::createLoopUnswitchPass(); (void) llvm::createLoopRotatePass(); - (void) llvm::createLoopIndexSplitPass(); (void) llvm::createLowerInvokePass(); (void) llvm::createLowerSetJmpPass(); (void) llvm::createLowerSwitchPass(); diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 0c35d7e01f..fa848459a7 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -131,13 +131,6 @@ Pass *createLoopRotatePass(); //===----------------------------------------------------------------------===// // -// LoopIndexSplit - This pass divides loop's iteration range by spliting loop -// such that each individual loop is executed efficiently. -// -Pass *createLoopIndexSplitPass(); - -//===----------------------------------------------------------------------===// -// // PromoteMemoryToRegister - This pass is used to promote memory references to // be register references. A simple example of the transformation performed by // this pass is: diff --git a/lib/Transforms/Scalar/LoopIndexSplit.cpp b/lib/Transforms/Scalar/LoopIndexSplit.cpp deleted file mode 100644 index f091a94bdd..0000000000 --- a/lib/Transforms/Scalar/LoopIndexSplit.cpp +++ /dev/null @@ -1,1270 +0,0 @@ -//===- LoopIndexSplit.cpp - Loop Index Splitting Pass ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements Loop Index Splitting Pass. This pass handles three -// kinds of loops. -// -// [1] A loop may be eliminated if the body is executed exactly once. -// For example, -// -// for (i = 0; i < N; ++i) { -// if (i == X) { -// body; -// } -// } -// -// is transformed to -// -// i = X; -// body; -// -// [2] A loop's iteration space may be shrunk if the loop body is executed -// for a proper sub-range of the loop's iteration space. For example, -// -// for (i = 0; i < N; ++i) { -// if (i > A && i < B) { -// ... -// } -// } -// -// is transformed to iterators from A to B, if A > 0 and B < N. -// -// [3] A loop may be split if the loop body is dominated by a branch. -// For example, -// -// for (i = LB; i < UB; ++i) { if (i < SV) A; else B; } -// -// is transformed into -// -// AEV = BSV = SV -// for (i = LB; i < min(UB, AEV); ++i) -// A; -// for (i = max(LB, BSV); i < UB; ++i); -// B; -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "loop-index-split" -#include "llvm/Transforms/Scalar.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/LLVMContext.h" -#include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/Dominators.h" -#include "llvm/Transforms/Utils/BasicBlockUtils.h" -#include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Transforms/Utils/Local.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/ADT/Statistic.h" - -using namespace llvm; - -STATISTIC(NumIndexSplit, "Number of loop index split"); -STATISTIC(NumIndexSplitRemoved, "Number of loops eliminated by loop index split"); -STATISTIC(NumRestrictBounds, "Number of loop iteration space restricted"); - -namespace { - - class LoopIndexSplit : public LoopPass { - public: - static char ID; // Pass ID, replacement for typeid - LoopIndexSplit() : LoopPass(ID) {} - - // Index split Loop L. Return true if loop is split. - bool runOnLoop(Loop *L, LPPassManager &LPM); - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addPreserved<ScalarEvolution>(); - AU.addRequiredID(LCSSAID); - AU.addPreservedID(LCSSAID); - AU.addRequired<LoopInfo>(); - AU.addPreserved<LoopInfo>(); - AU.addRequiredID(LoopSimplifyID); - AU.addPreservedID(LoopSimplifyID); - AU.addRequired<DominatorTree>(); - AU.addRequired<DominanceFrontier>(); - AU.addPreserved<DominatorTree>(); - AU.addPreserved<DominanceFrontier>(); - } - - private: - /// processOneIterationLoop -- Eliminate loop if loop body is executed - /// only once. For example, - /// for (i = 0; i < N; ++i) { - /// if ( i == X) { - /// ... - /// } - /// } - /// - bool processOneIterationLoop(); - - // -- Routines used by updateLoopIterationSpace(); - - /// updateLoopIterationSpace -- Update loop's iteration space if loop - /// body is executed for certain IV range only. For example, - /// - /// for (i = 0; i < N; ++i) { - /// if ( i > A && i < B) { - /// ... - /// } - /// } - /// is transformed to iterators from A to B, if A > 0 and B < N. - /// - bool updateLoopIterationSpace(); - - /// restrictLoopBound - Op dominates loop body. Op compares an IV based value - /// with a loop invariant value. Update loop's lower and upper bound based on - /// the loop invariant value. - bool restrictLoopBound(ICmpInst &Op); - - // --- Routines used by splitLoop(). --- / - - bool splitLoop(); - - /// removeBlocks - Remove basic block DeadBB and all blocks dominated by - /// DeadBB. This routine is used to remove split condition's dead branch, - /// dominated by DeadBB. LiveBB dominates split conidition's other branch. - void removeBlocks(BasicBlock *DeadBB, Loop *LP, BasicBlock *LiveBB); - - /// moveExitCondition - Move exit condition EC into split condition block. - void moveExitCondition(BasicBlock *CondBB, BasicBlock *ActiveBB, - BasicBlock *ExitBB, ICmpInst *EC, ICmpInst *SC, - PHINode *IV, Instruction *IVAdd, Loop *LP, - unsigned); - - /// updatePHINodes - CFG has been changed. - /// Before - /// - ExitBB's single predecessor was Latch - /// - Latch's second successor was Header - /// Now - /// - ExitBB's single predecessor was Header - /// - Latch's one and only successor was Header - /// - /// Update ExitBB PHINodes' to reflect this change. - void updatePHINodes(BasicBlock *ExitBB, BasicBlock *Latch, - BasicBlock *Header, - PHINode *IV, Instruction *IVIncrement, Loop *LP); - - // --- Utility routines --- / - - /// cleanBlock - A block is considered clean if all non terminal - /// instructions are either PHINodes or IV based values. - bool cleanBlock(BasicBlock *BB); - - /// IVisLT - If Op is comparing IV based value with an loop invariant and - /// IV based value is less than the loop invariant then return the loop - /// invariant. Otherwise return NULL. - Value * IVisLT(ICmpInst &Op); - - /// IVisLE - If Op is comparing IV based value with an loop invariant and - /// IV based value is less than or equal to the loop invariant then - /// return the loop invariant. Otherwise return NULL. - Value * IVisLE(ICmpInst &Op); - - /// IVisGT - If Op is comparing IV based value with an loop invariant and - /// IV based value is greater than the loop invariant then return the loop - /// invariant. Otherwise return NULL. - Value * IVisGT(ICmpInst &Op); - - /// IVisGE - If Op is comparing IV based value with an loop invariant and - /// IV based value is greater than or equal to the loop invariant then - /// return the loop invariant. Otherwise return NULL. - Value * IVisGE(ICmpInst &Op); - - private: - - // Current Loop information. - Loop *L; - LPPassManager *LPM; - LoopInfo *LI; - DominatorTree *DT; - DominanceFrontier *DF; - - PHINode *IndVar; - ICmpInst *ExitCondition; - ICmpInst *SplitCondition; - Value *IVStartValue; - Value *IVExitValue; - Instruction *IVIncrement; - SmallPtrSet<Value *, 4> IVBasedValues; - }; -} - -char LoopIndexSplit::ID = 0; -INITIALIZE_PASS(LoopIndexSplit, "loop-index-split", - "Index Split Loops", false, false) - -Pass *llvm::createLoopIndexSplitPass() { - return new LoopIndexSplit(); -} - -// Index split Loop L. Return true if loop is split. -bool LoopIndexSplit::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) { - L = IncomingLoop; - LPM = &LPM_Ref; - - // If LoopSimplify form is not available, stay out of trouble. - if (!L->isLoopSimplifyForm()) - return false; - - // FIXME - Nested loops make dominator info updates tricky. - if (!L->getSubLoops().empty()) - return false; - - DT = &getAnalysis<DominatorTree>(); - LI = &getAnalysis<LoopInfo>(); - DF = &getAnalysis<DominanceFrontier>(); - - // Initialize loop data. - IndVar = L->getCanonicalInductionVariable(); - if (!IndVar) return false; - - bool P1InLoop = L->contains(IndVar->getIncomingBlock(1)); - IVStartValue = IndVar->getIncomingValue(!P1InLoop); - IVIncrement = dyn_cast<Instruction>(IndVar->getIncomingValue(P1InLoop)); - if (!IVIncrement) return false; - - IVBasedValues.clear(); - IVBasedValues.insert(IndVar); - IVBasedValues.insert(IVIncrement); - for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); - I != E; ++I) - for(BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); - BI != BE; ++BI) { - if (BinaryOperator *BO = dyn_cast<BinaryOperator>(BI)) - if (BO != IVIncrement - && (BO->getOpcode() == Instruction::Add - || BO->getOpcode() == Instruction::Sub)) - if (IVBasedValues.count(BO->getOperand(0)) - && L->isLoopInvariant(BO->getOperand(1))) - IVBasedValues.insert(BO); - } - - // Reject loop if loop exit condition is not suitable. - BasicBlock *ExitingBlock = L->getExitingBlock(); - if (!ExitingBlock) - return false; - BranchInst *EBR = dyn_cast<BranchInst>(ExitingBlock->getTerminator()); - if (!EBR) return false; - ExitCondition = dyn_cast<ICmpInst>(EBR->getCondition()); - if (!ExitCondition) return false; - if (ExitingBlock != L->getLoopLatch()) return false; - IVExitValue = ExitCondition->getOperand(1); - if (!L->isLoopInvariant(IVExitValue)) - IVExitValue = ExitCondition->getOperand(0); - if (!L->isLoopInvariant(IVExitValue)) - return false; - if (!IVBasedValues.count( - ExitCondition->getOperand(IVExitValue == ExitCondition->getOperand(0)))) - return false; - - // If start value is more then exit value where induction variable - // increments by 1 then we are potentially dealing with an infinite loop. - // Do not index split this loop. - if (ConstantInt *SV = dyn_cast<ConstantInt>(IVStartValue)) - if (ConstantInt *EV = dyn_cast<ConstantInt>(IVExitValue)) - if (SV->getSExtValue() > EV->getSExtValue()) - return false; - - if (processOneIterationLoop()) - return true; - - if (updateLoopIterationSpace()) - return true; - - if (splitLoop()) - return true; - - return false; -} - -// --- Helper routines --- -// isUsedOutsideLoop - Returns true iff V is used outside the loop L. -static bool isUsedOutsideLoop(Value *V, Loop *L) { - for(Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI) - if (!L->contains(cast<Instruction>(*UI))) - return true; - return false; -} - -// Return V+1 -static Value *getPlusOne(Value *V, bool Sign, Instruction *InsertPt, - LLVMContext &Context) { - Constant *One = ConstantInt::get(V->getType(), 1, Sign); - return BinaryOperator::CreateAdd(V, One, "lsp", InsertPt); -} - -// Return V-1 -static Value *getMinusOne(Value *V, bool Sign, Instruction *InsertPt, - LLVMContext &Context) { - Constant *One = ConstantInt::get(V->getType(), 1, Sign); - return BinaryOperator::CreateSub(V, One, "lsp", InsertPt); -} - -// Return min(V1, V1) -static Value *getMin(Value *V1, Value *V2, bool Sign, Instruction *InsertPt) { - - Value *C = new ICmpInst(InsertPt, - Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - V1, V2, "lsp"); - return SelectInst::Create(C, V1, V2, "lsp", InsertPt); -} - -// Return max(V1, V2) -static Value *getMax(Value *V1, Value *V2, bool Sign, Instruction *InsertPt) { - - Value *C = new ICmpInst(InsertPt, - Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT, - V1, V2, "lsp"); - return SelectInst::Create(C, V2, V1, "lsp", InsertPt); -} - -/// processOneIterationLoop -- Eliminate loop if loop body is executed -/// only once. For example, -/// for (i = 0; i < N; ++i) { -/// if ( i == X) { -/// ... -/// } -/// } -/// -bool LoopIndexSplit::processOneIterationLoop() { - SplitCondition = NULL; - BasicBlock *Latch = L->getLoopLatch(); - BasicBlock *Header = L->getHeader(); - BranchInst *BR = dyn_cast<BranchInst>(Header->getTerminator()); - if (!BR) return false; - if (!isa<BranchInst>(Latch->getTerminator())) return false; - if (BR->isUnconditional()) return false; - SplitCondition = dyn_cast<ICmpInst>(BR->getCondition()); - if (!SplitCondition) return false; - if (SplitCondition == ExitCondition) return false; - if (SplitCondition->getPredicate() != ICmpInst::ICMP_EQ) return false; - if (BR->getOperand(1) != Latch) return false; - if (!IVBasedValues.count(SplitCondition->getOperand(0)) - && !IVBasedValues.count(SplitCondition->getOperand(1))) - return false; - - // If IV is used outside the loop then this loop traversal is required. - // FIXME: Calculate and use last IV value. - if (isUsedOutsideLoop(IVIncrement, L)) - return false; - - // If BR operands are not IV or not loop invariants then skip this loop. - Value *OPV = SplitCondition->getOperand(0); - Value *SplitValue = SplitCondition->getOperand(1); - if (!L->isLoopInvariant(SplitValue)) - std::swap(OPV, SplitValue); - if (!L->isLoopInvariant(SplitValue)) - return false; - Instruction *OPI = dyn_cast<Instruction>(OPV); - if (!OPI) - return false; - if (OPI->getParent() != Header || isUsedOutsideLoop(OPI, L)) - return false; - Value *StartValue = IVStartValue; - Value *ExitValue = IVExitValue;; - - if (OPV != IndVar) { - // If BR operand is IV based then use this operand to calculate - // effective conditions for loop body. - BinaryOperator *BOPV = dyn_cast<BinaryOperator>(OPV); - if (!BOPV) - return false; - if (BOPV->getOpcode() != Instruction::Add) - return false; - StartValue = BinaryOperator::CreateAdd(OPV, StartValue, "" , BR); - ExitValue = BinaryOperator::CreateAdd(OPV, ExitValue, "" , BR); - } - - if (!cleanBlock(Header)) - return false; - - if (!cleanBlock(Latch)) - return false; - - // If the merge point for BR is not loop latch then skip this loop. - if (BR->getSuccessor(0) != Latch) { - DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); - assert (DF0 != DF->end() && "Unable to find dominance frontier"); - if (!DF0->second.count(Latch)) - return false; - } - - if (BR->getSuccessor(1) != Latch) { - DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); - assert (DF1 != DF->end() && "Unable to find dominance frontier"); - if (!DF1->second.count(Latch)) - return false; - } - - // Now, Current loop L contains compare instruction - // that compares induction variable, IndVar, against loop invariant. And - // entire (i.e. meaningful) loop body is dominated by this compare - // instruction. In such case eliminate - // loop structure surrounding this loop body. For example, - // for (int i = start; i < end; ++i) { - // if ( i == somevalue) { - // loop_body - // } - // } - // can be transformed into - // if (somevalue >= start && somevalue < end) { - // i = somevalue; - // loop_body - // } - - // Replace index variable with split value in loop body. Loop body is executed - // only when index variable is equal to split value. - IndVar->replaceAllUsesWith(SplitValue); - - // Replace split condition in header. - // Transform - // SplitCondition : icmp eq i32 IndVar, SplitValue - // into - // c1 = icmp uge i32 SplitValue, StartValue - // c2 = icmp ult i32 SplitValue, ExitValue - // and i32 c1, c2 - Instruction *C1 = new ICmpInst(BR, ExitCondition->isSigned() ? - ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE, - SplitValue, StartValue, "lisplit"); - - CmpInst::Predicate C2P = ExitCondition->getPredicate(); - BranchInst *LatchBR = cast<BranchInst>(Latch->getTerminator()); - if (LatchBR->getOperand(1) != Header) - C2P = CmpInst::getInversePredicate(C2P); - Instruction *C2 = new ICmpInst(BR, C2P, SplitValue, ExitValue, "lisplit"); - Instruction *NSplitCond = BinaryOperator::CreateAnd(C1, C2, "lisplit", BR); - - SplitCondition->replaceAllUsesWith(NSplitCond); - SplitCondition->eraseFromParent(); - - // Remove Latch to Header edge. - BasicBlock *LatchSucc = NULL; - Header->removePredecessor(Latch); - for (succ_iterator SI = succ_begin(Latch), E = succ_end(Latch); - SI != E; ++SI) { - if (Header != *SI) - LatchSucc = *SI; - } - - // Clean up latch block. - Value *LatchBRCond = LatchBR->getCondition(); - LatchBR->setUnconditionalDest(LatchSucc); - RecursivelyDeleteTriviallyDeadInstructions(LatchBRCond); - - LPM->deleteLoopFromQueue(L); - - // Update Dominator Info. - // Only CFG change done is to remove Latch to Header edge. This - // does not change dominator tree because Latch did not dominate - // Header. - if (DF) { - DominanceFrontier::iterator HeaderDF = DF->find(Header); - if (HeaderDF != DF->end()) - DF->removeFromFrontier(HeaderDF, Header); - - DominanceFrontier::iterator LatchDF = DF->find(Latch); - if (LatchDF != DF->end()) - DF->removeFromFrontier(LatchDF, Header); - } - - ++NumIndexSplitRemoved; - return true; -} - -/// restrictLoopBound - Op dominates loop body. Op compares an IV based value -/// with a loop invariant value. Update loop's lower and upper bound based on -/// the loop invariant value. -bool LoopIndexSplit::restrictLoopBound(ICmpInst &Op) { - bool Sign = Op.isSigned(); - Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); - - if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { - BranchInst *EBR = - cast<BranchInst>(ExitCondition->getParent()->getTerminator()); - ExitCondition->setPredicate(ExitCondition->getInversePredicate()); - BasicBlock *T = EBR->getSuccessor(0); - EBR->setSuccessor(0, EBR->getSuccessor(1)); - EBR->setSuccessor(1, T); - } - - LLVMContext &Context = Op.getContext(); - - // New upper and lower bounds. - Value *NLB = NULL; - Value *NUB = NULL; - if (Value *V = IVisLT(Op)) { - // Restrict upper bound. - if (IVisLE(*ExitCondition)) - V = getMinusOne(V, Sign, PHTerm, Context); - NUB = getMin(V, IVExitValue, Sign, PHTerm); - } else if (Value *V = IVisLE(Op)) { - // Restrict upper bound. - if (IVisLT(*ExitCondition)) - V = getPlusOne(V, Sign, PHTerm, Context); - NUB = getMin(V, IVExitValue, Sign, PHTerm); - } else if (Value *V = IVisGT(Op)) { - // Restrict lower bound. - V = getPlusOne(V, Sign, PHTerm, Context); - NLB = getMax(V, IVStartValue, Sign, PHTerm); - } else if (Value *V = IVisGE(Op)) - // Restrict lower bound. - NLB = getMax(V, IVStartValue, Sign, PHTerm); - - if (!NLB && !NUB) - return false; - - if (NLB) { - unsigned i = IndVar->getBasicBlockIndex(L->getLoopPreheader()); - IndVar->setIncomingValue(i, NLB); - } - - if (NUB) { - unsigned i = (ExitCondition->getOperand(0) != IVExitValue); - ExitCondition->setOperand(i, NUB); - } - return true; -} - -/// updateLoopIterationSpace -- Update loop's iteration space if loop -/// body is executed for certain IV range only. For example, -/// -/// for (i = 0; i < N; ++i) { -/// if ( i > A && i < B) { -/// ... -/// } -/// } -/// is transformed to iterators from A to B, if A > 0 and B < N. -/// -bool LoopIndexSplit::updateLoopIterationSpace() { - SplitCondition = NULL; - if (ExitCondition->getPredicate() == ICmpInst::ICMP_NE - || ExitCondition->getPredicate() == ICmpInst::ICMP_EQ) - return false; - BasicBlock *Latch = L->getLoopLatch(); - BasicBlock *Header = L->getHeader(); - BranchInst *BR = dyn_cast<BranchInst>(Header->getTerminator()); - if (!BR) return false; - if (!isa<BranchInst>(Latch->getTerminator())) return false; - if (BR->isUnconditional()) return false; - BinaryOperator *AND = dyn_cast<BinaryOperator>(BR->getCondition()); - if (!AND) return false; - if (AND->getOpcode() != Instruction::And) return false; - ICmpInst *Op0 = dyn_cast<ICmpInst>(AND->getOperand(0)); - ICmpInst *Op1 = dyn_cast<ICmpInst>(AND->getOperand(1)); - if (!Op0 || !Op1) - return false; - IVBasedValues.insert(AND); - IVBasedValues.insert(Op0); - IVBasedValues.insert(Op1); - if (!cleanBlock(Header)) return false; - BasicBlock *ExitingBlock = ExitCondition->getParent(); - if (!cleanBlock(ExitingBlock)) return false; - - // If the merge point for BR is not loop latch then skip this loop. - if (BR->getSuccessor(0) != Latch) { - DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); - assert (DF0 != DF->end() && "Unable to find dominance frontier"); - if (!DF0->second.count(Latch)) - return false; - } - - if (BR->getSuccessor(1) != Latch) { - DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); - assert (DF1 != DF->end() && "Unable to find dominance frontier"); - if (!DF1->second.count(Latch)) - return false; - } - - // Verify that loop exiting block has only two predecessor, where one pred - // is split condition block. The other predecessor will become exiting block's - // dominator after CFG is updated. TODO : Handle CFG's wh |