forked from OSchip/llvm-project
[MSSA] Print more optimization information
In particular, when asked to print a MemoryAccess, we'll now print where defs are optimized to, and we'll print optimized access types. This patch also introduces an operator<< to make printing AliasResults easier. Patch by Juneyoung Lee! Differential Revision: https://reviews.llvm.org/D47860 llvm-svn: 334760
This commit is contained in:
parent
f85ca6abee
commit
aa283d80fe
|
@ -91,6 +91,9 @@ enum AliasResult : uint8_t {
|
|||
MustAlias,
|
||||
};
|
||||
|
||||
/// << operator for AliasResult.
|
||||
raw_ostream &operator<<(raw_ostream &OS, AliasResult AR);
|
||||
|
||||
/// Flags indicating whether a memory access modifies or references memory.
|
||||
///
|
||||
/// This is no access at all, a modification, a reference, or both
|
||||
|
|
|
@ -372,6 +372,24 @@ FunctionModRefBehavior AAResults::getModRefBehavior(const Function *F) {
|
|||
return Result;
|
||||
}
|
||||
|
||||
raw_ostream &llvm::operator<<(raw_ostream &OS, AliasResult AR) {
|
||||
switch (AR) {
|
||||
case NoAlias:
|
||||
OS << "NoAlias";
|
||||
break;
|
||||
case MustAlias:
|
||||
OS << "MustAlias";
|
||||
break;
|
||||
case MayAlias:
|
||||
OS << "MayAlias";
|
||||
break;
|
||||
case PartialAlias:
|
||||
OS << "PartialAlias";
|
||||
break;
|
||||
}
|
||||
return OS;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Helper method implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -41,7 +41,7 @@ static cl::opt<bool> PrintMustModRef("print-mustmodref", cl::ReallyHidden);
|
|||
|
||||
static cl::opt<bool> EvalAAMD("evaluate-aa-metadata", cl::ReallyHidden);
|
||||
|
||||
static void PrintResults(const char *Msg, bool P, const Value *V1,
|
||||
static void PrintResults(AliasResult AR, bool P, const Value *V1,
|
||||
const Value *V2, const Module *M) {
|
||||
if (PrintAll || P) {
|
||||
std::string o1, o2;
|
||||
|
@ -50,18 +50,15 @@ static void PrintResults(const char *Msg, bool P, const Value *V1,
|
|||
V1->printAsOperand(os1, true, M);
|
||||
V2->printAsOperand(os2, true, M);
|
||||
}
|
||||
|
||||
|
||||
if (o2 < o1)
|
||||
std::swap(o1, o2);
|
||||
errs() << " " << Msg << ":\t"
|
||||
<< o1 << ", "
|
||||
<< o2 << "\n";
|
||||
errs() << " " << AR << ":\t" << o1 << ", " << o2 << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr,
|
||||
Module *M) {
|
||||
static inline void PrintModRefResults(const char *Msg, bool P, Instruction *I,
|
||||
Value *Ptr, Module *M) {
|
||||
if (PrintAll || P) {
|
||||
errs() << " " << Msg << ": Ptr: ";
|
||||
Ptr->printAsOperand(errs(), true, M);
|
||||
|
@ -69,21 +66,19 @@ PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr,
|
|||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB,
|
||||
Module *M) {
|
||||
static inline void PrintModRefResults(const char *Msg, bool P, CallSite CSA,
|
||||
CallSite CSB, Module *M) {
|
||||
if (PrintAll || P) {
|
||||
errs() << " " << Msg << ": " << *CSA.getInstruction()
|
||||
<< " <-> " << *CSB.getInstruction() << '\n';
|
||||
errs() << " " << Msg << ": " << *CSA.getInstruction() << " <-> "
|
||||
<< *CSB.getInstruction() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
PrintLoadStoreResults(const char *Msg, bool P, const Value *V1,
|
||||
const Value *V2, const Module *M) {
|
||||
static inline void PrintLoadStoreResults(AliasResult AR, bool P,
|
||||
const Value *V1, const Value *V2,
|
||||
const Module *M) {
|
||||
if (PrintAll || P) {
|
||||
errs() << " " << Msg << ": " << *V1
|
||||
<< " <-> " << *V2 << '\n';
|
||||
errs() << " " << AR << ": " << *V1 << " <-> " << *V2 << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,22 +150,22 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
|
|||
Type *I2ElTy =cast<PointerType>((*I2)->getType())->getElementType();
|
||||
if (I2ElTy->isSized()) I2Size = DL.getTypeStoreSize(I2ElTy);
|
||||
|
||||
switch (AA.alias(*I1, I1Size, *I2, I2Size)) {
|
||||
AliasResult AR = AA.alias(*I1, I1Size, *I2, I2Size);
|
||||
switch (AR) {
|
||||
case NoAlias:
|
||||
PrintResults("NoAlias", PrintNoAlias, *I1, *I2, F.getParent());
|
||||
PrintResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
|
||||
++NoAliasCount;
|
||||
break;
|
||||
case MayAlias:
|
||||
PrintResults("MayAlias", PrintMayAlias, *I1, *I2, F.getParent());
|
||||
PrintResults(AR, PrintMayAlias, *I1, *I2, F.getParent());
|
||||
++MayAliasCount;
|
||||
break;
|
||||
case PartialAlias:
|
||||
PrintResults("PartialAlias", PrintPartialAlias, *I1, *I2,
|
||||
F.getParent());
|
||||
PrintResults(AR, PrintPartialAlias, *I1, *I2, F.getParent());
|
||||
++PartialAliasCount;
|
||||
break;
|
||||
case MustAlias:
|
||||
PrintResults("MustAlias", PrintMustAlias, *I1, *I2, F.getParent());
|
||||
PrintResults(AR, PrintMustAlias, *I1, *I2, F.getParent());
|
||||
++MustAliasCount;
|
||||
break;
|
||||
}
|
||||
|
@ -181,26 +176,23 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
|
|||
// iterate over all pairs of load, store
|
||||
for (Value *Load : Loads) {
|
||||
for (Value *Store : Stores) {
|
||||
switch (AA.alias(MemoryLocation::get(cast<LoadInst>(Load)),
|
||||
MemoryLocation::get(cast<StoreInst>(Store)))) {
|
||||
AliasResult AR = AA.alias(MemoryLocation::get(cast<LoadInst>(Load)),
|
||||
MemoryLocation::get(cast<StoreInst>(Store)));
|
||||
switch (AR) {
|
||||
case NoAlias:
|
||||
PrintLoadStoreResults("NoAlias", PrintNoAlias, Load, Store,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintNoAlias, Load, Store, F.getParent());
|
||||
++NoAliasCount;
|
||||
break;
|
||||
case MayAlias:
|
||||
PrintLoadStoreResults("MayAlias", PrintMayAlias, Load, Store,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintMayAlias, Load, Store, F.getParent());
|
||||
++MayAliasCount;
|
||||
break;
|
||||
case PartialAlias:
|
||||
PrintLoadStoreResults("PartialAlias", PrintPartialAlias, Load, Store,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintPartialAlias, Load, Store, F.getParent());
|
||||
++PartialAliasCount;
|
||||
break;
|
||||
case MustAlias:
|
||||
PrintLoadStoreResults("MustAlias", PrintMustAlias, Load, Store,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintMustAlias, Load, Store, F.getParent());
|
||||
++MustAliasCount;
|
||||
break;
|
||||
}
|
||||
|
@ -211,26 +203,23 @@ void AAEvaluator::runInternal(Function &F, AAResults &AA) {
|
|||
for (SetVector<Value *>::iterator I1 = Stores.begin(), E = Stores.end();
|
||||
I1 != E; ++I1) {
|
||||
for (SetVector<Value *>::iterator I2 = Stores.begin(); I2 != I1; ++I2) {
|
||||
switch (AA.alias(MemoryLocation::get(cast<StoreInst>(*I1)),
|
||||
MemoryLocation::get(cast<StoreInst>(*I2)))) {
|
||||
AliasResult AR = AA.alias(MemoryLocation::get(cast<StoreInst>(*I1)),
|
||||
MemoryLocation::get(cast<StoreInst>(*I2)));
|
||||
switch (AR) {
|
||||
case NoAlias:
|
||||
PrintLoadStoreResults("NoAlias", PrintNoAlias, *I1, *I2,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintNoAlias, *I1, *I2, F.getParent());
|
||||
++NoAliasCount;
|
||||
break;
|
||||
case MayAlias:
|
||||
PrintLoadStoreResults("MayAlias", PrintMayAlias, *I1, *I2,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintMayAlias, *I1, *I2, F.getParent());
|
||||
++MayAliasCount;
|
||||
break;
|
||||
case PartialAlias:
|
||||
PrintLoadStoreResults("PartialAlias", PrintPartialAlias, *I1, *I2,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintPartialAlias, *I1, *I2, F.getParent());
|
||||
++PartialAliasCount;
|
||||
break;
|
||||
case MustAlias:
|
||||
PrintLoadStoreResults("MustAlias", PrintMustAlias, *I1, *I2,
|
||||
F.getParent());
|
||||
PrintLoadStoreResults(AR, PrintMustAlias, *I1, *I2, F.getParent());
|
||||
++MustAliasCount;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1857,12 +1857,24 @@ void MemoryAccess::print(raw_ostream &OS) const {
|
|||
void MemoryDef::print(raw_ostream &OS) const {
|
||||
MemoryAccess *UO = getDefiningAccess();
|
||||
|
||||
auto printID = [&OS](MemoryAccess *A) {
|
||||
if (A && A->getID())
|
||||
OS << A->getID();
|
||||
else
|
||||
OS << LiveOnEntryStr;
|
||||
};
|
||||
|
||||
OS << getID() << " = MemoryDef(";
|
||||
if (UO && UO->getID())
|
||||
OS << UO->getID();
|
||||
else
|
||||
OS << LiveOnEntryStr;
|
||||
OS << ')';
|
||||
printID(UO);
|
||||
OS << ")";
|
||||
|
||||
if (isOptimized()) {
|
||||
OS << "->";
|
||||
printID(getOptimized());
|
||||
|
||||
if (Optional<AliasResult> AR = getOptimizedAccessType())
|
||||
OS << " " << *AR;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryPhi::print(raw_ostream &OS) const {
|
||||
|
@ -1899,6 +1911,9 @@ void MemoryUse::print(raw_ostream &OS) const {
|
|||
else
|
||||
OS << LiveOnEntryStr;
|
||||
OS << ')';
|
||||
|
||||
if (Optional<AliasResult> AR = getOptimizedAccessType())
|
||||
OS << " " << *AR;
|
||||
}
|
||||
|
||||
void MemoryAccess::dump() const {
|
||||
|
|
|
@ -18,16 +18,16 @@ entry:
|
|||
; CHECK: 4 = MemoryDef(3)
|
||||
; CHECK-NEXT: store i32 7, i32* %1, align 4
|
||||
store i32 7, i32* %1, align 4
|
||||
; CHECK: MemoryUse(3)
|
||||
; CHECK: MemoryUse(3) MustAlias
|
||||
; CHECK-NEXT: %2 = load i32, i32* %0, align 4
|
||||
%2 = load i32, i32* %0, align 4
|
||||
; CHECK: MemoryUse(4)
|
||||
; CHECK: MemoryUse(4) MustAlias
|
||||
; CHECK-NEXT: %3 = load i32, i32* %1, align 4
|
||||
%3 = load i32, i32* %1, align 4
|
||||
; CHECK: MemoryUse(3)
|
||||
; CHECK: MemoryUse(3) MustAlias
|
||||
; CHECK-NEXT: %4 = load i32, i32* %0, align 4
|
||||
%4 = load i32, i32* %0, align 4
|
||||
; CHECK: MemoryUse(4)
|
||||
; CHECK: MemoryUse(4) MustAlias
|
||||
; CHECK-NEXT: %5 = load i32, i32* %1, align 4
|
||||
%5 = load i32, i32* %1, align 4
|
||||
%add = add nsw i32 %3, %5
|
||||
|
|
Loading…
Reference in New Issue