117 lines · cpp
1//===- Mem2Reg.cpp - The -mem2reg pass, a wrapper around the Utils lib ----===//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 pass is a simple pass wrapper around the PromoteMemToReg function call10// exposed by the Utils library.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/Transforms/Utils/Mem2Reg.h"15#include "llvm/ADT/Statistic.h"16#include "llvm/Analysis/AssumptionCache.h"17#include "llvm/IR/BasicBlock.h"18#include "llvm/IR/Dominators.h"19#include "llvm/IR/Function.h"20#include "llvm/IR/Instructions.h"21#include "llvm/IR/PassManager.h"22#include "llvm/InitializePasses.h"23#include "llvm/Pass.h"24#include "llvm/Support/Casting.h"25#include "llvm/Transforms/Utils.h"26#include "llvm/Transforms/Utils/PromoteMemToReg.h"27#include <vector>28 29using namespace llvm;30 31#define DEBUG_TYPE "mem2reg"32 33STATISTIC(NumPromoted, "Number of alloca's promoted");34 35static bool promoteMemoryToRegister(Function &F, DominatorTree &DT,36 AssumptionCache &AC) {37 std::vector<AllocaInst *> Allocas;38 BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function39 bool Changed = false;40 41 while (true) {42 Allocas.clear();43 44 // Find allocas that are safe to promote, by looking at all instructions in45 // the entry node46 for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)47 if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?48 if (isAllocaPromotable(AI))49 Allocas.push_back(AI);50 51 if (Allocas.empty())52 break;53 54 PromoteMemToReg(Allocas, DT, &AC);55 NumPromoted += Allocas.size();56 Changed = true;57 }58 return Changed;59}60 61PreservedAnalyses PromotePass::run(Function &F, FunctionAnalysisManager &AM) {62 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);63 auto &AC = AM.getResult<AssumptionAnalysis>(F);64 if (!promoteMemoryToRegister(F, DT, AC))65 return PreservedAnalyses::all();66 67 PreservedAnalyses PA;68 PA.preserveSet<CFGAnalyses>();69 return PA;70}71 72namespace {73 74struct PromoteLegacyPass : public FunctionPass {75 // Pass identification, replacement for typeid76 static char ID;77 78 PromoteLegacyPass() : FunctionPass(ID) {79 initializePromoteLegacyPassPass(*PassRegistry::getPassRegistry());80 }81 82 // runOnFunction - To run this pass, first we calculate the alloca83 // instructions that are safe for promotion, then we promote each one.84 bool runOnFunction(Function &F) override {85 if (skipFunction(F))86 return false;87 88 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();89 AssumptionCache &AC =90 getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);91 return promoteMemoryToRegister(F, DT, AC);92 }93 94 void getAnalysisUsage(AnalysisUsage &AU) const override {95 AU.addRequired<AssumptionCacheTracker>();96 AU.addRequired<DominatorTreeWrapperPass>();97 AU.setPreservesCFG();98 }99};100 101} // end anonymous namespace102 103char PromoteLegacyPass::ID = 0;104 105INITIALIZE_PASS_BEGIN(PromoteLegacyPass, "mem2reg", "Promote Memory to "106 "Register",107 false, false)108INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)109INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)110INITIALIZE_PASS_END(PromoteLegacyPass, "mem2reg", "Promote Memory to Register",111 false, false)112 113// createPromoteMemoryToRegister - Provide an entry point to create this pass.114FunctionPass *llvm::createPromoteMemoryToRegisterPass() {115 return new PromoteLegacyPass();116}117