summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/Verifier.cpp
diff options
context:
space:
mode:
authorPat Gavlin <pagavlin@microsoft.com>2015-05-08 18:07:42 +0000
committerPat Gavlin <pagavlin@microsoft.com>2015-05-08 18:07:42 +0000
commitcc0431d1c0643862bd5f8952499ad7a6a178050e (patch)
tree9819d2c3af52fde69ec3735accef33f6ae433e5c /llvm/lib/IR/Verifier.cpp
parent78b0d51cd004f6c6ffe1b3fc3651a3c17f7a1b09 (diff)
downloadbcm5719-llvm-cc0431d1c0643862bd5f8952499ad7a6a178050e.tar.gz
bcm5719-llvm-cc0431d1c0643862bd5f8952499ad7a6a178050e.zip
Extend the statepoint intrinsic to allow statepoints to be marked as transitions from GC-aware code to code that is not GC-aware.
This changes the shape of the statepoint intrinsic from: @llvm.experimental.gc.statepoint(anyptr target, i32 # call args, i32 unused, ...call args, i32 # deopt args, ...deopt args, ...gc args) to: @llvm.experimental.gc.statepoint(anyptr target, i32 # call args, i32 flags, ...call args, i32 # transition args, ...transition args, i32 # deopt args, ...deopt args, ...gc args) This extension offers the backend the opportunity to insert (somewhat) arbitrary code to manage the transition from GC-aware code to code that is not GC-aware and back. In order to support the injection of transition code, this extension wraps the STATEPOINT ISD node generated by the usual lowering lowering with two additional nodes: GC_TRANSITION_START and GC_TRANSITION_END. The transition arguments that were passed passed to the intrinsic (if any) are lowered and provided as operands to these nodes and may be used by the backend during code generation. Eventually, the lowering of the GC_TRANSITION_{START,END} nodes should be informed by the GC strategy in use for the function containing the intrinsic call; for now, these nodes are instead replaced with no-ops. Differential Revision: http://reviews.llvm.org/D9501 llvm-svn: 236888
Diffstat (limited to 'llvm/lib/IR/Verifier.cpp')
-rw-r--r--llvm/lib/IR/Verifier.cpp37
1 files changed, 30 insertions, 7 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 4b54f278219..374f8f210be 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1529,9 +1529,12 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
Assert(NumCallArgs == NumParams,
"gc.statepoint mismatch in number of call args", &CI);
- const Value *Unused = CS.getArgument(2);
- Assert(isa<ConstantInt>(Unused) && cast<ConstantInt>(Unused)->isNullValue(),
- "gc.statepoint parameter #3 must be zero", &CI);
+ const Value *FlagsV = CS.getArgument(2);
+ Assert(isa<ConstantInt>(FlagsV),
+ "gc.statepoint flags must be constant integer", &CI);
+ const uint64_t Flags = cast<ConstantInt>(FlagsV)->getZExtValue();
+ Assert((Flags & ~(uint64_t)StatepointFlags::MaskAll) == 0,
+ "unknown flag used in gc.statepoint flags argument", &CI);
// Verify that the types of the call parameter arguments match
// the type of the wrapped callee.
@@ -1544,7 +1547,19 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
&CI);
}
const int EndCallArgsInx = 2+NumCallArgs;
- const Value *NumDeoptArgsV = CS.getArgument(EndCallArgsInx+1);
+
+ const Value *NumTransitionArgsV = CS.getArgument(EndCallArgsInx+1);
+ Assert(isa<ConstantInt>(NumTransitionArgsV),
+ "gc.statepoint number of transition arguments "
+ "must be constant integer",
+ &CI);
+ const int NumTransitionArgs =
+ cast<ConstantInt>(NumTransitionArgsV)->getZExtValue();
+ Assert(NumTransitionArgs >= 0,
+ "gc.statepoint number of transition arguments must be positive", &CI);
+ const int EndTransitionArgsInx = EndCallArgsInx + 1 + NumTransitionArgs;
+
+ const Value *NumDeoptArgsV = CS.getArgument(EndTransitionArgsInx+1);
Assert(isa<ConstantInt>(NumDeoptArgsV),
"gc.statepoint number of deoptimization arguments "
"must be constant integer",
@@ -1554,7 +1569,9 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) {
"must be positive",
&CI);
- Assert(4 + NumCallArgs + NumDeoptArgs <= (int)CS.arg_size(),
+ const int ExpectedNumArgs =
+ 5 + NumCallArgs + NumTransitionArgs + NumDeoptArgs;
+ Assert(ExpectedNumArgs <= (int)CS.arg_size(),
"gc.statepoint too few arguments according to length fields", &CI);
// Check that the only uses of this gc.statepoint are gc.result or
@@ -3346,11 +3363,17 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
Assert(StatepointCS.arg_size() > NumCallArgs+3,
"gc.statepoint: mismatch in number of call arguments");
Assert(isa<ConstantInt>(StatepointCS.getArgument(NumCallArgs+3)),
+ "gc.statepoint: number of transition arguments must be "
+ "a constant integer");
+ const int NumTransitionArgs =
+ cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue();
+ const int DeoptArgsStart = 2 + NumCallArgs + 1 + NumTransitionArgs + 1;
+ Assert(isa<ConstantInt>(StatepointCS.getArgument(DeoptArgsStart)),
"gc.statepoint: number of deoptimization arguments must be "
"a constant integer");
const int NumDeoptArgs =
- cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue();
- const int GCParamArgsStart = NumCallArgs + NumDeoptArgs + 4;
+ cast<ConstantInt>(StatepointCS.getArgument(DeoptArgsStart))->getZExtValue();
+ const int GCParamArgsStart = DeoptArgsStart + 1 + NumDeoptArgs;
const int GCParamArgsEnd = StatepointCS.arg_size();
Assert(GCParamArgsStart <= BaseIndex && BaseIndex < GCParamArgsEnd,
"gc.relocate: statepoint base index doesn't fall within the "
OpenPOWER on IntegriCloud