Index: llvm/trunk/docs/Statepoints.rst =================================================================== --- llvm/trunk/docs/Statepoints.rst +++ llvm/trunk/docs/Statepoints.rst @@ -236,13 +236,7 @@ :: 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: """"""""" Index: llvm/trunk/include/llvm/CodeGen/MachineValueType.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineValueType.h +++ llvm/trunk/include/llvm/CodeGen/MachineValueType.h @@ -152,7 +152,11 @@ // 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; @@ -245,7 +249,8 @@ /// 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); } @@ -380,6 +385,7 @@ case iAny: case fAny: case vAny: + case Any: llvm_unreachable("Value type is overloaded."); case Metadata: llvm_unreachable("Value type is metadata."); Index: llvm/trunk/include/llvm/CodeGen/ValueTypes.td =================================================================== --- llvm/trunk/include/llvm/CodeGen/ValueTypes.td +++ llvm/trunk/include/llvm/CodeGen/ValueTypes.td @@ -98,3 +98,6 @@ // 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>; Index: llvm/trunk/include/llvm/IR/Intrinsics.h =================================================================== --- llvm/trunk/include/llvm/IR/Intrinsics.h +++ llvm/trunk/include/llvm/IR/Intrinsics.h @@ -41,7 +41,7 @@ #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 Tys = None); @@ -69,7 +69,7 @@ /// 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 { @@ -79,7 +79,7 @@ Argument, ExtendArgument, TruncArgument, HalfVecArgument, SameVecWidthArgument, PtrToArgument } Kind; - + union { unsigned Integer_Width; unsigned Float_Width; @@ -88,8 +88,9 @@ unsigned Struct_NumElements; unsigned Argument_Info; }; - + enum ArgKind { + AK_Any, AK_AnyInteger, AK_AnyFloat, AK_AnyVector, @@ -99,25 +100,25 @@ 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 &T); - + } // End Intrinsic namespace } // End llvm namespace Index: llvm/trunk/include/llvm/IR/Intrinsics.td =================================================================== --- llvm/trunk/include/llvm/IR/Intrinsics.td +++ llvm/trunk/include/llvm/IR/Intrinsics.td @@ -123,6 +123,7 @@ class LLVMHalfElementsVectorType : LLVMMatchType; def llvm_void_ty : LLVMType; +def llvm_any_ty : LLVMType; def llvm_anyint_ty : LLVMType; def llvm_anyfloat_ty : LLVMType; def llvm_anyvector_ty : LLVMType; @@ -516,14 +517,16 @@ [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]>, Index: llvm/trunk/lib/Analysis/TargetTransformInfo.cpp =================================================================== --- llvm/trunk/lib/Analysis/TargetTransformInfo.cpp +++ llvm/trunk/lib/Analysis/TargetTransformInfo.cpp @@ -416,6 +416,7 @@ 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; Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -5604,7 +5604,8 @@ } 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; } Index: llvm/trunk/lib/IR/IRBuilder.cpp =================================================================== --- llvm/trunk/lib/IR/IRBuilder.cpp +++ llvm/trunk/lib/IR/IRBuilder.cpp @@ -263,16 +263,7 @@ 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); Index: llvm/trunk/lib/IR/Statepoint.cpp =================================================================== --- llvm/trunk/lib/IR/Statepoint.cpp +++ llvm/trunk/lib/IR/Statepoint.cpp @@ -54,7 +54,8 @@ 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; Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -2391,6 +2391,7 @@ 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(Ty); @@ -2721,7 +2722,8 @@ } 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 = Index: llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll +++ llvm/trunk/test/CodeGen/X86/statepoint-call-lowering.ll @@ -21,7 +21,7 @@ ; 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 } @@ -33,7 +33,7 @@ ; 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 } @@ -45,7 +45,7 @@ ; 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 } @@ -57,7 +57,7 @@ ; 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 } @@ -72,7 +72,7 @@ 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 } @@ -88,16 +88,16 @@ } 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, ...) Index: llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll +++ llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll @@ -22,7 +22,7 @@ %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) ; @@ -30,7 +30,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 Index: llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp +++ llvm/trunk/utils/TableGen/CodeGenDAGPatterns.cpp @@ -53,7 +53,7 @@ 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); } } Index: llvm/trunk/utils/TableGen/CodeGenTarget.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp @@ -57,6 +57,7 @@ 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"; Index: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp +++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp @@ -309,7 +309,7 @@ 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; @@ -319,7 +319,7 @@ } 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")); @@ -330,7 +330,8 @@ 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); @@ -339,8 +340,8 @@ 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: {