fixed a bug where the set of producers was not being added

This occurs during wavefront-scheduling when we are recomputing the
dependencies for the instructions that have been moved into instructions on the
wavefront

;Copyright (c) 2012, Joshua Scoggins
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or without
;modification, are permitted provided that the following conditions are met:
;    * Redistributions of source code must retain the above copyright
;      notice, this list of conditions and the following disclaimer.
;    * Redistributions in binary form must reproduce the above copyright
;      notice, this list of conditions and the following disclaimer in the
;      documentation and/or other materials provided with the distribution.
;    * Neither the name of Joshua Scoggins nor the
;      names of its contributors may be used to endorse or promote products
;      derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL Joshua Scoggins BE LIABLE FOR ANY
;DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;------------------------------------------------------------------------------
; This stage is the actual act of scheduling the blocks on the wavefront.
; The first step is to reacquire all dependencies of the given blocks by
; running the same rules as before. The only difference is that we have to do
; it specially for the blocks on the wavefront.
;
; I'm thinking of just copying the rules from the analysis pass to here. It
; would be a duplication but I frankly don't care anymore.
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::CreateDependencyAnalysisTargets
         (declare (salience 10))
         (object (is-a Wavefront)
                 (parent ?r)
                 (values $? ?e $?))
         (object (is-a BasicBlock)
                 (id ?e))
         (object (is-a PathAggregate)
                 (parent ?e)
                 (OriginalStopIndex ?si))
         =>
         ;only look at instructions starting at the original stop index. This
         ;prevents unncessary recomputation
         (assert (Evaluate ?e for dependencies starting at ?si)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::IdentifyWAR
         "Identifies a WAR dependency between two instructions. It will not
         match if it turns out the values are constant integers or constant
         floating point values"
         (Evaluate ?p for dependencies starting at ?si)
         ;TODO: Rewrite this to be more efficient
         ?i0 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t0)
                        (TimeIndex ?ti0)
                        (Operands $? ?c $?))
         (object (is-a Object&~ConstantInteger&~ConstantFloatingPoint)
                 (id ?c))
         ?i1 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t1)
                        (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                        (DestinationRegisters $? ?c $?))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::IdentifyRAW
         "Identifies a RAW dependency between two instructions in the same
         block. It will not match if it turns out that the values are constant
         integers or constant floating point values."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a Instruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (DestinationRegisters $? ?c $?))
         (object (is-a Object&~ConstantInteger&~ConstantFloatingPoint)
                 (id ?c))
         (object (is-a Instruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (Operands $? ?c $?))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::IdentifyWAW
         "Identifies a WAW dependency between two instructions in the same
         block. It will not match if it turns out that the values are constant
         integers or constant floating point values."
         (Evaluate ?p for dependencies starting at ?si)
         ?i0 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t0)
                        (TimeIndex ?ti0)
                        (DestinationRegisters $? ?c $?))
         (object (is-a Object&~ConstantInteger&~ConstantFloatingPoint)
                 (id ?c))
         ?i1 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t1)
                        (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                        (DestinationRegisters $? ?c $?))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
