C++, C# IR: Stabilize sort order for basic blocks.

This commit is contained in:
Cornelius Riemenschneider
2020-11-04 12:35:41 +01:00
parent 6ff939db5c
commit a13947424a
18 changed files with 213 additions and 127 deletions

View File

@@ -26,15 +26,6 @@ class IRBlockBase extends TIRBlock {
/** Gets the source location of the first non-`Phi` instruction in this block. */
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
*
* Gets a string that uniquely identifies this block within its enclosing function.
*
* This predicate is used by debugging and printing code only.
*/
final string getUniqueId() { result = getFirstInstruction(this).getUniqueId() }
/**
* INTERNAL: Do not use.
*
@@ -47,14 +38,15 @@ class IRBlockBase extends TIRBlock {
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride |
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
|
funcBlock order by sortOverride, funcBlock.getUniqueId()
funcBlock order by sortOverride, sortKey1, sortKey2
)
}

View File

@@ -171,6 +171,16 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getUniqueId() { result = Construction::getInstructionUniqueId(this) }
/**
* INTERNAL: Do not use.
*
* Gets two sort keys for this instruction - used to order instructions for printing
* in test outputs.
*/
final predicate hasSortKeys(int key1, int key2) {
Construction::instructionHasSortKeys(this, key1, key2)
}
/**
* Gets the basic block that contains this instruction.
*/

View File

@@ -856,7 +856,7 @@ private module CachedForDebugging {
exists(Alias::MemoryLocation location, OldBlock phiBlock, string specificity |
instr = getPhi(phiBlock, location) and
result =
"Phi Block(" + phiBlock.getUniqueId() + ")[" + specificity + "]: " + location.getUniqueId() and
"Phi Block(" + phiBlock.getFirstInstruction().getUniqueId() + ")[" + specificity + "]: " + location.getUniqueId() and
if location instanceof Alias::VirtualVariable
then
// Sort Phi nodes for virtual variables before Phi nodes for member locations.
@@ -873,6 +873,24 @@ private module CachedForDebugging {
result.getAST() = var.getAST() and
result.getTag() = var.getTag()
}
cached
predicate instructionHasSortKeys(Instruction instr, int key1, int key2) {
exists(OldInstruction oldInstr |
oldInstr = getOldInstruction(instr) and
oldInstr.hasSortKeys(key1, key2)
)
or
instr instanceof TUnreachedInstruction and
key1 = maxValue() and
key2 = maxValue()
}
/**
* Returns the value of the maximum representable integer.
*/
cached
int maxValue() { result = 2147483647 }
}
module SSAConsistency {

View File

@@ -26,15 +26,6 @@ class IRBlockBase extends TIRBlock {
/** Gets the source location of the first non-`Phi` instruction in this block. */
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
*
* Gets a string that uniquely identifies this block within its enclosing function.
*
* This predicate is used by debugging and printing code only.
*/
final string getUniqueId() { result = getFirstInstruction(this).getUniqueId() }
/**
* INTERNAL: Do not use.
*
@@ -47,14 +38,15 @@ class IRBlockBase extends TIRBlock {
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride |
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
|
funcBlock order by sortOverride, funcBlock.getUniqueId()
funcBlock order by sortOverride, sortKey1, sortKey2
)
}

View File

@@ -171,6 +171,16 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getUniqueId() { result = Construction::getInstructionUniqueId(this) }
/**
* INTERNAL: Do not use.
*
* Gets two sort keys for this instruction - used to order instructions for printing
* in test outputs.
*/
final predicate hasSortKeys(int key1, int key2) {
Construction::instructionHasSortKeys(this, key1, key2)
}
/**
* Gets the basic block that contains this instruction.
*/

View File

@@ -380,10 +380,21 @@ private module CachedForDebugging {
string getTempVariableUniqueId(IRTempVariable var) {
exists(TranslatedElement element |
var = element.getTempVariable(_) and
result = element.getId() + ":" + getTempVariableTagId(var.getTag())
result = element.getId().toString() + ":" + getTempVariableTagId(var.getTag())
)
}
cached
predicate instructionHasSortKeys(Instruction instruction, int key1, int key2) {
key1 = getInstructionTranslatedElement(instruction).getId() and
getInstructionTag(instruction) =
rank[key2](InstructionTag tag, string tagId |
tagId = getInstructionTagId(tag)
|
tag order by tagId
)
}
cached
string getInstructionUniqueId(Instruction instruction) {
result =

View File

@@ -752,10 +752,10 @@ abstract class TranslatedElement extends TTranslatedElement {
abstract TranslatedElement getChild(int id);
/**
* Gets the an identifier string for the element. This string is unique within
* Gets the an identifier string for the element. This id is unique within
* the scope of the element's function.
*/
final string getId() { result = getUniqueId().toString() }
final int getId() { result = getUniqueId() }
private TranslatedElement getChildByRank(int rankIndex) {
result =

View File

@@ -26,15 +26,6 @@ class IRBlockBase extends TIRBlock {
/** Gets the source location of the first non-`Phi` instruction in this block. */
final Language::Location getLocation() { result = getFirstInstruction().getLocation() }
/**
* INTERNAL: Do not use.
*
* Gets a string that uniquely identifies this block within its enclosing function.
*
* This predicate is used by debugging and printing code only.
*/
final string getUniqueId() { result = getFirstInstruction(this).getUniqueId() }
/**
* INTERNAL: Do not use.
*
@@ -47,14 +38,15 @@ class IRBlockBase extends TIRBlock {
config.shouldEvaluateDebugStringsForFunction(this.getEnclosingFunction())
) and
this =
rank[result + 1](IRBlock funcBlock, int sortOverride |
rank[result + 1](IRBlock funcBlock, int sortOverride, int sortKey1, int sortKey2 |
funcBlock.getEnclosingFunction() = getEnclosingFunction() and
funcBlock.getFirstInstruction().hasSortKeys(sortKey1, sortKey2) and
// Ensure that the block containing `EnterFunction` always comes first.
if funcBlock.getFirstInstruction() instanceof EnterFunctionInstruction
then sortOverride = 0
else sortOverride = 1
|
funcBlock order by sortOverride, funcBlock.getUniqueId()
funcBlock order by sortOverride, sortKey1, sortKey2
)
}

View File

@@ -171,6 +171,16 @@ class Instruction extends Construction::TStageInstruction {
*/
final string getUniqueId() { result = Construction::getInstructionUniqueId(this) }
/**
* INTERNAL: Do not use.
*
* Gets two sort keys for this instruction - used to order instructions for printing
* in test outputs.
*/
final predicate hasSortKeys(int key1, int key2) {
Construction::instructionHasSortKeys(this, key1, key2)
}
/**
* Gets the basic block that contains this instruction.
*/

View File

@@ -856,7 +856,7 @@ private module CachedForDebugging {
exists(Alias::MemoryLocation location, OldBlock phiBlock, string specificity |
instr = getPhi(phiBlock, location) and
result =
"Phi Block(" + phiBlock.getUniqueId() + ")[" + specificity + "]: " + location.getUniqueId() and
"Phi Block(" + phiBlock.getFirstInstruction().getUniqueId() + ")[" + specificity + "]: " + location.getUniqueId() and
if location instanceof Alias::VirtualVariable
then
// Sort Phi nodes for virtual variables before Phi nodes for member locations.
@@ -873,6 +873,24 @@ private module CachedForDebugging {
result.getAST() = var.getAST() and
result.getTag() = var.getTag()
}
cached
predicate instructionHasSortKeys(Instruction instr, int key1, int key2) {
exists(OldInstruction oldInstr |
oldInstr = getOldInstruction(instr) and
oldInstr.hasSortKeys(key1, key2)
)
or
instr instanceof TUnreachedInstruction and
key1 = maxValue() and
key2 = maxValue()
}
/**
* Returns the value of the maximum representable integer.
*/
cached
int maxValue() { result = 2147483647 }
}
module SSAConsistency {