@@ -3282,24 +3282,7 @@ static bool local_var_occurs(jl_value_t *e, int sl)
32823282    return  false ;
32833283}
32843284
3285- static  std::set<int > assigned_in_try (jl_array_t  *stmts, int  s, long  l)
3286- {
3287-     std::set<int > av;
3288-     for (int  i=s; i < l; i++) {
3289-         jl_value_t  *st = jl_array_ptr_ref (stmts,i);
3290-         if  (jl_is_expr (st)) {
3291-             if  (((jl_expr_t *)st)->head  == jl_assign_sym) {
3292-                 jl_value_t  *ar = jl_exprarg (st, 0 );
3293-                 if  (jl_is_slotnumber (ar)) {
3294-                     av.insert (jl_slot_number (ar)-1 );
3295-                 }
3296-             }
3297-         }
3298-     }
3299-     return  av;
3300- }
3301- 
3302- static  void  mark_volatile_vars (jl_array_t  *stmts, SmallVectorImpl<jl_varinfo_t > &slots)
3285+ static  bool  have_try_block (jl_array_t  *stmts)
33033286{
33043287    size_t  slength = jl_array_dim0 (stmts);
33053288    for  (int  i = 0 ; i < (int )slength; i++) {
@@ -3308,19 +3291,38 @@ static void mark_volatile_vars(jl_array_t *stmts, SmallVectorImpl<jl_varinfo_t>
33083291            int  last = jl_enternode_catch_dest (st);
33093292            if  (last == 0 )
33103293                continue ;
3311-             std::set<int > as = assigned_in_try (stmts, i + 1 , last - 1 );
3312-             for  (int  j = 0 ; j < (int )slength; j++) {
3313-                 if  (j < i || j > last) {
3314-                     std::set<int >::iterator it = as.begin ();
3315-                     for  (; it != as.end (); it++) {
3316-                         if  (local_var_occurs (jl_array_ptr_ref (stmts, j), *it)) {
3317-                             jl_varinfo_t  &vi = slots[*it];
3318-                             vi.isVolatile  = true ;
3319-                         }
3320-                     }
3294+             return  1 ;
3295+         }
3296+     }
3297+     return  0 ;
3298+ }
3299+ 
3300+ //  conservative marking of all variables potentially used after a catch block that were assigned before it
3301+ static  void  mark_volatile_vars (jl_array_t  *stmts, SmallVectorImpl<jl_varinfo_t > &slots, DenseSet<int > bbstarts)
3302+ {
3303+     if  (!have_try_block (stmts))
3304+         return ;
3305+     size_t  slength = jl_array_dim0 (stmts);
3306+     BitVector assigned_in_block (slots.size ()); //  conservatively only ignore slots assigned in the same basic block
3307+     for  (int  j = 0 ; j < (int )slength; j++) {
3308+         if  (bbstarts.contains (j + 1 ))
3309+             assigned_in_block.reset ();
3310+         jl_value_t  *stmt = jl_array_ptr_ref (stmts, j);
3311+         if  (jl_is_expr (stmt)) {
3312+             jl_expr_t  *e = (jl_expr_t *)stmt;
3313+             if  (e->head  == jl_assign_sym) {
3314+                 jl_value_t  *l = jl_exprarg (e, 0 );
3315+                 if  (jl_is_slotnumber (l)) {
3316+                     assigned_in_block.set (jl_slot_number (l)-1 );
33213317                }
33223318            }
33233319        }
3320+         for  (int  slot = 0 ; slot < (int )slots.size (); slot++) {
3321+             if  (!assigned_in_block.test (slot) && local_var_occurs (stmt, slot)) {
3322+                 jl_varinfo_t  &vi = slots[slot];
3323+                 vi.isVolatile  = true ;
3324+             }
3325+         }
33243326    }
33253327}
33263328
@@ -8439,7 +8441,6 @@ static jl_llvm_functions_t
84398441    ctx.code  = src->code ;
84408442    ctx.source  = src;
84418443
8442-     std::map<int , BasicBlock*> labels;
84438444    ctx.module  = jl_is_method (lam->def .method ) ? lam->def .method ->module  : lam->def .module ;
84448445    ctx.linfo  = lam;
84458446    ctx.name  = name_from_method_instance (lam);
@@ -8499,6 +8500,49 @@ static jl_llvm_functions_t
84998500    if  (dbgFuncName.empty ()) //  Should never happen anymore?
85008501        debug_enabled = false ;
85018502
8503+     //  First go through and collect all branch targets, so we know where to
8504+     //  split basic blocks.
8505+     DenseSet<int > branch_targets; //  1-indexed
8506+     for  (size_t  i = 0 ; i < stmtslen; ++i) {
8507+         jl_value_t  *stmt = jl_array_ptr_ref (stmts, i);
8508+         if  (jl_is_gotoifnot (stmt)) {
8509+             int  dest = jl_gotoifnot_label (stmt);
8510+             branch_targets.insert (dest);
8511+             //  The next 1-indexed statement
8512+             branch_targets.insert (i + 2 );
8513+         }
8514+         else  if  (jl_is_returnnode (stmt)) {
8515+             //  We don't do dead branch elimination before codegen
8516+             //  so we need to make sure to start a BB after any
8517+             //  return node, even if they aren't otherwise branch
8518+             //  targets.
8519+             if  (i + 2  <= stmtslen)
8520+                 branch_targets.insert (i + 2 );
8521+         }
8522+         else  if  (jl_is_enternode (stmt)) {
8523+             branch_targets.insert (i + 1 );
8524+             if  (i + 2  <= stmtslen)
8525+                 branch_targets.insert (i + 2 );
8526+             size_t  catch_dest = jl_enternode_catch_dest (stmt);
8527+             if  (catch_dest)
8528+                 branch_targets.insert (catch_dest);
8529+         }
8530+         else  if  (jl_is_gotonode (stmt)) {
8531+             int  dest = jl_gotonode_label (stmt);
8532+             branch_targets.insert (dest);
8533+             if  (i + 2  <= stmtslen)
8534+                 branch_targets.insert (i + 2 );
8535+         }
8536+         else  if  (jl_is_phinode (stmt)) {
8537+             jl_array_t  *edges = (jl_array_t *)jl_fieldref_noalloc (stmt, 0 );
8538+             for  (size_t  j = 0 ; j < jl_array_nrows (edges); ++j) {
8539+                 size_t  edge = jl_array_data (edges, int32_t )[j];
8540+                 if  (edge == i)
8541+                     branch_targets.insert (i + 1 );
8542+             }
8543+         }
8544+     }
8545+ 
85028546    //  step 2. process var-info lists to see what vars need boxing
85038547    int  n_ssavalues = jl_is_long (src->ssavaluetypes ) ? jl_unbox_long (src->ssavaluetypes ) : jl_array_nrows (src->ssavaluetypes );
85048548    size_t  vinfoslen = jl_array_dim0 (src->slotflags );
@@ -8559,7 +8603,7 @@ static jl_llvm_functions_t
85598603        simple_use_analysis (ctx, jl_array_ptr_ref (stmts, i));
85608604
85618605    //  determine which vars need to be volatile
8562-     mark_volatile_vars (stmts, ctx.slots );
8606+     mark_volatile_vars (stmts, ctx.slots , branch_targets );
85638607
85648608    //  step 4. determine function signature
85658609    if  (!specsig)
@@ -9310,8 +9354,8 @@ static jl_llvm_functions_t
93109354
93119355    //  step 11b. Do codegen in control flow order
93129356    SmallVector<int , 0 > workstack;
9313-     std::map< int , BasicBlock*> BB;
9314-     std::map <size_t , BasicBlock*> come_from_bb;
9357+     DenseMap< size_t , BasicBlock*> BB;
9358+     DenseMap <size_t , BasicBlock*> come_from_bb;
93159359    int  cursor = 0 ;
93169360    int  current_label = 0 ;
93179361    auto  find_next_stmt = [&] (int  seq_next) {
@@ -9430,47 +9474,6 @@ static jl_llvm_functions_t
94309474
94319475    come_from_bb[0 ] = ctx.builder .GetInsertBlock ();
94329476
9433-     //  First go through and collect all branch targets, so we know where to
9434-     //  split basic blocks.
9435-     std::set<int > branch_targets; //  1-indexed
9436-     {
9437-         for  (size_t  i = 0 ; i < stmtslen; ++i) {
9438-             jl_value_t  *stmt = jl_array_ptr_ref (stmts, i);
9439-             if  (jl_is_gotoifnot (stmt)) {
9440-                 int  dest = jl_gotoifnot_label (stmt);
9441-                 branch_targets.insert (dest);
9442-                 //  The next 1-indexed statement
9443-                 branch_targets.insert (i + 2 );
9444-             } else  if  (jl_is_returnnode (stmt)) {
9445-                 //  We don't do dead branch elimination before codegen
9446-                 //  so we need to make sure to start a BB after any
9447-                 //  return node, even if they aren't otherwise branch
9448-                 //  targets.
9449-                 if  (i + 2  <= stmtslen)
9450-                     branch_targets.insert (i + 2 );
9451-             } else  if  (jl_is_enternode (stmt)) {
9452-                 branch_targets.insert (i + 1 );
9453-                 if  (i + 2  <= stmtslen)
9454-                     branch_targets.insert (i + 2 );
9455-                 size_t  catch_dest = jl_enternode_catch_dest (stmt);
9456-                 if  (catch_dest)
9457-                     branch_targets.insert (catch_dest);
9458-             } else  if  (jl_is_gotonode (stmt)) {
9459-                 int  dest = jl_gotonode_label (stmt);
9460-                 branch_targets.insert (dest);
9461-                 if  (i + 2  <= stmtslen)
9462-                     branch_targets.insert (i + 2 );
9463-             } else  if  (jl_is_phinode (stmt)) {
9464-                 jl_array_t  *edges = (jl_array_t *)jl_fieldref_noalloc (stmt, 0 );
9465-                 for  (size_t  j = 0 ; j < jl_array_nrows (edges); ++j) {
9466-                     size_t  edge = jl_array_data (edges, int32_t )[j];
9467-                     if  (edge == i)
9468-                         branch_targets.insert (i + 1 );
9469-                 }
9470-             }
9471-         }
9472-     }
9473- 
94749477    for  (int  label : branch_targets) {
94759478        BasicBlock *bb = BasicBlock::Create (ctx.builder .getContext (),
94769479            " L" std::to_string (label), f);
0 commit comments