Skip to content

Commit

Permalink
Detect simple struct changes
Browse files Browse the repository at this point in the history
  • Loading branch information
zacikpa committed Nov 5, 2023
1 parent e0d80f7 commit d3a8039
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 5 deletions.
3 changes: 2 additions & 1 deletion diffkemp/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ def make_argument_parser():
"type-casts",
"control-flow-only",
"inverse-conditions",
"reordered-bin-ops"]
"reordered-bin-ops",
"struct-changes"]

# Semantic patterns options.
compare_ap.add_argument("--enable-pattern",
Expand Down
4 changes: 4 additions & 0 deletions diffkemp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def __init__(
control_flow_only=False,
inverse_conditions=True,
reordered_bin_ops=True,
struct_changes=True,
):
"""
Create a configuration of built-in patterns.
Expand All @@ -41,6 +42,7 @@ def __init__(
:param control_flow_only: Consider control-flow changes only.
:param inverse_conditions: Inverted branch conditions.
:param reordered_bin_ops: Match reordered binary operations.
:param struct_changes: Changes in local structs and variables.
"""
self.settings = {
"struct-alignment": struct_alignment,
Expand All @@ -54,6 +56,7 @@ def __init__(
"control-flow-only": control_flow_only,
"inverse-conditions": inverse_conditions,
"reordered-bin-ops": reordered_bin_ops,
"struct-changes": struct_changes,
}
self.resolve_dependencies()

Expand Down Expand Up @@ -101,6 +104,7 @@ def as_ffi_struct(self):
ffi_struct.ControlFlowOnly = self.settings["control-flow-only"]
ffi_struct.InverseConditions = self.settings["inverse-conditions"]
ffi_struct.ReorderedBinOps = self.settings["reordered-bin-ops"]
ffi_struct.StructChanges = self.settings["struct-changes"]
return ffi_struct


Expand Down
1 change: 1 addition & 0 deletions diffkemp/simpll/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct BuiltinPatterns {
bool ControlFlowOnly = false;
bool InverseConditions = true;
bool ReorderedBinOps = true;
bool StructChanges = true;
};

/// Tool configuration parsed from CLI options.
Expand Down
58 changes: 55 additions & 3 deletions diffkemp/simpll/DifferentialFunctionComparator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,25 @@ bool DifferentialFunctionComparator::maySkipInstruction(
if (auto Load = dyn_cast<LoadInst>(Inst)) {
return maySkipLoad(Load);
}
if (config.Patterns.StructChanges) {
if (isa<GetElementPtrInst>(Inst)
&& isOnlyUsedByIgnorableMemInstructions(Inst)) {
ignoredInstructions.insert(Inst);
return true;
}
if (auto store = dyn_cast<StoreInst>(Inst)) {
if (hasIgnoredAllocaAsPtrOperand(store)) {
ignoredInstructions.insert(Inst);
return true;
}
}
if (auto load = dyn_cast<LoadInst>(Inst)) {
if (hasIgnoredAllocaAsPtrOperand(load)) {
ignoredInstructions.insert(Inst);
return true;
}
}
}
return false;
}

Expand Down Expand Up @@ -670,9 +689,12 @@ bool DifferentialFunctionComparator::maySkipLoad(const LoadInst *Load) const {
/// of the same kind.
bool DifferentialFunctionComparator::maySkipReorderableBinaryOp(
const Instruction *Op) const {
return std::all_of(Op->user_begin(), Op->user_end(), [Op](auto user) {
auto userOp = dyn_cast<BinaryOperator>(user);
return userOp && userOp->getOpcode() == Op->getOpcode();
return std::all_of(Op->user_begin(), Op->user_end(), [&](auto user) {
if (auto userBinOp = dyn_cast<BinaryOperator>(user))
return userBinOp->getOpcode() == Op->getOpcode();
if (auto userStore = dyn_cast<StoreInst>(user))
return hasIgnoredAllocaAsPtrOperand(userStore);
return false;
});
}

Expand Down Expand Up @@ -1340,6 +1362,11 @@ int DifferentialFunctionComparator::cmpFieldAccess(
if (!(GEPL && GEPR))
RETURN_WITH_LOG(1);

if (config.Patterns.StructChanges
&& (hasIgnoredAllocaAsPtrOperand(GEPL)
|| hasIgnoredAllocaAsPtrOperand(GEPR)))
RETURN_WITH_LOG(1);

if (!GEPL->hasAllConstantIndices() || !GEPR->hasAllConstantIndices())
RETURN_WITH_LOG(1);

Expand Down Expand Up @@ -1958,3 +1985,28 @@ bool DifferentialFunctionComparator::collectBinaryOperands(
}
return false;
}

template <typename InstType>
bool DifferentialFunctionComparator::hasIgnoredAllocaAsPtrOperand(
const InstType *Inst) const {
const Value *Ptr = Inst->getPointerOperand();
if (auto GEP = dyn_cast<GetElementPtrInst>(Ptr))
return hasIgnoredAllocaAsPtrOperand(GEP);
return isIgnoredAlloca(Ptr);
}

bool DifferentialFunctionComparator::isOnlyUsedByIgnorableMemInstructions(
const Value *Val) const {
return std::all_of(
Val->user_begin(), Val->user_end(), [&](const User *user) {
if (auto store = dyn_cast<StoreInst>(user))
return hasIgnoredAllocaAsPtrOperand(store);
if (auto load = dyn_cast<StoreInst>(user))
return hasIgnoredAllocaAsPtrOperand(load);
return false;
});
}

bool DifferentialFunctionComparator::isIgnoredAlloca(const Value *Val) const {
return isa<AllocaInst>(Val) && ignoredInstructions.count(Val);
}
7 changes: 7 additions & 0 deletions diffkemp/simpll/DifferentialFunctionComparator.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,13 @@ class DifferentialFunctionComparator : public FunctionComparator {
std::multiset<int> &SNs,
std::multiset<int64_t> &Constants,
DenseMap<const Value *, int> &sn_map) const;

bool isIgnoredAlloca(const Value *Val) const;

template <typename InstType>
bool hasIgnoredAllocaAsPtrOperand(const InstType *Inst) const;

bool isOnlyUsedByIgnorableMemInstructions(const Value *Val) const;
};

#endif // DIFFKEMP_SIMPLL_DIFFERENTIALFUNCTIONCOMPARATOR_H
6 changes: 5 additions & 1 deletion diffkemp/simpll/SimpLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ cl::opt<bool> ReorderedBinOpsOpt(
"reordered-bin-ops",
cl::desc("Enable reordered binary operations pattern."),
cl::cat(BuiltinPatternsCategory));
cl::opt<bool> StructChangesOpt("struct-changes",
cl::desc("Enable struct changes pattern."),
cl::cat(BuiltinPatternsCategory));

/// Add suffix to the file name.
/// \param File Original file name.
Expand Down Expand Up @@ -162,7 +165,8 @@ int main(int argc, const char **argv) {
.TypeCasts = TypeCastsOpt,
.ControlFlowOnly = ControlFlowOnlyOpt,
.InverseConditions = InverseConditionsOpt,
.ReorderedBinOps = ReorderedBinOpsOpt};
.ReorderedBinOps = ReorderedBinOpsOpt,
.StructChanges = StructChangesOpt};

// Parse --fun option
auto FunName = parseFunOption();
Expand Down
1 change: 1 addition & 0 deletions diffkemp/simpll/library/FFI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ BuiltinPatterns BuiltinPatternsFromC(builtin_patterns PatternsC) {
.ControlFlowOnly = (bool)PatternsC.ControlFlowOnly,
.InverseConditions = (bool)PatternsC.InverseConditions,
.ReorderedBinOps = (bool)PatternsC.ReorderedBinOps,
.StructChanges = (bool)PatternsC.StructChanges,
};
}

Expand Down
1 change: 1 addition & 0 deletions diffkemp/simpll/library/FFI.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct builtin_patterns {
int ControlFlowOnly;
int InverseConditions;
int ReorderedBinOps;
int StructChanges;
};

struct config {
Expand Down

0 comments on commit d3a8039

Please sign in to comment.