[m-rev.] for review: allow pretest equality on java
Peter Wang
novalazy at gmail.com
Wed Sep 16 16:45:15 AEST 2009
Branches: main
Allow `--should-pretest-equality' on Java backend.
compiler/options.m:
compiler/handle_options.m:
Set an internal option when targetting Java which determines whether
"pretest equality" code casts values to pointers or integers before
comparing them.
Allow `should_pretest_equality' when targetting Java.
compiler/hlds_goal.m:
compiler/saved_vars.m:
Add a goal feature to be set on the unification in the pretest equality
code.
compiler/modecheck_unify.m:
Treat c_pointer unifications as a simple test if the previous goal
feature is set. Otherwise the result would be a runtime error.
compiler/unify_proc.m:
Make the pretest equality code cast values to pointers if
`pretest_equality_cast_pointers' is set.
Add the goal feature on the unification goal.
diff --git a/compiler/handle_options.m b/compiler/handle_options.m
index 8ce66e7..d608b79 100644
--- a/compiler/handle_options.m
+++ b/compiler/handle_options.m
@@ -661,9 +661,8 @@ postprocess_options_2(OptionTable0, Target, GC_Method, TagsMethod0,
% XXX Previously static ground terms used to not work with
% --high-level-data. But this has been (mostly?) fixed now.
% So we should investigate re-enabling static ground terms.
+ % - pretest-equality-cast-pointers
% - no library grade installation check with `mmc --make'.
- % - no pretest equality check
- % Because it assumes pointers can be cast to integers.
% - cross compiling
% Because ints in Java are 32-bits wide which may be different to
% that of the host compiler.
@@ -685,8 +684,9 @@ postprocess_options_2(OptionTable0, Target, GC_Method, TagsMethod0,
globals.set_option(unboxed_no_tag_types, bool(no), !Globals),
globals.set_option(static_ground_cells, bool(no), !Globals),
globals.set_option(put_nondet_env_on_heap, bool(yes), !Globals),
+ globals.set_option(pretest_equality_cast_pointers, bool(yes),
+ !Globals),
globals.set_option(libgrade_install_check, bool(no), !Globals),
- globals.set_option(should_pretest_equality, bool(no), !Globals),
globals.set_option(cross_compiling, bool(yes), !Globals)
;
( Target = target_c
diff --git a/compiler/hlds_goal.m b/compiler/hlds_goal.m
index b1bcf98..f200ce1 100644
--- a/compiler/hlds_goal.m
+++ b/compiler/hlds_goal.m
@@ -1463,6 +1463,11 @@
% circumstances we need to strip off this pretest, and replace
% the if-then-else with just its else branch.
+ ; feature_pretest_equality_condition
+ % This goal is the unification in the condition of a
+ % pretest-equality if-then-else goal. The goal feature is required
+ % to allow pointer comparisons generated by the compiler.
+
; feature_lambda_undetermined_mode.
% This goal is a lambda goal converted from a higher order term
% for which we don't know the mode of the call to the underlying
diff --git a/compiler/modecheck_unify.m b/compiler/modecheck_unify.m
index 5629925..a432161 100644
--- a/compiler/modecheck_unify.m
+++ b/compiler/modecheck_unify.m
@@ -66,6 +66,7 @@
:- import_module mdbcomp.
:- import_module mdbcomp.prim_data.
:- import_module parse_tree.
+:- import_module parse_tree.builtin_lib_types.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_type.
@@ -1050,6 +1051,13 @@ categorize_unify_var_var(ModeOfX, ModeOfY, LiveX, LiveY, X, Y, Det,
->
Unification = simple_test(X, Y)
;
+ % Unification of c_pointers is a runtime error unless introduced by
+ % the compiler.
+ Type = c_pointer_type,
+ goal_info_has_feature(GoalInfo, feature_pretest_equality_condition)
+ ->
+ Unification = simple_test(X, Y)
+ ;
modecheck_complicated_unify(X, Y, Type, ModeOfX, ModeOfY, Det,
UnifyContext, Unification0, Unification, !ModeInfo)
)
diff --git a/compiler/options.m b/compiler/options.m
index e059864..c9d6b0c 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -459,6 +459,11 @@
% constant, can be done by casting them both to integers and
% comparing the integers for equality.
+ ; pretest_equality_cast_pointers
+ % Should be set to yes if the test of whether two input arguments
+ % are object identical should be done by casting the arguments to a
+ % generic pointer type. Otherwise they will be cast to integers.
+
; can_compare_compound_values
% Should be set to yes if the target back end supports comparison
% of non-atomic values with builtin operators.
@@ -1297,6 +1302,7 @@ option_defaults_2(internal_use_option, [
trace_stack_layout - bool(no),
body_typeinfo_liveness - bool(no),
can_compare_constants_as_ints - bool(no),
+ pretest_equality_cast_pointers - bool(no),
can_compare_compound_values - bool(no),
lexically_order_constructors - bool(no),
mutable_always_boxed - bool(yes),
@@ -2150,6 +2156,7 @@ long_option("procid-stack-layout", procid_stack_layout).
long_option("trace-stack-layout", trace_stack_layout).
long_option("body-typeinfo-liveness", body_typeinfo_liveness).
long_option("can-compare-constants-as-ints", can_compare_constants_as_ints).
+long_option("pretest-equality-cast-pointers", pretest_equality_cast_pointers).
long_option("can-compare-compound-values", can_compare_compound_values).
long_option("lexically-order-constructors",
lexically_order_constructors).
@@ -4407,6 +4414,11 @@ options_help_compilation_model -->
% For documentation, see the comment in the type declaration.
% This is a developer only option.
+% "--pretest-equality-cast-pointers",
+% "(This option is not for general use.)",
+% For documentation, see the comment in the type declaration.
+
+ % This is a developer only option.
% "--can-compare-compound-values"
% "(This option is not for general use.)",
% For documentation, see the comment in the type declaration.
diff --git a/compiler/saved_vars.m b/compiler/saved_vars.m
index c318814..6e0eb7f 100644
--- a/compiler/saved_vars.m
+++ b/compiler/saved_vars.m
@@ -241,6 +241,7 @@ ok_to_duplicate(feature_will_not_modify_trail) = yes.
ok_to_duplicate(feature_will_not_call_mm_tabled) = yes.
ok_to_duplicate(feature_contains_trace) = yes.
ok_to_duplicate(feature_pretest_equality) = yes.
+ok_to_duplicate(feature_pretest_equality_condition) = yes.
ok_to_duplicate(feature_lambda_undetermined_mode) = yes.
% Divide a list of goals into an initial subsequence of goals
diff --git a/compiler/unify_proc.m b/compiler/unify_proc.m
index 050ecb8..6107e43 100644
--- a/compiler/unify_proc.m
+++ b/compiler/unify_proc.m
@@ -1945,18 +1945,21 @@ maybe_wrap_with_pretest_equality(Context, X, Y, MaybeCompareRes, Goal0, Goal,
Goal = Goal0
;
ShouldPretestEq = yes,
- info_new_named_var(int_type, "CastX", CastX, !Info),
- info_new_named_var(int_type, "CastY", CastY, !Info),
+ CastType = get_pretest_equality_cast_type(!.Info),
+ info_new_named_var(CastType, "CastX", CastX, !Info),
+ info_new_named_var(CastType, "CastY", CastY, !Info),
generate_cast(unsafe_type_cast, X, CastX, Context, CastXGoal0),
generate_cast(unsafe_type_cast, Y, CastY, Context, CastYGoal0),
goal_add_feature(feature_keep_constant_binding, CastXGoal0, CastXGoal),
goal_add_feature(feature_keep_constant_binding, CastYGoal0, CastYGoal),
create_pure_atomic_complicated_unification(CastX, rhs_var(CastY),
- Context, umc_explicit, [], EqualityGoal),
+ Context, umc_explicit, [], EqualityGoal0),
+ goal_add_feature(feature_pretest_equality_condition,
+ EqualityGoal0, EqualityGoal),
CondGoalExpr = conj(plain_conj, [CastXGoal, CastYGoal, EqualityGoal]),
goal_info_init(GoalInfo0),
goal_info_set_context(Context, GoalInfo0, ContextGoalInfo),
- CondGoal= hlds_goal(CondGoalExpr, ContextGoalInfo),
+ CondGoal = hlds_goal(CondGoalExpr, ContextGoalInfo),
(
MaybeCompareRes = no,
EqualGoal = true_goal_with_context(Context),
@@ -1986,6 +1989,20 @@ should_pretest_equality(Info) = ShouldPretestEq :-
module_info_get_globals(ModuleInfo, Globals),
lookup_bool_option(Globals, should_pretest_equality, ShouldPretestEq).
+:- func get_pretest_equality_cast_type(unify_proc_info) = mer_type.
+
+get_pretest_equality_cast_type(Info) = CastType :-
+ ModuleInfo = Info ^ upi_module_info,
+ module_info_get_globals(ModuleInfo, Globals),
+ lookup_bool_option(Globals, pretest_equality_cast_pointers, CastPointers),
+ (
+ CastPointers = yes,
+ CastType = c_pointer_type
+ ;
+ CastPointers = no,
+ CastType = int_type
+ ).
+
%-----------------------------------------------------------------------------%
:- pred quantify_clause_body(list(prog_var)::in, hlds_goal::in,
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list