[m-rev.] for review: fix predicate_table_insert bug

Peter Ross pro at missioncriticalit.com
Fri Oct 24 06:27:44 AEST 2003


Hi,

Sorry about the delay in fixing this bug, but here is the solution.
It passes the test case fjh supplied in his bug report, and is
bootchecking now.


===================================================================


Estimated hours taken: 3
Branches: main

predicate_table_insert modifies the pred_info before inserting it into
the pred_table, this "invalidates" the pred_info predicate_table_insert
is called with however there are places in the compiler which use this
invalid pred_info for further processing.

Fix this issue by no longer modifying the pred_info inside
predicate_table_insert instead record the extra information in a new
table.

compiler/hlds_module.m:
	Add a new field to the predicate_table which records the name
	accessibility of each predicate.  This information is used to
	replace the two pred_markers not_accessible_by_unqualifed_name
	and not_accessible_by_partially_qualified_names.
	Use these new table instead of the markers.

compiler/hlds_pred.m:
	Remove the pred markers not_accessible_by_unqualifed_name and
	not_accessible_by_partially_qualified_names which are no
	longer needed.

diff -u compiler/hlds_module.m compiler/hlds_module.m
--- compiler/hlds_module.m
+++ compiler/hlds_module.m
@@ -1358,7 +1358,10 @@
 		pred_ids	:: list(pred_id),	% the keys of the
 							% pred_table - cached
 							% here for efficiency
-
+		accessibility_table :: accessibility_table,
+							% How is the predicate
+							% accessible?
+		
 		% indexes on predicates
 
 		pred_name_index		:: name_index,	% map from pred name
@@ -1383,6 +1386,19 @@
 							% pred_id
 	).
 
+:- type accessibility_table == map(pred_id, name_accessibility).
+
+:- type name_accessibility --->
+	access(
+	 	accessible_by_unqualifed_name :: bool,
+				% Is this predicate accessible by its
+				% unqualified name.
+
+	 	accessible_by_partially_qualified_names :: bool
+				% Is this predicate accessible by any
+				% partially qualified names.
+	).
+
 :- type name_index	== map(string, list(pred_id)).
 
 
@@ -1396,11 +1412,13 @@
 
 predicate_table_init(PredicateTable) :-
 	PredicateTable = predicate_table(Preds, NextPredId, PredIds,
+				AccessibilityTable,
 				Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
 				Func_N_Index, Func_NA_Index, Func_MNA_Index),
 	map__init(Preds),
 	hlds_pred__initial_pred_id(NextPredId),
 	PredIds = [],
+	map__init(AccessibilityTable),
 	map__init(Pred_N_Index),
 	map__init(Pred_NA_Index),
 	map__init(Pred_MNA_Index),
@@ -1409,7 +1427,7 @@
 	map__init(Func_MNA_Index).
 
 predicate_table_optimize(PredicateTable0, PredicateTable) :-
-	PredicateTable0 = predicate_table(A, B, C,
+	PredicateTable0 = predicate_table(A, B, C, D,
 				Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
 				Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
 	map__optimize(Pred_N_Index0, Pred_N_Index),
@@ -1418,7 +1436,7 @@
 	map__optimize(Func_N_Index0, Func_N_Index),
 	map__optimize(Func_NA_Index0, Func_NA_Index),
 	map__optimize(Func_MNA_Index0, Func_MNA_Index),
-	PredicateTable = predicate_table(A, B, C,
+	PredicateTable = predicate_table(A, B, C, D,
 				Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
 				Func_N_Index, Func_NA_Index, Func_MNA_Index).
 
@@ -1435,9 +1453,11 @@
 
 predicate_table_remove_predicate(PredicateTable0, PredId, PredicateTable) :-
 	PredicateTable0 = predicate_table(Preds0, NextPredId, PredIds0, 
+		AccessibilityTable0,
 		PredN0, PredNA0, PredMNA0, FuncN0, FuncNA0, FuncMNA0),
 	list__delete_all(PredIds0, PredId, PredIds),
 	map__det_remove(Preds0, PredId, PredInfo, Preds),
+	map__det_remove(AccessibilityTable0, PredId, _, AccessibilityTable),
 	pred_info_module(PredInfo, Module),
 	pred_info_name(PredInfo, Name),
 	pred_info_arity(PredInfo, Arity),
@@ -1447,6 +1467,7 @@
 		predicate_table_remove_from_index(Module, Name, Arity, PredId,
 			PredN0, PredN, PredNA0, PredNA, PredMNA0, PredMNA),
 		PredicateTable = predicate_table(Preds, NextPredId, PredIds, 
+			AccessibilityTable,
 			PredN, PredNA, PredMNA, FuncN0, FuncNA0, FuncMNA0)
 	;
 		IsPredOrFunc = function,
@@ -1455,6 +1476,7 @@
 			PredId, FuncN0, FuncN, FuncNA0, FuncNA, 
 			FuncMNA0, FuncMNA),
 		PredicateTable = predicate_table(Preds, NextPredId, PredIds, 
+			AccessibilityTable,
 			PredN0, PredNA0, PredMNA0, FuncN, FuncNA, FuncMNA)
 	).
 
@@ -1793,6 +1815,8 @@
 		OrigPredicateTable, PredIds, PredicateTable) :-
 	predicate_table_reset(OrigPredicateTable, PredicateTable0),
 	predicate_table_get_preds(OrigPredicateTable, Preds),
