mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
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
This commit is contained in:
@@ -18,8 +18,10 @@
|
|||||||
#include "llvm/Transforms/Scalar.h"
|
#include "llvm/Transforms/Scalar.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
#include "llvm/iOperators.h"
|
#include "llvm/iOperators.h"
|
||||||
#include "llvm/iPHINode.h"
|
#include "llvm/iPHINode.h"
|
||||||
|
#include "llvm/iMemory.h"
|
||||||
#include "llvm/Support/InstVisitor.h"
|
#include "llvm/Support/InstVisitor.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "Support/STLExtras.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)");
|
" loop preds (bad, no loop pre-header)");
|
||||||
static Statistic<> NumHoistedPH("licm\t\t- Number of insts hoisted to a loop "
|
static Statistic<> NumHoistedPH("licm\t\t- Number of insts hoisted to a loop "
|
||||||
"pre-header");
|
"pre-header");
|
||||||
|
static Statistic<> NumHoistedLoads("licm\t\t- Number of load insts hoisted");
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct LICM : public FunctionPass, public InstVisitor<LICM> {
|
struct LICM : public FunctionPass, public InstVisitor<LICM> {
|
||||||
@@ -40,6 +43,7 @@ namespace {
|
|||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.preservesCFG();
|
AU.preservesCFG();
|
||||||
AU.addRequired<LoopInfo>();
|
AU.addRequired<LoopInfo>();
|
||||||
|
AU.addRequired<AliasAnalysis>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -48,8 +52,9 @@ namespace {
|
|||||||
//
|
//
|
||||||
std::vector<BasicBlock*> LoopPreds, LoopBackEdges;
|
std::vector<BasicBlock*> LoopPreds, LoopBackEdges;
|
||||||
|
|
||||||
Loop *CurLoop; // The current loop we are working on...
|
Loop *CurLoop; // The current loop we are working on...
|
||||||
bool Changed; // Set to true when we change anything.
|
bool Changed; // Set to true when we change anything.
|
||||||
|
AliasAnalysis *AA; // Currently AliasAnalysis information
|
||||||
|
|
||||||
// visitLoop - Hoist expressions out of the specified loop...
|
// visitLoop - Hoist expressions out of the specified loop...
|
||||||
void visitLoop(Loop *L);
|
void visitLoop(Loop *L);
|
||||||
@@ -70,6 +75,11 @@ namespace {
|
|||||||
//
|
//
|
||||||
void hoist(Instruction &I);
|
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
|
// isLoopInvariant - Return true if the specified value is loop invariant
|
||||||
inline bool isLoopInvariant(Value *V) {
|
inline bool isLoopInvariant(Value *V) {
|
||||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
if (Instruction *I = dyn_cast<Instruction>(V))
|
||||||
@@ -94,6 +104,13 @@ namespace {
|
|||||||
}
|
}
|
||||||
void visitShiftInst(ShiftInst &I) { visitBinaryOperator((Instruction&)I); }
|
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) {
|
void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
|
||||||
Instruction &I = (Instruction&)GEPI;
|
Instruction &I = (Instruction&)GEPI;
|
||||||
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
|
||||||
@@ -112,6 +129,9 @@ bool LICM::runOnFunction(Function &) {
|
|||||||
const std::vector<Loop*> &TopLevelLoops =
|
const std::vector<Loop*> &TopLevelLoops =
|
||||||
getAnalysis<LoopInfo>().getTopLevelLoops();
|
getAnalysis<LoopInfo>().getTopLevelLoops();
|
||||||
|
|
||||||
|
// Get our alias analysis information...
|
||||||
|
AA = &getAnalysis<AliasAnalysis>();
|
||||||
|
|
||||||
// Traverse loops in postorder, hoisting expressions out of the deepest loops
|
// Traverse loops in postorder, hoisting expressions out of the deepest loops
|
||||||
// first.
|
// first.
|
||||||
//
|
//
|
||||||
@@ -198,6 +218,9 @@ void LICM::hoist(Instruction &Inst) {
|
|||||||
string InstName = Inst.getName();
|
string InstName = Inst.getName();
|
||||||
Inst.setName("");
|
Inst.setName("");
|
||||||
|
|
||||||
|
if (isa<LoadInst>(Inst))
|
||||||
|
++NumHoistedLoads;
|
||||||
|
|
||||||
// The common case is that we have a pre-header. Generate special case code
|
// The common case is that we have a pre-header. Generate special case code
|
||||||
// that is faster if that is the case.
|
// that is faster if that is the case.
|
||||||
//
|
//
|
||||||
@@ -256,3 +279,13 @@ void LICM::hoist(Instruction &Inst) {
|
|||||||
Changed = true;
|
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;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user