C++: Treat asmStmt operands as input/output in IR

This commit is contained in:
Robert Marsh
2019-05-30 09:24:40 -07:00
parent 66d1efdb97
commit 98d6f5919f
11 changed files with 174 additions and 27 deletions

View File

@@ -73,7 +73,8 @@ module InstructionSanity {
operand.getOperandTag() = tag) and
not expectsOperand(instr, tag) and
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag)
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
}
/**

View File

@@ -73,7 +73,8 @@ module InstructionSanity {
operand.getOperandTag() = tag) and
not expectsOperand(instr, tag) and
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag)
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
}
/**

View File

@@ -84,7 +84,13 @@ newtype TInstructionTag =
} or
InitializerElementDefaultValueStoreTag(int elementIndex) {
elementIsInitialized(elementIndex)
}
} or
AsmTag() or
AsmInputTag(int elementIndex) {
exists(AsmStmt asm |
exists(asm.getChild(elementIndex))
)
}
class InstructionTag extends TInstructionTag {
final string toString() {
@@ -161,5 +167,9 @@ string getInstructionTagId(TInstructionTag tag) {
tag = InitializerElementDefaultValueStoreTag(index) and tagName = "InitElemDefValStore"
) and
result = tagName + "(" + index + ")"
) or
tag = AsmTag() and result = "Asm" or
exists(int index |
tag = AsmInputTag(index) and result = "AsmInputTag(" + index + ")"
)
}

View File

@@ -64,7 +64,7 @@ private predicate ignoreExprAndDescendants(Expr expr) {
// represent them.
newExpr.getInitializer().getFullyConverted() = expr
) or
// Ignore descendants of asm statements, since we can't differentiate inputs and outputs
// Do not translate input/output variables in GNU asm statements
getRealParent(expr) instanceof AsmStmt or
ignoreExprAndDescendants(getRealParent(expr)) // recursive case
}

View File

@@ -819,36 +819,69 @@ class TranslatedAsmStmt extends TranslatedStmt {
}
override Instruction getFirstInstruction() {
result = getInstruction(OnlyInstructionTag())
if exists(stmt.getChild(0))
then result = getInstruction(AsmInputTag(0))
else result = getInstruction(AsmTag())
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag,
Type resultType, boolean isGLValue) {
tag = OnlyInstructionTag() and
tag = AsmTag() and
opcode instanceof Opcode::InlineAsm and
resultType instanceof UnknownType and
isGLValue = false
or
exists(int index, VariableAccess va |
tag = AsmInputTag(index) and
stmt.getChild(index) = va and
opcode instanceof Opcode::VariableAddress and
resultType = va.getType().getUnspecifiedType() and
isGLValue = true
)
}
override IRVariable getInstructionVariable(InstructionTag tag) {
exists(int index |
tag = AsmInputTag(index) and
result = getIRUserVariable(stmt.getEnclosingFunction(), stmt.getChild(index).(VariableAccess).getTarget())
)
}
override Instruction getInstructionOperand(InstructionTag tag,
OperandTag operandTag) {
tag = OnlyInstructionTag() and
tag = AsmTag() and
operandTag instanceof SideEffectOperandTag and
result = getTranslatedFunction(stmt.getEnclosingFunction()).getUnmodeledDefinitionInstruction()
or
exists(int index |
tag = AsmTag() and
operandTag = asmOperand(index) and
result = getInstruction(AsmInputTag(index))
)
}
override final Type getInstructionOperandType(InstructionTag tag,
TypedOperandTag operandTag) {
tag = OnlyInstructionTag() and
tag = AsmTag() and
operandTag instanceof SideEffectOperandTag and
result instanceof UnknownType
}
override Instruction getInstructionSuccessor(InstructionTag tag,
EdgeKind kind) {
tag = OnlyInstructionTag() and
tag = AsmTag() and
result = getParent().getChildSuccessor(this) and
kind instanceof GotoEdge
or
exists(int index |
tag = AsmInputTag(index) and
kind instanceof GotoEdge and
if exists(stmt.getChild(index + 1))
then
result = getInstruction(AsmInputTag(index + 1))
else
result = getInstruction(AsmTag())
)
}
override Instruction getChildSuccessor(TranslatedElement child) {

View File

@@ -73,7 +73,8 @@ module InstructionSanity {
operand.getOperandTag() = tag) and
not expectsOperand(instr, tag) and
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag)
not (instr instanceof BuiltInInstruction and tag instanceof PositionalArgumentOperandTag) and
not (instr instanceof InlineAsmInstruction and tag instanceof AsmOperandTag)
}
/**

View File

@@ -28,7 +28,12 @@ private newtype TOperandTag =
)
} or
TChiTotalOperand() or
TChiPartialOperand()
TChiPartialOperand() or
TAsmOperand(int index) {
exists(AsmStmt asm |
exists(asm.getChild(index))
)
}
/**
* Identifies the kind of operand on an instruction. Each `Instruction` has at
@@ -362,3 +367,27 @@ class ChiPartialOperandTag extends MemoryOperandTag, TChiPartialOperand {
ChiPartialOperandTag chiPartialOperand() {
result = TChiPartialOperand()
}
class AsmOperandTag extends RegisterOperandTag, TAsmOperand {
int index;
AsmOperandTag() {
this = TAsmOperand(index)
}
override final string toString() {
result = "AsmOperand(" + index + ")"
}
override final int getSortOrder() {
result = 15 + index
}
override final string getLabel() {
result = index.toString() + ":"
}
}
AsmOperandTag asmOperand(int index) {
result = TAsmOperand(index)
}