1*9880d681SAndroid Build Coastguard Worker //===- llvm/unittest/IR/LegacyPassManager.cpp - Legacy PassManager tests --===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This unit test exercises the legacy pass manager infrastructure. We use the 11*9880d681SAndroid Build Coastguard Worker // old names as well to ensure that the source-level compatibility is preserved 12*9880d681SAndroid Build Coastguard Worker // where possible. 13*9880d681SAndroid Build Coastguard Worker // 14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LegacyPassManager.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/CallGraphSCCPass.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopInfo.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/LoopPass.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/BasicBlock.h" 21*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/CallingConv.h" 22*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h" 23*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h" 24*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h" 25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h" 26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h" 27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRPrintingPasses.h" 28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InlineAsm.h" 29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h" 30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h" 31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h" 32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Verifier.h" 33*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h" 34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h" 35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h" 36*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h" 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker using namespace llvm; 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker namespace llvm { 41*9880d681SAndroid Build Coastguard Worker void initializeModuleNDMPass(PassRegistry&); 42*9880d681SAndroid Build Coastguard Worker void initializeFPassPass(PassRegistry&); 43*9880d681SAndroid Build Coastguard Worker void initializeCGPassPass(PassRegistry&); 44*9880d681SAndroid Build Coastguard Worker void initializeLPassPass(PassRegistry&); 45*9880d681SAndroid Build Coastguard Worker void initializeBPassPass(PassRegistry&); 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Worker namespace { 48*9880d681SAndroid Build Coastguard Worker // ND = no deps 49*9880d681SAndroid Build Coastguard Worker // NM = no modifications 50*9880d681SAndroid Build Coastguard Worker struct ModuleNDNM: public ModulePass { 51*9880d681SAndroid Build Coastguard Worker public: 52*9880d681SAndroid Build Coastguard Worker static char run; 53*9880d681SAndroid Build Coastguard Worker static char ID; ModuleNDNMllvm::__anonab286df50111::ModuleNDNM54*9880d681SAndroid Build Coastguard Worker ModuleNDNM() : ModulePass(ID) { } runOnModulellvm::__anonab286df50111::ModuleNDNM55*9880d681SAndroid Build Coastguard Worker bool runOnModule(Module &M) override { 56*9880d681SAndroid Build Coastguard Worker run++; 57*9880d681SAndroid Build Coastguard Worker return false; 58*9880d681SAndroid Build Coastguard Worker } getAnalysisUsagellvm::__anonab286df50111::ModuleNDNM59*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 60*9880d681SAndroid Build Coastguard Worker AU.setPreservesAll(); 61*9880d681SAndroid Build Coastguard Worker } 62*9880d681SAndroid Build Coastguard Worker }; 63*9880d681SAndroid Build Coastguard Worker char ModuleNDNM::ID=0; 64*9880d681SAndroid Build Coastguard Worker char ModuleNDNM::run=0; 65*9880d681SAndroid Build Coastguard Worker 66*9880d681SAndroid Build Coastguard Worker struct ModuleNDM : public ModulePass { 67*9880d681SAndroid Build Coastguard Worker public: 68*9880d681SAndroid Build Coastguard Worker static char run; 69*9880d681SAndroid Build Coastguard Worker static char ID; ModuleNDMllvm::__anonab286df50111::ModuleNDM70*9880d681SAndroid Build Coastguard Worker ModuleNDM() : ModulePass(ID) {} runOnModulellvm::__anonab286df50111::ModuleNDM71*9880d681SAndroid Build Coastguard Worker bool runOnModule(Module &M) override { 72*9880d681SAndroid Build Coastguard Worker run++; 73*9880d681SAndroid Build Coastguard Worker return true; 74*9880d681SAndroid Build Coastguard Worker } 75*9880d681SAndroid Build Coastguard Worker }; 76*9880d681SAndroid Build Coastguard Worker char ModuleNDM::ID=0; 77*9880d681SAndroid Build Coastguard Worker char ModuleNDM::run=0; 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker struct ModuleNDM2 : public ModulePass { 80*9880d681SAndroid Build Coastguard Worker public: 81*9880d681SAndroid Build Coastguard Worker static char run; 82*9880d681SAndroid Build Coastguard Worker static char ID; ModuleNDM2llvm::__anonab286df50111::ModuleNDM283*9880d681SAndroid Build Coastguard Worker ModuleNDM2() : ModulePass(ID) {} runOnModulellvm::__anonab286df50111::ModuleNDM284*9880d681SAndroid Build Coastguard Worker bool runOnModule(Module &M) override { 85*9880d681SAndroid Build Coastguard Worker run++; 86*9880d681SAndroid Build Coastguard Worker return true; 87*9880d681SAndroid Build Coastguard Worker } 88*9880d681SAndroid Build Coastguard Worker }; 89*9880d681SAndroid Build Coastguard Worker char ModuleNDM2::ID=0; 90*9880d681SAndroid Build Coastguard Worker char ModuleNDM2::run=0; 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker struct ModuleDNM : public ModulePass { 93*9880d681SAndroid Build Coastguard Worker public: 94*9880d681SAndroid Build Coastguard Worker static char run; 95*9880d681SAndroid Build Coastguard Worker static char ID; ModuleDNMllvm::__anonab286df50111::ModuleDNM96*9880d681SAndroid Build Coastguard Worker ModuleDNM() : ModulePass(ID) { 97*9880d681SAndroid Build Coastguard Worker initializeModuleNDMPass(*PassRegistry::getPassRegistry()); 98*9880d681SAndroid Build Coastguard Worker } runOnModulellvm::__anonab286df50111::ModuleDNM99*9880d681SAndroid Build Coastguard Worker bool runOnModule(Module &M) override { 100*9880d681SAndroid Build Coastguard Worker run++; 101*9880d681SAndroid Build Coastguard Worker return false; 102*9880d681SAndroid Build Coastguard Worker } getAnalysisUsagellvm::__anonab286df50111::ModuleDNM103*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 104*9880d681SAndroid Build Coastguard Worker AU.addRequired<ModuleNDM>(); 105*9880d681SAndroid Build Coastguard Worker AU.setPreservesAll(); 106*9880d681SAndroid Build Coastguard Worker } 107*9880d681SAndroid Build Coastguard Worker }; 108*9880d681SAndroid Build Coastguard Worker char ModuleDNM::ID=0; 109*9880d681SAndroid Build Coastguard Worker char ModuleDNM::run=0; 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker template<typename P> 112*9880d681SAndroid Build Coastguard Worker struct PassTestBase : public P { 113*9880d681SAndroid Build Coastguard Worker protected: 114*9880d681SAndroid Build Coastguard Worker static int runc; 115*9880d681SAndroid Build Coastguard Worker static bool initialized; 116*9880d681SAndroid Build Coastguard Worker static bool finalized; 117*9880d681SAndroid Build Coastguard Worker int allocated; runllvm::__anonab286df50111::PassTestBase118*9880d681SAndroid Build Coastguard Worker void run() { 119*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(initialized); 120*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(finalized); 121*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, allocated); 122*9880d681SAndroid Build Coastguard Worker allocated++; 123*9880d681SAndroid Build Coastguard Worker runc++; 124*9880d681SAndroid Build Coastguard Worker } 125*9880d681SAndroid Build Coastguard Worker public: 126*9880d681SAndroid Build Coastguard Worker static char ID; finishedOKllvm::__anonab286df50111::PassTestBase127*9880d681SAndroid Build Coastguard Worker static void finishedOK(int run) { 128*9880d681SAndroid Build Coastguard Worker EXPECT_GT(runc, 0); 129*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(initialized); 130*9880d681SAndroid Build Coastguard Worker EXPECT_TRUE(finalized); 131*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(run, runc); 132*9880d681SAndroid Build Coastguard Worker } PassTestBasellvm::__anonab286df50111::PassTestBase133*9880d681SAndroid Build Coastguard Worker PassTestBase() : P(ID), allocated(0) { 134*9880d681SAndroid Build Coastguard Worker initialized = false; 135*9880d681SAndroid Build Coastguard Worker finalized = false; 136*9880d681SAndroid Build Coastguard Worker runc = 0; 137*9880d681SAndroid Build Coastguard Worker } 138*9880d681SAndroid Build Coastguard Worker releaseMemoryllvm::__anonab286df50111::PassTestBase139*9880d681SAndroid Build Coastguard Worker void releaseMemory() override { 140*9880d681SAndroid Build Coastguard Worker EXPECT_GT(runc, 0); 141*9880d681SAndroid Build Coastguard Worker EXPECT_GT(allocated, 0); 142*9880d681SAndroid Build Coastguard Worker allocated--; 143*9880d681SAndroid Build Coastguard Worker } 144*9880d681SAndroid Build Coastguard Worker }; 145*9880d681SAndroid Build Coastguard Worker template<typename P> char PassTestBase<P>::ID; 146*9880d681SAndroid Build Coastguard Worker template<typename P> int PassTestBase<P>::runc; 147*9880d681SAndroid Build Coastguard Worker template<typename P> bool PassTestBase<P>::initialized; 148*9880d681SAndroid Build Coastguard Worker template<typename P> bool PassTestBase<P>::finalized; 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker template<typename T, typename P> 151*9880d681SAndroid Build Coastguard Worker struct PassTest : public PassTestBase<P> { 152*9880d681SAndroid Build Coastguard Worker public: 153*9880d681SAndroid Build Coastguard Worker #ifndef _MSC_VER // MSVC complains that Pass is not base class. 154*9880d681SAndroid Build Coastguard Worker using llvm::Pass::doInitialization; 155*9880d681SAndroid Build Coastguard Worker using llvm::Pass::doFinalization; 156*9880d681SAndroid Build Coastguard Worker #endif doInitializationllvm::__anonab286df50111::PassTest157*9880d681SAndroid Build Coastguard Worker bool doInitialization(T &t) override { 158*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(PassTestBase<P>::initialized); 159*9880d681SAndroid Build Coastguard Worker PassTestBase<P>::initialized = true; 160*9880d681SAndroid Build Coastguard Worker return false; 161*9880d681SAndroid Build Coastguard Worker } doFinalizationllvm::__anonab286df50111::PassTest162*9880d681SAndroid Build Coastguard Worker bool doFinalization(T &t) override { 163*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(PassTestBase<P>::finalized); 164*9880d681SAndroid Build Coastguard Worker PassTestBase<P>::finalized = true; 165*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, PassTestBase<P>::allocated); 166*9880d681SAndroid Build Coastguard Worker return false; 167*9880d681SAndroid Build Coastguard Worker } 168*9880d681SAndroid Build Coastguard Worker }; 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker struct CGPass : public PassTest<CallGraph, CallGraphSCCPass> { 171*9880d681SAndroid Build Coastguard Worker public: CGPassllvm::__anonab286df50111::CGPass172*9880d681SAndroid Build Coastguard Worker CGPass() { 173*9880d681SAndroid Build Coastguard Worker initializeCGPassPass(*PassRegistry::getPassRegistry()); 174*9880d681SAndroid Build Coastguard Worker } runOnSCCllvm::__anonab286df50111::CGPass175*9880d681SAndroid Build Coastguard Worker bool runOnSCC(CallGraphSCC &SCMM) override { 176*9880d681SAndroid Build Coastguard Worker run(); 177*9880d681SAndroid Build Coastguard Worker return false; 178*9880d681SAndroid Build Coastguard Worker } 179*9880d681SAndroid Build Coastguard Worker }; 180*9880d681SAndroid Build Coastguard Worker 181*9880d681SAndroid Build Coastguard Worker struct FPass : public PassTest<Module, FunctionPass> { 182*9880d681SAndroid Build Coastguard Worker public: runOnFunctionllvm::__anonab286df50111::FPass183*9880d681SAndroid Build Coastguard Worker bool runOnFunction(Function &F) override { 184*9880d681SAndroid Build Coastguard Worker // FIXME: PR4112 185*9880d681SAndroid Build Coastguard Worker // EXPECT_TRUE(getAnalysisIfAvailable<DataLayout>()); 186*9880d681SAndroid Build Coastguard Worker run(); 187*9880d681SAndroid Build Coastguard Worker return false; 188*9880d681SAndroid Build Coastguard Worker } 189*9880d681SAndroid Build Coastguard Worker }; 190*9880d681SAndroid Build Coastguard Worker 191*9880d681SAndroid Build Coastguard Worker struct LPass : public PassTestBase<LoopPass> { 192*9880d681SAndroid Build Coastguard Worker private: 193*9880d681SAndroid Build Coastguard Worker static int initcount; 194*9880d681SAndroid Build Coastguard Worker static int fincount; 195*9880d681SAndroid Build Coastguard Worker public: LPassllvm::__anonab286df50111::LPass196*9880d681SAndroid Build Coastguard Worker LPass() { 197*9880d681SAndroid Build Coastguard Worker initializeLPassPass(*PassRegistry::getPassRegistry()); 198*9880d681SAndroid Build Coastguard Worker initcount = 0; fincount=0; 199*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(initialized); 200*9880d681SAndroid Build Coastguard Worker } finishedOKllvm::__anonab286df50111::LPass201*9880d681SAndroid Build Coastguard Worker static void finishedOK(int run, int finalized) { 202*9880d681SAndroid Build Coastguard Worker PassTestBase<LoopPass>::finishedOK(run); 203*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(run, initcount); 204*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(finalized, fincount); 205*9880d681SAndroid Build Coastguard Worker } 206*9880d681SAndroid Build Coastguard Worker using llvm::Pass::doInitialization; 207*9880d681SAndroid Build Coastguard Worker using llvm::Pass::doFinalization; doInitializationllvm::__anonab286df50111::LPass208*9880d681SAndroid Build Coastguard Worker bool doInitialization(Loop* L, LPPassManager &LPM) override { 209*9880d681SAndroid Build Coastguard Worker initialized = true; 210*9880d681SAndroid Build Coastguard Worker initcount++; 211*9880d681SAndroid Build Coastguard Worker return false; 212*9880d681SAndroid Build Coastguard Worker } runOnLoopllvm::__anonab286df50111::LPass213*9880d681SAndroid Build Coastguard Worker bool runOnLoop(Loop *L, LPPassManager &LPM) override { 214*9880d681SAndroid Build Coastguard Worker run(); 215*9880d681SAndroid Build Coastguard Worker return false; 216*9880d681SAndroid Build Coastguard Worker } doFinalizationllvm::__anonab286df50111::LPass217*9880d681SAndroid Build Coastguard Worker bool doFinalization() override { 218*9880d681SAndroid Build Coastguard Worker fincount++; 219*9880d681SAndroid Build Coastguard Worker finalized = true; 220*9880d681SAndroid Build Coastguard Worker return false; 221*9880d681SAndroid Build Coastguard Worker } 222*9880d681SAndroid Build Coastguard Worker }; 223*9880d681SAndroid Build Coastguard Worker int LPass::initcount=0; 224*9880d681SAndroid Build Coastguard Worker int LPass::fincount=0; 225*9880d681SAndroid Build Coastguard Worker 226*9880d681SAndroid Build Coastguard Worker struct BPass : public PassTestBase<BasicBlockPass> { 227*9880d681SAndroid Build Coastguard Worker private: 228*9880d681SAndroid Build Coastguard Worker static int inited; 229*9880d681SAndroid Build Coastguard Worker static int fin; 230*9880d681SAndroid Build Coastguard Worker public: finishedOKllvm::__anonab286df50111::BPass231*9880d681SAndroid Build Coastguard Worker static void finishedOK(int run, int N) { 232*9880d681SAndroid Build Coastguard Worker PassTestBase<BasicBlockPass>::finishedOK(run); 233*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(inited, N); 234*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(fin, N); 235*9880d681SAndroid Build Coastguard Worker } BPassllvm::__anonab286df50111::BPass236*9880d681SAndroid Build Coastguard Worker BPass() { 237*9880d681SAndroid Build Coastguard Worker inited = 0; 238*9880d681SAndroid Build Coastguard Worker fin = 0; 239*9880d681SAndroid Build Coastguard Worker } doInitializationllvm::__anonab286df50111::BPass240*9880d681SAndroid Build Coastguard Worker bool doInitialization(Module &M) override { 241*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(initialized); 242*9880d681SAndroid Build Coastguard Worker initialized = true; 243*9880d681SAndroid Build Coastguard Worker return false; 244*9880d681SAndroid Build Coastguard Worker } doInitializationllvm::__anonab286df50111::BPass245*9880d681SAndroid Build Coastguard Worker bool doInitialization(Function &F) override { 246*9880d681SAndroid Build Coastguard Worker inited++; 247*9880d681SAndroid Build Coastguard Worker return false; 248*9880d681SAndroid Build Coastguard Worker } runOnBasicBlockllvm::__anonab286df50111::BPass249*9880d681SAndroid Build Coastguard Worker bool runOnBasicBlock(BasicBlock &BB) override { 250*9880d681SAndroid Build Coastguard Worker run(); 251*9880d681SAndroid Build Coastguard Worker return false; 252*9880d681SAndroid Build Coastguard Worker } doFinalizationllvm::__anonab286df50111::BPass253*9880d681SAndroid Build Coastguard Worker bool doFinalization(Function &F) override { 254*9880d681SAndroid Build Coastguard Worker fin++; 255*9880d681SAndroid Build Coastguard Worker return false; 256*9880d681SAndroid Build Coastguard Worker } doFinalizationllvm::__anonab286df50111::BPass257*9880d681SAndroid Build Coastguard Worker bool doFinalization(Module &M) override { 258*9880d681SAndroid Build Coastguard Worker EXPECT_FALSE(finalized); 259*9880d681SAndroid Build Coastguard Worker finalized = true; 260*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(0, allocated); 261*9880d681SAndroid Build Coastguard Worker return false; 262*9880d681SAndroid Build Coastguard Worker } 263*9880d681SAndroid Build Coastguard Worker }; 264*9880d681SAndroid Build Coastguard Worker int BPass::inited=0; 265*9880d681SAndroid Build Coastguard Worker int BPass::fin=0; 266*9880d681SAndroid Build Coastguard Worker 267*9880d681SAndroid Build Coastguard Worker struct OnTheFlyTest: public ModulePass { 268*9880d681SAndroid Build Coastguard Worker public: 269*9880d681SAndroid Build Coastguard Worker static char ID; OnTheFlyTestllvm::__anonab286df50111::OnTheFlyTest270*9880d681SAndroid Build Coastguard Worker OnTheFlyTest() : ModulePass(ID) { 271*9880d681SAndroid Build Coastguard Worker initializeFPassPass(*PassRegistry::getPassRegistry()); 272*9880d681SAndroid Build Coastguard Worker } runOnModulellvm::__anonab286df50111::OnTheFlyTest273*9880d681SAndroid Build Coastguard Worker bool runOnModule(Module &M) override { 274*9880d681SAndroid Build Coastguard Worker for (Module::iterator I=M.begin(),E=M.end(); I != E; ++I) { 275*9880d681SAndroid Build Coastguard Worker Function &F = *I; 276*9880d681SAndroid Build Coastguard Worker { 277*9880d681SAndroid Build Coastguard Worker SCOPED_TRACE("Running on the fly function pass"); 278*9880d681SAndroid Build Coastguard Worker getAnalysis<FPass>(F); 279*9880d681SAndroid Build Coastguard Worker } 280*9880d681SAndroid Build Coastguard Worker } 281*9880d681SAndroid Build Coastguard Worker return false; 282*9880d681SAndroid Build Coastguard Worker } getAnalysisUsagellvm::__anonab286df50111::OnTheFlyTest283*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 284*9880d681SAndroid Build Coastguard Worker AU.addRequired<FPass>(); 285*9880d681SAndroid Build Coastguard Worker } 286*9880d681SAndroid Build Coastguard Worker }; 287*9880d681SAndroid Build Coastguard Worker char OnTheFlyTest::ID=0; 288*9880d681SAndroid Build Coastguard Worker TEST(PassManager,RunOnce)289*9880d681SAndroid Build Coastguard Worker TEST(PassManager, RunOnce) { 290*9880d681SAndroid Build Coastguard Worker LLVMContext Context; 291*9880d681SAndroid Build Coastguard Worker Module M("test-once", Context); 292*9880d681SAndroid Build Coastguard Worker struct ModuleNDNM *mNDNM = new ModuleNDNM(); 293*9880d681SAndroid Build Coastguard Worker struct ModuleDNM *mDNM = new ModuleDNM(); 294*9880d681SAndroid Build Coastguard Worker struct ModuleNDM *mNDM = new ModuleNDM(); 295*9880d681SAndroid Build Coastguard Worker struct ModuleNDM2 *mNDM2 = new ModuleNDM2(); 296*9880d681SAndroid Build Coastguard Worker 297*9880d681SAndroid Build Coastguard Worker mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0; 298*9880d681SAndroid Build Coastguard Worker 299*9880d681SAndroid Build Coastguard Worker legacy::PassManager Passes; 300*9880d681SAndroid Build Coastguard Worker Passes.add(mNDM2); 301*9880d681SAndroid Build Coastguard Worker Passes.add(mNDM); 302*9880d681SAndroid Build Coastguard Worker Passes.add(mNDNM); 303*9880d681SAndroid Build Coastguard Worker Passes.add(mDNM); 304*9880d681SAndroid Build Coastguard Worker 305*9880d681SAndroid Build Coastguard Worker Passes.run(M); 306*9880d681SAndroid Build Coastguard Worker // each pass must be run exactly once, since nothing invalidates them 307*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mNDM->run); 308*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mNDNM->run); 309*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mDNM->run); 310*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mNDM2->run); 311*9880d681SAndroid Build Coastguard Worker } 312*9880d681SAndroid Build Coastguard Worker TEST(PassManager,ReRun)313*9880d681SAndroid Build Coastguard Worker TEST(PassManager, ReRun) { 314*9880d681SAndroid Build Coastguard Worker LLVMContext Context; 315*9880d681SAndroid Build Coastguard Worker Module M("test-rerun", Context); 316*9880d681SAndroid Build Coastguard Worker struct ModuleNDNM *mNDNM = new ModuleNDNM(); 317*9880d681SAndroid Build Coastguard Worker struct ModuleDNM *mDNM = new ModuleDNM(); 318*9880d681SAndroid Build Coastguard Worker struct ModuleNDM *mNDM = new ModuleNDM(); 319*9880d681SAndroid Build Coastguard Worker struct ModuleNDM2 *mNDM2 = new ModuleNDM2(); 320*9880d681SAndroid Build Coastguard Worker 321*9880d681SAndroid Build Coastguard Worker mNDM->run = mNDNM->run = mDNM->run = mNDM2->run = 0; 322*9880d681SAndroid Build Coastguard Worker 323*9880d681SAndroid Build Coastguard Worker legacy::PassManager Passes; 324*9880d681SAndroid Build Coastguard Worker Passes.add(mNDM); 325*9880d681SAndroid Build Coastguard Worker Passes.add(mNDNM); 326*9880d681SAndroid Build Coastguard Worker Passes.add(mNDM2);// invalidates mNDM needed by mDNM 327*9880d681SAndroid Build Coastguard Worker Passes.add(mDNM); 328*9880d681SAndroid Build Coastguard Worker 329*9880d681SAndroid Build Coastguard Worker Passes.run(M); 330*9880d681SAndroid Build Coastguard Worker // Some passes must be rerun because a pass that modified the 331*9880d681SAndroid Build Coastguard Worker // module/function was run in between 332*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(2, mNDM->run); 333*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mNDNM->run); 334*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mNDM2->run); 335*9880d681SAndroid Build Coastguard Worker EXPECT_EQ(1, mDNM->run); 336*9880d681SAndroid Build Coastguard Worker } 337*9880d681SAndroid Build Coastguard Worker 338*9880d681SAndroid Build Coastguard Worker Module *makeLLVMModule(LLVMContext &Context); 339*9880d681SAndroid Build Coastguard Worker 340*9880d681SAndroid Build Coastguard Worker template<typename T> MemoryTestHelper(int run)341*9880d681SAndroid Build Coastguard Worker void MemoryTestHelper(int run) { 342*9880d681SAndroid Build Coastguard Worker LLVMContext Context; 343*9880d681SAndroid Build Coastguard Worker std::unique_ptr<Module> M(makeLLVMModule(Context)); 344*9880d681SAndroid Build Coastguard Worker T *P = new T(); 345*9880d681SAndroid Build Coastguard Worker legacy::PassManager Passes; 346*9880d681SAndroid Build Coastguard Worker Passes.add(P); 347*9880d681SAndroid Build Coastguard Worker Passes.run(*M); 348*9880d681SAndroid Build Coastguard Worker T::finishedOK(run); 349*9880d681SAndroid Build Coastguard Worker } 350*9880d681SAndroid Build Coastguard Worker 351*9880d681SAndroid Build Coastguard Worker template<typename T> MemoryTestHelper(int run,int N)352*9880d681SAndroid Build Coastguard Worker void MemoryTestHelper(int run, int N) { 353*9880d681SAndroid Build Coastguard Worker LLVMContext Context; 354*9880d681SAndroid Build Coastguard Worker Module *M = makeLLVMModule(Context); 355*9880d681SAndroid Build Coastguard Worker T *P = new T(); 356*9880d681SAndroid Build Coastguard Worker legacy::PassManager Passes; 357*9880d681SAndroid Build Coastguard Worker Passes.add(P); 358*9880d681SAndroid Build Coastguard Worker Passes.run(*M); 359*9880d681SAndroid Build Coastguard Worker T::finishedOK(run, N); 360*9880d681SAndroid Build Coastguard Worker delete M; 361*9880d681SAndroid Build Coastguard Worker } 362*9880d681SAndroid Build Coastguard Worker TEST(PassManager,Memory)363*9880d681SAndroid Build Coastguard Worker TEST(PassManager, Memory) { 364*9880d681SAndroid Build Coastguard Worker // SCC#1: test1->test2->test3->test1 365*9880d681SAndroid Build Coastguard Worker // SCC#2: test4 366*9880d681SAndroid Build Coastguard Worker // SCC#3: indirect call node 367*9880d681SAndroid Build Coastguard Worker { 368*9880d681SAndroid Build Coastguard Worker SCOPED_TRACE("Callgraph pass"); 369*9880d681SAndroid Build Coastguard Worker MemoryTestHelper<CGPass>(3); 370*9880d681SAndroid Build Coastguard Worker } 371*9880d681SAndroid Build Coastguard Worker 372*9880d681SAndroid Build Coastguard Worker { 373*9880d681SAndroid Build Coastguard Worker SCOPED_TRACE("Function pass"); 374*9880d681SAndroid Build Coastguard Worker MemoryTestHelper<FPass>(4);// 4 functions 375*9880d681SAndroid Build Coastguard Worker } 376*9880d681SAndroid Build Coastguard Worker 377*9880d681SAndroid Build Coastguard Worker { 378*9880d681SAndroid Build Coastguard Worker SCOPED_TRACE("Loop pass"); 379*9880d681SAndroid Build Coastguard Worker MemoryTestHelper<LPass>(2, 1); //2 loops, 1 function 380*9880d681SAndroid Build Coastguard Worker } 381*9880d681SAndroid Build Coastguard Worker { 382*9880d681SAndroid Build Coastguard Worker SCOPED_TRACE("Basic block pass"); 383*9880d681SAndroid Build Coastguard Worker MemoryTestHelper<BPass>(7, 4); //9 basic blocks 384*9880d681SAndroid Build Coastguard Worker } 385*9880d681SAndroid Build Coastguard Worker 386*9880d681SAndroid Build Coastguard Worker } 387*9880d681SAndroid Build Coastguard Worker TEST(PassManager,MemoryOnTheFly)388*9880d681SAndroid Build Coastguard Worker TEST(PassManager, MemoryOnTheFly) { 389*9880d681SAndroid Build Coastguard Worker LLVMContext Context; 390*9880d681SAndroid Build Coastguard Worker Module *M = makeLLVMModule(Context); 391*9880d681SAndroid Build Coastguard Worker { 392*9880d681SAndroid Build Coastguard Worker SCOPED_TRACE("Running OnTheFlyTest"); 393*9880d681SAndroid Build Coastguard Worker struct OnTheFlyTest *O = new OnTheFlyTest(); 394*9880d681SAndroid Build Coastguard Worker legacy::PassManager Passes; 395*9880d681SAndroid Build Coastguard Worker Passes.add(O); 396*9880d681SAndroid Build Coastguard Worker Passes.run(*M); 397*9880d681SAndroid Build Coastguard Worker 398*9880d681SAndroid Build Coastguard Worker FPass::finishedOK(4); 399*9880d681SAndroid Build Coastguard Worker } 400*9880d681SAndroid Build Coastguard Worker delete M; 401*9880d681SAndroid Build Coastguard Worker } 402*9880d681SAndroid Build Coastguard Worker makeLLVMModule(LLVMContext & Context)403*9880d681SAndroid Build Coastguard Worker Module *makeLLVMModule(LLVMContext &Context) { 404*9880d681SAndroid Build Coastguard Worker // Module Construction 405*9880d681SAndroid Build Coastguard Worker Module *mod = new Module("test-mem", Context); 406*9880d681SAndroid Build Coastguard Worker mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" 407*9880d681SAndroid Build Coastguard Worker "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-" 408*9880d681SAndroid Build Coastguard Worker "a:0:64-s:64:64-f80:128:128"); 409*9880d681SAndroid Build Coastguard Worker mod->setTargetTriple("x86_64-unknown-linux-gnu"); 410*9880d681SAndroid Build Coastguard Worker 411*9880d681SAndroid Build Coastguard Worker // Type Definitions 412*9880d681SAndroid Build Coastguard Worker std::vector<Type*>FuncTy_0_args; 413*9880d681SAndroid Build Coastguard Worker FunctionType *FuncTy_0 = FunctionType::get( 414*9880d681SAndroid Build Coastguard Worker /*Result=*/IntegerType::get(Context, 32), 415*9880d681SAndroid Build Coastguard Worker /*Params=*/FuncTy_0_args, 416*9880d681SAndroid Build Coastguard Worker /*isVarArg=*/false); 417*9880d681SAndroid Build Coastguard Worker 418*9880d681SAndroid Build Coastguard Worker std::vector<Type*>FuncTy_2_args; 419*9880d681SAndroid Build Coastguard Worker FuncTy_2_args.push_back(IntegerType::get(Context, 1)); 420*9880d681SAndroid Build Coastguard Worker FunctionType *FuncTy_2 = FunctionType::get( 421*9880d681SAndroid Build Coastguard Worker /*Result=*/Type::getVoidTy(Context), 422*9880d681SAndroid Build Coastguard Worker /*Params=*/FuncTy_2_args, 423*9880d681SAndroid Build Coastguard Worker /*isVarArg=*/false); 424*9880d681SAndroid Build Coastguard Worker 425*9880d681SAndroid Build Coastguard Worker // Function Declarations 426*9880d681SAndroid Build Coastguard Worker 427*9880d681SAndroid Build Coastguard Worker Function* func_test1 = Function::Create( 428*9880d681SAndroid Build Coastguard Worker /*Type=*/FuncTy_0, 429*9880d681SAndroid Build Coastguard Worker /*Linkage=*/GlobalValue::ExternalLinkage, 430*9880d681SAndroid Build Coastguard Worker /*Name=*/"test1", mod); 431*9880d681SAndroid Build Coastguard Worker func_test1->setCallingConv(CallingConv::C); 432*9880d681SAndroid Build Coastguard Worker AttributeSet func_test1_PAL; 433*9880d681SAndroid Build Coastguard Worker func_test1->setAttributes(func_test1_PAL); 434*9880d681SAndroid Build Coastguard Worker 435*9880d681SAndroid Build Coastguard Worker Function* func_test2 = Function::Create( 436*9880d681SAndroid Build Coastguard Worker /*Type=*/FuncTy_0, 437*9880d681SAndroid Build Coastguard Worker /*Linkage=*/GlobalValue::ExternalLinkage, 438*9880d681SAndroid Build Coastguard Worker /*Name=*/"test2", mod); 439*9880d681SAndroid Build Coastguard Worker func_test2->setCallingConv(CallingConv::C); 440*9880d681SAndroid Build Coastguard Worker AttributeSet func_test2_PAL; 441*9880d681SAndroid Build Coastguard Worker func_test2->setAttributes(func_test2_PAL); 442*9880d681SAndroid Build Coastguard Worker 443*9880d681SAndroid Build Coastguard Worker Function* func_test3 = Function::Create( 444*9880d681SAndroid Build Coastguard Worker /*Type=*/FuncTy_0, 445*9880d681SAndroid Build Coastguard Worker /*Linkage=*/GlobalValue::ExternalLinkage, 446*9880d681SAndroid Build Coastguard Worker /*Name=*/"test3", mod); 447*9880d681SAndroid Build Coastguard Worker func_test3->setCallingConv(CallingConv::C); 448*9880d681SAndroid Build Coastguard Worker AttributeSet func_test3_PAL; 449*9880d681SAndroid Build Coastguard Worker func_test3->setAttributes(func_test3_PAL); 450*9880d681SAndroid Build Coastguard Worker 451*9880d681SAndroid Build Coastguard Worker Function* func_test4 = Function::Create( 452*9880d681SAndroid Build Coastguard Worker /*Type=*/FuncTy_2, 453*9880d681SAndroid Build Coastguard Worker /*Linkage=*/GlobalValue::ExternalLinkage, 454*9880d681SAndroid Build Coastguard Worker /*Name=*/"test4", mod); 455*9880d681SAndroid Build Coastguard Worker func_test4->setCallingConv(CallingConv::C); 456*9880d681SAndroid Build Coastguard Worker AttributeSet func_test4_PAL; 457*9880d681SAndroid Build Coastguard Worker func_test4->setAttributes(func_test4_PAL); 458*9880d681SAndroid Build Coastguard Worker 459*9880d681SAndroid Build Coastguard Worker // Global Variable Declarations 460*9880d681SAndroid Build Coastguard Worker 461*9880d681SAndroid Build Coastguard Worker 462*9880d681SAndroid Build Coastguard Worker // Constant Definitions 463*9880d681SAndroid Build Coastguard Worker 464*9880d681SAndroid Build Coastguard Worker // Global Variable Definitions 465*9880d681SAndroid Build Coastguard Worker 466*9880d681SAndroid Build Coastguard Worker // Function Definitions 467*9880d681SAndroid Build Coastguard Worker 468*9880d681SAndroid Build Coastguard Worker // Function: test1 (func_test1) 469*9880d681SAndroid Build Coastguard Worker { 470*9880d681SAndroid Build Coastguard Worker 471*9880d681SAndroid Build Coastguard Worker BasicBlock *label_entry = 472*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "entry", func_test1, nullptr); 473*9880d681SAndroid Build Coastguard Worker 474*9880d681SAndroid Build Coastguard Worker // Block entry (label_entry) 475*9880d681SAndroid Build Coastguard Worker CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry); 476*9880d681SAndroid Build Coastguard Worker int32_3->setCallingConv(CallingConv::C); 477*9880d681SAndroid Build Coastguard Worker int32_3->setTailCall(false);AttributeSet int32_3_PAL; 478*9880d681SAndroid Build Coastguard Worker int32_3->setAttributes(int32_3_PAL); 479*9880d681SAndroid Build Coastguard Worker 480*9880d681SAndroid Build Coastguard Worker ReturnInst::Create(Context, int32_3, label_entry); 481*9880d681SAndroid Build Coastguard Worker } 482*9880d681SAndroid Build Coastguard Worker 483*9880d681SAndroid Build Coastguard Worker // Function: test2 (func_test2) 484*9880d681SAndroid Build Coastguard Worker { 485*9880d681SAndroid Build Coastguard Worker 486*9880d681SAndroid Build Coastguard Worker BasicBlock *label_entry_5 = 487*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "entry", func_test2, nullptr); 488*9880d681SAndroid Build Coastguard Worker 489*9880d681SAndroid Build Coastguard Worker // Block entry (label_entry_5) 490*9880d681SAndroid Build Coastguard Worker CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5); 491*9880d681SAndroid Build Coastguard Worker int32_6->setCallingConv(CallingConv::C); 492*9880d681SAndroid Build Coastguard Worker int32_6->setTailCall(false);AttributeSet int32_6_PAL; 493*9880d681SAndroid Build Coastguard Worker int32_6->setAttributes(int32_6_PAL); 494*9880d681SAndroid Build Coastguard Worker 495*9880d681SAndroid Build Coastguard Worker ReturnInst::Create(Context, int32_6, label_entry_5); 496*9880d681SAndroid Build Coastguard Worker } 497*9880d681SAndroid Build Coastguard Worker 498*9880d681SAndroid Build Coastguard Worker // Function: test3 (func_test3) 499*9880d681SAndroid Build Coastguard Worker { 500*9880d681SAndroid Build Coastguard Worker 501*9880d681SAndroid Build Coastguard Worker BasicBlock *label_entry_8 = 502*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "entry", func_test3, nullptr); 503*9880d681SAndroid Build Coastguard Worker 504*9880d681SAndroid Build Coastguard Worker // Block entry (label_entry_8) 505*9880d681SAndroid Build Coastguard Worker CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8); 506*9880d681SAndroid Build Coastguard Worker int32_9->setCallingConv(CallingConv::C); 507*9880d681SAndroid Build Coastguard Worker int32_9->setTailCall(false);AttributeSet int32_9_PAL; 508*9880d681SAndroid Build Coastguard Worker int32_9->setAttributes(int32_9_PAL); 509*9880d681SAndroid Build Coastguard Worker 510*9880d681SAndroid Build Coastguard Worker ReturnInst::Create(Context, int32_9, label_entry_8); 511*9880d681SAndroid Build Coastguard Worker } 512*9880d681SAndroid Build Coastguard Worker 513*9880d681SAndroid Build Coastguard Worker // Function: test4 (func_test4) 514*9880d681SAndroid Build Coastguard Worker { 515*9880d681SAndroid Build Coastguard Worker Function::arg_iterator args = func_test4->arg_begin(); 516*9880d681SAndroid Build Coastguard Worker Value *int1_f = &*args++; 517*9880d681SAndroid Build Coastguard Worker int1_f->setName("f"); 518*9880d681SAndroid Build Coastguard Worker 519*9880d681SAndroid Build Coastguard Worker BasicBlock *label_entry_11 = 520*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "entry", func_test4, nullptr); 521*9880d681SAndroid Build Coastguard Worker BasicBlock *label_bb = 522*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "bb", func_test4, nullptr); 523*9880d681SAndroid Build Coastguard Worker BasicBlock *label_bb1 = 524*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "bb1", func_test4, nullptr); 525*9880d681SAndroid Build Coastguard Worker BasicBlock *label_return = 526*9880d681SAndroid Build Coastguard Worker BasicBlock::Create(Context, "return", func_test4, nullptr); 527*9880d681SAndroid Build Coastguard Worker 528*9880d681SAndroid Build Coastguard Worker // Block entry (label_entry_11) 529*9880d681SAndroid Build Coastguard Worker BranchInst::Create(label_bb, label_entry_11); 530*9880d681SAndroid Build Coastguard Worker 531*9880d681SAndroid Build Coastguard Worker // Block bb (label_bb) 532*9880d681SAndroid Build Coastguard Worker BranchInst::Create(label_bb, label_bb1, int1_f, label_bb); 533*9880d681SAndroid Build Coastguard Worker 534*9880d681SAndroid Build Coastguard Worker // Block bb1 (label_bb1) 535*9880d681SAndroid Build Coastguard Worker BranchInst::Create(label_bb1, label_return, int1_f, label_bb1); 536*9880d681SAndroid Build Coastguard Worker 537*9880d681SAndroid Build Coastguard Worker // Block return (label_return) 538*9880d681SAndroid Build Coastguard Worker ReturnInst::Create(Context, label_return); 539*9880d681SAndroid Build Coastguard Worker } 540*9880d681SAndroid Build Coastguard Worker return mod; 541*9880d681SAndroid Build Coastguard Worker } 542*9880d681SAndroid Build Coastguard Worker 543*9880d681SAndroid Build Coastguard Worker } 544*9880d681SAndroid Build Coastguard Worker } 545*9880d681SAndroid Build Coastguard Worker 546*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(ModuleNDM, "mndm", "mndm", false, false) 547*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(CGPass, "cgp","cgp", false, false) 548*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 549*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(CGPass, "cgp","cgp", false, false) 550*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(FPass, "fp","fp", false, false) 551*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(LPass, "lp","lp", false, false) 552*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) 553*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(LPass, "lp","lp", false, false) 554*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(BPass, "bp","bp", false, false) 555