;these call instruction checks only work for new instructions or those that
; dont have a call dependency. As that was the only way they got into the
; block in the first place
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkCallInstructionDependency-ModifiesMemory
         "Creates a series of dependencies for all instructions following a
         call instruction if it turns out that the call could modify memory."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a CallInstruction)
                 (id ?name)
                 (parent ?p)
                 (DoesNotAccessMemory FALSE) (OnlyReadsMemory FALSE)
                 (MayWriteToMemory TRUE)
                 (TimeIndex ?t0))
         (object (is-a Instruction)
                 (parent ?p)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?t0 ?ti1)))
                 (HasCallDependency FALSE) (id ?following))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?following => ?name))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?name => ?following))
                 (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?following))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkCallInstructionDependency-InlineAsm
         "Creates a series of dependencies for all instructions following a
         call instruction if it turns out that the call is inline asm."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a CallInstruction)
                 (id ?name)
                 (parent ?p)
                 (IsInlineAsm TRUE)
                 (TimeIndex ?t0))
         (object (is-a Instruction)
                 (parent ?p)
                 (id ?following)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?t0 ?ti1)))
                 (HasCallDependency FALSE))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?following => ?name))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?name => ?following))
                 (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?following))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkCallInstructionDependency-SideEffects
         "Creates a series of dependencies for all instructions following a
         call instruction if it turns out that the call is inline asm."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a CallInstruction)
                 (id ?name)
                 (parent ?p)
                 (MayHaveSideEffects TRUE)
                 (MayWriteToMemory TRUE)
                 (TimeIndex ?t0))
         (object (is-a Instruction)
                 (parent ?p)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?t0 ?ti1)))
                 (HasCallDependency FALSE)
                 (id ?following))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?following => ?name))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?name => ?following))
                 (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?following))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkNonLocalDependencies
         (Evaluate ?p for dependencies starting at ?si)
         ?inst <- (object (is-a Instruction)
                          (parent ?p)
                          (TimeIndex ?t&:(>= ?t ?si))
                          (NonLocalDependencies $?nld)
                          (Operands $? ?o $?))
         (object (is-a Instruction)
                 (id ?o)
                 (parent ~?p))
         =>
         (if (not (member$ ?o $?nld)) then
         (modify-instance ?inst (NonLocalDependencies $?nld ?o))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::Wavefront-MarkHasCallDependency
         (declare (salience -2))
         ?fct <- (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?f))

         ?obj <- (object (is-a Instruction)
                         (id ?f))
         =>
         (modify-instance ?obj (HasCallDependency TRUE))
         (retract ?fct))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::InjectConsumers
         "Adds a given consumer to the target instruction"
         (declare (salience -5))
         ?fct <- (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?target => ?id))
         ?inst <- (object (is-a Instruction)
                          (id ?id)
                          (Consumers $?consumers))
         =>
         (retract ?fct)
         (if (not (member$ ?target $?consumers)) then
           (modify-instance ?inst (Consumers $?consumers ?target))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::InjectProducers
         "Adds a given producer to the target instruction"
         (declare (salience -5))
         ?fct <- (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?target => ?id))
         ?inst <- (object (is-a Instruction)
                          (id ?id)
                          (LocalDependencies $?ld)
                          (Producers $?prod))
         =>
         (retract ?fct)
         (modify-instance ?inst
                          (LocalDependencies $?ld
                                             (if (not (member$ ?target $?ld))
                                               then ?target))
                          (Producers $?prod
                                     (if (not (member$ ?target $?prod))
                                       then ?target))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::StoreToLoadDependency
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (MemoryTarget ?sym0))
         (object (is-a LoadInstruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (MemoryTarget ?sym1))
         (test (or (eq ?sym0 ?sym1)
                   (eq ?sym0 UNKNOWN)))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::StoreToStoreDependency
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (MemoryTarget ?sym0))
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (MemoryTarget ?sym1))
         (test (or (eq ?sym0 ?sym1)
                   (eq ?sym0 UNKNOWN)))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::LoadToStoreDependency
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a LoadInstruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (MemoryTarget ?sym0))
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (MemoryTarget ?sym1))
         (test (or (eq ?sym0 ?sym1)
                   (eq ?sym0 UNKNOWN)))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::FinishedDependencyAnalysis
         (declare (salience -800))
         ?fct <- (Evaluate ?p for dependencies starting at ?v)
         (object (is-a BasicBlock)
                 (id ?p)
                 (parent ?r))
         =>
         (retract ?fct))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RemoveInstructionsFromProducers
         (declare (salience 768))
         ?fct <- (message (to wavefront-scheduling)
                          (action remove-evidence)
                          (arguments ?tInst => ?inst $?insts))
         ?iObj <- (object (is-a Instruction)
                          (id ?inst)
                          (NonLocalDependencies $?nld)
                          (Producers $?pb ?tInst $?pa)
                          (LocalDependencies $?ldb ?tInst $?lda))
         =>
         (modify ?fct (arguments ?tInst => $?insts))
         (modify-instance ?iObj (Producers $?pb $?pa)
                          (LocalDependencies $?ldb $?lda)
                          (NonLocalDependencies $?nld ?tInst)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RetractRemoveInstructionsFromProducers
         (declare (salience 768))
         ?fct <- (message (to wavefront-scheduling)
                          (action remove-evidence)
                          (arguments ? =>))
         =>
         (retract ?fct))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::StartRecomputeBlock
         (declare (salience 100))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block)
                          (arguments ?b))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (contents $?instructions ?last))
         (object (is-a TerminatorInstruction)
                 (id ?last))
         =>
         (modify-instance ?bb
                          (ReadsFrom)
                          (WritesTo)
                          (HasMemoryBarrier FALSE))
         (modify ?fct
                 (action recompute-block-with-instructions)
                 (arguments ?b => $?instructions)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RecomputeNonMemoryInstructionForBlock
         (declare (salience 99))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b => ?inst $?rest))
         (object (is-a Instruction&~LoadInstruction&~StoreInstruction)
                 (id ?inst)
                 (parent ?b))
         =>
         (modify ?fct (arguments ?b => $?rest)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RecomputeLoadInstructionForBlock
         (declare (salience 99))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b => ?inst $?rest))
         (object (is-a LoadInstruction)
                 (id ?inst)
                 (parent ?b)
                 (MemoryTarget ?mt))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (ReadsFrom $?rf))
         =>
         (if (not (member$ ?mt $?rf)) then
           (modify-instance ?bb (ReadsFrom $?rf ?mt)))
         (modify ?fct (arguments ?b => $?rest)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RecomputeStoreInstructionForBlock
         (declare (salience 99))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b => ?inst $?rest))
         (object (is-a StoreInstruction)
                 (id ?inst)
                 (parent ?b)
                 (MemoryTarget ?mt))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (WritesTo $?wt))
         =>
         (if (not (member$ ?mt $?wt)) then
           (modify-instance ?bb (WritesTo $?wt ?mt)))
         (modify ?fct (arguments ?b => $?rest)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::FinishRecomputationForBlock
         (declare (salience 98))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b =>))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (ReadsFrom $?rf)
                        (WritesTo $?wt))
         =>
         (retract ?fct)
         (if (or (member$ UNKNOWN ?rf)
                 (member$ UNKNOWN ?wt)) then
           (modify-instance ?bb (HasMemoryBarrier TRUE))))
;------------------------------------------------------------------------------

