1*9880d681SAndroid Build Coastguard Worker //===-- AllocaHoisting.cpp - Hoist allocas to the entry block --*- C++ -*-===// 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 // Hoist the alloca instructions in the non-entry blocks to the entry blocks. 11*9880d681SAndroid Build Coastguard Worker // 12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker #include "NVPTXAllocaHoisting.h" 15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionAnalysis.h" 16*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/StackProtector.h" 17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h" 18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h" 20*9880d681SAndroid Build Coastguard Worker using namespace llvm; 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker namespace { 23*9880d681SAndroid Build Coastguard Worker // Hoisting the alloca instructions in the non-entry blocks to the entry 24*9880d681SAndroid Build Coastguard Worker // block. 25*9880d681SAndroid Build Coastguard Worker class NVPTXAllocaHoisting : public FunctionPass { 26*9880d681SAndroid Build Coastguard Worker public: 27*9880d681SAndroid Build Coastguard Worker static char ID; // Pass ID NVPTXAllocaHoisting()28*9880d681SAndroid Build Coastguard Worker NVPTXAllocaHoisting() : FunctionPass(ID) {} 29*9880d681SAndroid Build Coastguard Worker getAnalysisUsage(AnalysisUsage & AU) const30*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override { 31*9880d681SAndroid Build Coastguard Worker AU.addPreserved<MachineFunctionAnalysis>(); 32*9880d681SAndroid Build Coastguard Worker AU.addPreserved<StackProtector>(); 33*9880d681SAndroid Build Coastguard Worker } 34*9880d681SAndroid Build Coastguard Worker getPassName() const35*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override { 36*9880d681SAndroid Build Coastguard Worker return "NVPTX specific alloca hoisting"; 37*9880d681SAndroid Build Coastguard Worker } 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker bool runOnFunction(Function &function) override; 40*9880d681SAndroid Build Coastguard Worker }; 41*9880d681SAndroid Build Coastguard Worker } // namespace 42*9880d681SAndroid Build Coastguard Worker runOnFunction(Function & function)43*9880d681SAndroid Build Coastguard Workerbool NVPTXAllocaHoisting::runOnFunction(Function &function) { 44*9880d681SAndroid Build Coastguard Worker bool functionModified = false; 45*9880d681SAndroid Build Coastguard Worker Function::iterator I = function.begin(); 46*9880d681SAndroid Build Coastguard Worker TerminatorInst *firstTerminatorInst = (I++)->getTerminator(); 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker for (Function::iterator E = function.end(); I != E; ++I) { 49*9880d681SAndroid Build Coastguard Worker for (BasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE;) { 50*9880d681SAndroid Build Coastguard Worker AllocaInst *allocaInst = dyn_cast<AllocaInst>(BI++); 51*9880d681SAndroid Build Coastguard Worker if (allocaInst && isa<ConstantInt>(allocaInst->getArraySize())) { 52*9880d681SAndroid Build Coastguard Worker allocaInst->moveBefore(firstTerminatorInst); 53*9880d681SAndroid Build Coastguard Worker functionModified = true; 54*9880d681SAndroid Build Coastguard Worker } 55*9880d681SAndroid Build Coastguard Worker } 56*9880d681SAndroid Build Coastguard Worker } 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker return functionModified; 59*9880d681SAndroid Build Coastguard Worker } 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker char NVPTXAllocaHoisting::ID = 0; 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker namespace llvm { 64*9880d681SAndroid Build Coastguard Worker void initializeNVPTXAllocaHoistingPass(PassRegistry &); 65*9880d681SAndroid Build Coastguard Worker } 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS( 68*9880d681SAndroid Build Coastguard Worker NVPTXAllocaHoisting, "alloca-hoisting", 69*9880d681SAndroid Build Coastguard Worker "Hoisting alloca instructions in non-entry blocks to the entry block", 70*9880d681SAndroid Build Coastguard Worker false, false) 71*9880d681SAndroid Build Coastguard Worker createAllocaHoisting()72*9880d681SAndroid Build Coastguard WorkerFunctionPass *llvm::createAllocaHoisting() { return new NVPTXAllocaHoisting; } 73