[llvm] r229838 - Add invoke related functionality into StatepointSite classes.
Igor Laevsky
igmyrj at gmail.com
Thu Feb 19 03:02:11 PST 2015
Author: igor.laevsky
Date: Thu Feb 19 05:02:11 2015
New Revision: 229838
URL: http://llvm.org/viewvc/llvm-project?rev=229838&view=rev
Log:
Add invoke related functionality into StatepointSite classes.
Differential Revision: http://reviews.llvm.org/D7364
Modified:
llvm/trunk/include/llvm/IR/Statepoint.h
llvm/trunk/lib/IR/Statepoint.cpp
Modified: llvm/trunk/include/llvm/IR/Statepoint.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Statepoint.h?rev=229838&r1=229837&r2=229838&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Statepoint.h (original)
+++ llvm/trunk/include/llvm/IR/Statepoint.h Thu Feb 19 05:02:11 2015
@@ -24,14 +24,17 @@
namespace llvm {
+class GCRelocateOperands;
+class ImmutableStatepoint;
+
bool isStatepoint(const ImmutableCallSite &CS);
-bool isStatepoint(const Instruction *inst);
-bool isStatepoint(const Instruction &inst);
+bool isStatepoint(const Value *inst);
+bool isStatepoint(const Value &inst);
-bool isGCRelocate(const Instruction *inst);
+bool isGCRelocate(const Value *inst);
bool isGCRelocate(const ImmutableCallSite &CS);
-bool isGCResult(const Instruction *inst);
+bool isGCResult(const Value *inst);
bool isGCResult(const ImmutableCallSite &CS);
/// Analogous to CallSiteBase, this provides most of the actual
@@ -127,6 +130,11 @@ class StatepointBase {
return iterator_range<arg_iterator>(gc_args_begin(), gc_args_end());
}
+ /// Get list of all gc reloactes linked to this statepoint
+ /// May contain several relocations for the same base/derived pair.
+ /// For example this could happen due to relocations on unwinding
+ /// path of invoke.
+ std::vector<GCRelocateOperands> getRelocates(ImmutableStatepoint &IS);
#ifndef NDEBUG
/// Asserts if this statepoint is malformed. Common cases for failure
@@ -187,9 +195,39 @@ class GCRelocateOperands {
assert(isGCRelocate(CS));
}
+ /// Return true if this relocate is tied to the invoke statepoint.
+ /// This includes relocates which are on the unwinding path.
+ bool isTiedToInvoke() const {
+ const Value *Token = RelocateCS.getArgument(0);
+
+ return isa<ExtractValueInst>(Token) ||
+ isa<InvokeInst>(Token);
+ }
+
+ /// Get enclosed relocate intrinsic
+ ImmutableCallSite getUnderlyingCallSite() {
+ return RelocateCS;
+ }
+
/// The statepoint with which this gc.relocate is associated.
const Instruction *statepoint() {
- return cast<Instruction>(RelocateCS.getArgument(0));
+ const Value *token = RelocateCS.getArgument(0);
+
+ // This takes care both of relocates for call statepoints and relocates
+ // on normal path of invoke statepoint.
+ if (!isa<ExtractValueInst>(token)) {
+ return cast<Instruction>(token);
+ }
+
+ // This relocate is on exceptional path of an invoke statepoint
+ const BasicBlock *invokeBB =
+ cast<Instruction>(token)->getParent()->getUniquePredecessor();
+
+ assert(invokeBB && "safepoints should have unique landingpads");
+ assert(invokeBB->getTerminator() && "safepoint block should be well formed");
+ assert(isStatepoint(invokeBB->getTerminator()));
+
+ return invokeBB->getTerminator();
}
/// The index into the associate statepoint's argument list
/// which contains the base pointer of the pointer whose
@@ -211,5 +249,49 @@ class GCRelocateOperands {
return *(CS.arg_begin() + derivedPtrIndex());
}
};
+
+template <typename InstructionTy, typename ValueTy, typename CallSiteTy>
+std::vector<GCRelocateOperands>
+ StatepointBase<InstructionTy, ValueTy, CallSiteTy>::
+ getRelocates(ImmutableStatepoint &IS) {
+
+ std::vector<GCRelocateOperands> res;
+
+ ImmutableCallSite StatepointCS = IS.getCallSite();
+
+ // Search for relocated pointers. Note that working backwards from the
+ // gc_relocates ensures that we only get pairs which are actually relocated
+ // and used after the statepoint.
+ for (const User *U : StatepointCS.getInstruction()->users()) {
+ if (isGCRelocate(U)) {
+ res.push_back(GCRelocateOperands(U));
+ }
+ }
+
+ if (!StatepointCS.isInvoke()) {
+ return res;
+ }
+
+ // We need to scan thorough exceptional relocations if it is invoke statepoint
+ LandingPadInst *LandingPad =
+ cast<InvokeInst>(StatepointCS.getInstruction())->getLandingPadInst();
+
+ // Search for extract value from landingpad instruction to which
+ // gc relocates will be attached
+ for (const User *LandingPadUser : LandingPad->users()) {
+ if (!isa<ExtractValueInst>(LandingPadUser)) {
+ continue;
+ }
+
+ // gc relocates should be attached to this extract value
+ for (const User *U : LandingPadUser->users()) {
+ if (isGCRelocate(U)) {
+ res.push_back(GCRelocateOperands(U));
+ }
+ }
+ }
+ return res;
+}
+
}
#endif
Modified: llvm/trunk/lib/IR/Statepoint.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Statepoint.cpp?rev=229838&r1=229837&r2=229838&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Statepoint.cpp (original)
+++ llvm/trunk/lib/IR/Statepoint.cpp Thu Feb 19 05:02:11 2015
@@ -20,24 +20,34 @@ using namespace std;
using namespace llvm;
bool llvm::isStatepoint(const ImmutableCallSite &CS) {
+ if (!CS.getInstruction()) {
+ // This is not a call site
+ return false;
+ }
+
const Function *F = CS.getCalledFunction();
return (F && F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint);
}
-bool llvm::isStatepoint(const Instruction *inst) {
+bool llvm::isStatepoint(const Value *inst) {
if (isa<InvokeInst>(inst) || isa<CallInst>(inst)) {
ImmutableCallSite CS(inst);
return isStatepoint(CS);
}
return false;
}
-bool llvm::isStatepoint(const Instruction &inst) {
+bool llvm::isStatepoint(const Value &inst) {
return isStatepoint(&inst);
}
bool llvm::isGCRelocate(const ImmutableCallSite &CS) {
+ if (!CS.getInstruction()) {
+ // This is not a call site
+ return false;
+ }
+
return isGCRelocate(CS.getInstruction());
}
-bool llvm::isGCRelocate(const Instruction *inst) {
+bool llvm::isGCRelocate(const Value *inst) {
if (const CallInst *call = dyn_cast<CallInst>(inst)) {
if (const Function *F = call->getCalledFunction()) {
return F->getIntrinsicID() == Intrinsic::experimental_gc_relocate;
@@ -47,9 +57,14 @@ bool llvm::isGCRelocate(const Instructio
}
bool llvm::isGCResult(const ImmutableCallSite &CS) {
+ if (!CS.getInstruction()) {
+ // This is not a call site
+ return false;
+ }
+
return isGCResult(CS.getInstruction());
}
-bool llvm::isGCResult(const Instruction *inst) {
+bool llvm::isGCResult(const Value *inst) {
if (const CallInst *call = dyn_cast<CallInst>(inst)) {
if (Function *F = call->getCalledFunction()) {
return (F->getIntrinsicID() == Intrinsic::experimental_gc_result_int ||
More information about the llvm-commits
mailing list