[PATCH] D11606: Vtable aliasing improvement: makes obj->vtable noalias obj and modref(obj->virt_call, obj->vtable) = REF
Andrew Zhogin
andrew.zhogin at gmail.com
Wed Jul 29 12:46:20 PDT 2015
andrew.zhogin created this revision.
andrew.zhogin added reviewers: hfinkel, reames, sanjoy.
andrew.zhogin added a subscriber: llvm-commits.
This patch contains two improvements for basicaa alias analysis:
* Knowledge that object pointer can't be aliased with vtable loaded from this object (obj->vtable noalias obj).
* Knowledge that virtual call to object can't change this object's vtable.
modrefinfo(obj->virt_call, obj->vtable) = REF; modrefinfo(obj->virt_call, obj->vtable->fn) = REF;
Vtable is identified by TBAA metadata (isTBAAVtableAccess - already existing function).
Combined with this patch (http://reviews.llvm.org/D11547) it makes very simple in-loop devirtualization works. This bug's example is fixed: https://llvm.org/bugs/show_bug.cgi?id=20801
But just a bit more complex samples require AliasSetTracker's merge sets problem to be fixed.
"alias set collapse and LICM": https://groups.google.com/forum/#!topic/llvm-dev/Qy66vhi5NaY
http://reviews.llvm.org/D11606
Files:
include/llvm/Analysis/AliasAnalysis.h
lib/Analysis/AliasAnalysis.cpp
lib/Analysis/BasicAliasAnalysis.cpp
Index: lib/Analysis/BasicAliasAnalysis.cpp
===================================================================
--- lib/Analysis/BasicAliasAnalysis.cpp
+++ lib/Analysis/BasicAliasAnalysis.cpp
@@ -791,6 +791,31 @@
if (CI->isTailCall())
return MRI_NoModRef;
+ // If this is virtual call to obj, considering obj->vtable and obj->vtable->fn as not modifiable
+ if (CS.getNumArgOperands() > 0) {
+ const auto *CalleeVal = CS.getCalledValue(); // must be load vtable + offset
+ const auto *CallObj = CS.getArgOperand(0); // must be obj
+
+ if (const auto *CalleeLd = dyn_cast<LoadInst>(CalleeVal)) {
+ const auto *VtableVal = CalleeLd->getOperand(0);
+ const auto *VtableValUnder = GetUnderlyingObject(VtableVal, *DL);
+ if (const auto *VtableLd = dyn_cast<LoadInst>(VtableValUnder)) {
+ AAMDNodes AAInfo;
+ VtableLd->getAAMetadata(AAInfo);
+ if (AAInfo.TBAA) {
+ if (AAInfo.TBAA->isTBAAVtableAccess()) {
+ const auto *ObjForVtable = VtableLd->getOperand(0);
+
+ if (isMustAlias(GetUnderlyingObject(ObjForVtable, *DL), CallObj))
+ if (isMustAlias(VtableValUnder, Object)
+ || isMustAlias(ObjForVtable, Object))
+ return MRI_Ref;
+ }
+ }
+ }
+ }
+ }
+
// If the pointer is to a locally allocated object that does not escape,
// then the call can not mod/ref the pointer unless the call takes the pointer
// as an argument, and itself doesn't capture it.
@@ -1433,6 +1458,10 @@
return NoAlias;
if (isEscapeSource(O2) && isNonEscapingLocalObject(O1))
return NoAlias;
+
+ // Considering Object's Vtable can't alias Object
+ if (isVtableLoadFrom(O1, O2) || isVtableLoadFrom(O2, O1))
+ return NoAlias;
}
// If the size of one access is larger than the entire object on the other
Index: lib/Analysis/AliasAnalysis.cpp
===================================================================
--- lib/Analysis/AliasAnalysis.cpp
+++ lib/Analysis/AliasAnalysis.cpp
@@ -446,6 +446,17 @@
return false;
}
+/// isVtableLoadFrom - Return true if Vtable is vtable load from Obj
+bool AliasAnalysis::isVtableLoadFrom(const Value *Vtable, const Value *Obj) {
+ if (const auto *VtableLd = dyn_cast<LoadInst>(Vtable)) {
+ AAMDNodes AAInfo;
+ VtableLd->getAAMetadata(AAInfo);
+ if (AAInfo.TBAA && AAInfo.TBAA->isTBAAVtableAccess())
+ return GetUnderlyingObject(VtableLd->getOperand(0), *DL) == Obj;
+ }
+ return false;
+}
+
/// isNoAliasCall - Return true if this pointer is returned by a noalias
/// function.
bool llvm::isNoAliasCall(const Value *V) {
Index: include/llvm/Analysis/AliasAnalysis.h
===================================================================
--- include/llvm/Analysis/AliasAnalysis.h
+++ include/llvm/Analysis/AliasAnalysis.h
@@ -543,6 +543,8 @@
const ModRefInfo Mode) {
return canInstructionRangeModRef(I1, I2, MemoryLocation(Ptr, Size), Mode);
}
+ /// isVtableLoadFrom - Return true if Vtable is vtable load from Obj
+ bool isVtableLoadFrom(const Value *Vtable, const Value *Obj);
};
/// isNoAliasCall - Return true if this pointer is returned by a noalias
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11606.30938.patch
Type: text/x-patch
Size: 3301 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150729/efd4771b/attachment.bin>
More information about the llvm-commits
mailing list