mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-20 10:30:03 +00:00
Use GEPOperator more pervasively to simplify code.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89914 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9c6a0dcf0e
commit
539c9b99c2
@ -38,24 +38,24 @@ using namespace llvm;
|
|||||||
// Useful predicates
|
// Useful predicates
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static const Value *GetGEPOperands(const Value *V,
|
static const Value *GetGEPOperands(const GEPOperator *V,
|
||||||
SmallVector<Value*, 16> &GEPOps) {
|
SmallVector<Value*, 16> &GEPOps) {
|
||||||
assert(GEPOps.empty() && "Expect empty list to populate!");
|
assert(GEPOps.empty() && "Expect empty list to populate!");
|
||||||
GEPOps.insert(GEPOps.end(), cast<User>(V)->op_begin()+1,
|
GEPOps.insert(GEPOps.end(), V->op_begin()+1, V->op_end());
|
||||||
cast<User>(V)->op_end());
|
|
||||||
|
|
||||||
// Accumulate all of the chained indexes into the operand array
|
// Accumulate all of the chained indexes into the operand array.
|
||||||
V = cast<User>(V)->getOperand(0);
|
Value *BasePtr = V->getOperand(0);
|
||||||
|
while (1) {
|
||||||
while (const GEPOperator *G = dyn_cast<GEPOperator>(V)) {
|
V = dyn_cast<GEPOperator>(BasePtr);
|
||||||
if (!isa<Constant>(GEPOps[0]) || isa<GlobalValue>(GEPOps[0]) ||
|
if (V == 0) return BasePtr;
|
||||||
!cast<Constant>(GEPOps[0])->isNullValue())
|
|
||||||
break; // Don't handle folding arbitrary pointer offsets yet...
|
// Don't handle folding arbitrary pointer offsets yet.
|
||||||
|
if (!isa<Constant>(GEPOps[0]) || !cast<Constant>(GEPOps[0])->isNullValue())
|
||||||
|
return BasePtr;
|
||||||
|
|
||||||
GEPOps.erase(GEPOps.begin()); // Drop the zero index
|
GEPOps.erase(GEPOps.begin()); // Drop the zero index
|
||||||
GEPOps.insert(GEPOps.begin(), G->op_begin()+1, G->op_end());
|
GEPOps.insert(GEPOps.begin(), V->op_begin()+1, V->op_end());
|
||||||
V = G->getOperand(0);
|
|
||||||
}
|
}
|
||||||
return V;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isKnownNonNull - Return true if we know that the specified value is never
|
/// isKnownNonNull - Return true if we know that the specified value is never
|
||||||
@ -219,7 +219,7 @@ namespace {
|
|||||||
|
|
||||||
// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP
|
// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP
|
||||||
// instruction against another.
|
// instruction against another.
|
||||||
AliasResult aliasGEP(const Value *V1, unsigned V1Size,
|
AliasResult aliasGEP(const GEPOperator *V1, unsigned V1Size,
|
||||||
const Value *V2, unsigned V2Size);
|
const Value *V2, unsigned V2Size);
|
||||||
|
|
||||||
// aliasPHI - Provide a bunch of ad-hoc rules to disambiguate a PHI
|
// aliasPHI - Provide a bunch of ad-hoc rules to disambiguate a PHI
|
||||||
@ -405,21 +405,19 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
|
|||||||
return NoAA::getModRefInfo(CS1, CS2);
|
return NoAA::getModRefInfo(CS1, CS2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction
|
/// aliasGEP - Provide a bunch of ad-hoc rules to disambiguate a GEP instruction
|
||||||
// against another.
|
/// against another pointer. We know that V1 is a GEP, but we don't know
|
||||||
//
|
/// anything about V2.
|
||||||
|
///
|
||||||
AliasAnalysis::AliasResult
|
AliasAnalysis::AliasResult
|
||||||
BasicAliasAnalysis::aliasGEP(const Value *V1, unsigned V1Size,
|
BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, unsigned V1Size,
|
||||||
const Value *V2, unsigned V2Size) {
|
const Value *V2, unsigned V2Size) {
|
||||||
// If we have two gep instructions with must-alias'ing base pointers, figure
|
// If we have two gep instructions with must-alias'ing base pointers, figure
|
||||||
// out if the indexes to the GEP tell us anything about the derived pointer.
|
// out if the indexes to the GEP tell us anything about the derived pointer.
|
||||||
// Note that we also handle chains of getelementptr instructions as well as
|
// Note that we also handle chains of getelementptr instructions as well as
|
||||||
// constant expression getelementptrs here.
|
// constant expression getelementptrs here.
|
||||||
//
|
//
|
||||||
if (isa<GEPOperator>(V1) && isa<GEPOperator>(V2)) {
|
if (const GEPOperator *GEP2 = dyn_cast<GEPOperator>(V2)) {
|
||||||
const User *GEP1 = cast<User>(V1);
|
|
||||||
const User *GEP2 = cast<User>(V2);
|
|
||||||
|
|
||||||
// If V1 and V2 are identical GEPs, just recurse down on both of them.
|
// If V1 and V2 are identical GEPs, just recurse down on both of them.
|
||||||
// This allows us to analyze things like:
|
// This allows us to analyze things like:
|
||||||
// P = gep A, 0, i, 1
|
// P = gep A, 0, i, 1
|
||||||
@ -438,13 +436,13 @@ BasicAliasAnalysis::aliasGEP(const Value *V1, unsigned V1Size,
|
|||||||
while (isa<GEPOperator>(GEP1->getOperand(0)) &&
|
while (isa<GEPOperator>(GEP1->getOperand(0)) &&
|
||||||
GEP1->getOperand(1) ==
|
GEP1->getOperand(1) ==
|
||||||
Constant::getNullValue(GEP1->getOperand(1)->getType()))
|
Constant::getNullValue(GEP1->getOperand(1)->getType()))
|
||||||
GEP1 = cast<User>(GEP1->getOperand(0));
|
GEP1 = cast<GEPOperator>(GEP1->getOperand(0));
|
||||||
const Value *BasePtr1 = GEP1->getOperand(0);
|
const Value *BasePtr1 = GEP1->getOperand(0);
|
||||||
|
|
||||||
while (isa<GEPOperator>(GEP2->getOperand(0)) &&
|
while (isa<GEPOperator>(GEP2->getOperand(0)) &&
|
||||||
GEP2->getOperand(1) ==
|
GEP2->getOperand(1) ==
|
||||||
Constant::getNullValue(GEP2->getOperand(1)->getType()))
|
Constant::getNullValue(GEP2->getOperand(1)->getType()))
|
||||||
GEP2 = cast<User>(GEP2->getOperand(0));
|
GEP2 = cast<GEPOperator>(GEP2->getOperand(0));
|
||||||
const Value *BasePtr2 = GEP2->getOperand(0);
|
const Value *BasePtr2 = GEP2->getOperand(0);
|
||||||
|
|
||||||
// Do the base pointers alias?
|
// Do the base pointers alias?
|
||||||
@ -457,8 +455,8 @@ BasicAliasAnalysis::aliasGEP(const Value *V1, unsigned V1Size,
|
|||||||
|
|
||||||
// Collect all of the chained GEP operands together into one simple place
|
// Collect all of the chained GEP operands together into one simple place
|
||||||
SmallVector<Value*, 16> GEP1Ops, GEP2Ops;
|
SmallVector<Value*, 16> GEP1Ops, GEP2Ops;
|
||||||
BasePtr1 = GetGEPOperands(V1, GEP1Ops);
|
BasePtr1 = GetGEPOperands(GEP1, GEP1Ops);
|
||||||
BasePtr2 = GetGEPOperands(V2, GEP2Ops);
|
BasePtr2 = GetGEPOperands(GEP2, GEP2Ops);
|
||||||
|
|
||||||
// If GetGEPOperands were able to fold to the same must-aliased pointer,
|
// If GetGEPOperands were able to fold to the same must-aliased pointer,
|
||||||
// do the comparison.
|
// do the comparison.
|
||||||
@ -482,7 +480,7 @@ BasicAliasAnalysis::aliasGEP(const Value *V1, unsigned V1Size,
|
|||||||
return MayAlias;
|
return MayAlias;
|
||||||
|
|
||||||
SmallVector<Value*, 16> GEPOperands;
|
SmallVector<Value*, 16> GEPOperands;
|
||||||
const Value *BasePtr = GetGEPOperands(V1, GEPOperands);
|
const Value *BasePtr = GetGEPOperands(GEP1, GEPOperands);
|
||||||
|
|
||||||
AliasResult R = aliasCheck(BasePtr, ~0U, V2, V2Size);
|
AliasResult R = aliasCheck(BasePtr, ~0U, V2, V2Size);
|
||||||
if (R != MustAlias)
|
if (R != MustAlias)
|
||||||
@ -719,8 +717,8 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, unsigned V1Size,
|
|||||||
std::swap(V1, V2);
|
std::swap(V1, V2);
|
||||||
std::swap(V1Size, V2Size);
|
std::swap(V1Size, V2Size);
|
||||||
}
|
}
|
||||||
if (isa<GEPOperator>(V1))
|
if (const GEPOperator *GV1 = dyn_cast<GEPOperator>(V1))
|
||||||
return aliasGEP(V1, V1Size, V2, V2Size);
|
return aliasGEP(GV1, V1Size, V2, V2Size);
|
||||||
|
|
||||||
if (isa<PHINode>(V2) && !isa<PHINode>(V1)) {
|
if (isa<PHINode>(V2) && !isa<PHINode>(V1)) {
|
||||||
std::swap(V1, V2);
|
std::swap(V1, V2);
|
||||||
|
Loading…
Reference in New Issue
Block a user