aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Utils/PromoteMemoryToRegister.cpp')
-rw-r--r--lib/Transforms/Utils/PromoteMemoryToRegister.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
new file mode 100644
index 0000000000..e53150d643
--- /dev/null
+++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -0,0 +1,93 @@
+//===- 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/iMemory.h"
+#include "llvm/Pass.h"
+#include "llvm/Method.h"
+
+#include "llvm/Assembly/Writer.h" // For debugging
+
+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
+
+ // Transform each alloca in turn...
+ for (std::vector<AllocaInst*>::iterator I = Allocas.begin(),
+ E = Allocas.end(); I != E; ++I)
+ promoteAlloca(*I);
+
+ return !Allocas.empty();
+ }
+
+ // 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);
+};
+
+
+// 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) {
+ cerr << "TODO: Should process: " << AI;
+}
+
+
+
+Pass *newPromoteMemoryToRegister() {
+ return new PromotePass();
+}