From 6017c2ec5496ce7510e7bc4a30904c62084205e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ezgi=20=C3=87i=C3=A7ek?= Date: Wed, 5 Dec 2018 06:22:34 -0800 Subject: [PATCH] [cost] Fix control variables to pick up global vars in prune instructions Reviewed By: ngorogiannis Differential Revision: D13322062 fbshipit-source-id: 4e8081103 --- infer/src/checkers/control.ml | 14 +++++++++++--- infer/tests/codetoanalyze/c/performance/issues.exp | 3 +++ infer/tests/codetoanalyze/c/performance/loops.c | 11 +++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/infer/src/checkers/control.ml b/infer/src/checkers/control.ml index bc3b98ef3..e5faeb35b 100644 --- a/infer/src/checkers/control.ml +++ b/infer/src/checkers/control.ml @@ -73,10 +73,18 @@ module TransferFunctionsControlDeps (CFG : ProcCfg.S) = struct let get_vars_in_exp exp prune_node loop_head = - assert (Exp.program_vars exp |> Sequence.is_empty) ; - (* We should never have program variables in prune nodes *) + let global_control_vars = + Exp.program_vars exp + |> Sequence.fold ~init:ControlDepSet.empty ~f:(fun global_acc pvar -> + let cvar = Var.of_pvar pvar in + if Pvar.is_global pvar then ControlDepSet.add {cvar; loop_head} global_acc + else + Logging.die InternalError + "We should never have non-global program variables in prune nodes: %a@." Var.pp + cvar ) + in Exp.free_vars exp - |> Sequence.fold ~init:ControlDepSet.empty ~f:(fun acc id -> + |> Sequence.fold ~init:global_control_vars ~f:(fun acc id -> match Procdesc.Node.find_in_node_or_preds prune_node ~f:(find_vars_in_decl id loop_head) with diff --git a/infer/tests/codetoanalyze/c/performance/issues.exp b/infer/tests/codetoanalyze/c/performance/issues.exp index ab46baf25..f19a41f97 100644 --- a/infer/tests/codetoanalyze/c/performance/issues.exp +++ b/infer/tests/codetoanalyze/c/performance/issues.exp @@ -160,6 +160,9 @@ codetoanalyze/c/performance/loops.c, larger_state_FN, 3, EXPENSIVE_EXECUTION_TIM codetoanalyze/c/performance/loops.c, larger_state_FN, 4, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 1006, degree = 0] codetoanalyze/c/performance/loops.c, larger_state_FN, 5, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 1006, degree = 0] codetoanalyze/c/performance/loops.c, larger_state_FN, 7, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 1006, degree = 0] +codetoanalyze/c/performance/loops.c, loop_use_global_vars, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 4 + 4 ⋅ x.ub + 2 ⋅ (1+max(0, x.ub)), degree = 1] +codetoanalyze/c/performance/loops.c, loop_use_global_vars, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 3 + 4 ⋅ x.ub + 2 ⋅ (1+max(0, x.ub)), degree = 1] +codetoanalyze/c/performance/loops.c, loop_use_global_vars, 1, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 3 + 4 ⋅ x.ub + 2 ⋅ (1+max(0, x.ub)), degree = 1] codetoanalyze/c/performance/purity.c, loop, 2, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 7006, degree = 0] codetoanalyze/c/performance/purity.c, loop, 2, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 7006, degree = 0] codetoanalyze/c/performance/purity.c, loop, 3, EXPENSIVE_EXECUTION_TIME_CALL, no_bucket, ERROR, [with estimated cost 7006, degree = 0] diff --git a/infer/tests/codetoanalyze/c/performance/loops.c b/infer/tests/codetoanalyze/c/performance/loops.c index d70185622..a71118b74 100644 --- a/infer/tests/codetoanalyze/c/performance/loops.c +++ b/infer/tests/codetoanalyze/c/performance/loops.c @@ -59,3 +59,14 @@ void larger_state_FN() { } } } + +static int array1[] = {1, 2, 3}; +static int array2[] = {}; + +// Cvars will initially contain array1 and array2 but will be removed +// since they are invariant +void loop_use_global_vars(int x) { + for (int i = 0; i < x && array1 != array2; i++) { + // do something + } +}