;Copyright (c) 2012, Joshua Scoggins
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or without
;modification, are permitted provided that the following conditions are met:
;    * Redistributions of source code must retain the above copyright
;      notice, this list of conditions and the following disclaimer.
;    * Redistributions in binary form must reproduce the above copyright
;      notice, this list of conditions and the following disclaimer in the
;      documentation and/or other materials provided with the distribution.
;    * Neither the name of Joshua Scoggins nor the
;      names of its contributors may be used to endorse or promote products
;      derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL Joshua Scoggins BE LIABLE FOR ANY
;DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;------------------------------------------------------------------------------
; This stage is the actual act of scheduling the blocks on the wavefront.
; The first step is to reacquire all dependencies of the given blocks by
; running the same rules as before. The only difference is that we have to do
; it specially for the blocks on the wavefront.
;
; I'm thinking of just copying the rules from the analysis pass to here. It
; would be a duplication but I frankly don't care anymore.
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::CreateDependencyAnalysisTargets
         (declare (salience 10))
         (object (is-a Wavefront)
                 (parent ?r)
                 (values $? ?e $?))
         (object (is-a BasicBlock)
                 (id ?e))
         (object (is-a PathAggregate)
                 (parent ?e)
                 (OriginalStopIndex ?si))
         =>
         ;only look at instructions starting at the original stop index. This
         ;prevents unncessary recomputation
         (assert (Evaluate ?e for dependencies starting at ?si)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::IdentifyWAR
         "Identifies a WAR dependency between two instructions. It will not
         match if it turns out the values are constant integers or constant
         floating point values"
         (Evaluate ?p for dependencies starting at ?si)
         ;TODO: Rewrite this to be more efficient
         ?i0 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t0)
                        (TimeIndex ?ti0)
                        (Operands $? ?c $?))
         (object (is-a Object&~ConstantInteger&~ConstantFloatingPoint)
                 (id ?c))
         ?i1 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t1)
                        (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                        (DestinationRegisters $? ?c $?))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::IdentifyRAW
         "Identifies a RAW dependency between two instructions in the same
         block. It will not match if it turns out that the values are constant
         integers or constant floating point values."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a Instruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (DestinationRegisters $? ?c $?))
         (object (is-a Object&~ConstantInteger&~ConstantFloatingPoint)
                 (id ?c))
         (object (is-a Instruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (Operands $? ?c $?))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::IdentifyWAW
         "Identifies a WAW dependency between two instructions in the same
         block. It will not match if it turns out that the values are constant
         integers or constant floating point values."
         (Evaluate ?p for dependencies starting at ?si)
         ?i0 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t0)
                        (TimeIndex ?ti0)
                        (DestinationRegisters $? ?c $?))
         (object (is-a Object&~ConstantInteger&~ConstantFloatingPoint)
                 (id ?c))
         ?i1 <- (object (is-a Instruction)
                        (parent ?p)
                        (id ?t1)
                        (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                        (DestinationRegisters $? ?c $?))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
;these call instruction checks only work for new instructions or those that
; dont have a call dependency. As that was the only way they got into the
; block in the first place
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkCallInstructionDependency-ModifiesMemory
         "Creates a series of dependencies for all instructions following a
         call instruction if it turns out that the call could modify memory."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a CallInstruction)
                 (id ?name)
                 (parent ?p)
                 (DoesNotAccessMemory FALSE) (OnlyReadsMemory FALSE)
                 (MayWriteToMemory TRUE)
                 (TimeIndex ?t0))
         (object (is-a Instruction)
                 (parent ?p)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?t0 ?ti1)))
                 (HasCallDependency FALSE) (id ?following))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?following => ?name))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?name => ?following))
                 (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?following))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkCallInstructionDependency-InlineAsm
         "Creates a series of dependencies for all instructions following a
         call instruction if it turns out that the call is inline asm."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a CallInstruction)
                 (id ?name)
                 (parent ?p)
                 (IsInlineAsm TRUE)
                 (TimeIndex ?t0))
         (object (is-a Instruction)
                 (parent ?p)
                 (id ?following)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?t0 ?ti1)))
                 (HasCallDependency FALSE))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?following => ?name))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?name => ?following))
                 (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?following))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkCallInstructionDependency-SideEffects
         "Creates a series of dependencies for all instructions following a
         call instruction if it turns out that the call is inline asm."
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a CallInstruction)
                 (id ?name)
                 (parent ?p)
                 (MayHaveSideEffects TRUE)
                 (MayWriteToMemory TRUE)
                 (TimeIndex ?t0))
         (object (is-a Instruction)
                 (parent ?p)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?t0 ?ti1)))
                 (HasCallDependency FALSE)
                 (id ?following))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?following => ?name))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?name => ?following))
                 (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?following))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::MarkNonLocalDependencies
         (Evaluate ?p for dependencies starting at ?si)
         ?inst <- (object (is-a Instruction)
                          (parent ?p)
                          (TimeIndex ?t&:(>= ?t ?si))
                          (NonLocalDependencies $?nld)
                          (Operands $? ?o $?))
         (object (is-a Instruction)
                 (id ?o)
                 (parent ~?p))
         =>
         (if (not (member$ ?o $?nld)) then
         (modify-instance ?inst (NonLocalDependencies $?nld ?o))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::Wavefront-MarkHasCallDependency
         (declare (salience -2))
         ?fct <- (message (to wavefront-scheduling)
                          (action instruction-has-a-call-dependency)
                          (arguments ?f))

         ?obj <- (object (is-a Instruction)
                         (id ?f))
         =>
         (modify-instance ?obj (HasCallDependency TRUE))
         (retract ?fct))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::InjectConsumers
         "Adds a given consumer to the target instruction"
         (declare (salience -5))
         ?fct <- (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?target => ?id))
         ?inst <- (object (is-a Instruction)
                          (id ?id)
                          (Consumers $?consumers))
         =>
         (retract ?fct)
         (if (not (member$ ?target $?consumers)) then
           (modify-instance ?inst (Consumers $?consumers ?target))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::InjectProducers
         "Adds a given producer to the target instruction"
         (declare (salience -5))
         ?fct <- (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?target => ?id))
         ?inst <- (object (is-a Instruction)
                          (id ?id)
                          (LocalDependencies $?ld)
                          (Producers $?prod))
         =>
         (retract ?fct)
         (modify-instance ?inst
                          (LocalDependencies $?ld
                                             (if (not (member$ ?target $?ld))
                                               then ?target))
                          (Producers $?prod
                                     (if (not (member$ ?target $?prod))
                                       then ?target))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::StoreToLoadDependency
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (MemoryTarget ?sym0))
         (object (is-a LoadInstruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (MemoryTarget ?sym1))
         (test (or (eq ?sym0 ?sym1)
                   (eq ?sym0 UNKNOWN)))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::StoreToStoreDependency
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (MemoryTarget ?sym0))
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (MemoryTarget ?sym1))
         (test (or (eq ?sym0 ?sym1)
                   (eq ?sym0 UNKNOWN)))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::LoadToStoreDependency
         (Evaluate ?p for dependencies starting at ?si)
         (object (is-a LoadInstruction)
                 (parent ?p)
                 (id ?t0)
                 (TimeIndex ?ti0)
                 (MemoryTarget ?sym0))
         (object (is-a StoreInstruction)
                 (parent ?p)
                 (id ?t1)
                 (TimeIndex ?ti1&:(and (>= ?ti1 ?si) (< ?ti0 ?ti1)))
                 (MemoryTarget ?sym1))
         (test (or (eq ?sym0 ?sym1)
                   (eq ?sym0 UNKNOWN)))
         =>
         (assert (message (to wavefront-scheduling)
                          (action instruction-consumes)
                          (arguments ?t1 => ?t0))
                 (message (to wavefront-scheduling)
                          (action instruction-produces)
                          (arguments ?t0 => ?t1))))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-dependency-analysis::FinishedDependencyAnalysis
         (declare (salience -800))
         ?fct <- (Evaluate ?p for dependencies starting at ?v)
         (object (is-a BasicBlock)
                 (id ?p)
                 (parent ?r))
         =>
         (retract ?fct))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RemoveInstructionsFromProducers
         (declare (salience 768))
         ?fct <- (message (to wavefront-scheduling)
                          (action remove-evidence)
                          (arguments ?tInst => ?inst $?insts))
         ?iObj <- (object (is-a Instruction)
                          (id ?inst)
                          (NonLocalDependencies $?nld)
                          (Producers $?pb ?tInst $?pa)
                          (LocalDependencies $?ldb ?tInst $?lda))
         =>
         (modify ?fct (arguments ?tInst => $?insts))
         (modify-instance ?iObj (Producers $?pb $?pa)
                          (LocalDependencies $?ldb $?lda)
                          (NonLocalDependencies $?nld ?tInst)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RetractRemoveInstructionsFromProducers
         (declare (salience 768))
         ?fct <- (message (to wavefront-scheduling)
                          (action remove-evidence)
                          (arguments ? =>))
         =>
         (retract ?fct))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::StartRecomputeBlock
         (declare (salience 100))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block)
                          (arguments ?b))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (contents $?instructions ?last))
         (object (is-a TerminatorInstruction)
                 (id ?last))
         =>
         (modify-instance ?bb
                          (ReadsFrom)
                          (WritesTo)
                          (HasMemoryBarrier FALSE))
         (modify ?fct
                 (action recompute-block-with-instructions)
                 (arguments ?b => $?instructions)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RecomputeNonMemoryInstructionForBlock
         (declare (salience 99))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b => ?inst $?rest))
         (object (is-a Instruction&~LoadInstruction&~StoreInstruction)
                 (id ?inst)
                 (parent ?b))
         =>
         (modify ?fct (arguments ?b => $?rest)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RecomputeLoadInstructionForBlock
         (declare (salience 99))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b => ?inst $?rest))
         (object (is-a LoadInstruction)
                 (id ?inst)
                 (parent ?b)
                 (MemoryTarget ?mt))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (ReadsFrom $?rf))
         =>
         (if (not (member$ ?mt $?rf)) then
           (modify-instance ?bb (ReadsFrom $?rf ?mt)))
         (modify ?fct (arguments ?b => $?rest)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::RecomputeStoreInstructionForBlock
         (declare (salience 99))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b => ?inst $?rest))
         (object (is-a StoreInstruction)
                 (id ?inst)
                 (parent ?b)
                 (MemoryTarget ?mt))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (WritesTo $?wt))
         =>
         (if (not (member$ ?mt $?wt)) then
           (modify-instance ?bb (WritesTo $?wt ?mt)))
         (modify ?fct (arguments ?b => $?rest)))
