@@ -232,15 +232,17 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) {
232232/*
233233 * The following predicates compute the overlap relation between `VariableMemoryLocation`s in the
234234 * same `VirtualVariable` as follows:
235- * 1. Compute the set of offsets within each virtual variable in `isRelevantOffset` (linear in
235+ * 1. In `isRelevantOffset`, compute the set of offsets within each virtual variable (linear in
236236 * the number of VMLs)
237- * 2. Compute the set of offsets that each VML with known start and end offsets covers in
238- * `isCoveredOffset` (this is currently quadratic in the number of VMLs in a VVar, but
239- * could be optimized further. The quadratic portion is never materialized, and it seems to
240- * be performant in practice )
241- * 3 . In `getVariableMemoryLocationOverlap `, compute the set of overlapping pairs of VMLs using a
237+ * 2. In `isCoveredOffset`, rank the offsets within each virtual variable (linear in the number
238+ * of VMLs)
239+ * 3. In `isCoveredOffset`, compute the set of ranks that each VML with known start and end
240+ * offsets covers (linear in the size of the overlap set )
241+ * 4 . In `overlappingVariableMemoryLocations `, compute the set of overlapping pairs of VMLs using a
242242 * join on `isCoveredOffset` (linear in the size of the overlap set)
243- * 4. In `getVariableMemoryLocationOverlap`, compute the precise overlap relation for each
243+ * 5. In `overlappingIRVariableMemoryLocations`, restrict to only the pairs that share an
244+ * `IRVariable` (linear in the size of the overlap set)
245+ * 5. In `getVariableMemoryLocationOverlap`, compute the precise overlap relation for each
244246 * overlapping pair of VMLs (linear in the size of the overlap set)
245247 */
246248private predicate isRelevantOffset ( VirtualVariable vv , IntValue offset ) {
@@ -258,12 +260,14 @@ private predicate isRelatableMemoryLocation(VariableMemoryLocation vml) {
258260 vml .getStartBitOffset ( ) != Ints:: unknown ( )
259261}
260262
261- private predicate isCoveredOffset ( VariableMemoryLocation vml , VirtualVariable vv , IntValue offset ) {
262- isRelevantOffset ( vv , offset ) and
263- vv = vml .getVirtualVariable ( ) and
264- isRelatableMemoryLocation ( vml ) and
265- vml .getStartBitOffset ( ) <= offset and
266- offset <= vml .getEndBitOffset ( )
263+ private predicate isCoveredOffset ( VariableMemoryLocation vml , VirtualVariable vv , int offsetRank ) {
264+ exists ( int startRank , int endRank |
265+ vml .getStartBitOffset ( ) = rank [ startRank ] ( IntValue offset_ | isRelevantOffset ( vv , offset_ ) ) and
266+ vml .getEndBitOffset ( ) = rank [ endRank ] ( IntValue offset_ | isRelevantOffset ( vv , offset_ ) ) and
267+ vv = vml .getVirtualVariable ( ) and
268+ isRelatableMemoryLocation ( vml ) and
269+ offsetRank in [ startRank .. endRank ]
270+ )
267271}
268272
269273private predicate hasUnknownOffset ( VariableMemoryLocation vml , VirtualVariable vv ) {
@@ -274,18 +278,26 @@ private predicate hasUnknownOffset(VariableMemoryLocation vml, VirtualVariable v
274278 )
275279}
276280
277- private Overlap getVariableMemoryLocationOverlap ( VariableMemoryLocation def , VariableMemoryLocation use ) {
278- def .getVariable ( ) = use .getVariable ( ) and
279- (
280- exists ( VirtualVariable vv , IntValue offset | isCoveredOffset ( def , vv , offset ) and isCoveredOffset ( use , vv , offset ) )
281+ private predicate overlappingVariableMemoryLocations ( VariableMemoryLocation def , VariableMemoryLocation use ) {
282+ exists ( VirtualVariable vv , int offsetRank | isCoveredOffset ( def , vv , offsetRank ) and isCoveredOffset ( use , vv , offsetRank ) )
281283 or
282284 hasUnknownOffset ( def , use .getVirtualVariable ( ) )
283285 or
284286 hasUnknownOffset ( use , def .getVirtualVariable ( ) )
285- ) and
287+ }
288+
289+ pragma [ noopt] // Internal ticket: QL-937
290+ private predicate overlappingIRVariableMemoryLocations ( VariableMemoryLocation def , VariableMemoryLocation use ) {
291+ overlappingVariableMemoryLocations ( def , use ) and
292+ def .getVariable ( ) = use .getVariable ( )
293+ }
294+
295+ private Overlap getVariableMemoryLocationOverlap ( VariableMemoryLocation def , VariableMemoryLocation use ) {
296+ overlappingIRVariableMemoryLocations ( def , use ) and
286297 result = Interval:: getOverlap ( def .getStartBitOffset ( ) , def .getEndBitOffset ( ) , use .getStartBitOffset ( ) , use .getEndBitOffset ( ) )
287298}
288299
300+
289301MemoryLocation getResultMemoryLocation ( Instruction instr ) {
290302 exists ( MemoryAccessKind kind |
291303 kind = instr .getResultMemoryAccess ( ) and
0 commit comments