mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
Add support for not strength reducing GEPs where the element size is a small
power of two. This emphatically includes the zeroeth power of two. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20429 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8d46a268c5
commit
2f3c9b7562
@ -129,9 +129,12 @@ FunctionPass *createLICMPass();
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
|
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
|
||||||
// a loop's canonical induction variable as one of their indices.
|
// a loop's canonical induction variable as one of their indices. The
|
||||||
|
// MaxTargetAMSize is the largest element size that the target architecture
|
||||||
|
// can handle in its addressing modes. Power of two multipliers less than or
|
||||||
|
// equal to this value are not reduced.
|
||||||
//
|
//
|
||||||
FunctionPass *createLoopStrengthReducePass();
|
FunctionPass *createLoopStrengthReducePass(unsigned MaxTargetAMSize = 1);
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
|
@ -22,10 +22,12 @@
|
|||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Support/CFG.h"
|
#include "llvm/Support/CFG.h"
|
||||||
#include "llvm/Transforms/Utils/Local.h"
|
#include "llvm/Transforms/Utils/Local.h"
|
||||||
|
#include "llvm/Target/TargetData.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include <set>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
@ -37,7 +39,12 @@ namespace {
|
|||||||
LoopInfo *LI;
|
LoopInfo *LI;
|
||||||
DominatorSet *DS;
|
DominatorSet *DS;
|
||||||
bool Changed;
|
bool Changed;
|
||||||
|
unsigned MaxTargetAMSize;
|
||||||
public:
|
public:
|
||||||
|
LoopStrengthReduce(unsigned MTAMS = 1)
|
||||||
|
: MaxTargetAMSize(MTAMS) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool runOnFunction(Function &) {
|
virtual bool runOnFunction(Function &) {
|
||||||
LI = &getAnalysis<LoopInfo>();
|
LI = &getAnalysis<LoopInfo>();
|
||||||
DS = &getAnalysis<DominatorSet>();
|
DS = &getAnalysis<DominatorSet>();
|
||||||
@ -53,6 +60,7 @@ namespace {
|
|||||||
AU.addRequiredID(LoopSimplifyID);
|
AU.addRequiredID(LoopSimplifyID);
|
||||||
AU.addRequired<LoopInfo>();
|
AU.addRequired<LoopInfo>();
|
||||||
AU.addRequired<DominatorSet>();
|
AU.addRequired<DominatorSet>();
|
||||||
|
AU.addRequired<TargetData>();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void runOnLoop(Loop *L);
|
void runOnLoop(Loop *L);
|
||||||
@ -65,8 +73,8 @@ namespace {
|
|||||||
"Strength Reduce GEP Uses of Ind. Vars");
|
"Strength Reduce GEP Uses of Ind. Vars");
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPass *llvm::createLoopStrengthReducePass() {
|
FunctionPass *llvm::createLoopStrengthReducePass(unsigned MaxTargetAMSize) {
|
||||||
return new LoopStrengthReduce();
|
return new LoopStrengthReduce(MaxTargetAMSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DeleteTriviallyDeadInstructions - If any of the instructions is the
|
/// DeleteTriviallyDeadInstructions - If any of the instructions is the
|
||||||
@ -104,6 +112,7 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
|
|||||||
unsigned indvar = 0;
|
unsigned indvar = 0;
|
||||||
std::vector<Value *> pre_op_vector;
|
std::vector<Value *> pre_op_vector;
|
||||||
std::vector<Value *> inc_op_vector;
|
std::vector<Value *> inc_op_vector;
|
||||||
|
const Type *ty = GEPI->getOperand(0)->getType();
|
||||||
Value *CanonicalIndVar = L->getCanonicalInductionVariable();
|
Value *CanonicalIndVar = L->getCanonicalInductionVariable();
|
||||||
BasicBlock *Header = L->getHeader();
|
BasicBlock *Header = L->getHeader();
|
||||||
BasicBlock *Preheader = L->getLoopPreheader();
|
BasicBlock *Preheader = L->getLoopPreheader();
|
||||||
@ -111,6 +120,14 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
|
|||||||
|
|
||||||
for (unsigned op = 1, e = GEPI->getNumOperands(); op != e; ++op) {
|
for (unsigned op = 1, e = GEPI->getNumOperands(); op != e; ++op) {
|
||||||
Value *operand = GEPI->getOperand(op);
|
Value *operand = GEPI->getOperand(op);
|
||||||
|
if (ty->getTypeID() == Type::StructTyID) {
|
||||||
|
assert(isa<ConstantUInt>(operand));
|
||||||
|
ConstantUInt *c = dyn_cast<ConstantUInt>(operand);
|
||||||
|
ty = ty->getContainedType(unsigned(c->getValue()));
|
||||||
|
} else {
|
||||||
|
ty = ty->getContainedType(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (operand == CanonicalIndVar) {
|
if (operand == CanonicalIndVar) {
|
||||||
// FIXME: use getCanonicalInductionVariableIncrement to choose between
|
// FIXME: use getCanonicalInductionVariableIncrement to choose between
|
||||||
// one and neg one maybe? We need to support int *foo = GEP base, -1
|
// one and neg one maybe? We need to support int *foo = GEP base, -1
|
||||||
@ -139,6 +156,12 @@ void LoopStrengthReduce::strengthReduceGEP(GetElementPtrInst *GEPI, Loop *L,
|
|||||||
if (Instruction *GepPtrOp = dyn_cast<Instruction>(GEPI->getOperand(0)))
|
if (Instruction *GepPtrOp = dyn_cast<Instruction>(GEPI->getOperand(0)))
|
||||||
if (!DS->dominates(GepPtrOp, Preheader->getTerminator()))
|
if (!DS->dominates(GepPtrOp, Preheader->getTerminator()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Don't reduced multiplies that the target can handle via addressing modes.
|
||||||
|
uint64_t sz = getAnalysis<TargetData>().getTypeSize(ty);
|
||||||
|
for (unsigned i = 1; i <= MaxTargetAMSize; i *= 2)
|
||||||
|
if (i == sz)
|
||||||
|
return;
|
||||||
|
|
||||||
// If all operands of the GEP we are going to insert into the preheader
|
// If all operands of the GEP we are going to insert into the preheader
|
||||||
// are constants, generate a GEP ConstantExpr instead.
|
// are constants, generate a GEP ConstantExpr instead.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user