Skip to content

Commit c7e62b4

Browse files
author
Dave Bartolomeo
authored
Merge pull request #2613 from rdmarsh2/getPhiOperandDefinition-perf-2
C++: performance fixes for getPhiOperandDefinition
2 parents 53e10e4 + e040619 commit c7e62b4

File tree

3 files changed

+81
-63
lines changed

3 files changed

+81
-63
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,9 @@ private module Cached {
153153
)
154154
}
155155

156+
pragma[noopt]
156157
cached
157-
Instruction getPhiOperandDefinition(
158-
PhiInstruction instr, IRBlock newPredecessorBlock, Overlap overlap
159-
) {
158+
Instruction getPhiOperandDefinition(Phi instr, IRBlock newPredecessorBlock, Overlap overlap) {
160159
exists(
161160
Alias::MemoryLocation defLocation, Alias::MemoryLocation useLocation, OldBlock phiBlock,
162161
OldBlock predBlock, OldBlock defBlock, int defOffset, Alias::MemoryLocation actualDefLocation
@@ -563,28 +562,35 @@ module DefUse {
563562
/**
564563
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
565564
*/
566-
bindingset[defOffset, defLocation]
567-
pragma[inline]
568565
Instruction getDefinitionOrChiInstruction(
569566
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
570567
Alias::MemoryLocation actualDefLocation
571568
) {
572-
defOffset >= 0 and
573-
exists(OldInstruction oldInstr |
574-
oldInstr = defBlock.getInstruction(defOffset / 2) and
575-
if (defOffset % 2) > 0
576-
then (
577-
// An odd offset corresponds to the `Chi` instruction.
578-
result = Chi(oldInstr) and
579-
actualDefLocation = defLocation.getVirtualVariable()
580-
) else (
581-
// An even offset corresponds to the original instruction.
582-
result = getNewInstruction(oldInstr) and
583-
actualDefLocation = defLocation
584-
)
569+
exists(OldInstruction oldInstr, int oldOffset |
570+
oldInstr = defBlock.getInstruction(oldOffset) and
571+
oldOffset >= 0
572+
|
573+
// An odd offset corresponds to the `Chi` instruction.
574+
defOffset = oldOffset * 2 + 1 and
575+
result = Chi(oldInstr) and
576+
(
577+
defLocation = Alias::getResultMemoryLocation(oldInstr) or
578+
defLocation = Alias::getResultMemoryLocation(oldInstr).getVirtualVariable()
579+
) and
580+
actualDefLocation = defLocation.getVirtualVariable()
581+
or
582+
// An even offset corresponds to the original instruction.
583+
defOffset = oldOffset * 2 and
584+
result = getNewInstruction(oldInstr) and
585+
(
586+
defLocation = Alias::getResultMemoryLocation(oldInstr) or
587+
defLocation = Alias::getResultMemoryLocation(oldInstr).getVirtualVariable()
588+
) and
589+
actualDefLocation = defLocation
585590
)
586591
or
587-
defOffset < 0 and
592+
defOffset = -1 and
593+
hasDefinition(_, defLocation, defBlock, defOffset) and
588594
result = Phi(defBlock, defLocation) and
589595
actualDefLocation = defLocation
590596
}
@@ -811,16 +817,16 @@ module DefUse {
811817
* Holds if the `Phi` instruction for location `useLocation` at the beginning of block `phiBlock` has an operand along
812818
* the incoming edge from `predBlock`, where that operand's definition is at offset `defOffset` in block `defBlock`.
813819
*/
814-
pragma[inline]
820+
pragma[noopt]
815821
predicate hasPhiOperandDefinition(
816822
Alias::MemoryLocation defLocation, Alias::MemoryLocation useLocation, OldBlock phiBlock,
817823
OldBlock predBlock, OldBlock defBlock, int defOffset
818824
) {
819825
exists(int defRank |
820826
definitionHasPhiNode(useLocation, phiBlock) and
821827
predBlock = phiBlock.getAFeasiblePredecessor() and
822-
hasDefinitionAtRank(useLocation, defLocation, defBlock, defRank, defOffset) and
823828
definitionReachesEndOfBlock(useLocation, defBlock, defRank, predBlock) and
829+
hasDefinitionAtRank(useLocation, defLocation, defBlock, defRank, defOffset) and
824830
exists(Alias::getOverlap(defLocation, useLocation))
825831
)
826832
}

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,9 @@ private module Cached {
153153
)
154154
}
155155

156+
pragma[noopt]
156157
cached
157-
Instruction getPhiOperandDefinition(
158-
PhiInstruction instr, IRBlock newPredecessorBlock, Overlap overlap
159-
) {
158+
Instruction getPhiOperandDefinition(Phi instr, IRBlock newPredecessorBlock, Overlap overlap) {
160159
exists(
161160
Alias::MemoryLocation defLocation, Alias::MemoryLocation useLocation, OldBlock phiBlock,
162161
OldBlock predBlock, OldBlock defBlock, int defOffset, Alias::MemoryLocation actualDefLocation
@@ -563,28 +562,35 @@ module DefUse {
563562
/**
564563
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
565564
*/
566-
bindingset[defOffset, defLocation]
567-
pragma[inline]
568565
Instruction getDefinitionOrChiInstruction(
569566
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
570567
Alias::MemoryLocation actualDefLocation
571568
) {
572-
defOffset >= 0 and
573-
exists(OldInstruction oldInstr |
574-
oldInstr = defBlock.getInstruction(defOffset / 2) and
575-
if (defOffset % 2) > 0
576-
then (
577-
// An odd offset corresponds to the `Chi` instruction.
578-
result = Chi(oldInstr) and
579-
actualDefLocation = defLocation.getVirtualVariable()
580-
) else (
581-
// An even offset corresponds to the original instruction.
582-
result = getNewInstruction(oldInstr) and
583-
actualDefLocation = defLocation
584-
)
569+
exists(OldInstruction oldInstr, int oldOffset |
570+
oldInstr = defBlock.getInstruction(oldOffset) and
571+
oldOffset >= 0
572+
|
573+
// An odd offset corresponds to the `Chi` instruction.
574+
defOffset = oldOffset * 2 + 1 and
575+
result = Chi(oldInstr) and
576+
(
577+
defLocation = Alias::getResultMemoryLocation(oldInstr) or
578+
defLocation = Alias::getResultMemoryLocation(oldInstr).getVirtualVariable()
579+
) and
580+
actualDefLocation = defLocation.getVirtualVariable()
581+
or
582+
// An even offset corresponds to the original instruction.
583+
defOffset = oldOffset * 2 and
584+
result = getNewInstruction(oldInstr) and
585+
(
586+
defLocation = Alias::getResultMemoryLocation(oldInstr) or
587+
defLocation = Alias::getResultMemoryLocation(oldInstr).getVirtualVariable()
588+
) and
589+
actualDefLocation = defLocation
585590
)
586591
or
587-
defOffset < 0 and
592+
defOffset = -1 and
593+
hasDefinition(_, defLocation, defBlock, defOffset) and
588594
result = Phi(defBlock, defLocation) and
589595
actualDefLocation = defLocation
590596
}
@@ -811,16 +817,16 @@ module DefUse {
811817
* Holds if the `Phi` instruction for location `useLocation` at the beginning of block `phiBlock` has an operand along
812818
* the incoming edge from `predBlock`, where that operand's definition is at offset `defOffset` in block `defBlock`.
813819
*/
814-
pragma[inline]
820+
pragma[noopt]
815821
predicate hasPhiOperandDefinition(
816822
Alias::MemoryLocation defLocation, Alias::MemoryLocation useLocation, OldBlock phiBlock,
817823
OldBlock predBlock, OldBlock defBlock, int defOffset
818824
) {
819825
exists(int defRank |
820826
definitionHasPhiNode(useLocation, phiBlock) and
821827
predBlock = phiBlock.getAFeasiblePredecessor() and
822-
hasDefinitionAtRank(useLocation, defLocation, defBlock, defRank, defOffset) and
823828
definitionReachesEndOfBlock(useLocation, defBlock, defRank, predBlock) and
829+
hasDefinitionAtRank(useLocation, defLocation, defBlock, defRank, defOffset) and
824830
exists(Alias::getOverlap(defLocation, useLocation))
825831
)
826832
}

csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,9 @@ private module Cached {
153153
)
154154
}
155155

156+
pragma[noopt]
156157
cached
157-
Instruction getPhiOperandDefinition(
158-
PhiInstruction instr, IRBlock newPredecessorBlock, Overlap overlap
159-
) {
158+
Instruction getPhiOperandDefinition(Phi instr, IRBlock newPredecessorBlock, Overlap overlap) {
160159
exists(
161160
Alias::MemoryLocation defLocation, Alias::MemoryLocation useLocation, OldBlock phiBlock,
162161
OldBlock predBlock, OldBlock defBlock, int defOffset, Alias::MemoryLocation actualDefLocation
@@ -563,28 +562,35 @@ module DefUse {
563562
/**
564563
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
565564
*/
566-
bindingset[defOffset, defLocation]
567-
pragma[inline]
568565
Instruction getDefinitionOrChiInstruction(
569566
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
570567
Alias::MemoryLocation actualDefLocation
571568
) {
572-
defOffset >= 0 and
573-
exists(OldInstruction oldInstr |
574-
oldInstr = defBlock.getInstruction(defOffset / 2) and
575-
if (defOffset % 2) > 0
576-
then (
577-
// An odd offset corresponds to the `Chi` instruction.
578-
result = Chi(oldInstr) and
579-
actualDefLocation = defLocation.getVirtualVariable()
580-
) else (
581-
// An even offset corresponds to the original instruction.
582-
result = getNewInstruction(oldInstr) and
583-
actualDefLocation = defLocation
584-
)
569+
exists(OldInstruction oldInstr, int oldOffset |
570+
oldInstr = defBlock.getInstruction(oldOffset) and
571+
oldOffset >= 0
572+
|
573+
// An odd offset corresponds to the `Chi` instruction.
574+
defOffset = oldOffset * 2 + 1 and
575+
result = Chi(oldInstr) and
576+
(
577+
defLocation = Alias::getResultMemoryLocation(oldInstr) or
578+
defLocation = Alias::getResultMemoryLocation(oldInstr).getVirtualVariable()
579+
) and
580+
actualDefLocation = defLocation.getVirtualVariable()
581+
or
582+
// An even offset corresponds to the original instruction.
583+
defOffset = oldOffset * 2 and
584+
result = getNewInstruction(oldInstr) and
585+
(
586+
defLocation = Alias::getResultMemoryLocation(oldInstr) or
587+
defLocation = Alias::getResultMemoryLocation(oldInstr).getVirtualVariable()
588+
) and
589+
actualDefLocation = defLocation
585590
)
586591
or
587-
defOffset < 0 and
592+
defOffset = -1 and
593+
hasDefinition(_, defLocation, defBlock, defOffset) and
588594
result = Phi(defBlock, defLocation) and
589595
actualDefLocation = defLocation
590596
}
@@ -811,16 +817,16 @@ module DefUse {
811817
* Holds if the `Phi` instruction for location `useLocation` at the beginning of block `phiBlock` has an operand along
812818
* the incoming edge from `predBlock`, where that operand's definition is at offset `defOffset` in block `defBlock`.
813819
*/
814-
pragma[inline]
820+
pragma[noopt]
815821
predicate hasPhiOperandDefinition(
816822
Alias::MemoryLocation defLocation, Alias::MemoryLocation useLocation, OldBlock phiBlock,
817823
OldBlock predBlock, OldBlock defBlock, int defOffset
818824
) {
819825
exists(int defRank |
820826
definitionHasPhiNode(useLocation, phiBlock) and
821827
predBlock = phiBlock.getAFeasiblePredecessor() and
822-
hasDefinitionAtRank(useLocation, defLocation, defBlock, defRank, defOffset) and
823828
definitionReachesEndOfBlock(useLocation, defBlock, defRank, predBlock) and
829+
hasDefinitionAtRank(useLocation, defLocation, defBlock, defRank, defOffset) and
824830
exists(Alias::getOverlap(defLocation, useLocation))
825831
)
826832
}

0 commit comments

Comments
 (0)