summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2014-12-29 23:27:30 +0000
committerPhilip Reames <listmail@philipreames.com>2014-12-29 23:27:30 +0000
commit9db26ffc9a9b0b17562042a38f61f35d74acbcb6 (patch)
tree10e403c8c0ec29eeae9d1836508ec170d4e92b85 /llvm/lib
parentec3f49dfdf54289cd3fd2c71a5622a8107d4c717 (diff)
downloadbcm5719-llvm-9db26ffc9a9b0b17562042a38f61f35d74acbcb6.tar.gz
bcm5719-llvm-9db26ffc9a9b0b17562042a38f61f35d74acbcb6.zip
Carry facts about nullness and undef across GC relocation
This change implements four basic optimizations: If a relocated value isn't used, it doesn't need to be relocated. If the value being relocated is null, relocation doesn't change that. (Technically, this might be collector specific. I don't know of one which it doesn't work for though.) If the value being relocated is undef, the relocation is meaningless. If the value being relocated was known nonnull, the relocated pointer also isn't null. (Since it points to the same source language object.) I outlined other planned work in comments. Differential Revision: http://reviews.llvm.org/D6600 llvm-svn: 224968
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index b214b552df8..ec6a61307e1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1134,6 +1134,42 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
break;
}
+ case Intrinsic::experimental_gc_relocate: {
+ // Translate facts known about a pointer before relocating into
+ // facts about the relocate value, while being careful to
+ // preserve relocation semantics.
+ GCRelocateOperands Operands(II);
+ Value *DerivedPtr = Operands.derivedPtr();
+
+ // Remove the relocation if unused, note that this check is required
+ // to prevent the cases below from looping forever.
+ if (II->use_empty())
+ return EraseInstFromFunction(*II);
+
+ // Undef is undef, even after relocation.
+ // TODO: provide a hook for this in GCStrategy. This is clearly legal for
+ // most practical collectors, but there was discussion in the review thread
+ // about whether it was legal for all possible collectors.
+ if (isa<UndefValue>(DerivedPtr))
+ return ReplaceInstUsesWith(*II, DerivedPtr);
+
+ // The relocation of null will be null for most any collector.
+ // TODO: provide a hook for this in GCStrategy. There might be some weird
+ // collector this property does not hold for.
+ if (isa<ConstantPointerNull>(DerivedPtr))
+ return ReplaceInstUsesWith(*II, DerivedPtr);
+
+ // isKnownNonNull -> nonnull attribute
+ if (isKnownNonNull(DerivedPtr))
+ II->addAttribute(AttributeSet::ReturnIndex, Attribute::NonNull);
+
+ // TODO: dereferenceable -> deref attribute
+
+ // TODO: bitcast(relocate(p)) -> relocate(bitcast(p))
+ // Canonicalize on the type from the uses to the defs
+
+ // TODO: relocate((gep p, C, C2, ...)) -> gep(relocate(p), C, C2, ...)
+ }
}
return visitCallSite(II);
OpenPOWER on IntegriCloud