//===- PromoteMemoryToRegister.cpp - Convert memory refs to regs ----------===// // // This pass is used to promote memory references to be register references. A // simple example of the transformation performed by this pass is: // // FROM CODE TO CODE // %X = alloca int, uint 1 ret int 42 // store int 42, int *%X // %Y = load int* %X // ret int %Y // // To do this transformation, a simple analysis is done to ensure it is safe. // Currently this just loops over all alloca instructions, looking for // instructions that are only used in simple load and stores. // // After this, the code is transformed by... // //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar/PromoteMemoryToRegister.h" #include "llvm/Analysis/Dominators.h" #include "llvm/iMemory.h" #include "llvm/Pass.h" #include "llvm/Method.h" #include "llvm/Assembly/Writer.h" // For debugging using cfg::DominanceFrontier; // PromotePass - This class is implements the PromoteMemoryToRegister pass // class PromotePass : public MethodPass { public: // runOnMethod - To run this pass, first we calculate the alloca instructions // that are safe for promotion, then we promote each one. // virtual bool runOnMethod(Method *M) { std::vector Allocas; findSafeAllocas(M, Allocas); // Calculate safe allocas // Get dominance frontier information... DominanceFrontier &DF = getAnalysis(); // Transform each alloca in turn... for (std::vector::iterator I = Allocas.begin(), E = Allocas.end(); I != E; ++I) promoteAlloca(*I, DF); return !Allocas.empty(); } // getAnalysisUsageInfo - We need dominance frontiers // virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires, Pass::AnalysisSet &Destroyed, Pass::AnalysisSet &Provided) { Requires.push_back(DominanceFrontier::ID); } private: // findSafeAllocas - Find allocas that are safe to promote // void findSafeAllocas(Method *M, std::vector &Allocas) const; // promoteAlloca - Convert the use chain of an alloca instruction into // register references. // void promoteAlloca(AllocaInst *AI, DominanceFrontier &DF); }; // findSafeAllocas - Find allocas that are safe to promote // void PromotePass::findSafeAllocas(Method *M, std::vector &Allocas) const { BasicBlock *BB = M->front(); // Get the entry node for the method // Look at all instructions in the entry node for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (AllocaInst *AI = dyn_cast(*I)) // Is it an alloca? if (!AI->isArrayAllocation()) { bool isSafe = true; for (Value::use_iterator UI = AI->use_begin(), UE = AI->use_end(); UI != UE; ++UI) { // Loop over all of the uses of the alloca // Only allow nonindexed memory access instructions... if (MemAccessInst *MAI = dyn_cast(*UI)) { if (MAI->hasIndices()) { isSafe = false; break; } // indexed? } else { isSafe = false; break; // Not a load or store? } } if (isSafe) // If all checks pass, add alloca to safe list Allocas.push_back(AI); } } // promoteAlloca - Convert the use chain of an alloca instruction into // register references. // void PromotePass::promoteAlloca(AllocaInst *AI, DominanceFrontier &DFInfo) { cerr << "TODO: Should process: " << AI; } // newPromoteMemoryToRegister - Provide an entry point to create this pass. // Pass *newPromoteMemoryToRegister() { return new PromotePass(); }