@@ -44,6 +44,7 @@ struct endlabel_S {
4444 */
4545typedef struct {
4646 int is_seen_else ;
47+ int is_seen_skip_not ; // a block was unconditionally executed
4748 int is_had_return ; // every block ends in :return
4849 int is_if_label ; // instruction idx at IF or ELSEIF
4950 endlabel_T * is_end_label ; // instructions to set end label
@@ -2098,13 +2099,7 @@ generate_undo_cmdmods(cctx_T *cctx)
20982099may_generate_prof_end (cctx_T * cctx , int prof_lnum )
20992100{
21002101 if (cctx -> ctx_profiling && prof_lnum >= 0 )
2101- {
2102- int save_lnum = cctx -> ctx_lnum ;
2103-
2104- cctx -> ctx_lnum = prof_lnum ;
21052102 generate_instr (cctx , ISN_PROF_END );
2106- cctx -> ctx_lnum = save_lnum ;
2107- }
21082103}
21092104#endif
21102105
@@ -6735,6 +6730,18 @@ compile_if(char_u *arg, cctx_T *cctx)
67356730 else
67366731 scope -> se_u .se_if .is_if_label = -1 ;
67376732
6733+ #ifdef FEAT_PROFILE
6734+ if (cctx -> ctx_profiling && cctx -> ctx_skip == SKIP_YES
6735+ && skip_save != SKIP_YES )
6736+ {
6737+ // generated a profile start, need to generate a profile end, since it
6738+ // won't be done after returning
6739+ cctx -> ctx_skip = SKIP_NOT ;
6740+ generate_instr (cctx , ISN_PROF_END );
6741+ cctx -> ctx_skip = SKIP_YES ;
6742+ }
6743+ #endif
6744+
67386745 return p ;
67396746}
67406747
@@ -6758,6 +6765,25 @@ compile_elseif(char_u *arg, cctx_T *cctx)
67586765 if (!cctx -> ctx_had_return )
67596766 scope -> se_u .se_if .is_had_return = FALSE;
67606767
6768+ if (cctx -> ctx_skip == SKIP_NOT )
6769+ {
6770+ // previous block was executed, this one and following will not
6771+ cctx -> ctx_skip = SKIP_YES ;
6772+ scope -> se_u .se_if .is_seen_skip_not = TRUE;
6773+ }
6774+ if (scope -> se_u .se_if .is_seen_skip_not )
6775+ {
6776+ // A previous block was executed, skip over expression and bail out.
6777+ // Do not count the "elseif" for profiling.
6778+ #ifdef FEAT_PROFILE
6779+ if (cctx -> ctx_profiling && ((isn_T * )instr -> ga_data )[instr -> ga_len - 1 ]
6780+ .isn_type == ISN_PROF_START )
6781+ -- instr -> ga_len ;
6782+ #endif
6783+ skip_expr_cctx (& p , cctx );
6784+ return p ;
6785+ }
6786+
67616787 if (cctx -> ctx_skip == SKIP_UNKNOWN )
67626788 {
67636789 if (compile_jump_to_end (& scope -> se_u .se_if .is_end_label ,
@@ -6771,7 +6797,17 @@ compile_elseif(char_u *arg, cctx_T *cctx)
67716797 // compile "expr"; if we know it evaluates to FALSE skip the block
67726798 CLEAR_FIELD (ppconst );
67736799 if (cctx -> ctx_skip == SKIP_YES )
6800+ {
67746801 cctx -> ctx_skip = SKIP_UNKNOWN ;
6802+ #ifdef FEAT_PROFILE
6803+ if (cctx -> ctx_profiling )
6804+ {
6805+ // the previous block was skipped, need to profile this line
6806+ generate_instr (cctx , ISN_PROF_START );
6807+ instr_count = instr -> ga_len ;
6808+ }
6809+ #endif
6810+ }
67756811 if (compile_expr1 (& p , cctx , & ppconst ) == FAIL )
67766812 {
67776813 clear_ppconst (& ppconst );
@@ -6829,7 +6865,27 @@ compile_else(char_u *arg, cctx_T *cctx)
68296865 scope -> se_u .se_if .is_had_return = FALSE;
68306866 scope -> se_u .se_if .is_seen_else = TRUE;
68316867
6832- if (scope -> se_skip_save != SKIP_YES )
6868+ #ifdef FEAT_PROFILE
6869+ if (cctx -> ctx_profiling )
6870+ {
6871+ if (cctx -> ctx_skip == SKIP_NOT
6872+ && ((isn_T * )instr -> ga_data )[instr -> ga_len - 1 ]
6873+ .isn_type == ISN_PROF_START )
6874+ // the previous block was executed, do not count "else" for profiling
6875+ -- instr -> ga_len ;
6876+ if (cctx -> ctx_skip == SKIP_YES && !scope -> se_u .se_if .is_seen_skip_not )
6877+ {
6878+ // the previous block was not executed, this one will, do count the
6879+ // "else" for profiling
6880+ cctx -> ctx_skip = SKIP_NOT ;
6881+ generate_instr (cctx , ISN_PROF_END );
6882+ generate_instr (cctx , ISN_PROF_START );
6883+ cctx -> ctx_skip = SKIP_YES ;
6884+ }
6885+ }
6886+ #endif
6887+
6888+ if (!scope -> se_u .se_if .is_seen_skip_not && scope -> se_skip_save != SKIP_YES )
68336889 {
68346890 // jump from previous block to the end, unless the else block is empty
68356891 if (cctx -> ctx_skip == SKIP_UNKNOWN )
@@ -6884,6 +6940,17 @@ compile_endif(char_u *arg, cctx_T *cctx)
68846940 }
68856941 // Fill in the "end" label in jumps at the end of the blocks.
68866942 compile_fill_jump_to_end (& ifscope -> is_end_label , cctx );
6943+
6944+ #ifdef FEAT_PROFILE
6945+ // even when skipping we count the endif as executed, unless the block it's
6946+ // in is skipped
6947+ if (cctx -> ctx_profiling && cctx -> ctx_skip == SKIP_YES
6948+ && scope -> se_skip_save != SKIP_YES )
6949+ {
6950+ cctx -> ctx_skip = SKIP_NOT ;
6951+ generate_instr (cctx , ISN_PROF_START );
6952+ }
6953+ #endif
68876954 cctx -> ctx_skip = scope -> se_skip_save ;
68886955
68896956 // If all the blocks end in :return and there is an :else then the
@@ -8005,7 +8072,8 @@ compile_def_function(
80058072 {
80068073 // beyond the last line
80078074#ifdef FEAT_PROFILE
8008- may_generate_prof_end (& cctx , prof_lnum );
8075+ if (cctx .ctx_skip != SKIP_YES )
8076+ may_generate_prof_end (& cctx , prof_lnum );
80098077#endif
80108078 break ;
80118079 }
@@ -8023,7 +8091,8 @@ compile_def_function(
80238091 }
80248092
80258093#ifdef FEAT_PROFILE
8026- if (cctx .ctx_profiling && cctx .ctx_lnum != prof_lnum )
8094+ if (cctx .ctx_profiling && cctx .ctx_lnum != prof_lnum &&
8095+ cctx .ctx_skip != SKIP_YES )
80278096 {
80288097 may_generate_prof_end (& cctx , prof_lnum );
80298098
0 commit comments