aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-08-22 21:39:55 +0000
committerChris Lattner <sabre@nondot.org>2002-08-22 21:39:55 +0000
commitf5e84aa0887d3fcd752d4a4fa1bb0e526be49f20 (patch)
treeb38fb9605e2a6752c7f82c242f388a3cf91d0e96
parentb81258c278a342b8cbfb6a26f206fc3c82a7834c (diff)
Add capability of using pointer analysis to LICM
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3478 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/LICM.cpp37
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp
index 1cb899bf6e..3714d7b08f 100644
--- a/lib/Transforms/Scalar/LICM.cpp
+++ b/lib/Transforms/Scalar/LICM.cpp
@@ -18,8 +18,10 @@
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/iOperators.h"
#include "llvm/iPHINode.h"
+#include "llvm/iMemory.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/CFG.h"
#include "Support/STLExtras.h"
@@ -31,6 +33,7 @@ static Statistic<> NumHoistedNPH("licm\t\t- Number of insts hoisted to multiple"
" loop preds (bad, no loop pre-header)");
static Statistic<> NumHoistedPH("licm\t\t- Number of insts hoisted to a loop "
"pre-header");
+static Statistic<> NumHoistedLoads("licm\t\t- Number of load insts hoisted");
namespace {
struct LICM : public FunctionPass, public InstVisitor<LICM> {
@@ -40,6 +43,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.preservesCFG();
AU.addRequired<LoopInfo>();
+ AU.addRequired<AliasAnalysis>();
}
private:
@@ -48,8 +52,9 @@ namespace {
//
std::vector<BasicBlock*> LoopPreds, LoopBackEdges;
- Loop *CurLoop; // The current loop we are working on...
- bool Changed; // Set to true when we change anything.
+ Loop *CurLoop; // The current loop we are working on...
+ bool Changed; // Set to true when we change anything.
+ AliasAnalysis *AA; // Currently AliasAnalysis information
// visitLoop - Hoist expressions out of the specified loop...
void visitLoop(Loop *L);
@@ -70,6 +75,11 @@ namespace {
//
void hoist(Instruction &I);
+ // pointerInvalidatedByLoop - Return true if the body of this loop may store
+ // into the memory location pointed to by V.
+ //
+ bool pointerInvalidatedByLoop(Value *V);
+
// isLoopInvariant - Return true if the specified value is loop invariant
inline bool isLoopInvariant(Value *V) {
if (Instruction *I = dyn_cast<Instruction>(V))
@@ -94,6 +104,13 @@ namespace {
}
void visitShiftInst(ShiftInst &I) { visitBinaryOperator((Instruction&)I); }
+ void visitLoadInst(LoadInst &LI) {
+ assert(!LI.hasIndices());
+ if (isLoopInvariant(LI.getOperand(0)) &&
+ !pointerInvalidatedByLoop(LI.getOperand(0)))
+ hoist(LI);
+ }
+
void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
Instruction &I = (Instruction&)GEPI;
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
@@ -112,6 +129,9 @@ bool LICM::runOnFunction(Function &) {
const std::vector<Loop*> &TopLevelLoops =
getAnalysis<LoopInfo>().getTopLevelLoops();
+ // Get our alias analysis information...
+ AA = &getAnalysis<AliasAnalysis>();
+
// Traverse loops in postorder, hoisting expressions out of the deepest loops
// first.
//
@@ -198,6 +218,9 @@ void LICM::hoist(Instruction &Inst) {
string InstName = Inst.getName();
Inst.setName("");
+ if (isa<LoadInst>(Inst))
+ ++NumHoistedLoads;
+
// The common case is that we have a pre-header. Generate special case code
// that is faster if that is the case.
//
@@ -256,3 +279,13 @@ void LICM::hoist(Instruction &Inst) {
Changed = true;
}
+// pointerInvalidatedByLoop - Return true if the body of this loop may store
+// into the memory location pointed to by V.
+//
+bool LICM::pointerInvalidatedByLoop(Value *V) {
+ // Check to see if any of the basic blocks in CurLoop invalidate V.
+ for (unsigned i = 0, e = CurLoop->getBlocks().size(); i != e; ++i)
+ if (AA->canBasicBlockModify(*CurLoop->getBlocks()[i], V))
+ return true;
+ return false;
+}