1 //===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements flattening of CFG. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/Scalar.h" 15 #include "llvm/Analysis/AliasAnalysis.h" 16 #include "llvm/IR/CFG.h" 17 #include "llvm/Pass.h" 18 #include "llvm/Transforms/Utils/Local.h" 19 using namespace llvm; 20 21 #define DEBUG_TYPE "flattencfg" 22 23 namespace { 24 struct FlattenCFGPass : public FunctionPass { 25 static char ID; // Pass identification, replacement for typeid 26 public: 27 FlattenCFGPass() : FunctionPass(ID) { 28 initializeFlattenCFGPassPass(*PassRegistry::getPassRegistry()); 29 } 30 bool runOnFunction(Function &F) override; 31 32 void getAnalysisUsage(AnalysisUsage &AU) const override { 33 AU.addRequired<AAResultsWrapperPass>(); 34 } 35 36 private: 37 AliasAnalysis *AA; 38 }; 39 } 40 41 char FlattenCFGPass::ID = 0; 42 INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, 43 false) 44 INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 45 INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, 46 false) 47 48 // Public interface to the FlattenCFG pass 49 FunctionPass *llvm::createFlattenCFGPass() { return new FlattenCFGPass(); } 50 51 /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function, 52 /// iterating until no more changes are made. 53 static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) { 54 bool Changed = false; 55 bool LocalChange = true; 56 while (LocalChange) { 57 LocalChange = false; 58 59 // Loop over all of the basic blocks and remove them if they are unneeded... 60 // 61 for (Function::iterator BBIt = F.begin(); BBIt != F.end();) { 62 if (FlattenCFG(&*BBIt++, AA)) { 63 LocalChange = true; 64 } 65 } 66 Changed |= LocalChange; 67 } 68 return Changed; 69 } 70 71 bool FlattenCFGPass::runOnFunction(Function &F) { 72 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); 73 bool EverChanged = false; 74 // iterativelyFlattenCFG can make some blocks dead. 75 while (iterativelyFlattenCFG(F, AA)) { 76 removeUnreachableBlocks(F); 77 EverChanged = true; 78 } 79 return EverChanged; 80 } 81