@@ -941,21 +941,24 @@ static void emit_type_error(const jl_cgval_t &x, Value *type, const std::string
941
941
#endif
942
942
}
943
943
944
- static Value * emit_isa (const jl_cgval_t &x, jl_value_t *type, const std::string *msg, jl_codectx_t *ctx)
944
+ static std::pair< Value*, bool > emit_isa (const jl_cgval_t &x, jl_value_t *type, const std::string *msg, jl_codectx_t *ctx)
945
945
{
946
- bool maybe_isa = true ;
946
+ Optional< bool > known_isa ;
947
947
if (x.constant )
948
- maybe_isa = jl_isa (x.constant , type);
948
+ known_isa = jl_isa (x.constant , type);
949
+ else if (jl_subtype (x.typ , type))
950
+ known_isa = true ;
949
951
else if (jl_type_intersection (x.typ , type) == (jl_value_t *)jl_bottom_type)
950
- maybe_isa = false ;
951
- if (!maybe_isa && msg) {
952
- emit_type_error (x, literal_pointer_val (type), *msg, ctx);
953
- builder.CreateUnreachable ();
954
- BasicBlock *failBB = BasicBlock::Create (jl_LLVMContext, " fail" , ctx->f );
955
- builder.SetInsertPoint (failBB);
952
+ known_isa = false ;
953
+ if (known_isa) {
954
+ if (!*known_isa && msg) {
955
+ emit_type_error (x, literal_pointer_val (type), *msg, ctx);
956
+ builder.CreateUnreachable ();
957
+ BasicBlock *failBB = BasicBlock::Create (jl_LLVMContext, " fail" , ctx->f );
958
+ builder.SetInsertPoint (failBB);
959
+ }
960
+ return std::make_pair (ConstantInt::get (T_int1, *known_isa), true );
956
961
}
957
- if (!maybe_isa || x.constant )
958
- return ConstantInt::get (T_int1, maybe_isa);
959
962
960
963
// intersection with Type needs to be handled specially
961
964
if (jl_has_intersect_type_not_kind (type)) {
@@ -966,15 +969,15 @@ static Value *emit_isa(const jl_cgval_t &x, jl_value_t *type, const std::string
966
969
#else
967
970
builder.CreateCall2 (prepare_call (jltypeassert_func), vx, literal_pointer_val (type));
968
971
#endif
969
- return ConstantInt::get (T_int1, 1 );
972
+ return std::make_pair ( ConstantInt::get (T_int1, 1 ), true );
970
973
}
971
- return builder.CreateICmpNE (
974
+ return std::make_pair ( builder.CreateICmpNE (
972
975
#if JL_LLVM_VERSION >= 30700
973
976
builder.CreateCall (prepare_call (jlisa_func), { vx, literal_pointer_val (type) }),
974
977
#else
975
978
builder.CreateCall2 (prepare_call (jlisa_func), vx, literal_pointer_val (type)),
976
979
#endif
977
- ConstantInt::get (T_int32, 0 ));
980
+ ConstantInt::get (T_int32, 0 )), false ) ;
978
981
}
979
982
// tests for isa leaftype can be handled with pointer comparisons
980
983
if (jl_is_leaf_type (type)) {
@@ -983,7 +986,7 @@ static Value *emit_isa(const jl_cgval_t &x, jl_value_t *type, const std::string
983
986
if (tindex > 0 ) {
984
987
// optimize more when we know that this is a split union-type where tindex = 0 is invalid
985
988
Value *xtindex = builder.CreateAnd (x.TIndex , ConstantInt::get (T_int8, 0x7f ));
986
- return builder.CreateICmpEQ (xtindex, ConstantInt::get (T_int8, tindex));
989
+ return std::make_pair ( builder.CreateICmpEQ (xtindex, ConstantInt::get (T_int8, tindex)), false );
987
990
}
988
991
else {
989
992
// test for (x.TIndex == 0x80 && typeof(x.V) == type)
@@ -999,31 +1002,29 @@ static Value *emit_isa(const jl_cgval_t &x, jl_value_t *type, const std::string
999
1002
PHINode *istype = builder.CreatePHI (T_int1, 2 );
1000
1003
istype->addIncoming (ConstantInt::get (T_int1, 0 ), currBB);
1001
1004
istype->addIncoming (istype_boxed, isaBB);
1002
- return istype;
1005
+ return std::make_pair ( istype, false ) ;
1003
1006
}
1004
1007
}
1005
- return builder.CreateICmpEQ (emit_typeof_boxed (x, ctx), literal_pointer_val (type));
1008
+ return std::make_pair ( builder.CreateICmpEQ (emit_typeof_boxed (x, ctx), literal_pointer_val (type)), false );
1006
1009
}
1007
1010
// everything else can be handled via subtype tests
1008
1011
Value *vxt = emit_typeof_boxed (x, ctx);
1009
- return builder.CreateICmpNE (
1012
+ return std::make_pair ( builder.CreateICmpNE (
1010
1013
#if JL_LLVM_VERSION >= 30700
1011
1014
builder.CreateCall (prepare_call (jlsubtype_func), { vxt, literal_pointer_val (type) }),
1012
1015
#else
1013
1016
builder.CreateCall2 (prepare_call (jlsubtype_func), vxt, literal_pointer_val (type)),
1014
1017
#endif
1015
- ConstantInt::get (T_int32, 0 ));
1018
+ ConstantInt::get (T_int32, 0 )), false ) ;
1016
1019
}
1017
1020
1018
1021
static void emit_typecheck (const jl_cgval_t &x, jl_value_t *type, const std::string &msg,
1019
1022
jl_codectx_t *ctx)
1020
1023
{
1021
- // if (jl_subtype(x.typ, type)) {
1022
- // // This case should already be handled by the caller
1023
- // return;
1024
- // }
1025
- Value *istype = emit_isa (x, type, &msg, ctx);
1026
- if (!isa<Constant>(istype)) {
1024
+ Value *istype;
1025
+ bool handled_msg;
1026
+ std::tie (istype, handled_msg) = emit_isa (x, type, &msg, ctx);
1027
+ if (!handled_msg) {
1027
1028
BasicBlock *failBB = BasicBlock::Create (jl_LLVMContext, " fail" , ctx->f );
1028
1029
BasicBlock *passBB = BasicBlock::Create (jl_LLVMContext, " pass" );
1029
1030
builder.CreateCondBr (istype, passBB, failBB);
@@ -2176,12 +2177,11 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
2176
2177
strct = emit_static_alloca (lt);
2177
2178
2178
2179
unsigned idx = 0 ;
2179
- for (size_t i= 0 ; i < na; i++) {
2180
- jl_value_t *jtype = jl_svecref (sty->types ,i);
2180
+ for (size_t i = 0 ; i < na; i++) {
2181
+ jl_value_t *jtype = jl_svecref (sty->types , i);
2181
2182
Type *fty = julia_type_to_llvm (jtype);
2182
- jl_cgval_t fval_info = emit_expr (args[i+1 ], ctx);
2183
- if (!jl_subtype (fval_info.typ , jtype))
2184
- emit_typecheck (fval_info, jtype, " new" , ctx);
2183
+ jl_cgval_t fval_info = emit_expr (args[i + 1 ], ctx);
2184
+ emit_typecheck (fval_info, jtype, " new" , ctx);
2185
2185
if (!type_is_ghost (fty)) {
2186
2186
Value *fval = NULL , *dest = NULL ;
2187
2187
if (!init_as_value) {
@@ -2225,34 +2225,32 @@ static jl_cgval_t emit_new_struct(jl_value_t *ty, size_t nargs, jl_value_t **arg
2225
2225
jl_cgval_t strctinfo = mark_julia_type (strct, true , ty, ctx);
2226
2226
if (f1) {
2227
2227
jl_cgval_t f1info = mark_julia_type (f1, true , jl_any_type, ctx);
2228
- if (!jl_subtype (expr_type (args[1 ],ctx), jl_field_type (sty,0 )))
2229
- emit_typecheck (f1info, jl_field_type (sty,0 ), " new" , ctx);
2228
+ emit_typecheck (f1info, jl_field_type (sty, 0 ), " new" , ctx);
2230
2229
emit_setfield (sty, strctinfo, 0 , f1info, ctx, false , false );
2231
2230
}
2232
- for (size_t i= j; i < nf; i++) {
2231
+ for (size_t i = j; i < nf; i++) {
2233
2232
if (jl_field_isptr (sty, i)) {
2234
2233
tbaa_decorate (strctinfo.tbaa , builder.CreateStore (
2235
2234
V_null,
2236
2235
builder.CreatePointerCast (
2237
2236
builder.CreateGEP (emit_bitcast (strct, T_pint8),
2238
- ConstantInt::get (T_size, jl_field_offset (sty,i))),
2237
+ ConstantInt::get (T_size, jl_field_offset (sty, i))),
2239
2238
T_ppjlvalue)));
2240
2239
}
2241
2240
}
2242
2241
bool need_wb = false ;
2243
2242
// TODO: verify that nargs <= nf (currently handled by front-end)
2244
- for (size_t i=j+ 1 ; i < nargs; i++) {
2243
+ for (size_t i = j + 1 ; i < nargs; i++) {
2245
2244
jl_cgval_t rhs = emit_expr (args[i], ctx);
2246
2245
if (jl_field_isptr (sty, i - 1 ) && !rhs.isboxed ) {
2247
2246
need_wb = true ;
2248
2247
}
2249
2248
if (rhs.isboxed ) {
2250
- if (!jl_subtype (expr_type (args[i],ctx), jl_svecref (sty->types ,i-1 )))
2251
- emit_typecheck (rhs, jl_svecref (sty->types ,i-1 ), " new" , ctx);
2249
+ emit_typecheck (rhs, jl_svecref (sty->types , i - 1 ), " new" , ctx);
2252
2250
}
2253
2251
if (might_need_root (args[i])) // TODO: how to remove this?
2254
2252
need_wb = true ;
2255
- emit_setfield (sty, strctinfo, i- 1 , rhs, ctx, false , need_wb);
2253
+ emit_setfield (sty, strctinfo, i - 1 , rhs, ctx, false , need_wb);
2256
2254
}
2257
2255
return strctinfo;
2258
2256
}
0 commit comments