mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-16 23:38:40 +00:00
Remove LSR's use of the random AddrMode struct. These variables were
already in a class, just inline the four of them. I suspect that this class could be simplified some to not always keep distinct variables for these things, but it wasn't clear to me how given the usage so I opted for a trivial and mechanical translation. This removes one of the two remaining users of a header in include/llvm which does nothing more than define a 4 member struct. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171738 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e4ba75f43e
commit
a07dcb1498
@ -58,7 +58,6 @@
|
|||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/ADT/DenseSet.h"
|
||||||
#include "llvm/ADT/SetVector.h"
|
#include "llvm/ADT/SetVector.h"
|
||||||
#include "llvm/ADT/SmallBitVector.h"
|
#include "llvm/ADT/SmallBitVector.h"
|
||||||
#include "llvm/AddressingMode.h"
|
|
||||||
#include "llvm/Analysis/Dominators.h"
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm/Analysis/IVUsers.h"
|
#include "llvm/Analysis/IVUsers.h"
|
||||||
#include "llvm/Analysis/LoopPass.h"
|
#include "llvm/Analysis/LoopPass.h"
|
||||||
@ -224,16 +223,24 @@ namespace {
|
|||||||
/// computing satisfying a use. It may include broken-out immediates and scaled
|
/// computing satisfying a use. It may include broken-out immediates and scaled
|
||||||
/// registers.
|
/// registers.
|
||||||
struct Formula {
|
struct Formula {
|
||||||
/// AM - This is used to represent complex addressing, as well as other kinds
|
/// Global base address used for complex addressing.
|
||||||
/// of interesting uses.
|
GlobalValue *BaseGV;
|
||||||
AddrMode AM;
|
|
||||||
|
/// Base offset for complex addressing.
|
||||||
|
int64_t BaseOffset;
|
||||||
|
|
||||||
|
/// Whether any complex addressing has a base register.
|
||||||
|
bool HasBaseReg;
|
||||||
|
|
||||||
|
/// The scale of any complex addressing.
|
||||||
|
int64_t Scale;
|
||||||
|
|
||||||
/// BaseRegs - The list of "base" registers for this use. When this is
|
/// BaseRegs - The list of "base" registers for this use. When this is
|
||||||
/// non-empty, AM.HasBaseReg should be set to true.
|
/// non-empty,
|
||||||
SmallVector<const SCEV *, 2> BaseRegs;
|
SmallVector<const SCEV *, 2> BaseRegs;
|
||||||
|
|
||||||
/// ScaledReg - The 'scaled' register for this use. This should be non-null
|
/// ScaledReg - The 'scaled' register for this use. This should be non-null
|
||||||
/// when AM.Scale is not zero.
|
/// when Scale is not zero.
|
||||||
const SCEV *ScaledReg;
|
const SCEV *ScaledReg;
|
||||||
|
|
||||||
/// UnfoldedOffset - An additional constant offset which added near the
|
/// UnfoldedOffset - An additional constant offset which added near the
|
||||||
@ -241,7 +248,9 @@ struct Formula {
|
|||||||
/// live in an add immediate field rather than a register.
|
/// live in an add immediate field rather than a register.
|
||||||
int64_t UnfoldedOffset;
|
int64_t UnfoldedOffset;
|
||||||
|
|
||||||
Formula() : ScaledReg(0), UnfoldedOffset(0) {}
|
Formula()
|
||||||
|
: BaseGV(0), BaseOffset(0), HasBaseReg(false), Scale(0), ScaledReg(0),
|
||||||
|
UnfoldedOffset(0) {}
|
||||||
|
|
||||||
void InitialMatch(const SCEV *S, Loop *L, ScalarEvolution &SE);
|
void InitialMatch(const SCEV *S, Loop *L, ScalarEvolution &SE);
|
||||||
|
|
||||||
@ -327,13 +336,13 @@ void Formula::InitialMatch(const SCEV *S, Loop *L, ScalarEvolution &SE) {
|
|||||||
const SCEV *Sum = SE.getAddExpr(Good);
|
const SCEV *Sum = SE.getAddExpr(Good);
|
||||||
if (!Sum->isZero())
|
if (!Sum->isZero())
|
||||||
BaseRegs.push_back(Sum);
|
BaseRegs.push_back(Sum);
|
||||||
AM.HasBaseReg = true;
|
HasBaseReg = true;
|
||||||
}
|
}
|
||||||
if (!Bad.empty()) {
|
if (!Bad.empty()) {
|
||||||
const SCEV *Sum = SE.getAddExpr(Bad);
|
const SCEV *Sum = SE.getAddExpr(Bad);
|
||||||
if (!Sum->isZero())
|
if (!Sum->isZero())
|
||||||
BaseRegs.push_back(Sum);
|
BaseRegs.push_back(Sum);
|
||||||
AM.HasBaseReg = true;
|
HasBaseReg = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +358,7 @@ unsigned Formula::getNumRegs() const {
|
|||||||
Type *Formula::getType() const {
|
Type *Formula::getType() const {
|
||||||
return !BaseRegs.empty() ? BaseRegs.front()->getType() :
|
return !BaseRegs.empty() ? BaseRegs.front()->getType() :
|
||||||
ScaledReg ? ScaledReg->getType() :
|
ScaledReg ? ScaledReg->getType() :
|
||||||
AM.BaseGV ? AM.BaseGV->getType() :
|
BaseGV ? BaseGV->getType() :
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,29 +391,29 @@ bool Formula::hasRegsUsedByUsesOtherThan(size_t LUIdx,
|
|||||||
|
|
||||||
void Formula::print(raw_ostream &OS) const {
|
void Formula::print(raw_ostream &OS) const {
|
||||||
bool First = true;
|
bool First = true;
|
||||||
if (AM.BaseGV) {
|
if (BaseGV) {
|
||||||
if (!First) OS << " + "; else First = false;
|
if (!First) OS << " + "; else First = false;
|
||||||
WriteAsOperand(OS, AM.BaseGV, /*PrintType=*/false);
|
WriteAsOperand(OS, BaseGV, /*PrintType=*/false);
|
||||||
}
|
}
|
||||||
if (AM.BaseOffs != 0) {
|
if (BaseOffset != 0) {
|
||||||
if (!First) OS << " + "; else First = false;
|
if (!First) OS << " + "; else First = false;
|
||||||
OS << AM.BaseOffs;
|
OS << BaseOffset;
|
||||||
}
|
}
|
||||||
for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
|
for (SmallVectorImpl<const SCEV *>::const_iterator I = BaseRegs.begin(),
|
||||||
E = BaseRegs.end(); I != E; ++I) {
|
E = BaseRegs.end(); I != E; ++I) {
|
||||||
if (!First) OS << " + "; else First = false;
|
if (!First) OS << " + "; else First = false;
|
||||||
OS << "reg(" << **I << ')';
|
OS << "reg(" << **I << ')';
|
||||||
}
|
}
|
||||||
if (AM.HasBaseReg && BaseRegs.empty()) {
|
if (HasBaseReg && BaseRegs.empty()) {
|
||||||
if (!First) OS << " + "; else First = false;
|
if (!First) OS << " + "; else First = false;
|
||||||
OS << "**error: HasBaseReg**";
|
OS << "**error: HasBaseReg**";
|
||||||
} else if (!AM.HasBaseReg && !BaseRegs.empty()) {
|
} else if (!HasBaseReg && !BaseRegs.empty()) {
|
||||||
if (!First) OS << " + "; else First = false;
|
if (!First) OS << " + "; else First = false;
|
||||||
OS << "**error: !HasBaseReg**";
|
OS << "**error: !HasBaseReg**";
|
||||||
}
|
}
|
||||||
if (AM.Scale != 0) {
|
if (Scale != 0) {
|
||||||
if (!First) OS << " + "; else First = false;
|
if (!First) OS << " + "; else First = false;
|
||||||
OS << AM.Scale << "*reg(";
|
OS << Scale << "*reg(";
|
||||||
if (ScaledReg)
|
if (ScaledReg)
|
||||||
OS << *ScaledReg;
|
OS << *ScaledReg;
|
||||||
else
|
else
|
||||||
@ -927,8 +936,8 @@ void Cost::RateFormula(const Formula &F,
|
|||||||
// Tally up the non-zero immediates.
|
// Tally up the non-zero immediates.
|
||||||
for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
|
for (SmallVectorImpl<int64_t>::const_iterator I = Offsets.begin(),
|
||||||
E = Offsets.end(); I != E; ++I) {
|
E = Offsets.end(); I != E; ++I) {
|
||||||
int64_t Offset = (uint64_t)*I + F.AM.BaseOffs;
|
int64_t Offset = (uint64_t)*I + F.BaseOffset;
|
||||||
if (F.AM.BaseGV)
|
if (F.BaseGV)
|
||||||
ImmCost += 64; // Handle symbolic values conservatively.
|
ImmCost += 64; // Handle symbolic values conservatively.
|
||||||
// TODO: This should probably be the pointer size.
|
// TODO: This should probably be the pointer size.
|
||||||
else if (Offset != 0)
|
else if (Offset != 0)
|
||||||
@ -1345,8 +1354,8 @@ static bool isLegalUse(const TargetTransformInfo &TTI, int64_t MinOffset,
|
|||||||
static bool isLegalUse(const TargetTransformInfo &TTI, int64_t MinOffset,
|
static bool isLegalUse(const TargetTransformInfo &TTI, int64_t MinOffset,
|
||||||
int64_t MaxOffset, LSRUse::KindType Kind, Type *AccessTy,
|
int64_t MaxOffset, LSRUse::KindType Kind, Type *AccessTy,
|
||||||
const Formula &F) {
|
const Formula &F) {
|
||||||
return isLegalUse(TTI, MinOffset, MaxOffset, Kind, AccessTy, F.AM.BaseGV,
|
return isLegalUse(TTI, MinOffset, MaxOffset, Kind, AccessTy, F.BaseGV,
|
||||||
F.AM.BaseOffs, F.AM.HasBaseReg, F.AM.Scale);
|
F.BaseOffset, F.HasBaseReg, F.Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isAlwaysFoldable(const TargetTransformInfo &TTI,
|
static bool isAlwaysFoldable(const TargetTransformInfo &TTI,
|
||||||
@ -2187,10 +2196,10 @@ LSRInstance::FindUseWithSimilarFormula(const Formula &OrigF,
|
|||||||
// as OrigF.
|
// as OrigF.
|
||||||
if (F.BaseRegs == OrigF.BaseRegs &&
|
if (F.BaseRegs == OrigF.BaseRegs &&
|
||||||
F.ScaledReg == OrigF.ScaledReg &&
|
F.ScaledReg == OrigF.ScaledReg &&
|
||||||
F.AM.BaseGV == OrigF.AM.BaseGV &&
|
F.BaseGV == OrigF.BaseGV &&
|
||||||
F.AM.Scale == OrigF.AM.Scale &&
|
F.Scale == OrigF.Scale &&
|
||||||
F.UnfoldedOffset == OrigF.UnfoldedOffset) {
|
F.UnfoldedOffset == OrigF.UnfoldedOffset) {
|
||||||
if (F.AM.BaseOffs == 0)
|
if (F.BaseOffset == 0)
|
||||||
return &LU;
|
return &LU;
|
||||||
// This is the formula where all the registers and symbols matched;
|
// This is the formula where all the registers and symbols matched;
|
||||||
// there aren't going to be any others. Since we declined it, we
|
// there aren't going to be any others. Since we declined it, we
|
||||||
@ -2882,6 +2891,7 @@ void
|
|||||||
LSRInstance::InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx) {
|
LSRInstance::InsertInitialFormula(const SCEV *S, LSRUse &LU, size_t LUIdx) {
|
||||||
Formula F;
|
Formula F;
|
||||||
F.InitialMatch(S, L, SE);
|
F.InitialMatch(S, L, SE);
|
||||||
|
F.HasBaseReg = true;
|
||||||
bool Inserted = InsertFormula(LU, LUIdx, F);
|
bool Inserted = InsertFormula(LU, LUIdx, F);
|
||||||
assert(Inserted && "Initial formula already exists!"); (void)Inserted;
|
assert(Inserted && "Initial formula already exists!"); (void)Inserted;
|
||||||
}
|
}
|
||||||
@ -2893,7 +2903,6 @@ LSRInstance::InsertSupplementalFormula(const SCEV *S,
|
|||||||
LSRUse &LU, size_t LUIdx) {
|
LSRUse &LU, size_t LUIdx) {
|
||||||
Formula F;
|
Formula F;
|
||||||
F.BaseRegs.push_back(S);
|
F.BaseRegs.push_back(S);
|
||||||
F.AM.HasBaseReg = true;
|
|
||||||
bool Inserted = InsertFormula(LU, LUIdx, F);
|
bool Inserted = InsertFormula(LU, LUIdx, F);
|
||||||
assert(Inserted && "Supplemental formula already exists!"); (void)Inserted;
|
assert(Inserted && "Supplemental formula already exists!"); (void)Inserted;
|
||||||
}
|
}
|
||||||
@ -3182,7 +3191,7 @@ void LSRInstance::GenerateCombinations(LSRUse &LU, unsigned LUIdx,
|
|||||||
void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx,
|
void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx,
|
||||||
Formula Base) {
|
Formula Base) {
|
||||||
// We can't add a symbolic offset if the address already contains one.
|
// We can't add a symbolic offset if the address already contains one.
|
||||||
if (Base.AM.BaseGV) return;
|
if (Base.BaseGV) return;
|
||||||
|
|
||||||
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
|
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i) {
|
||||||
const SCEV *G = Base.BaseRegs[i];
|
const SCEV *G = Base.BaseRegs[i];
|
||||||
@ -3190,7 +3199,7 @@ void LSRInstance::GenerateSymbolicOffsets(LSRUse &LU, unsigned LUIdx,
|
|||||||
if (G->isZero() || !GV)
|
if (G->isZero() || !GV)
|
||||||
continue;
|
continue;
|
||||||
Formula F = Base;
|
Formula F = Base;
|
||||||
F.AM.BaseGV = GV;
|
F.BaseGV = GV;
|
||||||
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
|
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
|
||||||
continue;
|
continue;
|
||||||
F.BaseRegs[i] = G;
|
F.BaseRegs[i] = G;
|
||||||
@ -3214,7 +3223,7 @@ void LSRInstance::GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx,
|
|||||||
for (SmallVectorImpl<int64_t>::const_iterator I = Worklist.begin(),
|
for (SmallVectorImpl<int64_t>::const_iterator I = Worklist.begin(),
|
||||||
E = Worklist.end(); I != E; ++I) {
|
E = Worklist.end(); I != E; ++I) {
|
||||||
Formula F = Base;
|
Formula F = Base;
|
||||||
F.AM.BaseOffs = (uint64_t)Base.AM.BaseOffs - *I;
|
F.BaseOffset = (uint64_t)Base.BaseOffset - *I;
|
||||||
if (isLegalUse(TTI, LU.MinOffset - *I, LU.MaxOffset - *I, LU.Kind,
|
if (isLegalUse(TTI, LU.MinOffset - *I, LU.MaxOffset - *I, LU.Kind,
|
||||||
LU.AccessTy, F)) {
|
LU.AccessTy, F)) {
|
||||||
// Add the offset to the base register.
|
// Add the offset to the base register.
|
||||||
@ -3234,7 +3243,7 @@ void LSRInstance::GenerateConstantOffsets(LSRUse &LU, unsigned LUIdx,
|
|||||||
if (G->isZero() || Imm == 0)
|
if (G->isZero() || Imm == 0)
|
||||||
continue;
|
continue;
|
||||||
Formula F = Base;
|
Formula F = Base;
|
||||||
F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Imm;
|
F.BaseOffset = (uint64_t)F.BaseOffset + Imm;
|
||||||
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
|
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy, F))
|
||||||
continue;
|
continue;
|
||||||
F.BaseRegs[i] = G;
|
F.BaseRegs[i] = G;
|
||||||
@ -3256,7 +3265,7 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
|
|||||||
// Don't do this if there is more than one offset.
|
// Don't do this if there is more than one offset.
|
||||||
if (LU.MinOffset != LU.MaxOffset) return;
|
if (LU.MinOffset != LU.MaxOffset) return;
|
||||||
|
|
||||||
assert(!Base.AM.BaseGV && "ICmpZero use is not legal!");
|
assert(!Base.BaseGV && "ICmpZero use is not legal!");
|
||||||
|
|
||||||
// Check each interesting stride.
|
// Check each interesting stride.
|
||||||
for (SmallSetVector<int64_t, 8>::const_iterator
|
for (SmallSetVector<int64_t, 8>::const_iterator
|
||||||
@ -3264,10 +3273,10 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
|
|||||||
int64_t Factor = *I;
|
int64_t Factor = *I;
|
||||||
|
|
||||||
// Check that the multiplication doesn't overflow.
|
// Check that the multiplication doesn't overflow.
|
||||||
if (Base.AM.BaseOffs == INT64_MIN && Factor == -1)
|
if (Base.BaseOffset == INT64_MIN && Factor == -1)
|
||||||
continue;
|
continue;
|
||||||
int64_t NewBaseOffs = (uint64_t)Base.AM.BaseOffs * Factor;
|
int64_t NewBaseOffset = (uint64_t)Base.BaseOffset * Factor;
|
||||||
if (NewBaseOffs / Factor != Base.AM.BaseOffs)
|
if (NewBaseOffset / Factor != Base.BaseOffset)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check that multiplying with the use offset doesn't overflow.
|
// Check that multiplying with the use offset doesn't overflow.
|
||||||
@ -3279,14 +3288,14 @@ void LSRInstance::GenerateICmpZeroScales(LSRUse &LU, unsigned LUIdx,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Formula F = Base;
|
Formula F = Base;
|
||||||
F.AM.BaseOffs = NewBaseOffs;
|
F.BaseOffset = NewBaseOffset;
|
||||||
|
|
||||||
// Check that this scale is legal.
|
// Check that this scale is legal.
|
||||||
if (!isLegalUse(TTI, Offset, Offset, LU.Kind, LU.AccessTy, F))
|
if (!isLegalUse(TTI, Offset, Offset, LU.Kind, LU.AccessTy, F))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Compensate for the use having MinOffset built into it.
|
// Compensate for the use having MinOffset built into it.
|
||||||
F.AM.BaseOffs = (uint64_t)F.AM.BaseOffs + Offset - LU.MinOffset;
|
F.BaseOffset = (uint64_t)F.BaseOffset + Offset - LU.MinOffset;
|
||||||
|
|
||||||
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
|
const SCEV *FactorS = SE.getConstant(IntTy, Factor);
|
||||||
|
|
||||||
@ -3327,15 +3336,15 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
|||||||
if (!IntTy) return;
|
if (!IntTy) return;
|
||||||
|
|
||||||
// If this Formula already has a scaled register, we can't add another one.
|
// If this Formula already has a scaled register, we can't add another one.
|
||||||
if (Base.AM.Scale != 0) return;
|
if (Base.Scale != 0) return;
|
||||||
|
|
||||||
// Check each interesting stride.
|
// Check each interesting stride.
|
||||||
for (SmallSetVector<int64_t, 8>::const_iterator
|
for (SmallSetVector<int64_t, 8>::const_iterator
|
||||||
I = Factors.begin(), E = Factors.end(); I != E; ++I) {
|
I = Factors.begin(), E = Factors.end(); I != E; ++I) {
|
||||||
int64_t Factor = *I;
|
int64_t Factor = *I;
|
||||||
|
|
||||||
Base.AM.Scale = Factor;
|
Base.Scale = Factor;
|
||||||
Base.AM.HasBaseReg = Base.BaseRegs.size() > 1;
|
Base.HasBaseReg = Base.BaseRegs.size() > 1;
|
||||||
// Check whether this scale is going to be legal.
|
// Check whether this scale is going to be legal.
|
||||||
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
|
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
|
||||||
Base)) {
|
Base)) {
|
||||||
@ -3352,7 +3361,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
|||||||
// For an ICmpZero, negating a solitary base register won't lead to
|
// For an ICmpZero, negating a solitary base register won't lead to
|
||||||
// new solutions.
|
// new solutions.
|
||||||
if (LU.Kind == LSRUse::ICmpZero &&
|
if (LU.Kind == LSRUse::ICmpZero &&
|
||||||
!Base.AM.HasBaseReg && Base.AM.BaseOffs == 0 && !Base.AM.BaseGV)
|
!Base.HasBaseReg && Base.BaseOffset == 0 && !Base.BaseGV)
|
||||||
continue;
|
continue;
|
||||||
// For each addrec base reg, apply the scale, if possible.
|
// For each addrec base reg, apply the scale, if possible.
|
||||||
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i)
|
for (size_t i = 0, e = Base.BaseRegs.size(); i != e; ++i)
|
||||||
@ -3377,7 +3386,7 @@ void LSRInstance::GenerateScales(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
|||||||
/// GenerateTruncates - Generate reuse formulae from different IV types.
|
/// GenerateTruncates - Generate reuse formulae from different IV types.
|
||||||
void LSRInstance::GenerateTruncates(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
void LSRInstance::GenerateTruncates(LSRUse &LU, unsigned LUIdx, Formula Base) {
|
||||||
// Don't bother truncating symbolic values.
|
// Don't bother truncating symbolic values.
|
||||||
if (Base.AM.BaseGV) return;
|
if (Base.BaseGV) return;
|
||||||
|
|
||||||
// Determine the integer type for the base formula.
|
// Determine the integer type for the base formula.
|
||||||
Type *DstTy = Base.getType();
|
Type *DstTy = Base.getType();
|
||||||
@ -3534,14 +3543,13 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
|
|||||||
const Formula &F = LU.Formulae[L];
|
const Formula &F = LU.Formulae[L];
|
||||||
// Use the immediate in the scaled register.
|
// Use the immediate in the scaled register.
|
||||||
if (F.ScaledReg == OrigReg) {
|
if (F.ScaledReg == OrigReg) {
|
||||||
int64_t Offs = (uint64_t)F.AM.BaseOffs +
|
int64_t Offset = (uint64_t)F.BaseOffset + Imm * (uint64_t)F.Scale;
|
||||||
Imm * (uint64_t)F.AM.Scale;
|
|
||||||
// Don't create 50 + reg(-50).
|
// Don't create 50 + reg(-50).
|
||||||
if (F.referencesReg(SE.getSCEV(
|
if (F.referencesReg(SE.getSCEV(
|
||||||
ConstantInt::get(IntTy, -(uint64_t)Offs))))
|
ConstantInt::get(IntTy, -(uint64_t)Offset))))
|
||||||
continue;
|
continue;
|
||||||
Formula NewF = F;
|
Formula NewF = F;
|
||||||
NewF.AM.BaseOffs = Offs;
|
NewF.BaseOffset = Offset;
|
||||||
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
|
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset, LU.Kind, LU.AccessTy,
|
||||||
NewF))
|
NewF))
|
||||||
continue;
|
continue;
|
||||||
@ -3552,9 +3560,9 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
|
|||||||
// immediate itself, then the formula isn't worthwhile.
|
// immediate itself, then the formula isn't worthwhile.
|
||||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(NewF.ScaledReg))
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(NewF.ScaledReg))
|
||||||
if (C->getValue()->isNegative() !=
|
if (C->getValue()->isNegative() !=
|
||||||
(NewF.AM.BaseOffs < 0) &&
|
(NewF.BaseOffset < 0) &&
|
||||||
(C->getValue()->getValue().abs() * APInt(BitWidth, F.AM.Scale))
|
(C->getValue()->getValue().abs() * APInt(BitWidth, F.Scale))
|
||||||
.ule(abs64(NewF.AM.BaseOffs)))
|
.ule(abs64(NewF.BaseOffset)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// OK, looks good.
|
// OK, looks good.
|
||||||
@ -3566,7 +3574,7 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
|
|||||||
if (BaseReg != OrigReg)
|
if (BaseReg != OrigReg)
|
||||||
continue;
|
continue;
|
||||||
Formula NewF = F;
|
Formula NewF = F;
|
||||||
NewF.AM.BaseOffs = (uint64_t)NewF.AM.BaseOffs + Imm;
|
NewF.BaseOffset = (uint64_t)NewF.BaseOffset + Imm;
|
||||||
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset,
|
if (!isLegalUse(TTI, LU.MinOffset, LU.MaxOffset,
|
||||||
LU.Kind, LU.AccessTy, NewF)) {
|
LU.Kind, LU.AccessTy, NewF)) {
|
||||||
if (!TTI.isLegalAddImmediate((uint64_t)NewF.UnfoldedOffset + Imm))
|
if (!TTI.isLegalAddImmediate((uint64_t)NewF.UnfoldedOffset + Imm))
|
||||||
@ -3583,11 +3591,11 @@ void LSRInstance::GenerateCrossUseConstantOffsets() {
|
|||||||
J = NewF.BaseRegs.begin(), JE = NewF.BaseRegs.end();
|
J = NewF.BaseRegs.begin(), JE = NewF.BaseRegs.end();
|
||||||
J != JE; ++J)
|
J != JE; ++J)
|
||||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*J))
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*J))
|
||||||
if ((C->getValue()->getValue() + NewF.AM.BaseOffs).abs().slt(
|
if ((C->getValue()->getValue() + NewF.BaseOffset).abs().slt(
|
||||||
abs64(NewF.AM.BaseOffs)) &&
|
abs64(NewF.BaseOffset)) &&
|
||||||
(C->getValue()->getValue() +
|
(C->getValue()->getValue() +
|
||||||
NewF.AM.BaseOffs).countTrailingZeros() >=
|
NewF.BaseOffset).countTrailingZeros() >=
|
||||||
CountTrailingZeros_64(NewF.AM.BaseOffs))
|
CountTrailingZeros_64(NewF.BaseOffset))
|
||||||
goto skip_formula;
|
goto skip_formula;
|
||||||
|
|
||||||
// Ok, looks good.
|
// Ok, looks good.
|
||||||
@ -3785,7 +3793,7 @@ void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
|
|||||||
I = F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I) {
|
I = F.BaseRegs.begin(), E = F.BaseRegs.end(); I != E; ++I) {
|
||||||
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*I)) {
|
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(*I)) {
|
||||||
Formula NewF = F;
|
Formula NewF = F;
|
||||||
NewF.AM.BaseOffs += C->getValue()->getSExtValue();
|
NewF.BaseOffset += C->getValue()->getSExtValue();
|
||||||
NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
|
NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
|
||||||
(I - F.BaseRegs.begin()));
|
(I - F.BaseRegs.begin()));
|
||||||
if (LU.HasFormulaWithSameRegs(NewF)) {
|
if (LU.HasFormulaWithSameRegs(NewF)) {
|
||||||
@ -3798,9 +3806,9 @@ void LSRInstance::NarrowSearchSpaceByDetectingSupersets() {
|
|||||||
}
|
}
|
||||||
} else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(*I)) {
|
} else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(*I)) {
|
||||||
if (GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue()))
|
if (GlobalValue *GV = dyn_cast<GlobalValue>(U->getValue()))
|
||||||
if (!F.AM.BaseGV) {
|
if (!F.BaseGV) {
|
||||||
Formula NewF = F;
|
Formula NewF = F;
|
||||||
NewF.AM.BaseGV = GV;
|
NewF.BaseGV = GV;
|
||||||
NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
|
NewF.BaseRegs.erase(NewF.BaseRegs.begin() +
|
||||||
(I - F.BaseRegs.begin()));
|
(I - F.BaseRegs.begin()));
|
||||||
if (LU.HasFormulaWithSameRegs(NewF)) {
|
if (LU.HasFormulaWithSameRegs(NewF)) {
|
||||||
@ -3843,9 +3851,9 @@ void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
|
|||||||
for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
|
for (SmallVectorImpl<Formula>::const_iterator I = LU.Formulae.begin(),
|
||||||
E = LU.Formulae.end(); I != E; ++I) {
|
E = LU.Formulae.end(); I != E; ++I) {
|
||||||
const Formula &F = *I;
|
const Formula &F = *I;
|
||||||
if (F.AM.BaseOffs != 0 && F.AM.Scale == 0) {
|
if (F.BaseOffset != 0 && F.Scale == 0) {
|
||||||
if (LSRUse *LUThatHas = FindUseWithSimilarFormula(F, LU)) {
|
if (LSRUse *LUThatHas = FindUseWithSimilarFormula(F, LU)) {
|
||||||
if (reconcileNewOffset(*LUThatHas, F.AM.BaseOffs,
|
if (reconcileNewOffset(*LUThatHas, F.BaseOffset,
|
||||||
/*HasBaseReg=*/false,
|
/*HasBaseReg=*/false,
|
||||||
LU.Kind, LU.AccessTy)) {
|
LU.Kind, LU.AccessTy)) {
|
||||||
DEBUG(dbgs() << " Deleting use "; LU.print(dbgs());
|
DEBUG(dbgs() << " Deleting use "; LU.print(dbgs());
|
||||||
@ -3859,7 +3867,7 @@ void LSRInstance::NarrowSearchSpaceByCollapsingUnrolledCode() {
|
|||||||
LSRFixup &Fixup = *I;
|
LSRFixup &Fixup = *I;
|
||||||
if (Fixup.LUIdx == LUIdx) {
|
if (Fixup.LUIdx == LUIdx) {
|
||||||
Fixup.LUIdx = LUThatHas - &Uses.front();
|
Fixup.LUIdx = LUThatHas - &Uses.front();
|
||||||
Fixup.Offset += F.AM.BaseOffs;
|
Fixup.Offset += F.BaseOffset;
|
||||||
// Add the new offset to LUThatHas' offset list.
|
// Add the new offset to LUThatHas' offset list.
|
||||||
if (LUThatHas->Offsets.back() != Fixup.Offset) {
|
if (LUThatHas->Offsets.back() != Fixup.Offset) {
|
||||||
LUThatHas->Offsets.push_back(Fixup.Offset);
|
LUThatHas->Offsets.push_back(Fixup.Offset);
|
||||||
@ -4288,7 +4296,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF,
|
|||||||
|
|
||||||
// Expand the ScaledReg portion.
|
// Expand the ScaledReg portion.
|
||||||
Value *ICmpScaledV = 0;
|
Value *ICmpScaledV = 0;
|
||||||
if (F.AM.Scale != 0) {
|
if (F.Scale != 0) {
|
||||||
const SCEV *ScaledS = F.ScaledReg;
|
const SCEV *ScaledS = F.ScaledReg;
|
||||||
|
|
||||||
// If we're expanding for a post-inc user, make the post-inc adjustment.
|
// If we're expanding for a post-inc user, make the post-inc adjustment.
|
||||||
@ -4301,7 +4309,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF,
|
|||||||
// An interesting way of "folding" with an icmp is to use a negated
|
// An interesting way of "folding" with an icmp is to use a negated
|
||||||
// scale, which we'll implement by inserting it into the other operand
|
// scale, which we'll implement by inserting it into the other operand
|
||||||
// of the icmp.
|
// of the icmp.
|
||||||
assert(F.AM.Scale == -1 &&
|
assert(F.Scale == -1 &&
|
||||||
"The only scale supported by ICmpZero uses is -1!");
|
"The only scale supported by ICmpZero uses is -1!");
|
||||||
ICmpScaledV = Rewriter.expandCodeFor(ScaledS, 0, IP);
|
ICmpScaledV = Rewriter.expandCodeFor(ScaledS, 0, IP);
|
||||||
} else {
|
} else {
|
||||||
@ -4316,20 +4324,20 @@ Value *LSRInstance::Expand(const LSRFixup &LF,
|
|||||||
}
|
}
|
||||||
ScaledS = SE.getUnknown(Rewriter.expandCodeFor(ScaledS, 0, IP));
|
ScaledS = SE.getUnknown(Rewriter.expandCodeFor(ScaledS, 0, IP));
|
||||||
ScaledS = SE.getMulExpr(ScaledS,
|
ScaledS = SE.getMulExpr(ScaledS,
|
||||||
SE.getConstant(ScaledS->getType(), F.AM.Scale));
|
SE.getConstant(ScaledS->getType(), F.Scale));
|
||||||
Ops.push_back(ScaledS);
|
Ops.push_back(ScaledS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand the GV portion.
|
// Expand the GV portion.
|
||||||
if (F.AM.BaseGV) {
|
if (F.BaseGV) {
|
||||||
// Flush the operand list to suppress SCEVExpander hoisting.
|
// Flush the operand list to suppress SCEVExpander hoisting.
|
||||||
if (!Ops.empty()) {
|
if (!Ops.empty()) {
|
||||||
Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
|
Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty, IP);
|
||||||
Ops.clear();
|
Ops.clear();
|
||||||
Ops.push_back(SE.getUnknown(FullV));
|
Ops.push_back(SE.getUnknown(FullV));
|
||||||
}
|
}
|
||||||
Ops.push_back(SE.getUnknown(F.AM.BaseGV));
|
Ops.push_back(SE.getUnknown(F.BaseGV));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush the operand list to suppress SCEVExpander hoisting of both folded and
|
// Flush the operand list to suppress SCEVExpander hoisting of both folded and
|
||||||
@ -4341,7 +4349,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expand the immediate portion.
|
// Expand the immediate portion.
|
||||||
int64_t Offset = (uint64_t)F.AM.BaseOffs + LF.Offset;
|
int64_t Offset = (uint64_t)F.BaseOffset + LF.Offset;
|
||||||
if (Offset != 0) {
|
if (Offset != 0) {
|
||||||
if (LU.Kind == LSRUse::ICmpZero) {
|
if (LU.Kind == LSRUse::ICmpZero) {
|
||||||
// The other interesting way of "folding" with an ICmpZero is to use a
|
// The other interesting way of "folding" with an ICmpZero is to use a
|
||||||
@ -4382,9 +4390,9 @@ Value *LSRInstance::Expand(const LSRFixup &LF,
|
|||||||
if (LU.Kind == LSRUse::ICmpZero) {
|
if (LU.Kind == LSRUse::ICmpZero) {
|
||||||
ICmpInst *CI = cast<ICmpInst>(LF.UserInst);
|
ICmpInst *CI = cast<ICmpInst>(LF.UserInst);
|
||||||
DeadInsts.push_back(CI->getOperand(1));
|
DeadInsts.push_back(CI->getOperand(1));
|
||||||
assert(!F.AM.BaseGV && "ICmp does not support folding a global value and "
|
assert(!F.BaseGV && "ICmp does not support folding a global value and "
|
||||||
"a scale at the same time!");
|
"a scale at the same time!");
|
||||||
if (F.AM.Scale == -1) {
|
if (F.Scale == -1) {
|
||||||
if (ICmpScaledV->getType() != OpTy) {
|
if (ICmpScaledV->getType() != OpTy) {
|
||||||
Instruction *Cast =
|
Instruction *Cast =
|
||||||
CastInst::Create(CastInst::getCastOpcode(ICmpScaledV, false,
|
CastInst::Create(CastInst::getCastOpcode(ICmpScaledV, false,
|
||||||
@ -4394,7 +4402,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF,
|
|||||||
}
|
}
|
||||||
CI->setOperand(1, ICmpScaledV);
|
CI->setOperand(1, ICmpScaledV);
|
||||||
} else {
|
} else {
|
||||||
assert(F.AM.Scale == 0 &&
|
assert(F.Scale == 0 &&
|
||||||
"ICmp does not support folding a global value and "
|
"ICmp does not support folding a global value and "
|
||||||
"a scale at the same time!");
|
"a scale at the same time!");
|
||||||
Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy),
|
Constant *C = ConstantInt::getSigned(SE.getEffectiveSCEVType(OpTy),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user