brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 1335665 Raw
107 lines · cpp
1//===- FlattenCFGPass.cpp - CFG Flatten Pass ----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements flattening of CFG.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/Analysis/AliasAnalysis.h"14#include "llvm/IR/PassManager.h"15#include "llvm/IR/ValueHandle.h"16#include "llvm/InitializePasses.h"17#include "llvm/Pass.h"18#include "llvm/Transforms/Scalar.h"19#include "llvm/Transforms/Scalar/FlattenCFG.h"20#include "llvm/Transforms/Utils/Local.h"21 22using namespace llvm;23 24#define DEBUG_TYPE "flatten-cfg"25 26namespace {27struct FlattenCFGLegacyPass : public FunctionPass {28  static char ID; // Pass identification, replacement for typeid29public:30  FlattenCFGLegacyPass() : FunctionPass(ID) {31    initializeFlattenCFGLegacyPassPass(*PassRegistry::getPassRegistry());32  }33  bool runOnFunction(Function &F) override;34 35  void getAnalysisUsage(AnalysisUsage &AU) const override {36    AU.addRequired<AAResultsWrapperPass>();37  }38 39private:40  AliasAnalysis *AA;41};42} // namespace43 44/// iterativelyFlattenCFG - Call FlattenCFG on all the blocks in the function,45/// iterating until no more changes are made.46static bool iterativelyFlattenCFG(Function &F, AliasAnalysis *AA) {47  bool Changed = false;48  bool LocalChange = true;49 50  // Use block handles instead of iterating over function blocks directly51  // to avoid using iterators invalidated by erasing blocks.52  std::vector<WeakVH> Blocks;53  Blocks.reserve(F.size());54  for (auto &BB : F)55    Blocks.push_back(&BB);56 57  while (LocalChange) {58    LocalChange = false;59 60    // Loop over all of the basic blocks and try to flatten them.61    for (WeakVH &BlockHandle : Blocks) {62      // Skip blocks erased by FlattenCFG.63      if (auto *BB = cast_or_null<BasicBlock>(BlockHandle))64        if (FlattenCFG(BB, AA))65          LocalChange = true;66    }67    Changed |= LocalChange;68  }69  return Changed;70}71 72char FlattenCFGLegacyPass::ID = 0;73 74INITIALIZE_PASS_BEGIN(FlattenCFGLegacyPass, "flattencfg", "Flatten the CFG",75                      false, false)76INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)77INITIALIZE_PASS_END(FlattenCFGLegacyPass, "flattencfg", "Flatten the CFG",78                    false, false)79 80// Public interface to the FlattenCFG pass81FunctionPass *llvm::createFlattenCFGPass() {82  return new FlattenCFGLegacyPass();83}84 85bool FlattenCFGLegacyPass::runOnFunction(Function &F) {86  AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();87  bool EverChanged = false;88  // iterativelyFlattenCFG can make some blocks dead.89  while (iterativelyFlattenCFG(F, AA)) {90    removeUnreachableBlocks(F);91    EverChanged = true;92  }93  return EverChanged;94}95 96PreservedAnalyses FlattenCFGPass::run(Function &F,97                                      FunctionAnalysisManager &AM) {98  bool EverChanged = false;99  AliasAnalysis *AA = &AM.getResult<AAManager>(F);100  // iterativelyFlattenCFG can make some blocks dead.101  while (iterativelyFlattenCFG(F, AA)) {102    removeUnreachableBlocks(F);103    EverChanged = true;104  }105  return EverChanged ? PreservedAnalyses::none() : PreservedAnalyses::all();106}107