C++: Sync identical files.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-07-01 17:40:08 +01:00
parent 03ec184ee0
commit db525f5cee

View File

@@ -15,6 +15,43 @@ private class OldInstruction = Reachability::ReachableInstruction;
import Cached
/**
* Holds if `instruction` is the first instruction that may be followed by
* an `InitializeGroup` instruction, and the enclosing function of
* `instruction` is `func`.
*/
private predicate isFirstInstructionBeforeInitializeGroup(Instruction instruction, IRFunction func) {
instruction = getChi(any(OldIR::InitializeNonLocalInstruction init)) and
func = instruction.getEnclosingIRFunction()
}
/** Gets the `i`'th `InitializeGroup` instruction in `func`. */
private InitializeGroupInstruction getInitGroupInstruction(int i, IRFunction func) {
exists(Alias::VariableGroup vg |
vg.getIRFunction() = func and
vg.getInitializationOrder() = i and
result = initializeGroup(vg)
)
}
/**
* Holds if `instruction` is the last instruction in the chain of `InitializeGroup`
* instructions in `func`. The chain of instructions may be empty in which case
* `instruction` satisfies
* ```
* isFirstInstructionBeforeInitializeGroup(instruction, func)
* ```
*/
predicate isLastInstructionForInitializeGroups(Instruction instruction, IRFunction func) {
exists(int i |
instruction = getInitGroupInstruction(i, func) and
not exists(getInitGroupInstruction(i + 1, func))
)
or
isFirstInstructionBeforeInitializeGroup(instruction, func) and
not exists(getInitGroupInstruction(0, func))
}
cached
private module Cached {
cached
@@ -45,7 +82,8 @@ private module Cached {
}
class TStageInstruction =
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction;
TRawInstruction or TPhiInstruction or TChiInstruction or TUnreachedInstruction or
TInitializeGroupInstruction;
/**
* If `oldInstruction` is a `Phi` instruction that has exactly one reachable predecessor block,
@@ -78,6 +116,8 @@ private module Cached {
or
instr instanceof TChiInstruction
or
instr instanceof TInitializeGroupInstruction
or
instr instanceof TUnreachedInstruction
}
@@ -123,7 +163,8 @@ private module Cached {
predicate hasModeledMemoryResult(Instruction instruction) {
canModelResultForOldInstruction(getOldInstruction(instruction)) or
instruction instanceof PhiInstruction or // Phis always have modeled results
instruction instanceof ChiInstruction // Chis always have modeled results
instruction instanceof ChiInstruction or // Chis always have modeled results
instruction instanceof InitializeGroupInstruction // Group initializers always have modeled results
}
cached
@@ -143,7 +184,7 @@ private module Cached {
// conflated if it's associated with a conflated location.
exists(Alias::MemoryLocation location |
instruction = getPhi(_, location) and
not exists(location.getAllocation())
not exists(location.getAnAllocation())
)
}
@@ -264,7 +305,12 @@ private module Cached {
}
cached
IRVariable getAnInitializeGroupVariable(InitializeGroupInstruction instr) { none() }
IRVariable getAnInitializeGroupVariable(InitializeGroupInstruction init) {
exists(Alias::VariableGroup vg |
init = initializeGroup(vg) and
result = vg.getAnAllocation().getABaseInstruction().(VariableInstruction).getIRVariable()
)
}
/**
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
@@ -347,14 +393,28 @@ private module Cached {
)
}
/*
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
* that node is its successor in the new successor relation, and the Chi node's successors are
* the new instructions generated from the successors of the old instruction
*/
private InitializeGroupInstruction firstInstructionToInitializeGroup(
Instruction instruction, EdgeKind kind
) {
exists(IRFunction func |
isFirstInstructionBeforeInitializeGroup(instruction, func) and
result = getInitGroupInstruction(0, func) and
kind instanceof GotoEdge
)
}
cached
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
private Instruction getNextInitializeGroupInstruction(Instruction instruction, EdgeKind kind) {
exists(int i, IRFunction func |
func = instruction.getEnclosingIRFunction() and
instruction = getInitGroupInstruction(i, func) and
result = getInitGroupInstruction(i + 1, func) and
kind instanceof GotoEdge
)
}
private Instruction getInstructionSuccessorAfterInitializeGroup0(
Instruction instruction, EdgeKind kind
) {
if hasChiNode(_, getOldInstruction(instruction))
then
result = getChi(getOldInstruction(instruction)) and
@@ -374,6 +434,35 @@ private module Cached {
)
}
private Instruction getInstructionSuccessorAfterInitializeGroup(
Instruction instruction, EdgeKind kind
) {
exists(IRFunction func, Instruction firstBeforeInitializeGroup |
isLastInstructionForInitializeGroups(instruction, func) and
isFirstInstructionBeforeInitializeGroup(firstBeforeInitializeGroup, func) and
result = getInstructionSuccessorAfterInitializeGroup0(firstBeforeInitializeGroup, kind)
)
}
/**
* This adds Chi nodes to the instruction successor relation; if an instruction has a Chi node,
* that node is its successor in the new successor relation, and the Chi node's successors are
* the new instructions generated from the successors of the old instruction.
*
* Furthermore, the entry block is augmented with `InitializeGroup` instructions.
*/
cached
Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {
result = firstInstructionToInitializeGroup(instruction, kind)
or
result = getNextInitializeGroupInstruction(instruction, kind)
or
result = getInstructionSuccessorAfterInitializeGroup(instruction, kind)
or
not isFirstInstructionBeforeInitializeGroup(instruction, _) and
result = getInstructionSuccessorAfterInitializeGroup0(instruction, kind)
}
cached
Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind kind) {
exists(OldInstruction oldInstruction |
@@ -409,6 +498,11 @@ private module Cached {
exists(IRFunctionBase irFunc |
instr = unreachedInstruction(irFunc) and result = irFunc.getFunction()
)
or
exists(Alias::VariableGroup vg |
instr = initializeGroup(vg) and
result = vg.getIRFunction().getFunction()
)
}
cached
@@ -426,6 +520,11 @@ private module Cached {
result = vvar.getType()
)
or
exists(Alias::VariableGroup vg |
instr = initializeGroup(vg) and
result = vg.getType()
)
or
instr = reusedPhiInstruction(_) and
result = instr.(OldInstruction).getResultLanguageType()
or
@@ -451,6 +550,8 @@ private module Cached {
or
instr = chiInstruction(_) and opcode instanceof Opcode::Chi
or
instr = initializeGroup(_) and opcode instanceof Opcode::InitializeGroup
or
instr = unreachedInstruction(_) and opcode instanceof Opcode::Unreached
}
@@ -467,6 +568,11 @@ private module Cached {
instr = chiInstruction(primaryInstr) and result = primaryInstr.getEnclosingIRFunction()
)
or
exists(Alias::VariableGroup vg |
instr = initializeGroup(vg) and
result = vg.getIRFunction()
)
or
instr = unreachedInstruction(result)
}
@@ -671,6 +777,20 @@ private import DefUse
* potentially very sparse.
*/
module DefUse {
bindingset[index, block]
pragma[inline_late]
private int getNonChiOffset(int index, OldBlock block) {
exists(IRFunction func | func = block.getEnclosingIRFunction() |
if getNewBlock(block) = func.getEntryBlock()
then result = 2 * (index + count(VariableGroup vg | vg.getIRFunction() = func))
else result = 2 * index
)
}
bindingset[index, block]
pragma[inline_late]
private int getChiOffset(int index, OldBlock block) { result = getNonChiOffset(index, block) + 1 }
/**
* Gets the `Instruction` for the definition at offset `defOffset` in block `defBlock`.
*/
@@ -678,12 +798,9 @@ module DefUse {
OldBlock defBlock, int defOffset, Alias::MemoryLocation defLocation,
Alias::MemoryLocation actualDefLocation
) {
exists(OldInstruction oldInstr, int oldOffset |
oldInstr = defBlock.getInstruction(oldOffset) and
oldOffset >= 0
|
exists(OldInstruction oldInstr, int oldOffset | oldInstr = defBlock.getInstruction(oldOffset) |
// An odd offset corresponds to the `Chi` instruction.
defOffset = oldOffset * 2 + 1 and
defOffset = getChiOffset(oldOffset, defBlock) and
result = getChi(oldInstr) and
(
defLocation = Alias::getResultMemoryLocation(oldInstr) or
@@ -692,7 +809,7 @@ module DefUse {
actualDefLocation = defLocation.getVirtualVariable()
or
// An even offset corresponds to the original instruction.
defOffset = oldOffset * 2 and
defOffset = getNonChiOffset(oldOffset, defBlock) and
result = getNewInstruction(oldInstr) and
(
defLocation = Alias::getResultMemoryLocation(oldInstr) or
@@ -705,6 +822,26 @@ module DefUse {
hasDefinition(_, defLocation, defBlock, defOffset) and
result = getPhi(defBlock, defLocation) and
actualDefLocation = defLocation
or
exists(
Alias::VariableGroup vg, int index, InitializeGroupInstruction initGroup,
Alias::GroupedMemoryLocation gml
|
// Add 3 to account for the function prologue:
// v1(void) = EnterFunction
// m1(unknown) = AliasedDefinition
// m2(unknown) = InitializeNonLocal
index = 3 + vg.getInitializationOrder() and
not gml.isMayAccess() and
gml.isSome() and
gml.getGroup() = vg and
vg.getIRFunction().getEntryBlock() = defBlock and
initGroup = initializeGroup(vg) and
(defLocation = gml or defLocation = gml.getVirtualVariable()) and
result = initGroup and
defOffset = 2 * index and
actualDefLocation = defLocation
)
}
/**
@@ -845,8 +982,18 @@ module DefUse {
block.getInstruction(index) = def and
overlap = Alias::getOverlap(defLocation, useLocation) and
if overlap instanceof MayPartiallyOverlap
then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction.
else offset = index * 2 // The use will be connected to the definition on the original instruction.
then offset = getChiOffset(index, block) // The use will be connected to the definition on the `Chi` instruction.
else offset = getNonChiOffset(index, block) // The use will be connected to the definition on the original instruction.
)
or
exists(InitializeGroupInstruction initGroup, int index, VariableGroup vg |
initGroup.getEnclosingIRFunction().getEntryBlock() = getNewBlock(block) and
vg = defLocation.(Alias::GroupedMemoryLocation).getGroup() and
// EnterFunction + AliasedDefinition + InitializeNonLocal + index
index = 3 + vg.getInitializationOrder() and
initGroup = initializeGroup(vg) and
exists(Alias::getOverlap(defLocation, useLocation)) and
offset = 2 * index
)
}
@@ -907,10 +1054,11 @@ module DefUse {
block.getInstruction(index) = use and
(
// A direct use of the location.
useLocation = Alias::getOperandMemoryLocation(use.getAnOperand()) and offset = index * 2
useLocation = Alias::getOperandMemoryLocation(use.getAnOperand()) and
offset = getNonChiOffset(index, block)
or
// A `Chi` instruction will include a use of the virtual variable.
hasChiNode(useLocation, use) and offset = (index * 2) + 1
hasChiNode(useLocation, use) and offset = getChiOffset(index, block)
)
)
}
@@ -1061,4 +1209,6 @@ module Ssa {
predicate hasChiInstruction = Cached::hasChiInstructionCached/1;
predicate hasUnreachedInstruction = Cached::hasUnreachedInstructionCached/1;
class VariableGroup = Alias::VariableGroup;
}