+	AccessibilityTable = OrigPredicateTable ^ accessibility_table,
+
 	% Note that we use foldr here rather than foldl,
 	% so that the PredIds list in the predicate table
 	% is the same as the PredIds list argument here
@@ -1802,24 +1826,18 @@
 	PredicateTable = list__foldr(
 		(func(PredId, Table0) = Table :-
 			PredInfo = map__lookup(Preds, PredId),
-			pred_info_get_markers(PredInfo, Markers),
-			(
-			    check_marker(Markers,
-				not_accessible_by_unqualifed_name)
-			->
-			    NeedQual = must_be_qualified
-			;
-			    NeedQual = may_be_unqualified
+			Access = map__lookup(AccessibilityTable, PredId),
+			Access = access(Unqualified, PartiallyQualified),
+			( Unqualified = yes,
+				NeedQual = may_be_unqualified
+			; Unqualified = no,
+				NeedQual = must_be_qualified
 			),
-			(
-			    check_marker(Markers,
-			    	not_accessible_by_partially_qualified_names)
-			->
-			    MaybeQualInfo = no
-			;
-			    MaybeQualInfo = yes(PartialQualInfo)
+			( PartiallyQualified = yes,
+				MaybeQualInfo = yes(PartialQualInfo)
+			; PartiallyQualified = no,
+				MaybeQualInfo = no
 			),
-
 			predicate_table_insert_2(Table0,
 					yes(PredId), PredInfo,
 					NeedQual, MaybeQualInfo,
@@ -1832,7 +1850,8 @@
 predicate_table_reset(PredicateTable0, PredicateTable) :-
 	NextPredId = PredicateTable0 ^ next_pred_id,
 	PredicateTable = predicate_table(map__init, NextPredId, [], map__init,
-			map__init, map__init, map__init, map__init, map__init).
+			map__init, map__init, map__init,
+			map__init, map__init, map__init).
 
 %-----------------------------------------------------------------------------%
 
@@ -1851,15 +1870,16 @@
 		maybe(partial_qualifier_info), pred_id, predicate_table).
 :- mode predicate_table_insert_2(in, in, in, in, in, out, out) is det.
 
-predicate_table_insert_2(PredicateTable0, MaybePredId, PredInfo0,
+predicate_table_insert_2(PredicateTable0, MaybePredId, PredInfo,
 		NeedQual, MaybeQualInfo, PredId, PredicateTable) :-
 
 	PredicateTable0 = predicate_table(Preds0, NextPredId0, PredIds0,
+				AccessibilityTable0,
 				Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
 				Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
-	pred_info_module(PredInfo0, Module),
-	pred_info_name(PredInfo0, Name),
-	pred_info_arity(PredInfo0, Arity),
+	pred_info_module(PredInfo, Module),
+	pred_info_name(PredInfo, Name),
+	pred_info_arity(PredInfo, Arity),
 
 	( MaybePredId = yes(PredId),
 		NextPredId = NextPredId0
@@ -1872,15 +1892,15 @@
 
 		% insert the pred_id into either the function or predicate
 		% indices, as appropriate
-	pred_info_get_is_pred_or_func(PredInfo0, PredOrFunc),
+	pred_info_get_is_pred_or_func(PredInfo, PredOrFunc),
 	( 
 		PredOrFunc = predicate,
 		predicate_table_do_insert(Module, Name, Arity,
 			NeedQual, MaybeQualInfo, PredId,
+			AccessibilityTable0, AccessibilityTable,
 			Pred_N_Index0, Pred_N_Index, 
 			Pred_NA_Index0, Pred_NA_Index,
-			Pred_MNA_Index0, Pred_MNA_Index,
-			PredInfo0, PredInfo),
+			Pred_MNA_Index0, Pred_MNA_Index),
 
 		Func_N_Index = Func_N_Index0,
 		Func_NA_Index = Func_NA_Index0,
@@ -1890,10 +1910,10 @@
 		FuncArity = Arity - 1,
 		predicate_table_do_insert(Module, Name, FuncArity,
 			NeedQual, MaybeQualInfo, PredId,
+			AccessibilityTable0, AccessibilityTable,
 			Func_N_Index0, Func_N_Index, 
 			Func_NA_Index0, Func_NA_Index,
-			Func_MNA_Index0, Func_MNA_Index,
-			PredInfo0, PredInfo),
+			Func_MNA_Index0, Func_MNA_Index),
 
 		Pred_N_Index = Pred_N_Index0,
 		Pred_NA_Index = Pred_NA_Index0,
@@ -1901,26 +1921,28 @@
 	),
 
 		% insert the pred_id into the pred_id list
-	PredIds = [PredId | PredIds0],
+	PredIds = [PredId | PredIds0].
 
 		% save the pred_info for this pred_id
 	map__det_insert(Preds0, PredId, PredInfo, Preds),
 
 	PredicateTable = predicate_table(Preds, NextPredId, PredIds,
+				AccessibilityTable,
 				Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
 				Func_N_Index, Func_NA_Index, Func_MNA_Index).
 
 :- pred predicate_table_do_insert(module_name, string, arity,
 	need_qualifier, maybe(partial_qualifier_info),
-	pred_id, name_index, name_index, name_arity_index,
-	name_arity_index, module_name_arity_index, module_name_arity_index,
-	pred_info, pred_info).
+	pred_id, accessibility_table, accessibility_table,
+	name_index, name_index, name_arity_index,
+	name_arity_index, module_name_arity_index, module_name_arity_index).
 :- mode predicate_table_do_insert(in, in, in, in, in, in,
 	in, out, in, out, in, out, in, out) is det.
 
 predicate_table_do_insert(Module, Name, Arity, NeedQual, MaybeQualInfo,
-		PredId, N_Index0, N_Index, NA_Index0, NA_Index, 
-		MNA_Index0, MNA_Index, PredInfo0, PredInfo) :-
+		PredId, AccessibilityTable0, AccessibilityTable,
+		N_Index0, N_Index, NA_Index0, NA_Index, 
+		MNA_Index0, MNA_Index) :-
 	( NeedQual = may_be_unqualified ->
 			% insert the unqualified name into the name index
 		multi_map__set(N_Index0, Name, PredId, N_Index),
@@ -1930,15 +1952,11 @@
 		NA = Name / Arity,
 		multi_map__set(NA_Index0, NA, PredId, NA_Index),
 
-		PredInfo1 = PredInfo0
+		AccessibleByUnqualifiedName = yes
 	;
 		N_Index = N_Index0,
 		NA_Index = NA_Index0,
-
-		pred_info_get_markers(PredInfo0, MarkersA0),
-		add_marker(MarkersA0, not_accessible_by_unqualifed_name,
-				MarkersA),
-		pred_info_set_markers(PredInfo0, MarkersA, PredInfo1)
+		AccessibleByUnqualifiedName = no
 	),
 
 	( MaybeQualInfo = yes(QualInfo) ->
@@ -1952,21 +1970,22 @@
 					MNAs0, MNAs)),
 			PartialQuals, _, MNA_Index0, MNA_Index1),
 
