Skip to content

Commit 2f20486

Browse files
author
Robert Marsh
authored
Merge pull request #4604 from criemen/ir-block-sort-order
C++, C# IR: Stabilize sort order for basic blocks.
2 parents 48628fa + 78d885e commit 2f20486

File tree

19 files changed

+603
-514
lines changed

19 files changed

+603
-514
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ class IRBlockBase extends TIRBlock {
2626
/** Gets the source location of the first non-`Phi` instruction in this block. */
2727
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
2828

29-
/**
30-
* INTERNAL: Do not use.
31-
*
32-
* Gets a string that uniquely identifies this block within its enclosing function.
33-
*
34-
* This predicate is used by debugging and printing code only.
35-
*/
36-
final string getUniqueId() { result = getFirstInstruction(this).getUniqueId() }
37-
3829
/**
3930
* INTERNAL: Do not use.
4031
*
@@ -47,14 +38,15 @@ class IRBlockBase extends TIRBlock {
4738
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
4839
) and
4940
this =
50-
rank[result + 1](IRBlock funcBlock, int sortOverride |
41+
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
5142
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
43+
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
5244
// Ensure that the block containing `EnterFunction` always comes first.
5345
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
5446
then sortOverride = 0
5547
else sortOverride = 1
5648
|
57-
funcBlock order by sortOverride, funcBlock.getUniqueId()
49+
funcBlock order by sortOverride, sortKey1, sortKey2
5850
)
5951
}
6052

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ class Instruction extends Construction::TStageInstruction {
171171
*/
172172
final string getUniqueId() { result = Construction::getInstructionUniqueId(this) }
173173

174+
/**
175+
* INTERNAL: Do not use.
176+
*
177+
* Gets two sort keys for this instruction - used to order instructions for printing
178+
* in test outputs.
179+
*/
180+
final predicate hasSortKeys(int key1, int key2) {
181+
Construction::instructionHasSortKeys(this, key1, key2)
182+
}
183+
174184
/**
175185
* Gets the basic block that contains this instruction.
176186
*/

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,8 @@ private module CachedForDebugging {
856856
exists(Alias::MemoryLocation location, OldBlock phiBlock, string specificity |
857857
instr = getPhi(phiBlock, location) and
858858
result =
859-
"Phi Block(" + phiBlock.getUniqueId() + ")[" + specificity + "]: " + location.getUniqueId() and
859+
"Phi Block(" + phiBlock.getFirstInstruction().getUniqueId() + ")[" + specificity + "]: " +
860+
location.getUniqueId() and
860861
if location instanceof Alias::VirtualVariable
861862
then
862863
// Sort Phi nodes for virtual variables before Phi nodes for member locations.
@@ -873,6 +874,24 @@ private module CachedForDebugging {
873874
result.getAST() = var.getAST() and
874875
result.getTag() = var.getTag()
875876
}
877+
878+
cached
879+
predicate instructionHasSortKeys(Instruction instr, int key1, int key2) {
880+
exists(OldInstruction oldInstr |
881+
oldInstr = getOldInstruction(instr) and
882+
oldInstr.hasSortKeys(key1, key2)
883+
)
884+
or
885+
instr instanceof TUnreachedInstruction and
886+
key1 = maxValue() and
887+
key2 = maxValue()
888+
}
889+
890+
/**
891+
* Returns the value of the maximum representable integer.
892+
*/
893+
cached
894+
int maxValue() { result = 2147483647 }
876895
}
877896

878897
module SSAConsistency {

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRBlock.qll

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ class IRBlockBase extends TIRBlock {
2626
/** Gets the source location of the first non-`Phi` instruction in this block. */
2727
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
2828

29-
/**
30-
* INTERNAL: Do not use.
31-
*
32-
* Gets a string that uniquely identifies this block within its enclosing function.
33-
*
34-
* This predicate is used by debugging and printing code only.
35-
*/
36-
final string getUniqueId() { result = getFirstInstruction(this).getUniqueId() }
37-
3829
/**
3930
* INTERNAL: Do not use.
4031
*
@@ -47,14 +38,15 @@ class IRBlockBase extends TIRBlock {
4738
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
4839
) and
4940
this =
50-
rank[result + 1](IRBlock funcBlock, int sortOverride |
41+
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
5142
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
43+
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
5244
// Ensure that the block containing `EnterFunction` always comes first.
5345
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
5446
then sortOverride = 0
5547
else sortOverride = 1
5648
|
57-
funcBlock order by sortOverride, funcBlock.getUniqueId()
49+
funcBlock order by sortOverride, sortKey1, sortKey2
5850
)
5951
}
6052

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ class Instruction extends Construction::TStageInstruction {
171171
*/
172172
final string getUniqueId() { result = Construction::getInstructionUniqueId(this) }
173173

174+
/**
175+
* INTERNAL: Do not use.
176+
*
177+
* Gets two sort keys for this instruction - used to order instructions for printing
178+
* in test outputs.
179+
*/
180+
final predicate hasSortKeys(int key1, int key2) {
181+
Construction::instructionHasSortKeys(this, key1, key2)
182+
}
183+
174184
/**
175185
* Gets the basic block that contains this instruction.
176186
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,21 @@ private module CachedForDebugging {
380380
string getTempVariableUniqueId(IRTempVariable var) {
381381
exists(TranslatedElement element |
382382
var = element.getTempVariable(_) and
383-
result = element.getId() + ":" + getTempVariableTagId(var.getTag())
383+
result = element.getId().toString() + ":" + getTempVariableTagId(var.getTag())
384384
)
385385
}
386386

387+
cached
388+
predicate instructionHasSortKeys(Instruction instruction, int key1, int key2) {
389+
key1 = getInstructionTranslatedElement(instruction).getId() and
390+
getInstructionTag(instruction) =
391+
rank[key2](InstructionTag tag, string tagId |
392+
tagId = getInstructionTagId(tag)
393+
|
394+
tag order by tagId
395+
)
396+
}
397+
387398
cached
388399
string getInstructionUniqueId(Instruction instruction) {
389400
result =

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,10 +752,10 @@ abstract class TranslatedElement extends TTranslatedElement {
752752
abstract TranslatedElement getChild(int id);
753753

754754
/**
755-
* Gets the an identifier string for the element. This string is unique within
755+
* Gets the an identifier string for the element. This id is unique within
756756
* the scope of the element's function.
757757
*/
758-
final string getId() { result = getUniqueId().toString() }
758+
final int getId() { result = getUniqueId() }
759759

760760
private TranslatedElement getChildByRank(int rankIndex) {
761761
result =

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ class IRBlockBase extends TIRBlock {
2626
/** Gets the source location of the first non-`Phi` instruction in this block. */
2727
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
2828

29-
/**
30-
* INTERNAL: Do not use.
31-
*
32-
* Gets a string that uniquely identifies this block within its enclosing function.
33-
*
34-
* This predicate is used by debugging and printing code only.
35-
*/
36-
final string getUniqueId() { result = getFirstInstruction(this).getUniqueId() }
37-
3829
/**
3930
* INTERNAL: Do not use.
4031
*
@@ -47,14 +38,15 @@ class IRBlockBase extends TIRBlock {
4738
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
4839
) and
4940
this =
50-
rank[result + 1](IRBlock funcBlock, int sortOverride |
41+
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
5142
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
43+
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
5244
// Ensure that the block containing `EnterFunction` always comes first.
5345
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
5446
then sortOverride = 0
5547
else sortOverride = 1
5648
|
57-
funcBlock order by sortOverride, funcBlock.getUniqueId()
49+
funcBlock order by sortOverride, sortKey1, sortKey2
5850
)
5951
}
6052

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,16 @@ class Instruction extends Construction::TStageInstruction {
171171
*/
172172
final string getUniqueId() { result = Construction::getInstructionUniqueId(this) }
173173

174+
/**
175+
* INTERNAL: Do not use.
176+
*
177+
* Gets two sort keys for this instruction - used to order instructions for printing
178+
* in test outputs.
179+
*/
180+
final predicate hasSortKeys(int key1, int key2) {
181+
Construction::instructionHasSortKeys(this, key1, key2)
182+
}
183+
174184
/**
175185
* Gets the basic block that contains this instruction.
176186
*/

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,8 @@ private module CachedForDebugging {
856856
exists(Alias::MemoryLocation location, OldBlock phiBlock, string specificity |
857857
instr = getPhi(phiBlock, location) and
858858
result =
859-
"Phi Block(" + phiBlock.getUniqueId() + ")[" + specificity + "]: " + location.getUniqueId() and
859+
"Phi Block(" + phiBlock.getFirstInstruction().getUniqueId() + ")[" + specificity + "]: " +
860+
location.getUniqueId() and
860861
if location instanceof Alias::VirtualVariable
861862
then
862863
// Sort Phi nodes for virtual variables before Phi nodes for member locations.
@@ -873,6 +874,24 @@ private module CachedForDebugging {
873874
result.getAST() = var.getAST() and
874875
result.getTag() = var.getTag()
875876
}
877+
878+
cached
879+
predicate instructionHasSortKeys(Instruction instr, int key1, int key2) {
880+
exists(OldInstruction oldInstr |
881+
oldInstr = getOldInstruction(instr) and
882+
oldInstr.hasSortKeys(key1, key2)
883+
)
884+
or
885+
instr instanceof TUnreachedInstruction and
886+
key1 = maxValue() and
887+
key2 = maxValue()
888+
}
889+
890+
/**
891+
* Returns the value of the maximum representable integer.
892+
*/
893+
cached
894+
int maxValue() { result = 2147483647 }
876895
}
877896

878897
module SSAConsistency {

0 commit comments

Comments
 (0)