diff --git a/compiler/common.m b/compiler/common.m index e9b8fc341..1c9446c1a 100644 --- a/compiler/common.m +++ b/compiler/common.m @@ -1,5 +1,5 @@ %---------------------------------------------------------------------------% -% Copyright (C) 1995-2002 The University of Melbourne. +% Copyright (C) 1995-2003 The University of Melbourne. % This file may only be copied under the terms of the GNU General % Public License - see the file COPYING in the Mercury distribution. %---------------------------------------------------------------------------% @@ -155,12 +155,25 @@ common__optimise_unification(Unification0, _Left0, _Right0, Mode, _Context, construction, Info0, OldStruct) -> OldStruct = structure(OldVar, _, _, _), - UniMode = ((free - Inst) -> (Inst - Inst)), - common__generate_assign(Var, OldVar, UniMode, - GoalInfo0, Goal - GoalInfo, Info0, Info1), - simplify_info_set_requantify(Info1, Info2), - pd_cost__goal(Goal0 - GoalInfo0, Cost), - simplify_info_incr_cost_delta(Info2, Cost, Info) + ( ArgVars = [] -> + % Constants don't use memory, so there's + % no point optimizing away their + % construction -- in fact, doing so + % could cause more stack usage. + common__record_equivalence(Var, OldVar, + Info0, Info), + Goal = Goal0, + GoalInfo = GoalInfo0 + ; + UniMode = ((free - Inst) -> (Inst - Inst)), + common__generate_assign(Var, OldVar, UniMode, + GoalInfo0, Goal - GoalInfo, + Info0, Info1), + simplify_info_set_requantify(Info1, Info2), + pd_cost__goal(Goal0 - GoalInfo0, Cost), + simplify_info_incr_cost_delta(Info2, + Cost, Info) + ) ; Goal = Goal0, GoalInfo = GoalInfo0, @@ -356,22 +369,15 @@ common__vars_are_equiv(X, Y, VarEqv) :- common__record_cell(Var, ConsId, ArgVars, Info0, Info) :- simplify_info_get_common_info(Info0, CommonInfo0), simplify_info_get_var_types(Info0, VarTypes), - ( ArgVars = [] -> - % Constants do not have memory cells to reuse, - % at least in the memory models we are interested in. - CommonInfo = CommonInfo0 - ; - CommonInfo0 = common(VarEqv, StructMapAll0, + CommonInfo0 = common(VarEqv, StructMapAll0, StructMapLastCall0, SeenCalls), - map__lookup(VarTypes, Var, VarType), - Struct = structure(Var, VarType, ConsId, ArgVars), - common__do_record_cell(StructMapAll0, ConsId, - Struct, StructMapAll), - common__do_record_cell(StructMapLastCall0, ConsId, Struct, + map__lookup(VarTypes, Var, VarType), + Struct = structure(Var, VarType, ConsId, ArgVars), + common__do_record_cell(StructMapAll0, ConsId, Struct, StructMapAll), + common__do_record_cell(StructMapLastCall0, ConsId, Struct, StructMapLastCall), - CommonInfo = common(VarEqv, StructMapAll, - StructMapLastCall, SeenCalls) - ), + CommonInfo = common(VarEqv, StructMapAll, + StructMapLastCall, SeenCalls), simplify_info_set_common_info(Info0, CommonInfo, Info). :- pred common__do_record_cell(struct_map, cons_id, structure, struct_map). diff --git a/tests/warnings/Mercury.options b/tests/warnings/Mercury.options index af5dbc8cd..15b1c9806 100644 --- a/tests/warnings/Mercury.options +++ b/tests/warnings/Mercury.options @@ -12,6 +12,7 @@ MCFLAGS-arg_order_rearrangment = --introduce-accumulators \ --trace-optimized MCFLAGS-duplicate_call = --warn-duplicate-calls +MCFLAGS-duplicate_const = --warn-duplicate-calls MCFLAGS-unused_args_analysis = --intermodule-analysis \ --optimize-unused-args --warn-unused-args MCFLAGS-unused_args_analysis2 = --intermodule-analysis \ diff --git a/tests/warnings/Mmakefile b/tests/warnings/Mmakefile index 53c062d14..6557d1a48 100644 --- a/tests/warnings/Mmakefile +++ b/tests/warnings/Mmakefile @@ -12,6 +12,7 @@ ERRORCHECK_PROGS= \ det_infer_warning \ double_underscore \ duplicate_call \ + duplicate_const \ inf_recursion_lambda \ infinite_recursion \ inference_test \ diff --git a/tests/warnings/duplicate_const.exp b/tests/warnings/duplicate_const.exp new file mode 100644 index 000000000..1eef10612 --- /dev/null +++ b/tests/warnings/duplicate_const.exp @@ -0,0 +1,2 @@ +duplicate_const.m:016: Warning: redundant call to predicate `duplicate_const.called/4'. +duplicate_const.m:015: Here is the previous call to predicate `duplicate_const.called/4'. diff --git a/tests/warnings/duplicate_const.m b/tests/warnings/duplicate_const.m new file mode 100644 index 000000000..14df20552 --- /dev/null +++ b/tests/warnings/duplicate_const.m @@ -0,0 +1,20 @@ +% Test the warning for duplicate calls where some of the arguments are +% duplicated constants. +:- module duplicate_const. + +:- interface. + +:- pred dup_call(int::in, int::in, int::out) is det. + +:- pred called(T::in, int::in, int::in, int::out) is det. + +:- implementation. +:- import_module int. + +dup_call(Int1, Int2, Int) :- + called(1, Int1, Int2, Int3), + called(1, Int1, Int2, Int4), + Int is Int3 + Int4. + +called(_, Int1, Int2, Int) :- + Int is Int1 + Int2.