Commit Graph

31 Commits

Author SHA1 Message Date
Zoltan Somogyi
d00ea69529 Switch from using set(prog_var), which is represented using set_ordlist,
Estimated hours taken: 12
Branches: main

Switch from using set(prog_var), which is represented using set_ordlist,
to set_of_progvar, which is represented using tree_bitset, for most sets
of variables in the compiler, including the nonlocals sets in goal_infos.

This diff yields about a 5% speedup when compiling the training_cars_full.m
stress test, but also about a 1% slowdown on tools/speedtest. Both of these
are with the current default state in which tree_bitset is compiled with
a whole bunch of sanity checks. If these are disabled, we get roughly a 1%
speedup on tools/speedtest. I intend to disable those sanity checks after
a shakedown period of a week or two in which the updated version of the
compiler is installed on our platforms.

compiler/hlds_goal.m:
	Replace almost all occurrences of set(prog_var) with set_of_progvar.
	The main exceptions are the types supporting rbmm.

compiler/set_of_var.m:
	Add some more predicates and functions that previous existed on sets
	but not yet on set_of_vars.

compiler/*.m:
	Conform to the change in hlds_goal.m, and make similar changes
	in set representations.

library/bag.m:
	Add a predicate and function for creating a bag from a sorted list.
	We already had them for creating a bag from a set, but a set_of_progvar
	shouldn't have to be converted to a set.

library/robdd.m:
	Fix deviations from our programming style.
2011-08-16 03:26:40 +00:00
Zoltan Somogyi
295415090e Convert almost all remaining modules in the compiler to use
Estimated hours taken: 6
Branches: main

compiler/*.m:
	Convert almost all remaining modules in the compiler to use
	"$module, $pred" instead of "this_file" in error messages.

	In a few cases, the old error message was misleading, since it
	contained an incorrect, out-of-date or cut-and-pasted predicate name.

tests/invalid/unresolved_overloading.err_exp:
	Update an expected output containing an updated error message.
2011-05-23 05:08:24 +00:00
Julien Fischer
9f68c330f0 Change the argument order of many of the predicates in the map, bimap, and
Branches: main

Change the argument order of many of the predicates in the map, bimap, and
multi_map modules so they are more conducive to the use of state variable
notation, i.e. make the order the same as in the sv* modules.

Prepare for the deprecation of the sv{bimap,map,multi_map} modules by
removing their use throughout the system.

library/bimap.m:
library/map.m:
library/multi_map.m:
	As above.
NEWS:
	Announce the change.

	Separate out the "highlights" from the "detailed listing" for
	the post-11.01 NEWS.

	Reorganise the announcement of the Unicode support.

benchmarks/*/*.m:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
extras/*/*.m:
mdbcomp/*.m:
profiler/*.m:
tests/*/*.m:
ssdb/*.m:
samples/*/*.m
slice/*.m:
	Conform to the above change.

	Remove any dependencies on the sv{bimap,map,multi_map} modules.
2011-05-03 04:35:04 +00:00
Zoltan Somogyi
b3fa535100 A rewrite of the state variable transformation from the ground up.
Estimated hours taken: 60
Branches: main

A rewrite of the state variable transformation from the ground up.

The initial aim was to avoid situations (encountered in the g12 project)
in which the old state variable transformation generated code that
did not satisfy the mode checker, due to unnecessary unifications.
The new system tries hard to minimize the number of unifications added to the
program. It does this by relying extensively on the idea that in a branched
structure such as an disjunction, if two branches both update the same state
variable, and the variables representing the last state of the state variable
in the two branches are (say) X and Y, and we pick X to represent the current
state after the disjunction, then we don't have to put the assignment X := Y
into the second branch; instead, we can RENAME Y to X in that branch.
To avoid renaming a goal several times (for itself, for its parent, for its
grandparent etc), we delay all renamings until the end, when we do it all
in one traversal.

The old state var system was opaque and hard to understand, partly because
its basic operations did different things in different contexts. The new system
is a much more direct expression of the intuitive meaning of state variables;
it keeps track of their state much as the programmer writing the original code
would. It should therefore be significantly easier to understand and to modify
in the future.

The new system can also detect more kinds of errors in the use of state
variables. For example it can discover that some branches of a disjunction or
if-then-else set the initial value of a state variable and some do not.
This is ok if the non-setting-branch cannot succeed; if it can, then it is
a bug. We therefore generate messages about such branches, but print them
only if mode analysis finds a bug in the procedure, since in that case,
the lack of initialization may be the cause of the bug.

doc/reference_manual.texi:
	Replaced an old example that didn't know what it was talking about,
	and thoroughly confused the issue of what is legal use of state
	variables and what is not.

compiler/state_var.m:
	Rewrite this module along the lines mentioned above.

compiler/options.m:
	Add two new options. One, warn-state-var-shadowing, controls whether
	we generate warnings for one state var shadowing another (which
	G12 has lots of). The other, --allow-defn-for-builtins, is for
	developers only; it is needed to bootstrap changes that add new
	builtins. I needed this for a form of the state variable transformation
	that used calls to a new builtin predicate to copy the values of state
	variables in branches that did not modify them, even though other
	branches did. I ultimately used unifications to do this copying,
	for reasons documented in state_var.m.

compiler/add_clause.m:
compiler/add_pragma.m:
	Respect the new --allow-defn-for-builtins option.
	(Previously, we changed the code that now looks up the value of the
	option.)

doc/user_guide.texi:
	Document the --warn-state-var-shadowing option.

	Fix some old documentation about dump options.

compiler/simplify.m:
	Fix an old oversight: list the predicates in table_builtin.m that may
	have calls introduced to them by table_gen.m.

compiler/superhomogeneous.m:
compiler/field_access.m:
compiler/add_clause.m:
compiler/goal_expr_to_goal.m:
	Together with state_var.m, these modules contain the transformation
	from the parse tree to the HLDS. Since the change to state_var.m
	involves significant changes in its interface (such as separating out
	the persistent and location-dependent aspects of the information needed
	by the state variable transformation), and needing callbacks at
	different points than the old transformation, these modules had to
	change extensively as well to conform.

	goal_expr_to_goal.m is a new module carved out of add_clause.m.
	It deserves a module of its own because its code has a significantly
	different purpose than add_clause.m. The two separate modules each
	have much better cohesion than the old conjoined module did.

	In superhomogeneous.m, replace two predicates that did the same thing
	with one predicate.

compiler/make_hlds.m:
compiler/notes/compiler_design.html.m:
	Mention the new module.

compiler/hlds_goal.m:
	Add a mechanism to do the kind of incremental renaming that the state
	variable transformation needs.

	Add some utility predicates needed by the new code in other modules.

compiler/hlds_clause.m:
compiler/hlds_pred.m:
	Add an extra piece of information to clauses and proc_infos:
	a list of informational messages generated by the state variable
	transformation about some branches of branched goals not giving initial
	values to some state variables, while other branches do.

	The state variable transformation fills in this field in clauses
	where relevant.

compiler/clause_to_proc.m:
	Copy this list of messages from clauses to proc_infos.

compiler/modes.m:
	When generating an error message for a procedure, include this list
	of messages from the state var transformation in the output.

compiler/handle_options.m:
	Add a dump alias for debugging the state var transformation.

compiler/hlds_out_goal.m:
	Add a predicate that is useful in trace messages when debugging
	the compiler.

compiler/hlds_out_pred.m:
	Print goal path and goal id information in clauses as well as
	proc_infos, since the state var transformation now uses goal ids.

compiler/prog_item.m:
	In lists of quantified vars in scope headers, separate out the vars
	introduced as !S from those introduced as !.S and !:S. This makes it
	easier for the state var transformation to handle them.

	Document that we expect lists of quantified variables and state
	variables to contain no duplicates. The state var transformation
	is slightly simpler if we impose this requirement, and quantifying
	a variable twice in the same scope does not make sense, and is
	therefore almost certainly an error.

compiler/prog_io_util.m:
	Generate error messages when a variable or state variable IS
	listed twice in the same quantification list.

	Factor out some code used to generate error messages.

compiler/typecheck.m:
	Conform to the changes above.

	Break a very large predicate into two smaller pieces.

compiler/add_class.m:
compiler/add_pragma.m:
compiler/add_pred.m:
compiler/assertion.m:
compiler/dead_proc_elim.m:
compiler/dependency_graph.m:
compiler/goal_path.m:
compiler/goal_util.m:
compiler/headvar_names.m:
compiler/hhf.m:
compiler/hlds_out_module.m:
compiler/inlining.m:
compiler/intermod.m:
compiler/mercury_to_mercury.m:
compiler/module_imports.m:
compiler/module_qual.m:
compiler/post_typecheck.m:
compiler/prog_io_goal.m:
compiler/prog_util.m:
compiler/purity.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
	Conform to the changes above.

compiler/mode_constraints.m:
compiler/modules.m:
compiler/structure_reuse.analysis.m:
	Avoid the warnings we now generate about one state variable shadowing
	another.

browser/declarative_user.m:
compiler/hlds_out_util.m:
compiler/ordering_mode_constraints.m:
compiler/table_gen.m:
deep_profiler/read_profile.m:
	Improve programming style.

library/require.m:
	Add expect_not, a negated version of expect.

library/varset.m:
	Return lists of new variables in order, not reverse order.

mdbcomp/mdbcomp.goal_path.m:
compiler/prog_mode.m:
	Add a utility predicate.

tests/debugger/tailrec1.exp:
tests/invalid/any_passed_as_ground.err_exp:
tests/invalid/bad_sv_unify_msg.err_exp:
tests/invalid/state_vars_test1.err_exp:
tests/invalid/state_vars_test4.err_exp:
tests/invalid/try_bad_params.err_exp:
tests/invalid/try_detism.err_exp:
tests/invalid/purity/impure_pred_t1_fixed.err_exp:
tests/invalid/purity/impure_pred_t2.err_exp:
	Update the expected outputs of these test cases to account for
	incidental changes in variable numbers and goal paths after this
	change.

tests/general/state_vars_tests.{m,exp}:
	Remove the code that expected the state var transformation to do
	something that was actually AGAINST the reference manual: treating
	the step from the condition to the then part of an if-then-else
	expression (not a goal) as a sequence point.

tests/general/state_vars_trace.m:
	Add a test case that is not enabled yet, since we don't pass it.

tests/hard_coded/bit_buffer_test.m:
	Fix a bug in the test itself: the introduction of a state var twice
	in the same scope.

tests/hard_coded/try_syntax_6.m:
	Avoid a warning about state var shadowing.

tests/hard_coded/if_then_else_expr_state_var.{m,exp}:
	A new test to check the proper handling of state vars in if-then-else
	expressions.

tests/hard_coded/Mmakefile:
	Enable the new test.
2011-03-07 03:59:43 +00:00
Zoltan Somogyi
a2cd0da5b3 The existing representation of goal_paths is suboptimal for several reasons.
Estimated hours taken: 80
Branches: main

The existing representation of goal_paths is suboptimal for several reasons.

- Sometimes we need forward goal paths (e.g. to look up goals), and sometimes
  we need reverse goal paths (e.g. when computing goal paths in the first
  place). We had two types for them, but

  - their names, goal_path and goal_path_consable, were not expressive, and
  - we could store only one of them in goal_infos.

- Testing whether goal A is a subgoal of goal B is quite error-prone using
  either form of goal paths.

- Using a goal path as a key in a map, which several compiler passes want to
  do, requires lots of expensive comparisons.

This diff replaces most uses of goal paths with goal ids. A goal id is an
integer, so it can be used as a key in faster maps, or even in arrays.
Every goal in the body of a procedure gets its id allocated in a depth first
search. Since we process each goal before we dive into is descendants,
the goal representing the whole body of a procedure always gets goal id 0.
The depth first traversal also builds up a map (the containing goal map)
that tells us the parent goal of ever subgoal, with the obvious exception
of the root goal itself. From the containing goal map, one can compute
both reverse and forward goal paths. It can also serve as the basis of an
efficient test of whether the goal identified by goal id A is an ancestor
of another goal identified by goal id B. We don't yet use this test,
but I expect we will in the future.

mdbcomp/program_representation.m:
	Add the goal_id type.

	Replace the existing goal_path and goal_path_consable types
	with two new types, forward_goal_path and reverse_goal_path.
	Since these now have wrappers around the list of goal path steps
	that identify each kind of goal path, it is now ok to expose their
	representations. This makes several compiler passes easier to code.

	Update the set of operations on goal paths to work on the new data
	structures.

	Add a couple of step types to represent lambdas and try goals.
	Their omission prior to this would have been a bug for constraint-based
	mode analysis, or any other compiler pass prior to the expansion out
	of lambda and try goals that wanted to use goal paths to identify
	subgoals.

browser/declarative_tree.m:
mdbcomp/rtti_access.m:
mdbcomp/slice_and_dice.m:
mdbcomp/trace_counts.m:
slice/mcov.m:
deep_profiler/*.m:
	Conform to the changes in goal path representation.

compiler/hlds_goal:
	Replace the goal_path field with a goal_id field in the goal_info,
	indicating that from now on, this should be used to identify goals.

	Keep a reverse_goal_path field in the goal_info for use by RBMM and
	CTGC. Those analyses were too hard to convert to using goal_ids,
	especially since RBMM uses goal_paths to identify goals in multi-pass
	algorithms that should be one-pass and should not NEED to identify
	any goals for later processing.

compiler/goal_path:
	Add predicates to fill in goal_ids, and update the predicates
	filling in the now deprecated reverse goal path fields.

	Add the operations needed by the rest of the compiler
	on goal ids and containing goal maps.

	Remove the option to set goal paths using "mode equivalent steps".
	Constraint based mode analysis now uses goal ids, and can now
	do its own equivalent optimization quite simply.

	Move the goal_path module from the check_hlds package to the hlds
	package.

compiler/*.m:
	Conform to the changes in goal path representation.

	Most modules now use goal_ids to identify goals, and use a containing
	goal map to convert the goal ids to goal paths when needed.
	However, the ctgc and rbmm modules still use (reverse) goal paths.

library/digraph.m:
library/group.m:
library/injection.m:
library/pprint.m:
library/pretty_printer.m:
library/term_to_xml.m:
	Minor style improvements.
2010-12-20 07:47:49 +00:00
Zoltan Somogyi
8a28e40c9b Add the predicates sorry, unexpected and expect to library/error.m.
Estimated hours taken: 2
Branches: main

Add the predicates sorry, unexpected and expect to library/error.m.

compiler/compiler_util.m:
library/error.m:
	Move the predicates sorry, unexpected and expect from compiler_util
	to error.

	Put the predicates in error.m into the same order as their
	declarations.

compiler/*.m:
	Change imports as needed.

compiler/lp.m:
compiler/lp_rational.m:
	Change imports as needed, and some minor cleanups.

deep_profiler/*.m:
	Switch to using the new library predicates, instead of calling error
	directly. Some other minor cleanups.

NEWS:
	Mention the new predicates in the standard library.
2010-12-15 06:30:36 +00:00
Zoltan Somogyi
1bf42bbc38 Avoid more dependencies between the processing of different procedures
Estimated hours taken: 8
Branches: main

Avoid more dependencies between the processing of different procedures
when the compiler is executed in parallel.

compiler/accumulator.m:
	Instead of printing out error messages here, pass error_specs back
	to the top level.

compiler/complexity.m:
	Use trace goals to print progress messages.

compiler/passes_aux.m:
	Add the traversal type now needed by accumulator.m, and remove others
	that are no longer needed. Since now NO task needs I/O states, make
	the traversal predicates not take I/O state pair arguments any more.

compiler/deforest.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/ssdebug.m:
compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
	Conform to the changes in passes_aux.m and in accumulator.m.

compiler/error_util.m:
compiler/pd_util.m:
	Style fixes.

tests/warnings/arg_order_rearrangement.exp:
	Expect the new and improved warning message.

tests/warnings/arg_order_rearrangement.exp2:
	Mark this file as not an expected output, since a part of it
	doesn't seem to be ever generated by the compiler anymore.
2010-08-23 07:38:33 +00:00
Zoltan Somogyi
543fc6e342 Change the way the typechecker iterates over the predicates of the program.
Estimated hours taken: 12
Branches: main

Change the way the typechecker iterates over the predicates of the program.
We used to do it by looking up each predicate in the module_info,
typechecking it, and putting it back into the module_info. We now do it
by converting the predicate table into a list, iterating over the list
transforming each pred_info in it, converting the updated list back to
a predicate table.

The original intention of this change was to allow different predicates
to be typechecked in parallel by removing a synchronization bottleneck:
the typechecking of a predicate now doesn't have to wait for the typechecking
of the previous predicate to generate the updated version of the module_info.
However, it turned out that the change is good for sequential execution
as well, improving the time on tools/speedtest from 11.33 seconds to 11.08
seconds, a speedup of 2.2%. On tools/speedtest -l, which tests the compilation
of more modules, the speedup is even better: 3.1% (from 32.63 to 31.60s).

compiler/typecheck.m:
	Implement the above change.

compiler/hlds_module.m:
compiler/pred_table.m:
	Add a new operation, setting the list of valid pred_ids, now needed by
	typecheck.m, to both modules.

	Make the names of the predicates for accessing the predicate table
	more expressive, and make them conform to our naming conventions.

compiler/*.m:
	Trivial changes to conform to the change in hlds_module.m.

library/assoc_list.m:
	Add new predicates used by the new version of typecheck.m
	(at some time in its development).

NEWS:
	Mention the new predicates.

library/list.m:
	Improve documentation that is now copied to assoc_list.m.

tools/speedtest:
	Make the test command more easily configurable.
2010-07-30 05:16:26 +00:00
Zoltan Somogyi
30aafc69a0 Split up three big compiler modules: llds_out.m, hlds_out.m (5000+ lines each)
Estimated hours taken: 12
Branches: main

Split up three big compiler modules: llds_out.m, hlds_out.m (5000+ lines each)
and deep_profiling.m (3000+ lines). Put the predicates in the resulting
smaller modules into cohesive groups where possible. A few of the predicates
in the original modules were unused; this diff deletes them.

There are no algorithmic changes.

compiler/llds_out_code_addr.m:
	New module containing the part of llds_out.m that outputs
	code addresses and labels.

compiler/llds_out_data.m:
	New module containing the part of llds_out.m that outputs
	lvals, rvals and their components.

compiler/llds_out_global.m:
	New module containing the part of llds_out.m that generates
	global static C data structures.

compiler/llds_out_instr.m:
	New module containing the part of llds_out.m that outputs
	instructions

compiler/llds_out_file.m:
	New module containing the top level part of llds_out.m,
	which coordinates the generation of a whole C source file.

compiler/llds_out_util.m:
	New module containing the utility parts of llds_out.m.

compiler/llds_out.m:
	Replace everything in this file with just the includes of the
	submodules that now have all its previous contents.

compiler/hlds_llds.m:
	Move a predicate here from llds_out.m, since it is a utility
	predicate operating on a type defined here.

compiler/rtti_out.m:
	Move a predicate here from llds_out.m, since it is a predicate
	generating output from a rtti type.

compiler/hlds_out_mode.m:
	The part of hlds_out.m that deals with writing out insts and modes.

compiler/hlds_out_goal.m:
	The part of hlds_out.m that deals with writing out goals.

compiler/hlds_out_pred.m:
	The part of hlds_out.m that deals with writing out predicates and
	procedures.

compiler/hlds_out_module.m:
	The part of hlds_out.m that deals with writing out module-wide tables.

compiler/hlds_out_util.m:
	Parts of hlds_out.m that don't fit in anywhere else.

compiler/hlds_out.m:
	Replace everything in this file with just the includes of the
	submodules that now have all its previous contents.

compiler/simplify.m:
compiler/hlds_goal.m:
	Move some insts from simplify.m to hlds_goal.m to allow
	hlds_out_goal.m to use them also.

compiler/coverage_profiling.m:
	The part of deep_profiling.m that deals with coverage profiling.

compiler/deep_profiling.m:
	Remove the code moved to coverage_profiling.m, and export the utility
	predicates needed by coverage_profiling.m.

	Remove the things moved to prog_data.m and hlds_goal.m.

	Put the predicates into a more logical order.

compiler/hlds_goal.m:
	Move some predicates here from deep_profiling.m, since they
	belong here.

compiler/prog_data.m:
	Move a type from deep_profiling.m here, since it belongs here.

compiler/add_pragma.m:
	Add a predicate from llds_out.m that is used only here.

compiler/*.m:
	Conform to the changes above.
2009-11-04 03:44:52 +00:00
Zoltan Somogyi
4ebe3d0d7e Stop storing globals in the I/O state, and divide mercury_compile.m
Estimated hours taken: 60
Branches: main

Stop storing globals in the I/O state, and divide mercury_compile.m
into smaller, more cohesive modules. (This diff started out as doing
only the latter, but it became clear that this was effectively impossible
without the former, and the former ended up accounting for the bulk of the
changes.)

Taking the globals out of the I/O state required figuring out how globals
data flowed between pieces of code that were often widely separated.
Such flows were invisible when globals could be hidden in the I/O state,
but now they are visible, because the affected code now passes around
globals structures explicitly.

In some cases, the old flow looked buggy, as when one job invoked by
mmc --make could affect the globals value of its parent or the globals value
passed to the next job. I tried to fix such problems when I saw them. I am
not 100% sure I succeeded in every case (I may have replaced old bugs with
new ones), but at least now the flow is out in the open, and any bugs
should be much easier to track down and fix.

In most cases, changes the globals after the initial setup are intended to be
in effect only during the invocation of a few calls. This used to be done
by remembering the initial values of the to-be-changed options, changing their
values in the globals in the I/O state, making the calls, and restoring the old
values of the options. We now simply create a new version of the globals
structure, pass it to the calls to be affected, and then discard it.

In two cases, when discovering reasons why (1) smart recompilation should
not be done or (2) item version numbers should not be generated, the record
of the discovery needs to survive this discarding. This is why in those cases,
we record the discovery by setting a mutable attached to the I/O state.
We use pure code (with I/O states) both to read and to write the mutables,
so this is no worse semantically than storing the information in the globals
structure inside the I/O state. (Also, we were already using such a mutable
for recording whether -E could add more information.)

In many modules, the globals information had to be threaded through
several predicates in the module. In some places, this was made more
difficult by predicates being defined by many clauses. In those cases,
this diff converts those predicates to using explicit disjunctions.

compiler/globals.m:
	Stop storing the globals structure in the I/O state, and remove
	the predicates that accessed it there.

	Move a mutable and its access predicate here from handle_options.m,
	since here is when the mutables treated the same way are.

	In a couple of cases, the value of an option is available in a mutable
	for speed of access from inside performance-critical code. Set the
	values of those mutables from the option when the processing of option
	values is finished, not when it is starting, since otherwise the copies
	of each option could end up inconsistent.

	Validate the reuse strategy option here, since doing it during ctgc
	analysis (a) is too late, and (b) would require an update to the
	globals to be done at an otherwise inconvenient place in the code.
	Put the reuse strategy into the globals structure.

	Two fields in the globals structure were unused. One
	(have_printed_usage) was made redundant when the one predicate
	that used it itself became unused; the other (source_file_map)
	was effectively replaced by a mutable some time ago. Delete
	these fields from the globals.

	Give the fields of the globals structure a distinguishing prefix.

	Put the type declarations, predicate declarations and predicate
	definitions in a consistent order.

compiler/source_file_map.m:
	Record this module's results only in the mutable (it serves as a
	cache), not in globals structure. Use explicitly passed globals
	structure for other purposes.

compiler/handle_options.m:
	Rename handle_options as handle_given_options, since it does not
	process THE options to the program, but the options it is given,
	and even during the processing of a single module, it can be invoked
	up the three times in a row, each time being given different options.
	(It was up to four times in a row before this diff.)

	Make handle_given_options explicitly return the globals structure it
	creates. Since it does not take an old global structure as input
	and globals are not stored in the I/O state, it is now clear that
	the globals structure it returns is affected only by the default values
	of the options and the options it processes. Before this diff,
	in the presence of errors in the options, handle_options *could*
	return (implicitly, in the I/O state) the globals structure that
	happened to be in the I/O state when it was invoked.

	Provide a separate predicate for generating a dummy globals based only
	on the default values of options. This allows by mercury_compile.m
	to stop abusing a more general-purpose predicate from handle_options.m,
	which we no longer export.

	Remove the mutable and access predicate moved to globals.m.

compiler/options.m:
	Document the fact that two options, smart_recompilation and
	generate_item_version_numbers, should not be used without seeing
	whether the functionalities they call for have been disabled.

compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/mercury_compile_erl_back_end.m:
	New modules carved out of the old mercury_compile.m. They each cover
	exactly the areas suggested by their names.

	Each of the modules is more cohesive than the old mercury_compile.m.
	Their code is also arranged in a more logical order, with predicates
	representing compiler passes being defined in the order of their
	invocation.

	Some of these modules export predicates for use by their siblings,
	showing the dependencies between the groups of passes.

compiler/top_level.m:
compiler/notes/compiler_design.html:
	Add the new modules.

compiler/mark_static_terms.m:
	Move this module from the ml_backend package to the hlds package,
	since (a) it does not depend on the MLDS in any way, and (b) it is
	also needed by a compiler pass (loop invariants) in the middle passes.

compiler/hlds.m:
compiler/ml_backend.m:
compiler/notes/compiler_design.html:
	Reflect mark_static_terms.m's change of package.

compiler/passes_aux.m:
	Move the predicates for dumping out the hLDS here from
	mercury_compile.m, since the new modules also need them.

	Look up globals in the HLDS, not the I/O state.

compiler/hlds_module.m:
	Store the prefix (common part) of HLDS dump file names in the HLDS
	itself, so that the code moved to passes_aux.m can figure out the
	file name for a HLDS dump without doing system calls.

	Give the field names of some structures prefixes to avoid ambiguity.

compiler/mercury_compile.m:
	Remove the code moved to the other modules. This module now looks
	after only option handling (such as deciding whether to generate .int3
	files, .int files, .opt files etc), and the compilation passes
	up to and including the creation of the first version of the HLDS.
	Everything after that is subcontracted to the new modules.

	Simplify and make explicit the flow of globals information.
	When invoking predicates that could disable smart recompilation,
	check whether they have done so, and if yes, update the globals
	accordingly.

	When compiling via gcc, we need to link into the executable
	the object files of any separate C files we generate for C code
	foreign_procs, which we cannot translate into gcc's internal
	structures without becoming a C compiler as well as a Mercury compiler.
	Instead of adding such files to the accumulating option for extra
	object files in the globals structure, we return their names using
	the already existing mechanism we have always used to link the object
	files of fact tables into the executable.

	Give several predicates more descriptive names. Put predicates
	in a more logical order.

compiler/make.m:
compiler/make.dependencies.m:
compiler/make.module_target.m:
compiler/make.module_dep_file.m:
compiler/make.program_target.m:
compiler/make.util.m:
	Require callers to supply globals structures explicitly, not via the
	I/O state. Afterward pass them around explicitly, passing modified
	versions to mercury_compile.m when invoking it with module- and/or
	task-specific options.

	Due the extensive use of partial application for higher order code
	in these modules, passing around the globals structures explicitly
	is quite tricky here. There may be cases where a predicate uses
	an old globals structure it got from a closure instead of the updated
	module- and/or task-specific globals it should be using, or vice versa.
	However, it is just as likely that, this diff fixes old problems
	by preventing the implicit flow of updated-only-for-one-invocation
	globals structures back to the original invoking context.

	Although I have tried to be careful about this, it is also possible
	that in some places, the code is using an updated-for-an-invocation
	globals structure in some but not all of the places where it
	SHOULD be used.

compiler/c_util.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/error_util.m:
compiler/file_names.m:
compiler/file_util.m:
compiler/ilasm.m:
compiler/ml_optimize.m:
compiler/mlds_to_managed.m:
compiler/module_cmds.m:
compiler/modules.m:
compiler/options_file.m:
compiler/pd_debug.m:
compiler/prog_io.m:
compiler/transform_llds.m:
compiler/write_deps_file.m:
	Require callers to supply globals structures explicitly, not via the
	I/O state.

	In some cases, the explicit globals structure argument allows
	a predicate to dispense with the I/O states previously passed to it.

	In some modules, rename some predicates, types and/or function symbols
	to avoid ambiguity.

compiler/read_modules.m:
	Require callers to supply globals structures explicitly, not via the
	I/O state.

	Record when smart recompilation and the generation of item version
	numbers should be disabled.

compiler/opt_debug.m:
compiler/process_util.m:
	Require callers to supply the needed options explicitly, not via the
	globals in the I/O state.

compiler/analysis.m:
compiler/analysis.file.m:
compiler/mmc_analysis.m:
	Make the analysis framework's methods take their global structures
	as explicit arguments, not as implicit data stored in the I/O state.

	Stop using `with_type` and `with_inst` declarations unnecessarily.

	Rename some predicates to avoid ambiguity.

compiler/hlds_out.m:
compiler/llds_out.m:
compiler/mercury_to_mercury.m:
compiler/mlds_to_c.m:
compiler/mlds_to_java.m:
compiler/optimize.m:
	Make these modules stop accessing the globals from the I/O state.
	Do this by requiring the callers of their top predicates to explicitly
	supply a globals structure. To compensate for the cost of having to
	pass around a representation of the options, look up the values of the
	options of interest just once, to make further access much faster.

	(In the case of mlds_to_c.m, the code already did much of this,
	but it still had a few accesses to globals in the I/O state that
	this diff eliminates.)

	If the module exports a predicate that needs these pre-looked-up
	options, then export the type of this data structure and its
	initialization function.

compiler/frameopt.m:
	Since this module needs only one option from the globals, pass that
	option instead of the globals.

compiler/accumulator.m:
compiler/add_clause.m:
compiler/closure_analysis.m:
compiler/complexity.m:
compiler/deforest.m:
compiler/delay_construct.m:
compiler/elds_to_erlang.m:
compiler/exception_analysis.m:
compiler/fact_table.m:
compiler/intermod.m:
compiler/mode_constraints.m:
compiler/mode_errors.m:
compiler/pd_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/size_prof.usage.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_errors.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/term_constr_util.m:
compiler/trailing_analysis.m:
compiler/trans_opt.m:
compiler/typecheck_info.m:
	Look up globals information from the HLDS, not the I/O state.

	Conform to the changes above.

compiler/gcc.m:
compiler/maybe_mlds_to_gcc.pp:
compiler/mlds_to_gcc.m:
	Look up globals information from the HLDS, not the I/O state.

	Conform to the changes above.

	Convert these modules to our current programming style.

compiler/termination.m:
	Look up globals information from the HLDS, not the I/O state.

	Conform to the changes above.

	Report some warnings with error_specs, instead of immediately
	printing them out.

compiler/export.m:
compiler/il_peephole.m:
compiler/layout_out.m:
compiler/rtti_out.m:
compiler/liveness.m:
compiler/make_hlds.m:
compiler/make_hlds_passes.m:
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/recompilation.check.m:
compiler/stack_opt.m:
compiler/superhomogeneous.m:
compiler/tupling..m:
compiler/unneeded_code.m:
compiler/unused_args.m:
compiler/unused_import.m:
compiler/xml_documentation.m:
	Conform to the changes above.

compiler/equiv_type_hlds.m:
	Give the field names of a structure prefixes to avoid ambiguity.

	Stop using `with_type` and `with_inst` declarations unnecessarily.

compiler/loop_inv.m:
compiler/pd_info.m:
compiler/stack_layout.m:
	Give the field names of some structures prefixes to avoid ambiguity.

compiler/add_pragma.m:
	Add notes.

compiler/string.m:
NEWS:
	Add a det version of remove_suffix, for use by new code above.
2009-10-14 05:28:53 +00:00
Peter Wang
a37c4f3b75 Avoid a linking problem that can occur when using structure reuse and
Branches: main

Avoid a linking problem that can occur when using structure reuse and
`--intermodule-analysis'.  When making an `.analysis' we may find that a
procedure has conditional reuse, but when making the target code we may find
that procedure has unconditional or no reuse.  If another module calls the
conditional reuse version of the procedure, which doesn't exist, that would
lead to a linking error.

The solution is to produce a fake conditional reuse procedure which forwards
to the unconditional/no-reuse procedure if we detect this situation.  We
already did that when using `--intermodule-optimisation'.

compiler/structure_reuse.analysis.m:
	As above.
2008-09-08 02:33:50 +00:00
Peter Wang
0d10146979 Memoise type_contains_subtype. This greatly speeds up structure
Branches: main

compiler/ctgc.selector.m:
	Memoise type_contains_subtype.  This greatly speeds up structure
	sharing/reuse analysis on some modules.

	Add a predicate to reset the memo table.

	Add a comment.

compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
	Reset the memo table after these analyses.
2008-08-07 02:56:04 +00:00
Peter Wang
04608b04e7 In structure sharing and structure reuse analyses, we weren't renaming
Branches: main

In structure sharing and structure reuse analyses, we weren't renaming
variables from imported `sharing_as' and `reuse_as' structures to match the
variable names used in the current compiler run.  It was only by luck if a
particular variable number referred to the same thing in an imported answer
as in the procedure being analysed.

We *were* doing it for `--transitive-' and `--intermodule-optimisation'
but not for `--intermodule-analysis'.

compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
	Change structure sharing and reuse answers to store
	`structure_sharing_domain', `structure_reuse_domain' structures instead
	of `sharing_as' and `reuse_as' structures.

	Rename the variables from imported answers.

	Bump analysis versions.

compiler/structure_sharing.domain.m:
	Hide `sharing_as' again as we no longer need it outside this module.

tests/analysis/ctgc/reuse_runtest.sh:
	Update test cases for changed answer formats.
2008-07-28 03:10:36 +00:00
Peter Wang
1339110d8d Fix a problem with intermodule analysis and structure reuse analysis.
Branches: main

Fix a problem with intermodule analysis and structure reuse analysis.
During the `--make-analysis-registry' step we may find one set of reuse
conditions for a procedure, but during the making target code step, we find
a different, harsher set of reuse conditions (due to extra information being
available later).  We cannot generate code which would violate the weaker
conditions presented in the analysis file, as calls from external modules
may satisfy the weaker conditions but not the stronger conditions.

The same problem occurs with --transitive- and `--intermodule-optimisation'.

compiler/structure_reuse.versions.m:
compiler/structure_reuse.analysis.m:
	Fix the problem above.

compiler/structure_reuse.domain.m:
	Improve reverse lookups for a field in the reuse_as_table.

compiler/structure_reuse.indirect.m:
	Conform to reuse_as_table change.
2008-07-23 05:13:20 +00:00
Zoltan Somogyi
a00596c283 The file modules.m contains lots of different kinds of functionality.
Estimated hours taken: 16
Branches: main

The file modules.m contains lots of different kinds of functionality.
While much of it belongs together, much of it does not. This diff moves
most of the functionality that does not belong with the rest to several
new modules:

	libs.file_util
	parse_tree.deps_map
	parse_tree.file_names
	parse_tree.module_cmds
	parse_tree.module_imports
	parse_tree.read_module
	parse_tree.write_deps_file

To make them coherent, move some predicates from hlds.passes_aux,
parse_tree.prog_io and parse_tree.prog_out to the new modules, making them
more accessible, reducing the required access from the hlds package to
parse_tree, or from the parse_tree package to libs.

In the same spirit, this diff also moves some simple predicates and functions
dealing with sym_names from prog_util.m to mdbcomp/prim_data.m. This allows
several modules to avoid depending on parse_tree.prog_util.

Rename some of the moved predicates and function symbols where this avoids
ambiguity. (There were several that differed from other predicates or function
symbols only in arity.)

Replace several uses of bools with purpose-specific types. This makes some
of the code significantly easier to read.

This diff moves modules.m from being by far the largest module, to being
only the seventh largest, from 8900+ lines to just 4200+. It also reduces
the number of modules that import parse_tree.modules considerably; most
modules that imported it now import only one or two of the new modules instead.

Despite the size of the diff, there should be no algorithmic changes.

compiler/modules.m:
compiler/passes_aux.m:
compiler/prog_io.m:
compiler/prog_out.m:
	Delete the moved functionality.

compiler/file_util.m:
	New module in the libs package. Its predicates search for files
	and do simple error or progress reporting.

compiler/file_names.m:
	New module in the parse_tree package. It contains predicates for
	converting module names to file names.

compiler/module_cmds.m:
	New module in the parse_tree package. Its predicates handle the
	commands for manipulating interface files of various kinds.

compiler/module_import.m:
	New module in the parse_tree package. It contains the module_imports
	type and its access predicates, and the predicates that compute
	various sorts of direct dependencies (those caused by imports)
	between modules.

compiler/deps_map.m:
	New module in the parse_tree package. It contains the data structure
	for recording indirect dependencies between modules, and the predicates
	for creating it.

compiler/read_module.m:
	New module in the parse_tree package. Its job is reading in modules,
	both human-written and machine-written (such as interface and
	optimization files).

compiler/write_deps_file.m:
	New module in the parse_tree package. Its job is writing out
	makefile fragments.

compiler/libs.m:
compiler/parse_tree.m:
	Include the new modules.

compiler/notes/compiler_design.m:
	Document the new modules.

mdbcomp/prim_data.m:
compiler/prog_util.m:
	Move the predicates that operate on nothing but sym_names from
	prog_util to prim_data.

	Move get_ancestors from modules to prim_data.

compiler/prog_item.m:
	Move stuff that looks for foreign code in a list of items here from
	modules.m.

compiler/source_file_map.m:
	Note why this module needs to be in the parse_tree package.

compiler/add_pred.m:
compiler/add_special_pred.m:
compiler/analysis.file.m:
compiler/analysis.m:
compiler/assertion.m:
compiler/check_typeclass.m:
compiler/compile_target_code.m:
compiler/cse_detection.m:
compiler/det_analysis.m:
compiler/elds_to_erlang.m:
compiler/exception_analysis.m:
compiler/export.m:
compiler/fact_table.m:
compiler/higher_order.m:
compiler/hlds_module.m:
compiler/hlds_pred.m:
compiler/intermod.m:
compiler/llds_out.m:
compiler/make.dependencies.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/make_hlds_passes.m:
compiler/maybe_mlds_to_gcc.pp:
compiler/mercury_compile.m:
compiler/mlds.m:
compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_java.m:
compiler/mmc_analysis.m:
compiler/mode_constraints.m:
compiler/mode_debug.m:
compiler/modes.m:
compiler/module_qual.m:
compiler/optimize.m:
compiler/passes_aux.m:
compiler/proc_gen.m:
compiler/prog_foreign.m:
compiler/prog_io.m:
compiler/prog_io_util.m:
compiler/prog_mutable.m:
compiler/prog_out.m:
compiler/pseudo_type_info.m:
compiler/purity.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/simplify.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_reuse.direct.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/trans_opt.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/typecheck_info.m:
compiler/unify_proc.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
	Minor changes to conform to the changes above.
2008-07-21 03:10:29 +00:00
Peter Wang
36b7bd4ea0 Store call and answer patterns as terms in `.analysis' (and related) files and
Branches: main

Store call and answer patterns as terms in `.analysis' (and related) files and
not strings.  It's easier to convert complex patterns to/from terms than
strings.  Also change the module names and function-ids while we're at it.

compiler/analysis.m:
	Replace the `to_string' typeclass with a `to_term' typeclass.  Make
	call and answer patterns convert to/from terms instead of strings.

compiler/analysis.file.m:
	Read/write terms for call and answer patterns.

	Read/write module names and function-ids with more natural syntax
	than the term representations of internal data structures.

	Bump the analysis file version number.

	Move some code around.

	Use promise_equivalent_solutions goals instead of
	promise_equivalent_solution_io.

compiler/exception_analysis.m:
compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
compiler/unused_args.m:
	Conform to `to_term' typeclass interface.

tests/analysis/ctgc/reuse_runtest.sh:
tests/analysis/excp/excp_runtest.sh:
tests/analysis/sharing/sharing_runtest.sh:
tests/analysis/unused_args/unused_args_runtest.sh:
	Update test scripts for changed file formats.

compiler/mercury_compile.m:
	Print verbose messages and report stats when reading in files for
	intermodule analysis.
2008-06-06 02:18:07 +00:00
Peter Wang
6eab527191 More changes to the intermodule analysis framework.
Branches: main

More changes to the intermodule analysis framework.  This patch mainly deals
with incorrect treatment of :- external procedures, opt_imported procedures,
and forcing the correct reanalyses when answers change or requests are
satisfied.

- Previously, the way to ensure that a module M is reanalysed if a request in
  module N is satisfied was, while analysing M: assume an answer for the
  procedure in N; record that as a result in N; and record that M has a
  dependency on that answer.  When N is analysed, if the real answer is
  better than the assumed answer, M would be marked `suboptimal' and later
  reanalysed.

  That's complicated and wasn't always done correctly.  Now we remember the
  module which makes a request.  When the request is satisfied, we mark the
  requesting module as `suboptimal'.  This also means the `.analysis' file of
  a module will only be modified when analysing that module and no others,
  which should be useful for parallel builds.

- In most analyses we weren't recording results for exported `:- external'
  procedures as we don't have their clauses and don't analyse them.  Other
  modules would happily make requests for `:- external' procedures, which
  would never be satisfied.

- We shouldn't make intermodule requests for `opt_imported' procedures as we
  actually have their clauses.  Even if the request is satisfied, we'd
  probably not look them up since we do have their clauses.

- If a module M opt_imports a procedure P from module N (its clauses are
  available while analysing M) then M also needs to depend on any answers
  required by P.  Otherwise a change to an answer required by P won't cause M
  to be reanalysed.

- There doesn't seem to be any reason to keep track of the analysis status of
  individual results.  If an answer changes requiring another module to be
  reanalysed, the *whole module* will be marked suboptimal or invalid.  And
  if that results in changed answers, its dependant modules will be marked.
  This patch doesn't remove the status of individual results but makes them
  always `optimal'.


compiler/analysis.m:
	Remember the name of the module being analysed in the analysis_info.
	Simplify some predicate interfaces with this information.

	Remember whether we're currently making an analysis file or just
	reading from them.  Make the record_* predicates do nothing in the
	latter case, so the caller doesn't need to check.  Also make the
	record predicates do the right thing if the callee module is
	non-local, e.g.  don't make requests to non-local modules.

	Automatically add a request if depending on a result that doesn't
	exist.

	Add a procedure to return the existing call patterns for a procedure,
	regardless of whether the module has been marked `invalid'.

	Add some assertions to check the analysis framework is being used as
	intended.

	Minor cleanups.

compiler/analysis.file.m:
	Record the module that made the request in `.request' files.

	Bump the analysis file version number.

compiler/hlds_module.m:
	Pass extra arguments to `init_analysis_info'.

compiler/hlds_pred.m:
	Add `pred_info_is_imported_not_external' which doesn't succeed on
	`:- external' procedures (defined in the current module), unlike
	`pred_info_is_imported'.

compiler/exception_analysis.m:
compiler/tabling_analysis.m:
compiler/trailing_analysis.m:
compiler/unused_args.m:
	Record results for `:- external' procedures.

	Don't look up results for our own `:- external' procedures from the
	analysis registry.  In general, fix many spots where external procs
	would be treated as imported.

	Write out results for procedures which are exported to submodules.

	Conform to analysis framework changes.  Remove some redundant checks
	which have been moved into the framework.

compiler/mercury_compile.m:
	Conform to analysis framework changes.

compiler/structure_reuse.analysis.m:
	Be careful not to read in requests and call patterns for
	`opt_imported' procedures as if they were defined in the current
	module.

	If depending on an answer that doesn't exist, also make a request for
	that answer.

	Conform to analysis framework changes.

	Write out messages when removing useless reuse version procedures.

compiler/structure_reuse.indirect.m:
	Use `pred_info_is_imported_not_external' so as not to look up results
	for our own `:- external' procedures from the analysis registry.

	Treat `opt_imported' procedures as intra-module as far as requests
	are concerned.  We need to satisfy requests for them in the current
	compiler invocation rather than when analysing imported modules.

compiler/structure_sharing.analysis.m:
	Fix treatment of `:- external' procedures.

	Conform to analysis framework changes.

compiler/structure_sharing.domain.m:
	Don't return suboptimal when unable to look up a result.

compiler/mmc_analysis.m:
	Replace pred_or_func_name_arity_to_func_id by a higher-level
	predicate.

tests/Mmakefile:
tests/analysis/Mmakefile:
tests/analysis/common.sh:
tests/analysis/excp/Mercury.options:
tests/analysis/excp/Mmakefile:
tests/analysis/excp/excp_m1.m.exception:
tests/analysis/excp/excp_m1.m.no_exception:
tests/analysis/excp/excp_m2.m:
tests/analysis/excp/excp_m3.m:
tests/analysis/excp/excp_runtest.sh:
tests/analysis/ext/Mercury.options:
tests/analysis/ext/Mmakefile:
tests/analysis/ext/ext.m:
tests/analysis/ext/ext2.m:
tests/analysis/ext/ext2_runtest.sh:
tests/analysis/ext/ext_runtest.sh:
tests/analysis/sharing/Mercury.options:
tests/analysis/sharing/Mmakefile:
tests/analysis/sharing/sharing_m1.m.no_share:
tests/analysis/sharing/sharing_m1.m.share:
tests/analysis/sharing/sharing_m2.m:
tests/analysis/sharing/sharing_m3.m:
tests/analysis/sharing/sharing_runtest.sh:
tests/analysis/table/Mercury.options:
tests/analysis/table/Mmakefile:
tests/analysis/table/table_m1.m.no_tabling:
tests/analysis/table/table_m1.m.tabling:
tests/analysis/table/table_m2.m:
tests/analysis/table/table_m3.m:
tests/analysis/table/table_runtest.sh:
tests/analysis/trail/Mercury.options:
tests/analysis/trail/Mmakefile:
tests/analysis/trail/trail_m1.m.no_trail:
tests/analysis/trail/trail_m1.m.trail:
tests/analysis/trail/trail_m2.m:
tests/analysis/trail/trail_m3.m:
tests/analysis/trail/trail_runtest.sh:
tests/analysis/unused_args/Mercury.options:
tests/analysis/unused_args/Mmakefile:
tests/analysis/unused_args/ua_m1.m.no_unused_args:
tests/analysis/unused_args/ua_m1.m.unused_args:
tests/analysis/unused_args/ua_m2.m:
tests/analysis/unused_args/ua_m3.m:
tests/analysis/unused_args/unused_args_runtest.sh:
	Add test cases.
2008-06-05 06:25:20 +00:00
Peter Wang
470fc542e7 Add initial support for performing call-specific structure reuse analysis.
Branches: main

Add initial support for performing call-specific structure reuse analysis.
If a call site violates the conditions for calling the reuse version of a
procedure, it can request a different reuse version of the procedure with
possibly laxer reuse conditions.  At least for now, I have chosen call
patterns to simply be lists of argument positions, the arguments which
cannot be clobbered by the callee.

Requests across module boundaries are supported when using the
`--intermodule-analysis' option.

This initial version does a lot of unnecessary reanalysis so must be switched
on explicitly with a `--structure-reuse-repeat <n>' option.  This option
shouldn't be needed in the future.


compiler/options.m:
	Add a `--structure-reuse-repeat <n>' option.

compiler/analysis.m:
compiler/mercury_compile.m:
	Read in the `.request' file for the current module being analysed
	when we're preparing to use the intermodule analysis framework.

	Don't return duplicates when looking up analysis requests.

compiler/structure_reuse.analysis.m:
	Read in old reuse analysis answers and new requests when using
	`--intermodule-analysis'.  Make procedures corresponding to old
	Answers (as expected by other modules) and new requests (so we
	analyse the procedures with the requested call patterns).

	When `--structure-reuse-repeat' is used, use the requests from the
	latest indirect reuse pass to create new reuse procedures with the
	extra constraints on some of the head variables (that they must not
	be clobbered).  Perform direct reuse analysis on those procedures,
	then repeat indirect reuse on the whole module so those new
	procedures might be called.

	Record intermodule requests when using `--intermodule-analysis'.

	Delete reuse versions of procedures we may have created, which after
	analysis turn out to have no reuse opportunities at all.

compiler/structure_reuse.lfu.m:
	Add a procedure that adds a set of variables to all the
	local-forward-use sets of a procedure.

compiler/structure_reuse.direct.m:
	Add code to perform direct reuse on a specific list of procedures
	instead of all the procedures in a module.

compiler/structure_reuse.indirect.m:
	Add code to re-run indirect reuse analysis which when analysing an
	SCC also analyses the reuse versions of procedures that were created
	from the procedures in the SCC.

	Remember and return intra- and inter-module requests when existing
	reuse procedures can't be called, for later passes and for later
	analyses of other modules.

	When looking up reuse information for a procedure, if we don't have
	that information we should take that assumed result is `optimal'.
	Otherwise, the analysis results of mutually recursive procedures will
	never get out of the `suboptimal' state.  (Other analyses make the
	same mistake.)

compiler/structure_reuse.domain.m:
	Extend the `reuse_as_table' with a mapping from an original
	(non-reuse) procedure plus call pattern to the procedure which
	actually implements that reuse.

	Make `reuse_as_satisfied' try to return all of the variables at a call
	site that violate the reuse conditions.  That is, instead of just
	giving one reason that a reuse procedure call can't be made, try to
	return all the reasons so we don't waste effort requesting laxer reuse
	procedures which wouldn't be lax enough for the call site anyway.

compiler/structure_reuse.versions.m:
	Account for multiple reuse versions of procedures.

compiler/prog_util.m:
	Use `make_pred_name' to make the names for reuse predicates.

compiler/hlds_goal.m:
compiler/hlds_out.m:
	Record in HLDS goals which reuse version of a procedure to call,
	since there can be multiple to choose from.

compiler/hlds_module.m:
compiler/trans_opt.m:
	Replace the `structure_reuse_map' field in the module structure by a
	simple set of pred_ids of reuse predicates.  The old map from
	procedures to their reuse counterparts is not needed outside of the
	structure reuse passes, which has the same information in a separate
	table anyway.

compiler/structure_sharing.analysis.m:
	Assume guessed structure sharing answers are `optimal' instead of
	`suboptimal', as above.

compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
	Module import changes.
2008-05-28 00:52:29 +00:00
Peter Wang
d302ab27b7 A recent change caused (useless) structure sharing and structure reuse
Estimated hours taken: 0.5
Branches: main

compiler/structure_reuse.analysis.m:
compiler/structure_sharing.analysis.m:
	A recent change caused (useless) structure sharing and structure reuse
	pragmas to be written to `.trans_opt' files even when those analyses
	were not run.  Fix that.
2008-05-12 01:37:05 +00:00
Peter Wang
2dffc6b4c5 Make the structure reuse analysis able to use the intermodule analysis
Branches: main

Make the structure reuse analysis able to use the intermodule analysis
framework.

compiler/hlds_pred.m:
	Keep the analysis status with the structure reuse domain in the
	proc_info.

compiler/hlds_out.m:
	Conform to the above.

compiler/mmc_analysis.m:
	Add structure reuse to the list of analyses.

compiler/structure_reuse.analysis.m:
	Add the usual code to interface an analysis pass with the analysis
	framework.

	Load reuse information about imported procedures from the analysis
	registry.

	Record reuse analysis results and dependencies to the analysis
	registry.

	We were not writing out results for `:- external' procedures even if
	they were exported; do that.

	Write out the results for type specialised procedures if making
	`.analysis' files, because we can, but not for `.opt' files, since we
	can't.

compiler/structure_reuse.direct.m:
	Add reuse results for `:- external' procedures to the reuse table so
	that they will be written out to `.opt' and `.analysis' files.

compiler/structure_reuse.domain.m:
	Keep the analysis status with the reuse_as in the reuse table.

	Change a semidet function to a predicate.

compiler/structure_reuse.indirect.m:
	Keep track of the procedures which we depended on during the analysis.

	Rename AnalysisInfo to IrInfo everywhere as AnalysisInfo usually
	refers to the analysis_info of the intermodule analysis framework.

compiler/structure_reuse.versions.m:
	Don't try to create reuse versions of imported procedures which may
	appear in the reuse table.

compiler/structure_sharing.analysis.m:
	Write out results for `:- external' procedures.

	Make sure not to write out results for unify/compare predicates
	(although it doesn't seem to happen anyway).

	Write out results for type specialised procedures to `.analysis'
	files but not `.opt' files.

compiler/structure_sharing.domain.m:
	Add a question to investigate later.
2008-05-07 05:05:52 +00:00
Peter Wang
033d854ef1 Various fixes for intermodule optimisation and structure reuse analysis.
Branches: main

Various fixes for intermodule optimisation and structure reuse analysis.

compiler/structure_reuse.analysis.m:
	Write `:- pragma structure_reuse' declarations when making `.opt'
	files.

	Write structure_reuse pragmas for procedures exported to submodules.

	Don't write structure_reuse pragmas for the reuse versions of
	procedures.

	Create forwarding procedures for procedures that, according to the
	.opt file, have conditional reuse versions, but when generating target
	code we find has no reuse.

compiler/structure_reuse.versions.m:
	Add predicates to create forwarding procedures.

	Record the origin of reuse procedures as `transform_structure_reuse'.

	Mark reuse versions of procedures as `status_local' if the original
	procedure was `opt_imported' so they don't get removed by dead proc
	elimination.

compiler/intermod.m:
	If structure reuse is enabled, read in a module's own `.opt' file and
	keep any `:- pragma structure_reuse' declarations so that we can know
	whether we need to create forwarding procedures.

compiler/mercury_compile.m:
	Perform higher-order specialisation, inlining and deforestation before
	CTGC passes when making intermodule optimisation or analysis files.
	This reduces the discrepancy between the CTGC results we get while
	making .opt/.trans_opt files and while making .c files.

compiler/ctgc.util.m:
	Don't abort in get_type_substitution if the caller's actual arguments
	don't match the callee's argument types and some compiler-generated
	procedures are type-incorrect.

compiler/hlds_pred.m:
compiler/layout_out.m:
	Add `transform_structure_reuse' option for `pred_transformation'.
2008-04-17 04:21:51 +00:00
Peter Wang
29f25e0bf2 Commit some simple changes accumulating in a workspaces to reduce clutter.
Branches: main

Commit some simple changes accumulating in a workspaces to reduce clutter.

compiler/ctgc.datastruct.m:
	Write datastructs_subsumed_by_list more declaratively.

compiler/ctgc.util.m:
	Rename `preds_requiring_no_analysis' to
	`some_preds_requiring_no_analysis' to reflect what it does and
	simplify the implementation.

compiler/hlds_goal.m:
	Use `needs_update' instead of `bool' in a spot.

	Update comments.

compiler/quantification.m:
compiler/structure_reuse.versions.m:
	Conform to use of `needs_update' instead of `bool'.

compiler/hlds_pred.m:
compiler/prog_data.m:
compiler/prog_io_pragma.m:
compiler/structure_reuse.direct.m:
	Update comments.

compiler/liveness.m:
	Move a goal into execution order.

compiler/structure_reuse.direct.detect_garbage.m:
	Delete an unnecessary (and overloaded) predicate.

compiler/structure_reuse.analysis.m:
compiler/structure_reuse.domain.m:
	Make the reuse information dump more readable (longer strings instead
	of single character codes, names instead of ids).

compiler/structure_reuse.indirect.m:
	Use `map.apply_to_list' instead of higher order calls.

	Use readable strings for fixpoint table short descriptions.

compiler/structure_sharing.analysis.m:
	Rename some variables.

	Use `map.apply_to_list' instead of higher order calls.

compiler/trans_opt.m:
	Use `assoc_list.keys' instead of higher order calls.

compiler/type_util.m:
	Fix typo.
2008-01-10 04:29:54 +00:00
Zoltan Somogyi
27aaaf412c Fix the failure of the invalid/modes_erroneous test case, whose symptom was
Estimated hours taken: 5
Branches: main

Fix the failure of the invalid/modes_erroneous test case, whose symptom was
an error message about a "mode error in unification of `X' and `X'".
The root cause of the problem was that the renaming of head variables
computed by headvar_names.m was being applied too early, during typechecking.
The fix is to apply it after the frontend (all the passes that can generate
error messages).

To avoid slowdowns from larger pred_infos, this diff also moves the least
frequently used fields of pred_infos to a subterm. (Proc_infos already had
a subterm.) This leads to an almost 3% speedup.

compiler/headvar_names.m:
	Store the renaming instead of applying it.

compiler/simplify.m:
	Apply the renaming in invocations after the front end, since doing so
	may allow some excess assignments to be eliminated.

compiler/hlds_pred.m:
	Add fields to pred_infos and proc_infos for the renaming.

	Move the least frequently used fields of pred_infos into a
	pred_sub_info.

	Some fields of pred_infos were being accessed using predicates
	that did not follow our naming conventions, and some were accessed
	using field access functions that are now inappropriate; fix them all.

	Require the caller to provide the renaming when creating new pred_infos
	and proc_infos. This is to force the compiler components that do this
	to propagate the renaming fields of the original predicates and/or
	procedures to their modified versions.

	Convert that some old code that used if-then-elses to use switches
	instead.

compiler/hlds_out.m:
	Write out the new pred_info and proc_info fields.

compiler/*.m:
	Conform to the changes in hlds_pred.m.

compiler/hlds_clauses.m:
	Avoid ambiguity by giving a prefix to the fields of the clauses_info
	type.

tests/invalid/ho_type_mode_bug.err_exp:
tests/invalid/merge_ground_any.err_exp:
	Don't expect error messages about "X = X" anymore.
2007-05-17 03:53:13 +00:00
Zoltan Somogyi
b56885be93 Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail.
Estimated hours taken: 12
Branches: main

Fix a bug that caused bootchecks with --optimize-constructor-last-call to fail.

The problem was not in lco.m, but in follow_code.m. In some cases,
(specifically, the LCMC version of insert_2 in sparse_bitset.m),
follow_code.m moved an impure goal (store_at_ref) into the arms of an
if-then-else without marking those arms, or the if-then-else, as impure.
The next pass, simplify, then deleted the entire if-then-else, since it
had no outputs. (The store_at_ref that originally appeared after the
if-then-else was the only consumer of its only output.)

The fix is to get follow_code.m to make branched control structures such as
if-then-elses, as well as their arms, semipure or impure if a goal being moved
into them is semipure or impure, or if they came from an semipure or impure
conjunction.

Improve the optimization of the LCMC version of sparse_bitset.insert_2, which
had a foreign_proc invocation of bits_per_int in it: replace such invocations
with a unification of the bits_per_int constant if not cross compiling.

Add a new option, --optimize-constructor-last-call-null. When set, LCMC will
assign NULLs to the fields not yet filled in, to avoid any junk happens to be
there from being followed by the garbage collector's mark phase.

This diff also makes several other changes that helped me to track down
the bug above.

compiler/follow_code.m:
	Make the fix described above.

	Delete all the provisions for --prev-code; it won't be implemented.

	Don't export a predicate that is not now used anywhere else.

compiler/simplify.m:
	Make the optimization described above.

compiler/lco.m:
	Make sure that the LCMC specialized procedure is a predicate, not a
	function: having a function with the mode LCMC_insert_2(in, in) = in
	looks wrong.

	To avoid name collisions when a function and a predicate with the same
	name and arity have LCMC applied to them, include the predicate vs
	function status of the original procedure included in the name of the
	new procedure.

	Update the sym_name of calls to LCMC variants, not just the pred_id,
	because without that, the HLDS dump looks misleading.

compiler/pred_table.m:
	Don't have optimizations like LCMC insert new predicates at the front
	of the list of predicates. Maintain the list of predicates in the
	module as a two part list, to allow efficient addition of new pred_ids
	at the (logical) end without using O(N^2) algorithms. Having predicates
	in chronological order makes it easier to look at HLDS dumps and
	.c files.

compiler/hlds_module.m:
	Make module_info_predids return a module_info that is physically
	updated though logically unchanged.

compiler/options.m:
	Add --optimize-constructor-last-call-null.

	Make the options --dump-hlds-pred-id, --debug-opt-pred-id and
	--debug-opt-pred-name into accumulating options, to allow the user
	to specify more than one predicate to be dumped (e.g. insert_2 and
	its LCMC variant).

	Delete --prev-code.

doc/user_guide.texi:
	Document the changes in options.m.

compiler/code_info.m:
	Record the value of --optimize-constructor-last-call-null in the
	code_info, to avoid lookup at every cell construction.

compiler/unify_gen.m:
compiler/var_locn.m:
	When deciding whether a cell can be static or not, make sure that
	we never make static a cell that has some fields initialized with
	dummy zeros, to be filled in for real later.

compiler/hlds_out.m:
	For goals that are semipure or impure, note this fact. This info was
	lost when I changed the representation of impurity from markers to a
	field.

mdbcomp/prim_data.m:
	Rename some ambiguous function symbols.

compiler/intermod.m:
compiler/trans_opt.m:
	Rename the main predicates (and some function symbols) of these modules
	to avoid ambiguity and to make them more expressive.

compiler/llds.m:
	Don't print line numbers for foreign_code fragments if the user has
	specified --no-line-numbers.

compiler/make.dependencies.m:
compiler/mercury_to_mercury.m:
compiler/recompilation.usage.m:
	Don't use io.write to write out information to files we may need to
	parse again, because this is vulnerable to changes to the names of
	function symbols (e.g. the one to mdbcomp/prim_data.m).

	The compiler still contains some uses of io.write, but they are
	for debugging. I added an item to the todo list of the one exception,
	ilasm.m.

compiler/recompilation.m:
	Rename a misleading function symbol name.

compiler/parse_tree.m:
	Don't import recompilation.m here. It is not needed (all the components
	of parse_tree that need recompilation.m already import it themselves),
	and deleting the import avoids recompiling almost everything when
	recompilation.m changes.

compiler/*.m:
	Conform to the changes above.

compiler/*.m:
browser/*.m:
slice/*.m:
	Conform to the change to mdbcomp.

library/sparse_bitset.m:
	Use some better variable names.
2007-01-19 07:05:06 +00:00
Julien Fischer
b4c3bb1387 Clean up in unused module imports in the Mercury system detected
Estimated hours taken: 3
Branches: main

Clean up in unused module imports in the Mercury system detected
by --warn-unused-imports.

analysis/*.m:
browser/*.m:
deep_profiler/*.m:
compiler/*.m:
library/*.m:
mdbcomp/*.m:
profiler/*.m:
slice/*.m:
	Remove unused module imports.

	Fix some minor departures from our coding standards.

analysis/Mercury.options:
browser/Mercury.options:
deep_profiler/Mercury.options:
compiler/Mercury.options:
library/Mercury.options:
mdbcomp/Mercury.options:
profiler/Mercury.options:
slice/Mercury.options:
	Set --no-warn-unused-imports for those modules that are used as
	packages or otherwise break --warn-unused-imports, e.g. because they
	contain predicates with both foreign and Mercury clauses and some of
	the imports only depend on the latter.
2006-12-01 15:04:40 +00:00
Zoltan Somogyi
2b2f3d3cbe This diff contains no algorithmic changes.
Estimated hours taken: 8
Branches: main

This diff contains no algorithmic changes. It merely renames apart a bunch of
function symbols to reduce ambiguity. Basically I went through prog_data.m,
prog_item.m, hlds_data.m, hlds_goal.m and hlds_pred.m looking for type
definitions containing function symbol names that were either language
"keywords" (e.g. "terminates", which is an annotation on foreign_procs),
used with slightly different meanings in several types (e.g. "sym"),
or both (e.g. "call"). When I found such type definitions, I changed the
names of the function symbols, usually by adding a prefix or suffix
indicating the type to all function symbols of the type. For example,
the old function symbol "foreign_proc" in type "pragma_type" is now named
"pragma_foreign_proc", and the names of all other function symbols in that
type also start with "pragma_".

All of this should yield simpler compiler error messages when we make mistakes,
and will make it more likely that looking up a function symbol using a tags
file will take you to the actual definition of the relevant instance of that
function symbol. However, the most important benefit is the increase in
the readability of unfamiliar code; the reader won't have to emulate the
compiler's type ambiguity resolution algorithm (which in many cases used to
require distinguishing between f/14 and f/15 by counting the arguments,
e.g. for "pred_or_func").

compiler/prog_data.m:
compiler/prog_item.m:
compiler/hlds_data.m:
compiler/hlds_goal.m:
compiler/hlds_pred.m:
	Rename function symbols as explained above.

compiler/*.m:
	Conform to the function symbol renames.

	In some cases, rename other function symbols as well.

	Minor style fixes, e.g. replace if-then-elses with switches,
	or simple det predicates with functions.
2006-08-20 08:21:36 +00:00
Julien Fischer
aeeedd2c13 Standardize formatting of comments at the beginning of modules.
compiler/*.m:
	Standardize formatting of comments at the beginning of modules.
2006-07-31 08:32:11 +00:00
Nancy Mazur
3e88907653 Create optimised versions for all the procedures for which possibilities for
Estimated hours taken: 20
Branches: main

Create optimised versions for all the procedures for which possibilities for
structure reuse are detected. Put the mechanism in place to generate reuse
pragmas, and to parse them back in.

compiler/add_pragma.m:
compiler/structure_sharing.analysis.m:
compiler/hlds_pred.m:
	Postpone the processing (renaming) of structure sharing pragmas
	until the beginning of the actual structure sharing analysis.

compiler/add_pragma.m:
compiler/hlds_pred.m:
compiler/make_hlds_passes.m:
compiler/mercury_to_mercury.m:
compiler/prog_ctgc.m:
compiler/prog_io_pragma.m:
compiler/trans_opt.m:
	Add the mechanism to output and parse the structure_reuse pragmas.
	(Remove the name of the reuse-version procedures in the
	pragma structure_reuse).

compiler/hlds_module.m:
	Simplify the type structure_reuse_info.

compiler/prog_data.m:
	Add types for the public representation of reuse conditions.
	(remove the previous name "reuse_tuple", which simply does not sound
	adequate).

compiler/module_qual.m:
compiler/modules.m:
compiler/prog_item.m:
compiler/recompilation.version.m:
	Remove the name of the reuse-version procedures in the pragma
	structure_reuse.

compiler/prog_type.m:
compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
	Add functions to remove all typeinfo-vars from a given list (resp. set)
	of vars. These functions are used when deriving the variables in
	local and forward use, where typeinfo-variables are irrelevant.

compiler/structure_reuse.analysis.m:
compiler/structure_reuse.versions.m:
compiler/structure_reuse.m:
	Process the reuse information of any imported procedures.
	Create optimised versions for the procedures for which
	reuse was detected.
	(structure_reuse.versions.m = new file)

compiler/structure_reuse.domain.m:
	Conversion procedures between the public and private representation
	for structure reuse conditions.

compiler/structure_reuse.indirect.m:
	Do not try to replace call information even when you know the
	pred_proc_id of the reuse version of that call (which is the case for
	imported procedures with reuse). It is more consistent
	to do this at the same time when all the other conversions are done,
	i.e. when generating the optimised versions of the procedures with
	reuse (even with unconditional reuse).
2006-06-15 19:37:12 +00:00
Julien Fischer
f5de906db6 Minor style cleanups for the CTGC system. There are no changes to any
Estimated hours taken: 1
Branches: main

Minor style cleanups for the CTGC system.  There are no changes to any
algorithms.

compiler/ctgc.*.m:
compiler/prog_ctgc.m:
compiler/structure_reuse.*.m:
compiler/structure_sharing.*.m:
	Minor style cleanups.

compiler/builtin_ops.m:
compiler/check_hlds.m:
compiler/exception_analysis.m:
compiler/hlds_rtti.m:
compiler/process_util.m:
	s/__/./ in a couple of spots and fix a few other formatting problems.
2006-06-05 05:23:27 +00:00
Nancy Mazur
c3e7b34393 Provide the indirect reuse analysis part of the CTGC system.
Estimated hours taken: 12
Branches: main

Provide the indirect reuse analysis part of the CTGC system. Using a fixpoint
computation, this propagates the reuse conditions determined by the direct
reuse analysis step through procedure calls.

compiler/ctgc.datastruct.m:
	Minor additions.

compiler/ctgc.livedata.m:
	(new file) Types and operations needed for defining the lattice of
	possibly live datastructures.

compiler/ctgc.m:
	Add livedata submodule.

compiler/ctgc.util.m:
	Provide the operations for determining variable and type renamings,
	used both by the structure sharing analysis as well as the reuse
	analysis.

compiler/hlds_module.m:
	Add structure reuse information to collect the mapping between
	procedures, and their reuse versions.

compiler/prog_data.m:
	New types "dead_vars", "live_vars".

compiler/structure_reuse.analysis.m:
	Add the indirect reuse analysis step.

compiler/structure_reuse.direct.detect_garbage.m:
compiler/structure_sharing.domain.m:
	Mainly moving the operation of looking up sharing information and
	combining it with existing sharing to a more appropriate place, namely
	structure_sharing.domain.m
	(also rename the bottom and top elements of the structure sharing
	domain).

compiler/structure_reuse.domain.m:
	Add a renaming operation but especially two predicates needed to
	verify whether a given procedure call satisfies the derived reuse
	conditions, and to translate these reuse conditions to the
	head variables of the procedure in which the procedure call occurs.

compiler/structure_reuse.indirect.m:
	The actual indirect reuse analysis.

compiler/structure_reuse.m:
	Add "structure_reuse.indirect" as a submodule.

compiler/structure_sharing.analysis.m:
	small changes.
2006-05-29 13:04:35 +00:00
Nancy Mazur
d3e5a8eda4 Provide the direct reuse analysis part of the structure reuse analysis (which
Estimated hours taken: 25
Branches: main

Provide the direct reuse analysis part of the structure reuse analysis (which
itself is part of the CTGC system).

compiler/ctgc.datastruct.m:
compiler/ctgc.util.m:
	Additional predicates.

compiler/ctgc.m:
	Add structure reuse module.

compiler/handle_options.m:
compiler/options.m:
	Add new options "structure_reuse_analysis" and related ones.

compiler/handle_options.m:
compiler/hlds_out.m:
	Add dump option "R" to dump structure reuse related information
	in the hlds_dump files.

compiler/hlds_goal.m:
	Types to record structure reuse information at the level of each
	goal.
	Additional "case_get_goal" function to extract the goal from an case.

compiler/mercury_compile.m:
	Add structure reuse analysis as a new compiler stage.

compiler/structure_reuse.analysis.m:
	The top level analysis predicates.

compiler/structure_reuse.direct.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/structure_reuse.direct.detect_garbage.m:
	Direct reuse analysis is split into 2 steps: determining when and how
	data structures become garbage, and then choosing how these dead
	data structures might best be reused.

compiler/structure_reuse.domain.m:
	The abstract domain for keeping track of reuse conditions, the main
	domain in the structure reuse analysis.

compiler/structure_reuse.lbu.m:
compiler/structure_reuse.lfu.m:
	To determine whether data structures become dead or not, one needs to
	know which variables in a goal are needed with respect to forward
	execution (lfu = local forward use), and backward execution, i.e.
	backtracking (lbu = local backward use). These two modules provide
	the necessary functionality to pre-annotate the goals with lfu and
	lbu information.

compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
	Remove the structure sharing table from the interface of the analysis
	predicate in structure_sharing.analysis.m;
	Move predicates to structure_sharing.domain.m so that they become
	more easily accessible for the structure_reuse modules.

compiler/prog_data.m:
	New types "dead_var", "live_var" and alike.
2006-05-10 10:56:57 +00:00