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:
Chandler Carruth 2013-01-07 15:04:40 +00:00
parent e4ba75f43e
commit a07dcb1498

View File

@ -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),