Skip to content

Commit

Permalink
Thread const correctness through a bunch of AliasAnalysis interfaces and
Browse files Browse the repository at this point in the history
eliminate several const_casts.

Make CallSite implicitly convertible to ImmutableCallSite.

Rename the getModRefBehavior for intrinsic IDs to
getIntrinsicModRefBehavior to avoid overload ambiguity with CallSite,
which happens to be implicitly convertible to bool.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110155 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Dan Gohman committed Aug 3, 2010
1 parent d1fb583 commit 79fca6f
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 103 deletions.
53 changes: 29 additions & 24 deletions include/llvm/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,17 @@ class AliasAnalysis {
};

/// getModRefBehavior - Return the behavior when calling the given call site.
virtual ModRefBehavior getModRefBehavior(CallSite CS,
virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS,
std::vector<PointerAccessInfo> *Info = 0);

/// getModRefBehavior - Return the behavior when calling the given function.
/// For use when the call site is not known.
virtual ModRefBehavior getModRefBehavior(Function *F,
virtual ModRefBehavior getModRefBehavior(const Function *F,
std::vector<PointerAccessInfo> *Info = 0);

/// getModRefBehavior - Return the modref behavior of the intrinsic with the
/// given id.
static ModRefBehavior getModRefBehavior(unsigned iid);
/// getIntrinsicModRefBehavior - Return the modref behavior of the intrinsic
/// with the given id.
static ModRefBehavior getIntrinsicModRefBehavior(unsigned iid);

/// doesNotAccessMemory - If the specified call is known to never read or
/// write memory, return true. If the call only reads from known-constant
Expand All @@ -201,14 +201,14 @@ class AliasAnalysis {
///
/// This property corresponds to the GCC 'const' attribute.
///
bool doesNotAccessMemory(CallSite CS) {
bool doesNotAccessMemory(ImmutableCallSite CS) {
return getModRefBehavior(CS) == DoesNotAccessMemory;
}

/// doesNotAccessMemory - If the specified function is known to never read or
/// write memory, return true. For use when the call site is not known.
///
bool doesNotAccessMemory(Function *F) {
bool doesNotAccessMemory(const Function *F) {
return getModRefBehavior(F) == DoesNotAccessMemory;
}

Expand All @@ -221,7 +221,7 @@ class AliasAnalysis {
///
/// This property corresponds to the GCC 'pure' attribute.
///
bool onlyReadsMemory(CallSite CS) {
bool onlyReadsMemory(ImmutableCallSite CS) {
ModRefBehavior MRB = getModRefBehavior(CS);
return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
}
Expand All @@ -230,7 +230,7 @@ class AliasAnalysis {
/// non-volatile memory (or not access memory at all), return true. For use
/// when the call site is not known.
///
bool onlyReadsMemory(Function *F) {
bool onlyReadsMemory(const Function *F) {
ModRefBehavior MRB = getModRefBehavior(F);
return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
}
Expand All @@ -244,36 +244,41 @@ class AliasAnalysis {
/// a particular call site modifies or reads the memory specified by the
/// pointer.
///
virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size);

/// getModRefInfo - Return information about whether two call sites may refer
/// to the same set of memory locations. This function returns NoModRef if
/// the two calls refer to disjoint memory locations, Ref if CS1 reads memory
/// written by CS2, Mod if CS1 writes to memory read or written by CS2, or
/// ModRef if CS1 might read or write memory accessed by CS2.
///
virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2);

public:
/// Convenience functions...
ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size);
ModRefResult getModRefInfo(StoreInst *S, Value *P, unsigned Size);
ModRefResult getModRefInfo(CallInst *C, Value *P, unsigned Size) {
return getModRefInfo(CallSite(C), P, Size);
ModRefResult getModRefInfo(const LoadInst *L, const Value *P, unsigned Size);
ModRefResult getModRefInfo(const StoreInst *S, const Value *P, unsigned Size);
ModRefResult getModRefInfo(const CallInst *C, const Value *P, unsigned Size) {
return getModRefInfo(ImmutableCallSite(C), P, Size);
}
ModRefResult getModRefInfo(InvokeInst *I, Value *P, unsigned Size) {
return getModRefInfo(CallSite(I), P, Size);
ModRefResult getModRefInfo(const InvokeInst *I,
const Value *P, unsigned Size) {
return getModRefInfo(ImmutableCallSite(I), P, Size);
}
ModRefResult getModRefInfo(VAArgInst* I, Value* P, unsigned Size) {
ModRefResult getModRefInfo(const VAArgInst* I,
const Value* P, unsigned Size) {
return AliasAnalysis::ModRef;
}
ModRefResult getModRefInfo(Instruction *I, Value *P, unsigned Size) {
ModRefResult getModRefInfo(const Instruction *I,
const Value *P, unsigned Size) {
switch (I->getOpcode()) {
case Instruction::VAArg: return getModRefInfo((VAArgInst*)I, P, Size);
case Instruction::Load: return getModRefInfo((LoadInst*)I, P, Size);
case Instruction::Store: return getModRefInfo((StoreInst*)I, P, Size);
case Instruction::Call: return getModRefInfo((CallInst*)I, P, Size);
case Instruction::Invoke: return getModRefInfo((InvokeInst*)I, P, Size);
case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, P,Size);
case Instruction::Load: return getModRefInfo((const LoadInst*)I, P, Size);
case Instruction::Store: return getModRefInfo((const StoreInst*)I, P,Size);
case Instruction::Call: return getModRefInfo((const CallInst*)I, P, Size);
case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,P,Size);
default: return NoModRef;
}
}
Expand Down
11 changes: 7 additions & 4 deletions include/llvm/Analysis/LibCallAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ namespace llvm {
}
~LibCallAliasAnalysis();

ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size);

ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) {
// TODO: Could compare two direct calls against each other if we cared to.
return AliasAnalysis::getModRefInfo(CS1,CS2);
return AliasAnalysis::getModRefInfo(CS1, CS2);
}

virtual void getAnalysisUsage(AnalysisUsage &AU) const;
Expand All @@ -61,7 +63,8 @@ namespace llvm {

private:
ModRefResult AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
CallSite CS, Value *P, unsigned Size);
ImmutableCallSite CS,
const Value *P, unsigned Size);
};
} // End of llvm namespace

Expand Down
5 changes: 3 additions & 2 deletions include/llvm/Analysis/LibCallSemantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ namespace llvm {
enum LocResult {
Yes, No, Unknown
};
LocResult (*isLocation)(CallSite CS, const Value *Ptr, unsigned Size);
LocResult (*isLocation)(ImmutableCallSite CS,
const Value *Ptr, unsigned Size);
};

/// LibCallFunctionInfo - Each record in the array of FunctionInfo structs
Expand Down Expand Up @@ -142,7 +143,7 @@ namespace llvm {

/// getFunctionInfo - Return the LibCallFunctionInfo object corresponding to
/// the specified function if we have it. If not, return null.
const LibCallFunctionInfo *getFunctionInfo(Function *F) const;
const LibCallFunctionInfo *getFunctionInfo(const Function *F) const;


//===------------------------------------------------------------------===//
Expand Down
21 changes: 11 additions & 10 deletions include/llvm/Support/CallSite.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,6 @@ class CallSiteBase {
}
};

/// ImmutableCallSite - establish a view to a call site for examination
class ImmutableCallSite : public CallSiteBase<> {
typedef CallSiteBase<> Base;
public:
ImmutableCallSite(const Value* V) : Base(V) {}
ImmutableCallSite(const CallInst *CI) : Base(CI) {}
ImmutableCallSite(const InvokeInst *II) : Base(II) {}
ImmutableCallSite(const Instruction *II) : Base(II) {}
};

class CallSite : public CallSiteBase<Function, Value, User, Instruction,
CallInst, InvokeInst, User::op_iterator> {
typedef CallSiteBase<Function, Value, User, Instruction,
Expand Down Expand Up @@ -313,6 +303,17 @@ class CallSite : public CallSiteBase<Function, Value, User, Instruction,
User::op_iterator getCallee() const;
};

/// ImmutableCallSite - establish a view to a call site for examination
class ImmutableCallSite : public CallSiteBase<> {
typedef CallSiteBase<> Base;
public:
ImmutableCallSite(const Value* V) : Base(V) {}
ImmutableCallSite(const CallInst *CI) : Base(CI) {}
ImmutableCallSite(const InvokeInst *II) : Base(II) {}
ImmutableCallSite(const Instruction *II) : Base(II) {}
ImmutableCallSite(CallSite CS) : Base(CS.getInstruction()) {}
};

} // End llvm namespace

#endif
28 changes: 15 additions & 13 deletions lib/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void AliasAnalysis::copyValue(Value *From, Value *To) {
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
AliasAnalysis::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
// FIXME: we can do better.
assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
return AA->getModRefInfo(CS1, CS2);
Expand All @@ -77,7 +77,7 @@ AliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
//===----------------------------------------------------------------------===//

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
AliasAnalysis::getModRefInfo(const LoadInst *L, const Value *P, unsigned Size) {
// If the load address doesn't alias the given address, it doesn't read
// or write the specified memory.
if (!alias(L->getOperand(0), getTypeStoreSize(L->getType()), P, Size))
Expand All @@ -92,7 +92,7 @@ AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
AliasAnalysis::getModRefInfo(const StoreInst *S, const Value *P, unsigned Size) {
// If the stored address cannot alias the pointer in question, then the
// pointer cannot be modified by the store.
if (!alias(S->getOperand(1),
Expand All @@ -113,7 +113,7 @@ AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
}

AliasAnalysis::ModRefBehavior
AliasAnalysis::getModRefBehavior(CallSite CS,
AliasAnalysis::getModRefBehavior(ImmutableCallSite CS,
std::vector<PointerAccessInfo> *Info) {
if (CS.doesNotAccessMemory())
// Can't do better than this.
Expand All @@ -125,7 +125,7 @@ AliasAnalysis::getModRefBehavior(CallSite CS,
}

AliasAnalysis::ModRefBehavior
AliasAnalysis::getModRefBehavior(Function *F,
AliasAnalysis::getModRefBehavior(const Function *F,
std::vector<PointerAccessInfo> *Info) {
if (F) {
if (F->doesNotAccessMemory())
Expand All @@ -134,19 +134,21 @@ AliasAnalysis::getModRefBehavior(Function *F,
if (F->onlyReadsMemory())
return OnlyReadsMemory;
if (unsigned id = F->getIntrinsicID())
return getModRefBehavior(id);
return getIntrinsicModRefBehavior(id);
}
return UnknownModRefBehavior;
}

AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(unsigned iid) {
AliasAnalysis::ModRefBehavior
AliasAnalysis::getIntrinsicModRefBehavior(unsigned iid) {
#define GET_INTRINSIC_MODREF_BEHAVIOR
#include "llvm/Intrinsics.gen"
#undef GET_INTRINSIC_MODREF_BEHAVIOR
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
AliasAnalysis::getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size) {
ModRefBehavior MRB = getModRefBehavior(CS);
if (MRB == DoesNotAccessMemory)
return NoModRef;
Expand All @@ -156,7 +158,7 @@ AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
Mask = Ref;
else if (MRB == AliasAnalysis::AccessesArguments) {
bool doesAlias = false;
for (CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();
AI != AE; ++AI)
if (!isNoAlias(*AI, ~0U, P, Size)) {
doesAlias = true;
Expand Down Expand Up @@ -223,12 +225,12 @@ bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
const Value *Ptr, unsigned Size) {
assert(I1.getParent() == I2.getParent() &&
"Instructions not in same basic block!");
BasicBlock::iterator I = const_cast<Instruction*>(&I1);
BasicBlock::iterator E = const_cast<Instruction*>(&I2);
BasicBlock::const_iterator I = &I1;
BasicBlock::const_iterator E = &I2;
++E; // Convert from inclusive to exclusive range.

for (; I != E; ++I) // Check every instruction in range
if (getModRefInfo(I, const_cast<Value*>(Ptr), Size) & Mod)
if (getModRefInfo(I, Ptr, Size) & Mod)
return true;
return false;
}
Expand All @@ -237,7 +239,7 @@ bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
/// function.
bool llvm::isNoAliasCall(const Value *V) {
if (isa<CallInst>(V) || isa<InvokeInst>(V))
return CallSite(const_cast<Instruction*>(cast<Instruction>(V)))
return ImmutableCallSite(cast<Instruction>(V))
.paramHasAttr(0, Attribute::NoAlias);
return false;
}
Expand Down
9 changes: 6 additions & 3 deletions lib/Analysis/AliasAnalysisCounter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ namespace {
AliasResult alias(const Value *V1, unsigned V1Size,
const Value *V2, unsigned V2Size);

ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size);
ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) {
return AliasAnalysis::getModRefInfo(CS1,CS2);
}
};
Expand Down Expand Up @@ -145,7 +147,8 @@ AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size,
}

AliasAnalysis::ModRefResult
AliasAnalysisCounter::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
AliasAnalysisCounter::getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size) {
ModRefResult R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, P, Size);

const char *MRString;
Expand Down
6 changes: 4 additions & 2 deletions lib/Analysis/AliasDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,14 @@ namespace {
return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
}

ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) {
ModRefResult getModRefInfo(ImmutableCallSite CS,
const Value *P, unsigned Size) {
assert(Vals.find(P) != Vals.end() && "Never seen value in AA before");
return AliasAnalysis::getModRefInfo(CS, P, Size);
}

ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
ModRefResult getModRefInfo(ImmutableCallSite CS1,
ImmutableCallSite CS2) {
return AliasAnalysis::getModRefInfo(CS1,CS2);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/Analysis/AliasSetTracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size,
// Check the call sites list and invoke list...
if (!CallSites.empty()) {
for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
if (AA.getModRefInfo(CallSites[i], const_cast<Value*>(Ptr), Size)
if (AA.getModRefInfo(CallSites[i], Ptr, Size)
!= AliasAnalysis::NoModRef)
return true;
}
Expand Down
Loading

0 comments on commit 79fca6f

Please sign in to comment.