mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
Estimated hours taken: 40
Branches: main
Until now, the only indexing we did for switches on strings was using a hash
table containing jump targets (represented as indices into a list of labels).
This diff supplements this with
- binary searches of tables containing jump targets,
- binary searches of tables containing values (lookup tables), and
- hash searches of tables containing values (lookup tables).
For now, the new methods exist in the LLDS backend only.
NEWS:
Mention the new capability.
compiler/string_switch.m:
Add predicates that implement the new indexing methods on strings.
Factor out code from existing predicates as required for this.
compiler/switch_gen.m:
Invoke the new predicates in string_switch.m when relevant.
Avoid passing the constant "no" as the initial value of !MaybeEnd
to predicates where we know this will ALWAYS happen.
compiler/options.m:
doc/user_guide.texi:
Add an option to control when we use binary searches for switches
on strings.
compiler/lookup_switch.m:
This module previously handled lookup switches on integers.
Generalize it so that pieces of it are now also usable to help
implement lookup switches on strings. Rename the predicates specific
to switches on integers to make clear this specificity, and separate
them from the predicates that help implement lookup switches on
variables of all the supported types.
Export some types, predicates and functions for use in string_switch.m.
Fix the code so that it correctly handles det switches, which
can happen e.g. if we know the possible set of values of the
switched-on variable.
Use tail-recursive code to handle the list of switch arms, to allow us
to handle very large switches.
Remove an obsolete comment from the top about a previously implemented
optimization.
compiler/lookup_util.m:
Make set_liveness_and_end_branch update MaybeEnd, to account for the
reservation of stack slots for holding the current and last rows in
later solutions tables for model_non lookup switches.
compiler/switch_util.m:
Make the exported predicates of this module more general, making them
usable for switches on strings as well as ints. Also make them easier
to use. In one case this meant bundling two predicates that were always
used together into one predicate. In another, it meant splitting one
predicate into two, since some of its callers needed an intermediate
result. In the case of a type, it means reordering its fields
to make the order match the order of their use in the implementation.
Add some predicates specifically for switches on strings.
compiler/ml_lookup_switch.m:
compiler/ml_string_switch.m:
compiler/ml_switch_gen.m:
Conform to the changes to switch_util.m.
compiler/jumpopt.m:
If the comment associated with a label ends with "nofulljump", then
inhibit fulljump optimization of jumps to that label. That
optimization would replace the jumps with the code starting at that
label. This is avoids the overhead of jump instructions, and it is a
good idea in the usual case of forward jumps. However, for the few
backward jumps we generate, the block that replaces the jump
instruction can actually END with the same jump instruction (which may
be conditionally executed), which means that our usual repeated
invocation of jumpopt can replace the original jump instruction
with MANY copies of the block it jumps to. In some cases, such as those
in hash switches, you get more copies than can ever be executed in any
actual execution. Lookup switches therefore now mark the labels that
are targets of backward jumps with this marker.
compiler/llds.m:
Document the new behavior of jumpopt.
compiler/code_info.m:
Export a predicate for use in improving the code we generate for lookup
switches.
Make some other predicates simpler and/or more efficient.
compiler/builtin_ops.m:
Add a builtin op for doing string comparisons by calling strcmp.
This is to prevent the need for two traversals of the strings being
compared in each iteration of binary search.
compiler/bytecode.m:
compiler/c_util.m:
compiler/mlds_to_gcc.m:
compiler/mlds_to_il.m:
compiler/llds.m:
compiler/llds_to_x86_64.m:
Conform to the change in builtin_ops.m.
compiler/disj_gen.m:
Conform to the change in lookup_util.m
compiler/frameopt.m:
compiler/proc_gen.m:
compiler/unify_gen.m:
Take advantage of the change in fulljump optimization.
compiler/opt_debug.m:
Improve the string representation of rvals by recording the types of
the operands of binary operations, and making the output a bit more
consistent looking.
compiler/dupproc.m:
compiler/var_locn.m:
Minor style fixes.
runtime/mercury_string.h:
Add a version of strcmp for use by our code generator. This version
casts the arguments before calling the real strcmp. We need it since we
usually specify the arguments as r1, r2 etc, which are declared as
MR_Word, not char *.
tests/hard_coded/lookup_disj.{m,exp}:
tests/hard_coded/string_switch.{m,exp}:
Make these existing tests significantly tougher by making them exercise
a wider range of use scenarios.
tests/hard_coded/string_switch{2,3}.{m,exp}:
tests/hard_coded/Mercury.options
While the string_switch test case tests the handling of jump switches,
these two new test cases test the handling of binary search tables and
hash tables respectively. Their code is identical to the code of
the string_switch test case, but Mercury.options causes them to be
compiled with different options.
tests/hard_coded/int_switch.{m,exp}:
A new test case, equivalent in structure to the string switch test
cases, to test the handling of lookup switches on atomic values.
73 lines
1.6 KiB
Plaintext
73 lines
1.6 KiB
Plaintext
jump 1 -> 51
|
|
jump 2 -> 52
|
|
jump 3 failed
|
|
jump 11 -> 11
|
|
jump 12 -> 11
|
|
jump 13 failed
|
|
jump 21 -> 62
|
|
jump 22 -> 62
|
|
jump 23 failed
|
|
jump 31 -> 13
|
|
jump 32 failed
|
|
jump 33 failed
|
|
one 1 -> 1
|
|
one 2 -> 2
|
|
one 3 failed
|
|
one 11 -> 11
|
|
one 12 -> 11
|
|
one 13 failed
|
|
one 21 -> 12
|
|
one 22 -> 12
|
|
one 23 failed
|
|
one 31 -> 13
|
|
one 32 failed
|
|
one 33 failed
|
|
one known 1 failed
|
|
one known 2 failed
|
|
one known 3 failed
|
|
one known 11 -> 11
|
|
one known 12 failed
|
|
one known 13 failed
|
|
one known 21 failed
|
|
one known 22 -> 12
|
|
one known 23 failed
|
|
one known 31 failed
|
|
one known 32 failed
|
|
one known 33 failed
|
|
several 1 -> [1]
|
|
several 2 -> [2]
|
|
several 3 -> []
|
|
several 11 -> [11, 12]
|
|
several 12 -> [11, 12]
|
|
several 13 -> []
|
|
several 21 -> [13, 14, 15]
|
|
several 22 -> [13, 14, 15]
|
|
several 23 -> []
|
|
several 31 -> [16]
|
|
several 32 -> [16]
|
|
several 33 -> []
|
|
several known 1 -> []
|
|
several known 2 -> []
|
|
several known 3 -> []
|
|
several known 11 -> [11, 12]
|
|
several known 12 -> []
|
|
several known 13 -> []
|
|
several known 21 -> []
|
|
several known 22 -> [13, 14, 15]
|
|
several known 23 -> []
|
|
several known 31 -> []
|
|
several known 32 -> []
|
|
several known 33 -> []
|
|
several nested 1 -> [1001, 11001, 12001]
|
|
several nested 2 -> [11002, 12002]
|
|
several nested 3 -> []
|
|
several nested 11 -> [11011, 11012, 12011, 12012]
|
|
several nested 12 -> [11011, 11012, 12011, 12012]
|
|
several nested 13 -> []
|
|
several nested 21 -> [13013, 13014, 13015, 14013, 14014, 14015, 15013, 15014, 15015]
|
|
several nested 22 -> [13013, 13014, 13015, 14013, 14014, 14015, 15013, 15014, 15015]
|
|
several nested 23 -> []
|
|
several nested 31 -> [16016]
|
|
several nested 32 -> [16016]
|
|
several nested 33 -> []
|