Automatic, transparent parallelization of logic programs at compile time

Some calls in pure logic programs can be executed concurrently without disturbing the program's standard sequential execution behavior. Sequential execution determines a producer/consumer relationship among the calls in each clause; transparent parallelizations preserve these relationships. We restrict our attention to execution models in which producers and consumers execute serially. Four issues in automatic parallelization are addressed. First, we present an algorithm that constructs call synchronization graphs that are used to control parallelism during clause execution. The algorithm parallelizes calls that previous methods do not, viz., some calls that share free variables at invocation time. Another algorithm modifies call synchronization graphs to handle problems that arise in implementations that represent shared free variables by shared storage locations. Second, we give algorithms for selective backtracking in parallel logic program interpreters based on Conery's And/Or Process Model. Our algorithms reset old call solutions more selectively than do other techniques. The third and largest contribution has two parts: (1) a (parameterized) abstract interpretation framework for generating program analyzers, and, based on that analysis, (2) a general purpose, source-level transformation that produces multiple specializations of each clause. Parallelization is the specialization of interest. Program analysis is performed over an abstract domain composed of representations of sets of substitutions, called substitution descriptions. For each call in the program, the analyzer collects several activation substitution descriptions and maps each of them to a result substitution description. The collection of activation descriptions obeys a useful closure property under a natural reachability relation, which allows the transformation to create multiple parallelizations of each clause with compile-time selection of the appropriate parallelization for each clause invocation (except the first). The transformation expands programs to define and use several variants of each predicate so that each variant is used to solve a restricted class of call invocations. The restriction allows more calls to be parallelized. The transformation also annotates each clause with substitution descriptions that characterize actual execution. This information is used by the parallelization algorithm. Fourth, we provide an abstract domain that generates an analyzer that is quite effective at inferring information needed for parallelization.