LLVM API Documentation

FlattenCFGPass.cpp
Go to the documentation of this file.
00001 //===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements flattening of CFG.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Transforms/Scalar.h"
00015 #include "llvm/Analysis/AliasAnalysis.h"
00016 #include "llvm/IR/CFG.h"
00017 #include "llvm/Pass.h"
00018 #include "llvm/Transforms/Utils/Local.h"
00019 using namespace llvm;
00020 
00021 #define DEBUG_TYPE "flattencfg"
00022 
00023 namespace {
00024 struct FlattenCFGPass : public FunctionPass {
00025   static char ID; // Pass identification, replacement for typeid
00026 public:
00027   FlattenCFGPass() : FunctionPass(ID) {
00028     initializeFlattenCFGPassPass(*PassRegistry::getPassRegistry());
00029   }
00030   bool runOnFunction(Function &F) override;
00031 
00032   void getAnalysisUsage(AnalysisUsage &AU) const override {
00033     AU.addRequired<AliasAnalysis>();
00034   }
00035 
00036 private:
00037   AliasAnalysis *AA;
00038 };
00039 }
00040 
00041 char FlattenCFGPass::ID = 0;
00042 INITIALIZE_PASS_BEGIN(FlattenCFGPass, "flattencfg", "Flatten the CFG", false,
00043                       false)
00044 INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
00045 INITIALIZE_PASS_END(FlattenCFGPass, "flattencfg", "Flatten the CFG", false,
00046                     false)
00047 
00048 // Public interface to the FlattenCFG pass
00049 FunctionPass *llvm::createFlattenCFGPass() { return new FlattenCFGPass(); }
00050 
00051 /// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function,
00052 /// iterating until no more changes are made.
00053 static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {
00054   bool Changed = false;
00055   bool LocalChange = true;
00056   while (LocalChange) {
00057     LocalChange = false;
00058 
00059     // Loop over all of the basic blocks and remove them if they are unneeded...
00060     //
00061     for (Function::iterator BBIt = F.begin(); BBIt != F.end();) {
00062       if (FlattenCFG(BBIt++, AA)) {
00063         LocalChange = true;
00064       }
00065     }
00066     Changed |= LocalChange;
00067   }
00068   return Changed;
00069 }
00070 
00071 bool FlattenCFGPass::runOnFunction(Function &F) {
00072   AA = &getAnalysis<AliasAnalysis>();
00073   bool EverChanged = false;
00074   // iterativelyFlattenCFG can make some blocks dead.
00075   while (iterativelyFlattenCFG(F, AA)) {
00076     removeUnreachableBlocks(F);
00077     EverChanged = true;
00078   }
00079   return EverChanged;
00080 }