;------------------------------------------------------------------------------
(defrule wavefront-scheduling-merge-update::FinishRecomputationForBlock
         (declare (salience 98))
         ?fct <- (message (to wavefront-scheduling)
                          (action recompute-block-with-instructions)
                          (arguments ?b =>))
         ?bb <- (object (is-a BasicBlock)
                        (id ?b)
                        (ReadsFrom $?rf)
                        (WritesTo $?wt))
         =>
         (retract ?fct)
         (if (or (member$ UNKNOWN ?rf)
                 (member$ UNKNOWN ?wt)) then
           (modify-instance ?bb (HasMemoryBarrier TRUE))))
;------------------------------------------------------------------------------


init/DeclareLogicFunctions.clp: Fixed bugs in logic-files

I renamed the ?name variable to ?offset

;------------------------------------------------------------------------------
;Copyright (c) 2013, Joshua Scoggins
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or without
;modification, are permitted provided that the following conditions are met:
;    * Redistributions of source code must retain the above copyright
;      notice, this list of conditions and the following disclaimer.
;    * Redistributions in binary form must reproduce the above copyright
;      notice, this list of conditions and the following disclaimer in the
;      documentation and/or other materials provided with the distribution.
;    * Neither the name of Joshua Scoggins nor the
;      names of its contributors may be used to endorse or promote products
;      derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL Joshua Scoggins BE LIABLE FOR ANY
;DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;------------------------------------------------------------------------------
; DeclareLogicFunctions.clp - Defines functions to load code from the
; logic folder
;
; Written by Joshua Scoggins
; Started on 3/13/2013
;------------------------------------------------------------------------------
(deffunction init::load-logic
             "Loads logic/<folder-name>/Entry.clp."
             (?folder-name)
             (batch* (format nil "logic/%s/Entry.clp" ?folder-name)))
;------------------------------------------------------------------------------
(deffunction init::logic-files
             "Loads a series of logic files from the specified path"
             (?offset $?files)
             (bind ?coreOffset (format nil "logic/%s/%s" ?offset "%s"))
             (progn$ (?a $?files)
                     (batch* (format nil ?coreOffset ?a))))
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
;Copyright (c) 2013, Joshua Scoggins
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or without
;modification, are permitted provided that the following conditions are met:
;    * Redistributions of source code must retain the above copyright
;      notice, this list of conditions and the following disclaimer.
;    * Redistributions in binary form must reproduce the above copyright
;      notice, this list of conditions and the following disclaimer in the
;      documentation and/or other materials provided with the distribution.
;    * Neither the name of Joshua Scoggins nor the
;      names of its contributors may be used to endorse or promote products
;      derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL Joshua Scoggins BE LIABLE FOR ANY
;DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;------------------------------------------------------------------------------
; DeclareLogicFunctions.clp - Defines functions to load code from the
; logic folder
;
; Written by Joshua Scoggins
; Started on 3/13/2013
;------------------------------------------------------------------------------
(deffunction init::load-logic
             "Loads logic/<folder-name>/Entry.clp."
             (?folder-name)
             (batch* (format nil "logic/%s/Entry.clp" ?folder-name)))
;------------------------------------------------------------------------------
(deffunction init::logic-files
 "Loads a series of files from the specified path in the logic folder"
 (?name $?files)
 (bind ?coreOffset (format nil "logic/%s/%s" ?offset "%s"))
 (progn$ (?a $?files)
  (batch* (format nil ?coreOffset ?a))))
;------------------------------------------------------------------------------


Modified MemoryBarrierCreation.clp to speed up merger of ReadsFrom and WritesTo

I did this by modifying the merger process to only merge with a single
"control" fact that contained all of the merged elements. This merged message
was then used solely to great effect in the actual update process.

