mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-08 04:52:50 +00:00
[SCEV] Replace a struct with a function; NFC
We can do this now thanks to C++11 lambdas. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282515 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9f114d87fc
commit
e42a387356
@ -448,180 +448,163 @@ bool SCEVUnknown::isOffsetOf(Type *&CTy, Constant *&FieldNo) const {
|
|||||||
// SCEV Utilities
|
// SCEV Utilities
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
namespace {
|
// Return negative, zero, or positive, if LHS is less than, equal to, or greater
|
||||||
/// SCEVComplexityCompare - Return true if the complexity of the LHS is less
|
// than RHS, respectively. A three-way result allows recursive comparisons to be
|
||||||
/// than the complexity of the RHS. This comparator is used to canonicalize
|
// more efficient.
|
||||||
/// expressions.
|
static int CompareSCEVComplexity(const LoopInfo *const LI, const SCEV *LHS,
|
||||||
class SCEVComplexityCompare {
|
const SCEV *RHS) {
|
||||||
const LoopInfo *const LI;
|
// Fast-path: SCEVs are uniqued so we can do a quick equality check.
|
||||||
public:
|
if (LHS == RHS)
|
||||||
explicit SCEVComplexityCompare(const LoopInfo *li) : LI(li) {}
|
return 0;
|
||||||
|
|
||||||
// Return true or false if LHS is less than, or at least RHS, respectively.
|
// Primarily, sort the SCEVs by their getSCEVType().
|
||||||
bool operator()(const SCEV *LHS, const SCEV *RHS) const {
|
unsigned LType = LHS->getSCEVType(), RType = RHS->getSCEVType();
|
||||||
return compare(LHS, RHS) < 0;
|
if (LType != RType)
|
||||||
}
|
return (int)LType - (int)RType;
|
||||||
|
|
||||||
// Return negative, zero, or positive, if LHS is less than, equal to, or
|
// Aside from the getSCEVType() ordering, the particular ordering
|
||||||
// greater than RHS, respectively. A three-way result allows recursive
|
// isn't very important except that it's beneficial to be consistent,
|
||||||
// comparisons to be more efficient.
|
// so that (a + b) and (b + a) don't end up as different expressions.
|
||||||
int compare(const SCEV *LHS, const SCEV *RHS) const {
|
switch (static_cast<SCEVTypes>(LType)) {
|
||||||
// Fast-path: SCEVs are uniqued so we can do a quick equality check.
|
case scUnknown: {
|
||||||
if (LHS == RHS)
|
const SCEVUnknown *LU = cast<SCEVUnknown>(LHS);
|
||||||
return 0;
|
const SCEVUnknown *RU = cast<SCEVUnknown>(RHS);
|
||||||
|
|
||||||
// Primarily, sort the SCEVs by their getSCEVType().
|
// Sort SCEVUnknown values with some loose heuristics. TODO: This is
|
||||||
unsigned LType = LHS->getSCEVType(), RType = RHS->getSCEVType();
|
// not as complete as it could be.
|
||||||
if (LType != RType)
|
const Value *LV = LU->getValue(), *RV = RU->getValue();
|
||||||
return (int)LType - (int)RType;
|
|
||||||
|
|
||||||
// Aside from the getSCEVType() ordering, the particular ordering
|
// Order pointer values after integer values. This helps SCEVExpander
|
||||||
// isn't very important except that it's beneficial to be consistent,
|
// form GEPs.
|
||||||
// so that (a + b) and (b + a) don't end up as different expressions.
|
bool LIsPointer = LV->getType()->isPointerTy(),
|
||||||
switch (static_cast<SCEVTypes>(LType)) {
|
RIsPointer = RV->getType()->isPointerTy();
|
||||||
case scUnknown: {
|
if (LIsPointer != RIsPointer)
|
||||||
const SCEVUnknown *LU = cast<SCEVUnknown>(LHS);
|
return (int)LIsPointer - (int)RIsPointer;
|
||||||
const SCEVUnknown *RU = cast<SCEVUnknown>(RHS);
|
|
||||||
|
|
||||||
// Sort SCEVUnknown values with some loose heuristics. TODO: This is
|
// Compare getValueID values.
|
||||||
// not as complete as it could be.
|
unsigned LID = LV->getValueID(), RID = RV->getValueID();
|
||||||
const Value *LV = LU->getValue(), *RV = RU->getValue();
|
if (LID != RID)
|
||||||
|
return (int)LID - (int)RID;
|
||||||
|
|
||||||
// Order pointer values after integer values. This helps SCEVExpander
|
// Sort arguments by their position.
|
||||||
// form GEPs.
|
if (const Argument *LA = dyn_cast<Argument>(LV)) {
|
||||||
bool LIsPointer = LV->getType()->isPointerTy(),
|
const Argument *RA = cast<Argument>(RV);
|
||||||
RIsPointer = RV->getType()->isPointerTy();
|
unsigned LArgNo = LA->getArgNo(), RArgNo = RA->getArgNo();
|
||||||
if (LIsPointer != RIsPointer)
|
return (int)LArgNo - (int)RArgNo;
|
||||||
return (int)LIsPointer - (int)RIsPointer;
|
|
||||||
|
|
||||||
// Compare getValueID values.
|
|
||||||
unsigned LID = LV->getValueID(),
|
|
||||||
RID = RV->getValueID();
|
|
||||||
if (LID != RID)
|
|
||||||
return (int)LID - (int)RID;
|
|
||||||
|
|
||||||
// Sort arguments by their position.
|
|
||||||
if (const Argument *LA = dyn_cast<Argument>(LV)) {
|
|
||||||
const Argument *RA = cast<Argument>(RV);
|
|
||||||
unsigned LArgNo = LA->getArgNo(), RArgNo = RA->getArgNo();
|
|
||||||
return (int)LArgNo - (int)RArgNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For instructions, compare their loop depth, and their operand
|
|
||||||
// count. This is pretty loose.
|
|
||||||
if (const Instruction *LInst = dyn_cast<Instruction>(LV)) {
|
|
||||||
const Instruction *RInst = cast<Instruction>(RV);
|
|
||||||
|
|
||||||
// Compare loop depths.
|
|
||||||
const BasicBlock *LParent = LInst->getParent(),
|
|
||||||
*RParent = RInst->getParent();
|
|
||||||
if (LParent != RParent) {
|
|
||||||
unsigned LDepth = LI->getLoopDepth(LParent),
|
|
||||||
RDepth = LI->getLoopDepth(RParent);
|
|
||||||
if (LDepth != RDepth)
|
|
||||||
return (int)LDepth - (int)RDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare the number of operands.
|
|
||||||
unsigned LNumOps = LInst->getNumOperands(),
|
|
||||||
RNumOps = RInst->getNumOperands();
|
|
||||||
return (int)LNumOps - (int)RNumOps;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case scConstant: {
|
// For instructions, compare their loop depth, and their operand
|
||||||
const SCEVConstant *LC = cast<SCEVConstant>(LHS);
|
// count. This is pretty loose.
|
||||||
const SCEVConstant *RC = cast<SCEVConstant>(RHS);
|
if (const Instruction *LInst = dyn_cast<Instruction>(LV)) {
|
||||||
|
const Instruction *RInst = cast<Instruction>(RV);
|
||||||
|
|
||||||
// Compare constant values.
|
// Compare loop depths.
|
||||||
const APInt &LA = LC->getAPInt();
|
const BasicBlock *LParent = LInst->getParent(),
|
||||||
const APInt &RA = RC->getAPInt();
|
*RParent = RInst->getParent();
|
||||||
unsigned LBitWidth = LA.getBitWidth(), RBitWidth = RA.getBitWidth();
|
if (LParent != RParent) {
|
||||||
if (LBitWidth != RBitWidth)
|
unsigned LDepth = LI->getLoopDepth(LParent),
|
||||||
return (int)LBitWidth - (int)RBitWidth;
|
RDepth = LI->getLoopDepth(RParent);
|
||||||
return LA.ult(RA) ? -1 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
case scAddRecExpr: {
|
|
||||||
const SCEVAddRecExpr *LA = cast<SCEVAddRecExpr>(LHS);
|
|
||||||
const SCEVAddRecExpr *RA = cast<SCEVAddRecExpr>(RHS);
|
|
||||||
|
|
||||||
// Compare addrec loop depths.
|
|
||||||
const Loop *LLoop = LA->getLoop(), *RLoop = RA->getLoop();
|
|
||||||
if (LLoop != RLoop) {
|
|
||||||
unsigned LDepth = LLoop->getLoopDepth(),
|
|
||||||
RDepth = RLoop->getLoopDepth();
|
|
||||||
if (LDepth != RDepth)
|
if (LDepth != RDepth)
|
||||||
return (int)LDepth - (int)RDepth;
|
return (int)LDepth - (int)RDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addrec complexity grows with operand count.
|
// Compare the number of operands.
|
||||||
unsigned LNumOps = LA->getNumOperands(), RNumOps = RA->getNumOperands();
|
unsigned LNumOps = LInst->getNumOperands(),
|
||||||
if (LNumOps != RNumOps)
|
RNumOps = RInst->getNumOperands();
|
||||||
return (int)LNumOps - (int)RNumOps;
|
|
||||||
|
|
||||||
// Lexicographically compare.
|
|
||||||
for (unsigned i = 0; i != LNumOps; ++i) {
|
|
||||||
long X = compare(LA->getOperand(i), RA->getOperand(i));
|
|
||||||
if (X != 0)
|
|
||||||
return X;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case scAddExpr:
|
|
||||||
case scMulExpr:
|
|
||||||
case scSMaxExpr:
|
|
||||||
case scUMaxExpr: {
|
|
||||||
const SCEVNAryExpr *LC = cast<SCEVNAryExpr>(LHS);
|
|
||||||
const SCEVNAryExpr *RC = cast<SCEVNAryExpr>(RHS);
|
|
||||||
|
|
||||||
// Lexicographically compare n-ary expressions.
|
|
||||||
unsigned LNumOps = LC->getNumOperands(), RNumOps = RC->getNumOperands();
|
|
||||||
if (LNumOps != RNumOps)
|
|
||||||
return (int)LNumOps - (int)RNumOps;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i != LNumOps; ++i) {
|
|
||||||
if (i >= RNumOps)
|
|
||||||
return 1;
|
|
||||||
long X = compare(LC->getOperand(i), RC->getOperand(i));
|
|
||||||
if (X != 0)
|
|
||||||
return X;
|
|
||||||
}
|
|
||||||
return (int)LNumOps - (int)RNumOps;
|
return (int)LNumOps - (int)RNumOps;
|
||||||
}
|
}
|
||||||
|
|
||||||
case scUDivExpr: {
|
return 0;
|
||||||
const SCEVUDivExpr *LC = cast<SCEVUDivExpr>(LHS);
|
}
|
||||||
const SCEVUDivExpr *RC = cast<SCEVUDivExpr>(RHS);
|
|
||||||
|
|
||||||
// Lexicographically compare udiv expressions.
|
case scConstant: {
|
||||||
long X = compare(LC->getLHS(), RC->getLHS());
|
const SCEVConstant *LC = cast<SCEVConstant>(LHS);
|
||||||
|
const SCEVConstant *RC = cast<SCEVConstant>(RHS);
|
||||||
|
|
||||||
|
// Compare constant values.
|
||||||
|
const APInt &LA = LC->getAPInt();
|
||||||
|
const APInt &RA = RC->getAPInt();
|
||||||
|
unsigned LBitWidth = LA.getBitWidth(), RBitWidth = RA.getBitWidth();
|
||||||
|
if (LBitWidth != RBitWidth)
|
||||||
|
return (int)LBitWidth - (int)RBitWidth;
|
||||||
|
return LA.ult(RA) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case scAddRecExpr: {
|
||||||
|
const SCEVAddRecExpr *LA = cast<SCEVAddRecExpr>(LHS);
|
||||||
|
const SCEVAddRecExpr *RA = cast<SCEVAddRecExpr>(RHS);
|
||||||
|
|
||||||
|
// Compare addrec loop depths.
|
||||||
|
const Loop *LLoop = LA->getLoop(), *RLoop = RA->getLoop();
|
||||||
|
if (LLoop != RLoop) {
|
||||||
|
unsigned LDepth = LLoop->getLoopDepth(), RDepth = RLoop->getLoopDepth();
|
||||||
|
if (LDepth != RDepth)
|
||||||
|
return (int)LDepth - (int)RDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addrec complexity grows with operand count.
|
||||||
|
unsigned LNumOps = LA->getNumOperands(), RNumOps = RA->getNumOperands();
|
||||||
|
if (LNumOps != RNumOps)
|
||||||
|
return (int)LNumOps - (int)RNumOps;
|
||||||
|
|
||||||
|
// Lexicographically compare.
|
||||||
|
for (unsigned i = 0; i != LNumOps; ++i) {
|
||||||
|
long X = CompareSCEVComplexity(LI, LA->getOperand(i), RA->getOperand(i));
|
||||||
if (X != 0)
|
if (X != 0)
|
||||||
return X;
|
return X;
|
||||||
return compare(LC->getRHS(), RC->getRHS());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case scTruncate:
|
return 0;
|
||||||
case scZeroExtend:
|
|
||||||
case scSignExtend: {
|
|
||||||
const SCEVCastExpr *LC = cast<SCEVCastExpr>(LHS);
|
|
||||||
const SCEVCastExpr *RC = cast<SCEVCastExpr>(RHS);
|
|
||||||
|
|
||||||
// Compare cast expressions by operand.
|
|
||||||
return compare(LC->getOperand(), RC->getOperand());
|
|
||||||
}
|
|
||||||
|
|
||||||
case scCouldNotCompute:
|
|
||||||
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
|
||||||
}
|
|
||||||
llvm_unreachable("Unknown SCEV kind!");
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
} // end anonymous namespace
|
case scAddExpr:
|
||||||
|
case scMulExpr:
|
||||||
|
case scSMaxExpr:
|
||||||
|
case scUMaxExpr: {
|
||||||
|
const SCEVNAryExpr *LC = cast<SCEVNAryExpr>(LHS);
|
||||||
|
const SCEVNAryExpr *RC = cast<SCEVNAryExpr>(RHS);
|
||||||
|
|
||||||
|
// Lexicographically compare n-ary expressions.
|
||||||
|
unsigned LNumOps = LC->getNumOperands(), RNumOps = RC->getNumOperands();
|
||||||
|
if (LNumOps != RNumOps)
|
||||||
|
return (int)LNumOps - (int)RNumOps;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i != LNumOps; ++i) {
|
||||||
|
if (i >= RNumOps)
|
||||||
|
return 1;
|
||||||
|
long X = CompareSCEVComplexity(LI, LC->getOperand(i), RC->getOperand(i));
|
||||||
|
if (X != 0)
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
return (int)LNumOps - (int)RNumOps;
|
||||||
|
}
|
||||||
|
|
||||||
|
case scUDivExpr: {
|
||||||
|
const SCEVUDivExpr *LC = cast<SCEVUDivExpr>(LHS);
|
||||||
|
const SCEVUDivExpr *RC = cast<SCEVUDivExpr>(RHS);
|
||||||
|
|
||||||
|
// Lexicographically compare udiv expressions.
|
||||||
|
long X = CompareSCEVComplexity(LI, LC->getLHS(), RC->getLHS());
|
||||||
|
if (X != 0)
|
||||||
|
return X;
|
||||||
|
return CompareSCEVComplexity(LI, LC->getRHS(), RC->getRHS());
|
||||||
|
}
|
||||||
|
|
||||||
|
case scTruncate:
|
||||||
|
case scZeroExtend:
|
||||||
|
case scSignExtend: {
|
||||||
|
const SCEVCastExpr *LC = cast<SCEVCastExpr>(LHS);
|
||||||
|
const SCEVCastExpr *RC = cast<SCEVCastExpr>(RHS);
|
||||||
|
|
||||||
|
// Compare cast expressions by operand.
|
||||||
|
return CompareSCEVComplexity(LI, LC->getOperand(), RC->getOperand());
|
||||||
|
}
|
||||||
|
|
||||||
|
case scCouldNotCompute:
|
||||||
|
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
|
||||||
|
}
|
||||||
|
llvm_unreachable("Unknown SCEV kind!");
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a list of SCEV objects, order them by their complexity, and group
|
/// Given a list of SCEV objects, order them by their complexity, and group
|
||||||
/// objects of the same complexity together by value. When this routine is
|
/// objects of the same complexity together by value. When this routine is
|
||||||
@ -640,13 +623,16 @@ static void GroupByComplexity(SmallVectorImpl<const SCEV *> &Ops,
|
|||||||
// This is the common case, which also happens to be trivially simple.
|
// This is the common case, which also happens to be trivially simple.
|
||||||
// Special case it.
|
// Special case it.
|
||||||
const SCEV *&LHS = Ops[0], *&RHS = Ops[1];
|
const SCEV *&LHS = Ops[0], *&RHS = Ops[1];
|
||||||
if (SCEVComplexityCompare(LI)(RHS, LHS))
|
if (CompareSCEVComplexity(LI, RHS, LHS) < 0)
|
||||||
std::swap(LHS, RHS);
|
std::swap(LHS, RHS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do the rough sort by complexity.
|
// Do the rough sort by complexity.
|
||||||
std::stable_sort(Ops.begin(), Ops.end(), SCEVComplexityCompare(LI));
|
std::stable_sort(Ops.begin(), Ops.end(),
|
||||||
|
[LI](const SCEV *LHS, const SCEV *RHS) {
|
||||||
|
return CompareSCEVComplexity(LI, LHS, RHS) < 0;
|
||||||
|
});
|
||||||
|
|
||||||
// Now that we are sorted by complexity, group elements of the same
|
// Now that we are sorted by complexity, group elements of the same
|
||||||
// complexity. Note that this is, at worst, N^2, but the vector is likely to
|
// complexity. Note that this is, at worst, N^2, but the vector is likely to
|
||||||
|
Loading…
Reference in New Issue
Block a user