Updated AssertScheduleCPVIntoTargetBlock to be a single rule fire

I also reformatted some of the doc strings in WavefrontInstructionMerging.clp
Broke out the producers/consumers merging into their own stages

I also removed the merging of producers and consumers after the Analysis stage
because the extra sets of merging were slowing things down. The Acts of merging
and injecting consumers, producers, and such have been moved into their own
stages. This not only reduces the work load per stage but also makes sure that
all corresponding facts have been emitted before operating on them.

Ironically, the slowest part of the wavefront scheduling pass is the act of
merging producers.

I added stages for
1) Injecting producers and consumers,
2) Setting call barriers
3) Merging producers and consumers
4) Settifying producers, consumers, and non-local dependencies

I also rewrote the injection of producers and consumers so that the checks for
existence are performed during merging instead of through rules.
Disabled the check to see if the given non local dependency already exists

This check was not only inefficient but unnecessary as the settify non local
dependencies command will do the same thing with fewer message passes.
Modified the act of producer injection such that local dependencies are now set
in MarkLockDependencies

This change not only greatly improves the running time of the optimization but
also exposes the fact that existence checks performed by
ExtendedInjectProducers for local dependencies were overkill. At most the
number of elements within the local dependencies set will be the total number
of operands for the target element. Duplicate entries in this case mean that
the same dependency is used multiple times. It is safer to have the settify
commands take care of the uniqueness requirement then the injection rules
Added the FrequencyAnalysis stage

This stage pushes the act of frequency analysis out into its own group to
ensure that all frequency counting has taken place before we get to the
analysis phase.
Reformatted MemoryBarrierCreation.clp
Moved the merge rules out into a separate file

I added support for separate merging of local dependencies
Undid the individual local dependency updating and added an interleaved inject
rule

There is now a rule that will inject both producers and consumers if both exist
for a given instruction. If both do not exist then the previous Inject rules
take over.

I also modified MergeConsumers and MergeProducers so that the check for
inequality is done within the second conditional expression instead of a third
one. This has decreased the running time of the optimization from 1.25 seconds
for flops-no-opt to 1.18 seconds.
started rewriting the code handling merging potentially valid and invalid
blocks together

The original code used a rule based approach that makes small incremental
changes. The new version operates on the entire list of blocks at once.
Rewrote how uses are replaced in CLIPS

It turns out that I was not checking to make sure that the target instruction
to have operands replaced in even contained the original target. This reduction
of the search from a brute force was easy to do by checking to see if the
target original operand exists in the instructions operands. It does require a
ton of messages being sent to get the list of operands but even with the
increase in messages the code is significantly faster.
Simplified the encoding scheme in WavefrontOperandRename for facts

I originally had some verbose facts being asserted that worked but were almost
ambiguous in their design. The new encoding scheme { clips|llvm ! ... } is far
more readable
Deleted two rules dealing with MergingSlice analysis facts

These two rules were MultiSingle merge rules. The problem is that these rules
were complex enough that generating the agenda on a change stage was causing
some functions to take nearly have a minute to schedule. Removing these two
rules have yielded a significant performance improvement.

The reason for the performance degredation has to do with what I'm matching.
Let's use the first deleted rule MergeSliceAnalysisFacts-SingleMulti to
describe the performance issues

(defrule MergeSliceAnalysisFacts-SingleMulti
         (Stage WavefrontSchedule $?)
         (Substage Analyze $?)
         ?f0 <- (Analyze slice ?s0 for ?e and cpv ?cpv)
         ?f1 <- (Analyze in ?e using cpv ?cpv and slices $?z)
         (test (not (member$ ?s0 ?z)))
         ;(test (eq FALSE (member$ ?s0 $?z)))
         =>
         (retract ?f0 ?f1)
         (assert (Analyze in ?e using cpv ?cpv and slices $?z ?s0)))

Alright, while the rule's condition is pretty simple the problem is that I'm
actually comparing two fact pools that can become quite massive. So if there
are roughly 3000 singular facts and 3000 plural facts then it's necessary to
take facts from each pool and compare them. Not only that but also make sure
that ?s0 is not a member of $?z. The problem is that this is a linear operation
so not only do we do a linear existence operation but also comparing two
massive fact pools. Combined with whatever the running time of the agenda
generator is it's possible to really slow the scheduler down.

The other side of the condition where ?s0 is a subset of $?z it doesn't really
matter because the existence check necessary as well.

Removing these two rules should speed things up greatly.

This issue falls under the same idea as trying to merge more than two facts
together at the same time.
Removed a redundant test condition
discovered object-pattern-match-delay and modified the region loop merging
conditions to improve the running time of the optimization

object-pattern-match-delay prevents pattern matching from occuring until the
function returns. This is nice because there may be a ton of changes that you
make that cause all sorts of patterns to match and then unmatch. This prevents
that matching from occuring until all changes have been made. I also found out
that modify-instance bypasses message-passing. Combining these two features
together equates to an improvement in performance
Updated several rules in MergeRules to delay object pattern matching
delayed object pattern matching for several rules in
LLVMScheduleConstruction.clp
Delayed object pattern matching for several rules in WavefrontAdvancement.clp
Modified MoveInstructionIntoBlock and CloneInstructionIntoBlock

Object pattern matching has been disabled temporarily within these two rules to
speed up the optimization. MoveInstructionIntoBlock has also been modified to
use modify-instance as much as possible.

CloneInstructionIntoBlock still needs to be updated to reflect these changes
Fixed a bug in LLVMScheduleConstruction.clp where basic block scheduling wasn't
being performed

It seems that when I stripped out the use of instruction groups I disabled the
basic block scheduler as well. This has been fixed by adding a rule to assert
the initial scheduling operation fact and modified another rule to continue the
scheduling if proper.
Fixed a bug in LLVMScheduleConstruction.clp

Uncommented the fact assertion for failure conditions of basic block
scheduling.

I also modified some of the match parameters during schedule object creation to
not use message passing.