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" 19using namespace llvm; 20 21#define DEBUG_TYPE "flattencfg" 22 23namespace { 24struct FlattenCFGPass : public FunctionPass { 25 static char ID; // Pass identification, replacement for typeid 26public: 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 36private: 37 AliasAnalysis *AA; 38}; 39} 40 41char FlattenCFGPass::ID = 0; 42INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, 43 false) 44INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) 45INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false, 46 false) 47 48// Public interface to the FlattenCFG pass 49FunctionPass *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. 53static 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 71bool 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