Initial checkin of new memory -> register promotion pass
authorChris Lattner <sabre@nondot.org>
Tue, 12 Feb 2002 17:16:22 +0000 (17:16 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 12 Feb 2002 17:16:22 +0000 (17:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1739 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h [new file with mode: 0644]
lib/Transforms/Utils/PromoteMemoryToRegister.cpp [new file with mode: 0644]

diff --git a/include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h b/include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h
new file mode 100644 (file)
index 0000000..6a16784
--- /dev/null
@@ -0,0 +1,22 @@
+//===- PromoteMemoryToRegister.h - Convert memory refs to regs ---*- C++ -*--=//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_PROMOTEMEMORYTOREGISTER_H
+#define LLVM_TRANSFORMS_SCALAR_PROMOTEMEMORYTOREGISTER_H
+
+class Pass;
+
+// newPromoteMemoryToRegister - Return the pass to perform this transformation.
+Pass *newPromoteMemoryToRegister();
+
+#endif
diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
new file mode 100644 (file)
index 0000000..e53150d
--- /dev/null
@@ -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();
+}