llvm-6502/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
Chris Lattner 4fb71ba29d Namespaces
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1791 91177308-0d34-0410-b5e6-96231b3b80d8
2002-02-24 23:03:09 +00:00

114 lines
3.8 KiB
C++

//===- 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/BasicBlock.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<AllocaInst*> Allocas;
findSafeAllocas(M, Allocas); // Calculate safe allocas
// Get dominance frontier information...
DominanceFrontier &DF = getAnalysis<DominanceFrontier>();
// Transform each alloca in turn...
for (std::vector<AllocaInst*>::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<AllocaInst*> &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<AllocaInst*> &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<AllocaInst>(*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<MemAccessInst>(*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) {
std::cerr << "TODO: Should process: " << AI;
}
// newPromoteMemoryToRegister - Provide an entry point to create this pass.
//
Pass *newPromoteMemoryToRegister() {
return new PromotePass();
}