;Copyright (c) 2012, Joshua Scoggins
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or without
;modification, are permitted provided that the following conditions are met:
;    * Redistributions of source code must retain the above copyright
;      notice, this list of conditions and the following disclaimer.
;    * Redistributions in binary form must reproduce the above copyright
;      notice, this list of conditions and the following disclaimer in the
;      documentation and/or other materials provided with the distribution.
;    * Neither the name of Joshua Scoggins nor the
;      names of its contributors may be used to endorse or promote products
;      derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL Joshua Scoggins BE LIABLE FOR ANY
;DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;------------------------------------------------------------------------------
; MemoryBarrierCreation.clp - Contains rules pertaining to the creation of
; memory barriers to prevent loads and stores from being moved above a specific
; point within the program during the act of scheduling.
; Written by Joshua Scoggins (7/1/2012)
;------------------------------------------------------------------------------
; Barriers consist of reads and writes that can't be verified as to their exact
; source.
;------------------------------------------------------------------------------
; TODO: Put in a field for load and store instructions that describes what
; is being referenced. By default this slot is UNKNOWN.
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::AssertLoadBarrierEvaluation
			"Creates a fact that tells the system to analyze the given load
			instruction to see if it is necessary to create a memory barrier for
			the given instruction"
			(declare (salience 5))
			(object (is-a LoadInstruction) (id ?t0) (Operands ?target $?))
			=>
			(assert (Analyze ?target for load ?t0)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::AssertStoreBarrierEvaluation
			"Creates a fact that tells the system to analyze the given store
			instruction to see if it is necessary to create a memory barrier for
			the given instruction"
			(declare (salience 5))
			(object (is-a StoreInstruction) (id ?t0)
					  (DestinationRegisters ?target))
			=>
			(assert (Analyze ?target for store ?t0)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGetElementPointerLoadBarrier
			"Creates a load memory barrier hint if it turns out that the load
			instruction refers to a getelementptr instruction but that
			getelementptr doesn't refer to a alloca instruction or constant."
			(declare (salience 4))
			?fct <- (Analyze ?target for load ?t0)
			?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
			(object (is-a GetElementPointerInstruction) (id ?target)
					  (Operands ?a $?))
			(object (is-a ~AllocaInstruction&~Constant) (id ?a))
			(object (is-a BasicBlock) (id ?p) (parent ?r))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget UNKNOWN))
			(assert (element ?p reads from UNKNOWN)
					  (Element ?p has a MemoryBarrier)
					  (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-Alloca
			"Does a check to see if the load instruction refers directly to an
			AllocaInstruction or Constant. If it does then mark it as though the
			block reads from it"
			(declare (salience 4))
			?fct <- (Analyze ?target for load ?t0)
			?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
			(object (is-a AllocaInstruction) (id ?target))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?target))
			(assert (element ?p reads from ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-Constant
			"Does a check to see if the load instruction refers directly to an
			AllocaInstruction or Constant. If it does then mark it as though the
			block reads from it"
			(declare (salience 4))
			?fct <- (Analyze ?target for load ?t0)
			?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
			(object (is-a Constant) (id ?target))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?target))
			(assert (element ?p reads from ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-GetElementPointer-Alloca
			"Does a check to see if a given LoadInstruction referring to a
			GetElementPointerInstruction refers to an AllocaInstruction or
			Constant. If it does then mark it in the ReadsFrom multifield"
			(declare (salience 4))
			?fct <- (Analyze ?target for load ?t0)
			?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
			(object (is-a GetElementPointerInstruction) (id ?target)
					  (Operands ?a $?))
			(object (is-a AllocaInstruction) (id ?a))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?a))
			(assert (element ?p reads from ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-GetElementPointer-Constant
			"Does a check to see if a given LoadInstruction referring to a
			GetElementPointerInstruction refers to an AllocaInstruction or
			Constant. If it does then mark it in the ReadsFrom multifield"
			(declare (salience 4))
			?fct <- (Analyze ?target for load ?t0)
			?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
			(object (is-a GetElementPointerInstruction) (id ?target)
					  (Operands ?a $?))
			(object (is-a Constant) (id ?a))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?a))
			(assert (element ?p reads from ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGeneralLoadBarrier
			"Creates a load memory barrier hint if it turns out that the load
			instruction in question refers to a register that isn't an
			AllocaInstruction, GetElementPointerInstruction, or Constant."
			(declare (salience 3))
			?fct <- (Analyze ?target for load ?t0)
			?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
			(object (is-a BasicBlock) (id ?p) (parent ?r))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget UNKNOWN))
			(assert (element ?p reads from UNKNOWN)
					  (Element ?p has a MemoryBarrier)
					  (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGetElementPointerStoreBarrier
			"Creates a store memory barrier hint if it turns out that the store
			instruction refers to a getelementptr instruction but that
			getelementptr doesn't refer to a alloca instruction or constant."
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (parent ?p) (id ?t0))
			(object (is-a GetElementPointerInstruction) (id ?target)
					  (Operands ?a $?))
			(object (is-a ~AllocaInstruction&~Constant) (id ?a))
			(object (is-a BasicBlock) (id ?p) (parent ?r))
			=>
			(modify-instance ?i0 (MemoryTarget UNKNOWN))
			(retract ?fct)
			(assert (element ?p writes to UNKNOWN)
					  (Element ?p has a MemoryBarrier)
					  (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Alloca
			"Does a check to see if the load instruction refers directly to an
			AllocaInstruction or Constant. If it does then mark it as though the
			block writes to it"
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a AllocaInstruction) (id ?target))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?target))
			(assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Constant
			"Does a check to see if the store instruction refers directly to an
			AllocaInstruction or Constant. If it does then mark it as though the
			block writes to it"
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a Constant) (id ?target))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?target))
			(assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Single-Alloca
			"Does a check to see if the store instruction refers directly to an
			AllocaInstruction or Constant. If it does then mark it as though the
			block writes to it"
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a AllocaInstruction) (id ?target))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?target))
			(assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Single-Constant
			"Does a check to see if the store instruction refers directly to an
			AllocaInstruction or Constant. If it does then mark it as though the
			block writes to it"
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a Constant) (id ?target))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?target))
			(assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-GetElementPointer-Alloca
			"Does a check to see if a given StoreInstruction referring to a
			GetElementPointerInstruction refers to an AllocaInstruction or
			Constant. If it does then mark it in the WritesTo multifield"
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a GetElementPointerInstruction) (id ?target)
					  (Operands ?a $?))
			(object (is-a AllocaInstruction) (id ?a))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?a))
			(assert (element ?p writes to ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-GetElementPointer-Constant
			"Does a check to see if a given StoreInstruction referring to a
			GetElementPointerInstruction refers to an AllocaInstruction or
			Constant. If it does then mark it in the WritesTo multifield"
			(declare (salience 4))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a GetElementPointerInstruction) (id ?target)
					  (Operands ?a $?))
			(object (is-a Constant) (id ?a))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget ?a))
			(assert (element ?p writes to ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGeneralStoreBarrier
			"Creates a store memory barrier hint if it turns out that the load
			instruction in question refers to a register that isn't an
			AllocaInstruction, GetElementPointerInstruction, or Constant."
			(declare (salience 3))
			?fct <- (Analyze ?target for store ?t0)
			?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
			(object (is-a BasicBlock) (id ?p) (parent ?r))
			=>
			(retract ?fct)
			(modify-instance ?i0 (MemoryTarget UNKNOWN))
			(assert (element ?p writes to UNKNOWN)
					  (Element ?p has a MemoryBarrier)
					  (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InitializeReadsFromMerger
			?f0 <- (element ?p reads from $?t0)
			(not (exists (message (to dependency-analysis)
										 (action reads-from-list)
										 (arguments ?p => $?))))
			=>
			(retract ?f0)
			(assert (message (to dependency-analysis)
								  (action reads-from-list)
								  (arguments ?p => $?t0))))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InitializeWritesToMerger
			?f0 <- (element ?p writes to $?t0)
			(not (exists (message (to dependency-analysis)
										 (action writes-to-list)
										 (arguments ?p => $?))))
			=>
			(retract ?f0)
			(assert (message (to dependency-analysis)
								  (action writes-to-list)
								  (arguments ?p => $?t0))))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::MergeReadsFrom
			?f0 <- (element ?p reads from $?t0)
			?f1 <- (message (to dependency-analysis)
								 (action reads-from-list)
								 (arguments ?p => $?t1))
			=>
			(retract ?f0)
			(modify ?f1 (arguments ?p => $?t1 $?t0)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::MergeWritesTo
			?f0 <- (element ?p writes to $?t0)
			?f1 <- (message (to dependency-analysis)
								 (action writes-to-list)
								 (arguments ?p => $?t1))
			=>
			(retract ?f0)
			(modify ?f1 (arguments ?p => $?t1 $?t0)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatReadsFrom-ParentDoesntExist
			(declare (salience -9))
			?fct <- (message (to dependency-analysis)
								  (action reads-from-list)
								  (arguments ?p => $?t))
			?bb <- (object (is-a Diplomat) (id ?p) (parent ?q))
			(not (exists (object (is-a Diplomat)
										(id ?q))))
			=>
			(retract ?fct)
			(slot-insert$ ?bb ReadsFrom 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatReadsFrom-ParentExists
			(declare (salience -9))
			?fct <- (message (to dependency-analysis)
								  (action reads-from-list)
								  (arguments ?p => $?t))
			?bb <- (object (is-a Diplomat)
								(id ?p)
								(parent ?q))
			(exists (object (is-a Diplomat)
								 (id ?q)))
			=>
			(modify ?fct (arguments ?q => ?t))
			(slot-insert$ ?bb ReadsFrom 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatWritesTo-ParentDoesntExist
			(declare (salience -9))
			?fct <- (message (to dependency-analysis)
								  (action writes-to-list)
								  (arguments ?p => $?t))
			?bb <- (object (is-a Diplomat)
								(id ?p)
								(parent ?q))
			(not (exists (object (is-a Diplomat)
										(id ?q))))
			=>
			(retract ?fct)
			(slot-insert$ ?bb WritesTo 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatWritesTo-ParentExists
			(declare (salience -9))
			?fct <- (message (to dependency-analysis)
								  (action writes-to-list)
								  (arguments ?p => $?t))
			?bb <- (object (is-a Diplomat) (id ?p) (parent ?q))
			(exists (object (is-a Diplomat) (id ?q)))
			=>
			(modify ?fct (arguments ?q => $?t))
			(slot-insert$ ?bb WritesTo 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::UpdateDiplomatHasMemoryBarrier
			(declare (salience -10))
			?fct <- (Element ?b has a MemoryBarrier)
			?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier FALSE)
								 (parent ?p))
			(exists (object (is-a Diplomat) (id ?p)))
			=>
			(retract ?fct)
			(assert (Element ?p has a MemoryBarrier))
			(modify-instance ?obj (HasMemoryBarrier TRUE)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::RetractDiplomatHasMemoryBarrier
			(declare (salience -10))
			?fct <- (Element ?b has a MemoryBarrier)
			?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier TRUE)
								 (parent ?p))
			(exists (object (is-a Diplomat) (id ?p)))
			=>
			(retract ?fct)
			(assert (Element ?p has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::UpdateDiplomatHasMemoryBarrier-ParentDoesntExist
			(declare (salience -10))
			?fct <- (Element ?b has a MemoryBarrier)
			?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier FALSE)
								 (parent ?p))
			(not (exists (object (is-a Diplomat) (id ?p))))
			=>
			(retract ?fct)
			(modify-instance ?obj (HasMemoryBarrier TRUE)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::RetractDiplomatHasMemoryBarrier-ParentDoesntExist
			(declare (salience -10))
			?fct <- (Element ?b has a MemoryBarrier)
			?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier TRUE)
								 (parent ?p))
			(not (exists (object (is-a Diplomat) (id ?p))))
			=>
			(retract ?fct))
;------------------------------------------------------------------------------

;Copyright (c) 2012, Joshua Scoggins
;All rights reserved.
;
;Redistribution and use in source and binary forms, with or without
;modification, are permitted provided that the following conditions are met:
;    * Redistributions of source code must retain the above copyright
;      notice, this list of conditions and the following disclaimer.
;    * Redistributions in binary form must reproduce the above copyright
;      notice, this list of conditions and the following disclaimer in the
;      documentation and/or other materials provided with the distribution.
;    * Neither the name of Joshua Scoggins nor the
;      names of its contributors may be used to endorse or promote products
;      derived from this software without specific prior written permission.
;
;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
;ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;DISCLAIMED. IN NO EVENT SHALL Joshua Scoggins BE LIABLE FOR ANY
;DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
;(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
;ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;------------------------------------------------------------------------------
; MemoryBarrierCreation.clp - Contains rules pertaining to the creation of
; memory barriers to prevent loads and stores from being moved above a specific
; point within the program during the act of scheduling.
; Written by Joshua Scoggins (7/1/2012)
;------------------------------------------------------------------------------
; Barriers consist of reads and writes that can't be verified as to their exact
; source.
;------------------------------------------------------------------------------
; TODO: Put in a field for load and store instructions that describes what
; is being referenced. By default this slot is UNKNOWN.
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::AssertLoadBarrierEvaluation
         "Creates a fact that tells the system to analyze the given load
         instruction to see if it is necessary to create a memory barrier for
         the given instruction"
         (declare (salience 5))
         (object (is-a LoadInstruction) (id ?t0) (Operands ?target $?))
         =>
         (assert (Analyze ?target for load ?t0)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::AssertStoreBarrierEvaluation
         "Creates a fact that tells the system to analyze the given store
         instruction to see if it is necessary to create a memory barrier for
         the given instruction"
         (declare (salience 5))
         (object (is-a StoreInstruction) (id ?t0)
                 (DestinationRegisters ?target))
         =>
         (assert (Analyze ?target for store ?t0)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGetElementPointerLoadBarrier
         "Creates a load memory barrier hint if it turns out that the load
         instruction refers to a getelementptr instruction but that
         getelementptr doesn't refer to a alloca instruction or constant."
         (declare (salience 4))
         ?fct <- (Analyze ?target for load ?t0)
         ?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
         (object (is-a GetElementPointerInstruction) (id ?target)
                 (Operands ?a $?))
         (object (is-a ~AllocaInstruction&~Constant) (id ?a))
         (object (is-a BasicBlock) (id ?p) (parent ?r))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget UNKNOWN))
         (assert (element ?p reads from UNKNOWN)
                 (Element ?p has a MemoryBarrier)
                 (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-Alloca
         "Does a check to see if the load instruction refers directly to an
         AllocaInstruction or Constant. If it does then mark it as though the
         block reads from it"
         (declare (salience 4))
         ?fct <- (Analyze ?target for load ?t0)
         ?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
         (object (is-a AllocaInstruction) (id ?target))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?target))
         (assert (element ?p reads from ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-Constant
         "Does a check to see if the load instruction refers directly to an
         AllocaInstruction or Constant. If it does then mark it as though the
         block reads from it"
         (declare (salience 4))
         ?fct <- (Analyze ?target for load ?t0)
         ?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
         (object (is-a Constant) (id ?target))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?target))
         (assert (element ?p reads from ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-GetElementPointer-Alloca
         "Does a check to see if a given LoadInstruction referring to a
         GetElementPointerInstruction refers to an AllocaInstruction or
         Constant. If it does then mark it in the ReadsFrom multifield"
         (declare (salience 4))
         ?fct <- (Analyze ?target for load ?t0)
         ?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
         (object (is-a GetElementPointerInstruction) (id ?target)
                 (Operands ?a $?))
         (object (is-a AllocaInstruction) (id ?a))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?a))
         (assert (element ?p reads from ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithReadFrom-GetElementPointer-Constant
         "Does a check to see if a given LoadInstruction referring to a
         GetElementPointerInstruction refers to an AllocaInstruction or
         Constant. If it does then mark it in the ReadsFrom multifield"
         (declare (salience 4))
         ?fct <- (Analyze ?target for load ?t0)
         ?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
         (object (is-a GetElementPointerInstruction) (id ?target)
                 (Operands ?a $?))
         (object (is-a Constant) (id ?a))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?a))
         (assert (element ?p reads from ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGeneralLoadBarrier
         "Creates a load memory barrier hint if it turns out that the load
         instruction in question refers to a register that isn't an
         AllocaInstruction, GetElementPointerInstruction, or Constant."
         (declare (salience 3))
         ?fct <- (Analyze ?target for load ?t0)
         ?i0 <- (object (is-a LoadInstruction) (id ?t0) (parent ?p))
         (object (is-a BasicBlock) (id ?p) (parent ?r))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget UNKNOWN))
         (assert (element ?p reads from UNKNOWN)
                 (Element ?p has a MemoryBarrier)
                 (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGetElementPointerStoreBarrier
         "Creates a store memory barrier hint if it turns out that the store
         instruction refers to a getelementptr instruction but that
         getelementptr doesn't refer to a alloca instruction or constant."
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (parent ?p) (id ?t0))
         (object (is-a GetElementPointerInstruction) (id ?target)
                 (Operands ?a $?))
         (object (is-a ~AllocaInstruction&~Constant) (id ?a))
         (object (is-a BasicBlock) (id ?p) (parent ?r))
         =>
         (modify-instance ?i0 (MemoryTarget UNKNOWN))
         (retract ?fct)
         (assert (element ?p writes to UNKNOWN)
                 (Element ?p has a MemoryBarrier)
                 (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Alloca
         "Does a check to see if the load instruction refers directly to an
         AllocaInstruction or Constant. If it does then mark it as though the
         block writes to it"
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a AllocaInstruction) (id ?target))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?target))
         (assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Constant
         "Does a check to see if the store instruction refers directly to an
         AllocaInstruction or Constant. If it does then mark it as though the
         block writes to it"
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a Constant) (id ?target))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?target))
         (assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Single-Alloca
         "Does a check to see if the store instruction refers directly to an
         AllocaInstruction or Constant. If it does then mark it as though the
         block writes to it"
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a AllocaInstruction) (id ?target))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?target))
         (assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-Single-Constant
         "Does a check to see if the store instruction refers directly to an
         AllocaInstruction or Constant. If it does then mark it as though the
         block writes to it"
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a Constant) (id ?target))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?target))
         (assert (element ?p writes to ?target)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-GetElementPointer-Alloca
         "Does a check to see if a given StoreInstruction referring to a
         GetElementPointerInstruction refers to an AllocaInstruction or
         Constant. If it does then mark it in the WritesTo multifield"
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a GetElementPointerInstruction) (id ?target)
                 (Operands ?a $?))
         (object (is-a AllocaInstruction) (id ?a))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?a))
         (assert (element ?p writes to ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::PopulateBasicBlockWithWriteTo-GetElementPointer-Constant
         "Does a check to see if a given StoreInstruction referring to a
         GetElementPointerInstruction refers to an AllocaInstruction or
         Constant. If it does then mark it in the WritesTo multifield"
         (declare (salience 4))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a GetElementPointerInstruction) (id ?target)
                 (Operands ?a $?))
         (object (is-a Constant) (id ?a))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget ?a))
         (assert (element ?p writes to ?a)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::IdentifyGeneralStoreBarrier
         "Creates a store memory barrier hint if it turns out that the load
         instruction in question refers to a register that isn't an
         AllocaInstruction, GetElementPointerInstruction, or Constant."
         (declare (salience 3))
         ?fct <- (Analyze ?target for store ?t0)
         ?i0 <- (object (is-a StoreInstruction) (id ?t0) (parent ?p))
         (object (is-a BasicBlock) (id ?p) (parent ?r))
         =>
         (retract ?fct)
         (modify-instance ?i0 (MemoryTarget UNKNOWN))
         (assert (element ?p writes to UNKNOWN)
                 (Element ?p has a MemoryBarrier)
                 (Element ?r has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::MergeReadsFrom
         ?f0 <- (element ?p reads from $?t0)
         ?f1 <- (element ?p reads from $?t1)
         (test (neq ?f0 ?f1))
         =>
         (retract ?f0 ?f1)
         (assert (element ?p reads from $?t0 $?t1)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::MergeWritesTo
         ?f0 <- (element ?p writes to $?t0)
         ?f1 <- (element ?p writes to $?t1)
         (test (neq ?f0 ?f1))
         =>
         (retract ?f0 ?f1)
         (assert (element ?p writes to $?t0 $?t1)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatReadsFrom-ParentDoesntExist
         (declare (salience -9))
         ?fct <- (element ?p reads from $?t)
         ?bb <- (object (is-a Diplomat) (id ?p) (parent ?q))
         (not (exists (object (is-a Diplomat) (id ?q))))
         =>
         (retract ?fct)
         (slot-insert$ ?bb ReadsFrom 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatReadsFrom-ParentExists
         (declare (salience -9))
         ?fct <- (element ?p reads from $?t)
         ?bb <- (object (is-a Diplomat) (id ?p) (parent ?q))
         (exists (object (is-a Diplomat) (id ?q)))
         =>
         (retract ?fct)
         (assert (element ?q reads from ?t))
         (slot-insert$ ?bb ReadsFrom 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatWritesTo-ParentDoesntExist
         (declare (salience -9))
         ?fct <- (element ?p writes to $?t)
         ?bb <- (object (is-a Diplomat) (id ?p) (parent ?q))
         (not (exists (object (is-a Diplomat) (id ?q))))
         =>
         (retract ?fct)
         (slot-insert$ ?bb WritesTo 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::InsertIntoDiplomatWritesTo-ParentExists
         (declare (salience -9))
         ?fct <- (element ?p writes to $?t)
         ?bb <- (object (is-a Diplomat) (id ?p) (parent ?q))
         (exists (object (is-a Diplomat) (id ?q)))
         =>
         (retract ?fct)
         (assert (element ?q writes to ?t))
         (slot-insert$ ?bb WritesTo 1 ?t))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::UpdateDiplomatHasMemoryBarrier
         (declare (salience -10))
         ?fct <- (Element ?b has a MemoryBarrier)
         ?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier FALSE)
                         (parent ?p))
         (exists (object (is-a Diplomat) (id ?p)))
         =>
         (retract ?fct)
         (assert (Element ?p has a MemoryBarrier))
         (modify-instance ?obj (HasMemoryBarrier TRUE)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::RetractDiplomatHasMemoryBarrier
         (declare (salience -10))
         ?fct <- (Element ?b has a MemoryBarrier)
         ?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier TRUE)
                         (parent ?p))
         (exists (object (is-a Diplomat) (id ?p)))
         =>
         (retract ?fct)
         (assert (Element ?p has a MemoryBarrier)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::UpdateDiplomatHasMemoryBarrier-ParentDoesntExist
         (declare (salience -10))
         ?fct <- (Element ?b has a MemoryBarrier)
         ?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier FALSE)
                         (parent ?p))
         (not (exists (object (is-a Diplomat) (id ?p))))
         =>
         (retract ?fct)
         (modify-instance ?obj (HasMemoryBarrier TRUE)))
;------------------------------------------------------------------------------
(defrule dependency-analysis-analysis::RetractDiplomatHasMemoryBarrier-ParentDoesntExist
         (declare (salience -10))
         ?fct <- (Element ?b has a MemoryBarrier)
         ?obj <- (object (is-a Diplomat) (id ?b) (HasMemoryBarrier TRUE)
                         (parent ?p))
         (not (exists (object (is-a Diplomat) (id ?p))))
         =>
         (retract ?fct))
;------------------------------------------------------------------------------


Archivo Clips

Archivo Clips

Ejemplo básico en Clips.

; Datos de Empresas

(deftemplate Empresas
(field Nombre)
(field Tipo)
(field Pais)
(field Ciudad)
(field ComercioExterior)
(field Puntaje)
)

(deffacts VariasEmpresasHechos
(Empresas
	(Nombre "Empresa 1")
	(Tipo "Pymes")
	(Pais Argentina)
	(Ciudad "Buenos Aires")
	(ComercioExterior "Nada")
	(Puntaje 40))
(Empresas
	(Nombre "Empresa 2")
	(Tipo "Pymes")
	(Pais Argentina)
	(Ciudad "Buenos Aires")
	(ComercioExterior "Importa")
	(Puntaje 60))
(Empresas
	(Nombre "Empresa 3")
	(Tipo "MicroPymes")
	(Pais Argentina)
	(Ciudad "Cordoba")
	(ComercioExterior "Importa-Exporta")
	(Puntaje 74))
(Empresas
	(Nombre "Empresa 4")
	(Tipo "Profesional")
	(Pais Argentina)
	(Ciudad "Concordia")
	(ComercioExterior "Exporta")
	(Puntaje 90))
(Empresas
	(Nombre "Empresa 5")
	(Tipo "Pymes")
	(Pais Argentina)
	(Ciudad "Concordia")
	(ComercioExterior "Exporta")
	(Puntaje 93))
(Empresas
	(Nombre "Empresa 6")
	(Tipo "Pymes")
	(Pais Argentina)
	(Ciudad "Concordia")
	(ComercioExterior "Exporta")
	(Puntaje 60))
(Empresas
	(Nombre "Empresa 7")
	(Tipo "Pymes")
	(Pais Argentina)
	(Ciudad "Buenos Aires")
	(ComercioExterior "Exporta")
	(Puntaje 80))

(Empresas
	(Nombre "Empresa 8")
	(Tipo "Pymes")
	(Pais Argentina)
	(Ciudad "La Plata")
	(ComercioExterior "Exporta")
	(Puntaje 30))

(Empresas
	(Nombre "Empresa 9")
	(Tipo "Pymes")
	(Pais Mexico)
	(Ciudad "Guadalajara")
	(ComercioExterior "Importa-Exporta")
	(Puntaje 30))

(Empresas
	(Nombre "Empresa 10")
	(Tipo "MicroPymes")
	(Pais Peru)
	(Ciudad "Lima")
	(ComercioExterior "Nada")
	(Puntaje 30))

(Empresas
	(Nombre "Empresa 11")
	(Tipo "Pymes")
	(Pais Peru)
	(Ciudad "Trujillo")
	(ComercioExterior "Importa-Exporta")
	(Puntaje 30))
)

(defrule ImprimeExporta
	(Empresas (ComercioExterior ?ComercioExterior & "Exporta"|"Importa-Exporta")
	(Nombre ?Nombre)
	)
	=>
	(printout
	t crlf "****************************"
	t crlf ?Nombre " - " ?ComercioExterior " sus productos."
	t crlf "****************************")
)

(defrule ImprimePymes
	(Empresas (Tipo ?Tipo & "Pymes")
	(Nombre ?Nombre)
	(ComercioExterior ?ComercioExterior)
	)
	=>
	(printout
	t crlf "****************************"
	t crlf ?Nombre " Es una Pyme. "
	t crlf "Comercio Exterior: " ?ComercioExterior)
	t crlf "****************************"
)

(defrule ImprimeMayorPtos60
	(Empresas
	 	(Puntaje ?Puntaje & :(> ?Puntaje 60))
		(Nombre ?Nombre)
	)
	=>
	(printout
	t crlf "****************************"
	t crlf ?Nombre " ha completado sus datos. "
	t crlf "Puntaje : " ?Puntaje)
	t crlf "****************************"
)

error: pathspec 'Empresas.clp' did not match any file(s) known to git