From d3db02248264b3ede56753cbb28df9d4ae45a1dd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 12 Feb 2002 17:16:22 +0000 Subject: [PATCH] Initial checkin of new memory -> register promotion pass git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1739 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/PromoteMemoryToRegister.h | 22 +++++ .../Utils/PromoteMemoryToRegister.cpp | 93 +++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h create mode 100644 lib/Transforms/Utils/PromoteMemoryToRegister.cpp diff --git a/include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h b/include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h new file mode 100644 index 00000000000..6a16784fd20 --- /dev/null +++ b/include/llvm/Transforms/Scalar/PromoteMemoryToRegister.h @@ -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 index 00000000000..e53150d643d --- /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 Allocas; + findSafeAllocas(M, Allocas); // Calculate safe allocas + + // Transform each alloca in turn... + for (std::vector::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 &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 &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) { + cerr << "TODO: Should process: " << AI; +} + + + +Pass *newPromoteMemoryToRegister() { + return new PromotePass(); +} -- 2.34.1