-		PredInfo = PredInfo1
+		AccessibleByPartiallyQualifiedNames = yes
 	;
 		MNA_Index1 = MNA_Index0,
-
-		pred_info_get_markers(PredInfo1, MarkersB0),
-		add_marker(MarkersB0,
-				not_accessible_by_partially_qualified_names,
-				MarkersB),
-		pred_info_set_markers(PredInfo1, MarkersB, PredInfo)
+		AccessibleByPartiallyQualifiedNames = no
 	),
 
 		% insert the fully-qualified name into the
 		% module:name/arity index
 	insert_into_mna_index(Module, Name, Arity, PredId,
-			MNA_Index1, MNA_Index).
+			MNA_Index1, MNA_Index),
+
+
+	Access = access(AccessibleByUnqualifiedName,
+			AccessibleByPartiallyQualifiedNames),
+	map__set(AccessibilityTable0, PredId, Access,
+			AccessibilityTable).
 
 :- pred insert_into_mna_index(module_name, string, arity, pred_id,
 			module_name_arity_index, module_name_arity_index).
only in patch2:
--- compiler/hlds_pred.m	20 Oct 2003 07:29:06 -0000	1.131
+++ compiler/hlds_pred.m	23 Oct 2003 20:12:09 -0000
@@ -497,14 +497,6 @@
 				% fully qualified. This occurs for
 				% predicates read from `.opt' files
 				% and compiler-generated predicates.
-
-	;	not_accessible_by_unqualifed_name
-				% This predicate is not accessible by its
-				% unqualified name.
-
-	;	not_accessible_by_partially_qualified_names
-				% This predicate is not accessible by any
-				% partially qualified names.
 	.
 
 

-- 
Peter Ross		
Software Engineer                                (Work)   +32 2 757 10 15
Mission Critical                                 (Mobile) +32 485 482 559
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list