Move logic for determining CallSideEffect opcode out of TranslatedCall.

This is the first step to fixing the order of side effects on call instructions. The goal is to move all side effects (argument side effects, allocation side effects, and conservative call side effects) to be treated as elements in a single sequence of side effects, which will then be handled in a single place similar to how we already handle argument side effects.
This commit is contained in:
Dave Bartolomeo
2021-09-03 09:58:31 -04:00
parent d22620f72f
commit 47e16b0480
2 changed files with 33 additions and 22 deletions

View File

@@ -111,6 +111,32 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff
)
}
/**
* Gets the `SideEffectFunction` called by the specified expression.class, if known.
*
* Thie will return a result only for `Call`, in which case it returns the target of the call, or
* for `NewExpr` and `NewArrayExpr`, in which case it returns the allocator function called by the
* expression.
*/
private SideEffectFunction getCallOrAllocationSideEffectFunction(Expr expr) {
result = expr.(Call).getTarget()
or
result = expr.(NewOrNewArrayExpr).getAllocator()
}
/**
* Returns the side effect opcode, if any, that represents any side effects not specifically modeled
* by an argument side effect.
*/
Opcode getCallSideEffectOpcode(Expr expr) {
if not getCallOrAllocationSideEffectFunction(expr).hasOnlySpecificWriteSideEffects()
then result instanceof Opcode::CallSideEffect
else (
not getCallOrAllocationSideEffectFunction(expr).hasOnlySpecificReadSideEffects() and
result instanceof Opcode::CallReadSideEffect
)
}
/**
* Returns a side effect opcode for parameter index `i` of the specified call.
*

View File

@@ -50,17 +50,14 @@ abstract class TranslatedCall extends TranslatedExpr {
opcode instanceof Opcode::Call and
resultType = getTypeForPRValue(getCallResultType())
or
hasSideEffect() and
tag = CallSideEffectTag() and
opcode = getCallSideEffectOpcode(expr) and
(
if hasWriteSideEffect()
then (
opcode instanceof Opcode::CallSideEffect and
resultType = getUnknownType()
) else (
opcode instanceof Opcode::CallReadSideEffect and
resultType = getVoidType()
)
opcode instanceof Opcode::CallSideEffect and
resultType = getUnknownType()
or
opcode instanceof Opcode::CallReadSideEffect and
resultType = getVoidType()
)
}
@@ -200,11 +197,7 @@ abstract class TranslatedCall extends TranslatedExpr {
*/
abstract predicate hasArguments();
predicate hasReadSideEffect() { any() }
predicate hasWriteSideEffect() { any() }
private predicate hasSideEffect() { hasReadSideEffect() or hasWriteSideEffect() }
final private predicate hasSideEffect() { exists(getCallSideEffectOpcode(expr)) }
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
hasSideEffect() and
@@ -325,14 +318,6 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
tag = CallTargetTag() and result = expr.getTarget()
}
override predicate hasReadSideEffect() {
not expr.getTarget().(SideEffectFunction).hasOnlySpecificReadSideEffects()
}
override predicate hasWriteSideEffect() {
not expr.getTarget().(SideEffectFunction).hasOnlySpecificWriteSideEffects()
}
override Instruction getQualifierResult() {
hasQualifier() and
result = getQualifier().getResult()