::
declare type*
- @gc.result_ptr(i32 %statepoint_token)
-
- declare fX
- @gc.result_float(i32 %statepoint_token)
-
- declare iX
- @gc.result_int(i32 %statepoint_token)
+ @gc.result(i32 %statepoint_token)
Overview:
"""""""""
// iPTR - An int value the size of the pointer of the current
// target. This should only be used internal to tblgen!
- iPTR = 255
+ iPTR = 255,
+
+ // Any - Any type. This is used for intrinsics that have overloadings.
+ // This is only for tblgen's consumption!
+ Any = 256
};
SimpleValueType SimpleTy;
/// isOverloaded - Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
- return (SimpleTy==MVT::iAny || SimpleTy==MVT::fAny ||
+ return (SimpleTy==MVT::Any ||
+ SimpleTy==MVT::iAny || SimpleTy==MVT::fAny ||
SimpleTy==MVT::vAny || SimpleTy==MVT::iPTRAny);
}
case iAny:
case fAny:
case vAny:
+ case Any:
llvm_unreachable("Value type is overloaded.");
case Metadata:
llvm_unreachable("Value type is metadata.");
// Pseudo valuetype mapped to the current pointer size.
def iPTR : ValueType<0 , 255>;
+
+// Pseudo valuetype to represent "any type of any size".
+def Any : ValueType<0 , 256>;
#undef GET_INTRINSIC_ENUM_VALUES
, num_intrinsics
};
-
+
/// Return the LLVM name for an intrinsic, such as "llvm.ppc.altivec.lvx".
std::string getName(ID id, ArrayRef<Type*> Tys = None);
/// Map a MS builtin name to an intrinsic ID.
ID getIntrinsicForMSBuiltin(const char *Prefix, const char *BuiltinName);
-
+
/// This is a type descriptor which explains the type requirements of an
/// intrinsic. This is returned by getIntrinsicInfoTableEntries.
struct IITDescriptor {
Argument, ExtendArgument, TruncArgument, HalfVecArgument,
SameVecWidthArgument, PtrToArgument
} Kind;
-
+
union {
unsigned Integer_Width;
unsigned Float_Width;
unsigned Struct_NumElements;
unsigned Argument_Info;
};
-
+
enum ArgKind {
+ AK_Any,
AK_AnyInteger,
AK_AnyFloat,
AK_AnyVector,
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument);
- return Argument_Info >> 2;
+ return Argument_Info >> 3;
}
ArgKind getArgumentKind() const {
assert(Kind == Argument || Kind == ExtendArgument ||
Kind == TruncArgument || Kind == HalfVecArgument ||
Kind == SameVecWidthArgument || Kind == PtrToArgument);
- return (ArgKind)(Argument_Info & 3);
+ return (ArgKind)(Argument_Info & 7);
}
-
+
static IITDescriptor get(IITDescriptorKind K, unsigned Field) {
IITDescriptor Result = { K, { Field } };
return Result;
}
};
-
+
/// Return the IIT table descriptor for the specified intrinsic into an array
/// of IITDescriptors.
void getIntrinsicInfoTableEntries(ID id, SmallVectorImpl<IITDescriptor> &T);
-
+
} // End Intrinsic namespace
} // End llvm namespace
class LLVMHalfElementsVectorType<int num> : LLVMMatchType<num>;
def llvm_void_ty : LLVMType<isVoid>;
+def llvm_any_ty : LLVMType<Any>;
def llvm_anyint_ty : LLVMType<iAny>;
def llvm_anyfloat_ty : LLVMType<fAny>;
def llvm_anyvector_ty : LLVMType<vAny>;
[llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty, llvm_vararg_ty]>;
+def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_i32_ty]>;
+def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
+
+// Deprecated: will be removed in a couple of weeks
def int_experimental_gc_result_int : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty]>;
-def int_experimental_gc_result_float : Intrinsic<[llvm_anyfloat_ty],
+def int_experimental_gc_result_float : Intrinsic<[llvm_anyfloat_ty],
[llvm_i32_ty]>;
def int_experimental_gc_result_ptr : Intrinsic<[llvm_anyptr_ty], [llvm_i32_ty]>;
-def int_experimental_gc_relocate : Intrinsic<[llvm_anyptr_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;
-
//===-------------------------- Other Intrinsics --------------------------===//
//
def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
case Intrinsic::experimental_gc_result_int:
case Intrinsic::experimental_gc_result_float:
case Intrinsic::experimental_gc_result_ptr:
+ case Intrinsic::experimental_gc_result:
case Intrinsic::experimental_gc_relocate:
// These intrinsics don't actually represent code after lowering.
return TCC_Free;
}
case Intrinsic::experimental_gc_result_int:
case Intrinsic::experimental_gc_result_float:
- case Intrinsic::experimental_gc_result_ptr: {
+ case Intrinsic::experimental_gc_result_ptr:
+ case Intrinsic::experimental_gc_result: {
visitGCResult(I);
return nullptr;
}
CallInst *IRBuilderBase::CreateGCResult(Instruction *Statepoint,
Type *ResultType,
const Twine &Name) {
- Intrinsic::ID ID;
- if (ResultType->isIntegerTy()) {
- ID = Intrinsic::experimental_gc_result_int;
- } else if (ResultType->isFloatingPointTy()) {
- ID = Intrinsic::experimental_gc_result_float;
- } else if (ResultType->isPointerTy()) {
- ID = Intrinsic::experimental_gc_result_ptr;
- } else {
- llvm_unreachable("unimplemented result type for gc.result");
- }
+ Intrinsic::ID ID = Intrinsic::experimental_gc_result;
Module *M = BB->getParent()->getParent();
Type *Types[] = {ResultType};
Value *FnGCResult = Intrinsic::getDeclaration(M, ID, Types);
if (Function *F = call->getCalledFunction()) {
return (F->getIntrinsicID() == Intrinsic::experimental_gc_result_int ||
F->getIntrinsicID() == Intrinsic::experimental_gc_result_float ||
- F->getIntrinsicID() == Intrinsic::experimental_gc_result_ptr);
+ F->getIntrinsicID() == Intrinsic::experimental_gc_result_ptr ||
+ F->getIntrinsicID() == Intrinsic::experimental_gc_result);
}
}
return false;
ArgTys.push_back(Ty);
switch (D.getArgumentKind()) {
+ case IITDescriptor::AK_Any: return false; // Success
case IITDescriptor::AK_AnyInteger: return !Ty->isIntOrIntVectorTy();
case IITDescriptor::AK_AnyFloat: return !Ty->isFPOrFPVectorTy();
case IITDescriptor::AK_AnyVector: return !isa<VectorType>(Ty);
}
case Intrinsic::experimental_gc_result_int:
case Intrinsic::experimental_gc_result_float:
- case Intrinsic::experimental_gc_result_ptr: {
+ case Intrinsic::experimental_gc_result_ptr:
+ case Intrinsic::experimental_gc_result: {
// Are we tied to a statepoint properly?
CallSite StatepointCS(CI.getArgOperand(0));
const Function *StatepointFn =
; CHECK: retq
entry:
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0)
- %call1 = call zeroext i1 @llvm.experimental.gc.result.int.i1(i32 %safepoint_token)
+ %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
ret i1 %call1
}
; CHECK: retq
entry:
%safepoint_token = tail call i32 (i32 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()* @return_i32, i32 0, i32 0, i32 0)
- %call1 = call zeroext i32 @llvm.experimental.gc.result.int.i32(i32 %safepoint_token)
+ %call1 = call zeroext i32 @llvm.experimental.gc.result.i32(i32 %safepoint_token)
ret i32 %call1
}
; CHECK: retq
entry:
%safepoint_token = tail call i32 (i32* ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()* @return_i32ptr, i32 0, i32 0, i32 0)
- %call1 = call i32* @llvm.experimental.gc.result.ptr.p0i32(i32 %safepoint_token)
+ %call1 = call i32* @llvm.experimental.gc.result.p0i32(i32 %safepoint_token)
ret i32* %call1
}
; CHECK: retq
entry:
%safepoint_token = tail call i32 (float ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_f32f(float ()* @return_float, i32 0, i32 0, i32 0)
- %call1 = call float @llvm.experimental.gc.result.float.f32(i32 %safepoint_token)
+ %call1 = call float @llvm.experimental.gc.result.f32(i32 %safepoint_token)
ret float %call1
}
entry:
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 addrspace(1)* %a)
%call1 = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 4, i32 4)
- %call2 = call zeroext i1 @llvm.experimental.gc.result.int.i1(i32 %safepoint_token)
+ %call2 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
ret i1 %call2
}
}
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
-declare i1 @llvm.experimental.gc.result.int.i1(i32)
+declare i1 @llvm.experimental.gc.result.i1(i32)
declare i32 @llvm.experimental.gc.statepoint.p0f_i32f(i32 ()*, i32, i32, ...)
-declare i32 @llvm.experimental.gc.result.int.i32(i32)
+declare i32 @llvm.experimental.gc.result.i32(i32)
declare i32 @llvm.experimental.gc.statepoint.p0f_p0i32f(i32* ()*, i32, i32, ...)
-declare i32* @llvm.experimental.gc.result.ptr.p0i32(i32)
+declare i32* @llvm.experimental.gc.result.p0i32(i32)
declare i32 @llvm.experimental.gc.statepoint.p0f_f32f(float ()*, i32, i32, ...)
-declare float @llvm.experimental.gc.result.float.f32(i32)
+declare float @llvm.experimental.gc.result.f32(i32)
declare i32 @llvm.experimental.gc.statepoint.p0f_isVoidi32varargf(void (i32, ...)*, i32, i32, ...)
%metadata1 = alloca i32 addrspace(1)*, i32 2, align 8
store i32 addrspace(1)* null, i32 addrspace(1)** %metadata1
%safepoint_token = tail call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 2, i32 addrspace(1)* %ptr, i32 addrspace(1)* null, i32 addrspace(1)* %ptr, i32 addrspace(1)* null)
- %call1 = call zeroext i1 @llvm.experimental.gc.result.int.i1(i32 %safepoint_token)
+ %call1 = call zeroext i1 @llvm.experimental.gc.result.i1(i32 %safepoint_token)
%a = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 6, i32 6)
%b = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %safepoint_token, i32 7, i32 7)
;
}
declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
-declare i1 @llvm.experimental.gc.result.int.i1(i32)
+declare i1 @llvm.experimental.gc.result.i1(i32)
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #3
EnforceVector(TP);
else {
assert((VT < MVT::LAST_VALUETYPE || VT == MVT::iPTR ||
- VT == MVT::iPTRAny) && "Not a concrete type!");
+ VT == MVT::iPTRAny || VT == MVT::Any) && "Not a concrete type!");
TypeVec.push_back(VT);
}
}
case MVT::i32: return "MVT::i32";
case MVT::i64: return "MVT::i64";
case MVT::i128: return "MVT::i128";
+ case MVT::Any: return "MVT::Any";
case MVT::iAny: return "MVT::iAny";
case MVT::fAny: return "MVT::fAny";
case MVT::vAny: return "MVT::vAny";
Sig.push_back(IIT_HALF_VEC_ARG);
else if (R->isSubClassOf("LLVMVectorSameWidth")) {
Sig.push_back(IIT_SAME_VEC_WIDTH_ARG);
- Sig.push_back((Number << 2) | ArgCodes[Number]);
+ Sig.push_back((Number << 3) | ArgCodes[Number]);
MVT::SimpleValueType VT = getValueType(R->getValueAsDef("ElTy"));
EncodeFixedValueType(VT, Sig);
return;
}
else
Sig.push_back(IIT_ARG);
- return Sig.push_back((Number << 2) | ArgCodes[Number]);
+ return Sig.push_back((Number << 3) | ArgCodes[Number]);
}
MVT::SimpleValueType VT = getValueType(R->getValueAsDef("VT"));
case MVT::iPTRAny: ++Tmp; // FALL THROUGH.
case MVT::vAny: ++Tmp; // FALL THROUGH.
case MVT::fAny: ++Tmp; // FALL THROUGH.
- case MVT::iAny: {
+ case MVT::iAny: ++Tmp; // FALL THROUGH.
+ case MVT::Any: {
// If this is an "any" valuetype, then the type is the type of the next
// type in the list specified to getIntrinsic().
Sig.push_back(IIT_ARG);
unsigned ArgNo = ArgCodes.size();
ArgCodes.push_back(Tmp);
- // Encode what sort of argument it must be in the low 2 bits of the ArgNo.
- return Sig.push_back((ArgNo << 2) | Tmp);
+ // Encode what sort of argument it must be in the low 3 bits of the ArgNo.
+ return Sig.push_back((ArgNo << 3) | Tmp);
}
case MVT::iPTR: {