Update node_id_map & FindMutators structure

Added function in node_id_map to check a given id is valid and fresh.

Currently, the structure of FindMutators declares node_id_map as const, which causes issues when we want to call `GetFreshId` from the argument that is passed by reference. A simple work around is to pass a non-const node_id_map as argument directly. That way `GetFreshId` function in node_id_map can continue to be non-const and conveniently update next fresh id whenever a fresh id has been taken.

Change-Id: Ia7e1d247cf92dfefd2ef7e7c1b4bf32363d9ce3f
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/61100
Reviewed-by: Paul Thomson <paulthomson@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Paul Thomson <paulthomson@google.com>
This commit is contained in:
Shiyu Liu 2021-08-10 16:43:15 +00:00 committed by Tint LUCI CQ
parent 34f7eedf74
commit 0c22b1aaea
6 changed files with 19 additions and 8 deletions

View File

@ -54,7 +54,7 @@ class MutationFinder {
/// @return all the found mutations. /// @return all the found mutations.
virtual MutationList FindMutations( virtual MutationList FindMutations(
const tint::Program& program, const tint::Program& program,
const NodeIdMap& node_id_map, NodeIdMap* node_id_map,
ProbabilityContext* probability_context) const = 0; ProbabilityContext* probability_context) const = 0;
/// @brief Compute a probability of applying a single mutation, returned by /// @brief Compute a probability of applying a single mutation, returned by

View File

@ -29,7 +29,7 @@ namespace ast_fuzzer {
MutationList MutationFinderReplaceIdentifiers::FindMutations( MutationList MutationFinderReplaceIdentifiers::FindMutations(
const tint::Program& program, const tint::Program& program,
const NodeIdMap& node_id_map, NodeIdMap* node_id_map,
ProbabilityContext* probability_context) const { ProbabilityContext* probability_context) const {
MutationList result; MutationList result;
@ -61,8 +61,8 @@ MutationList MutationFinderReplaceIdentifiers::FindMutations(
candidate_variables)]; candidate_variables)];
result.push_back(std::make_unique<MutationReplaceIdentifier>( result.push_back(std::make_unique<MutationReplaceIdentifier>(
node_id_map.GetId(user->Declaration()), node_id_map->GetId(user->Declaration()),
node_id_map.GetId(replacement->Declaration()))); node_id_map->GetId(replacement->Declaration())));
} }
} }

View File

@ -29,7 +29,7 @@ class MutationFinderReplaceIdentifiers : public MutationFinder {
public: public:
MutationList FindMutations( MutationList FindMutations(
const tint::Program& program, const tint::Program& program,
const NodeIdMap& node_id_map, NodeIdMap* node_id_map,
ProbabilityContext* probability_context) const override; ProbabilityContext* probability_context) const override;
uint32_t GetChanceOfApplyingMutation( uint32_t GetChanceOfApplyingMutation(
ProbabilityContext* probability_context) const override; ProbabilityContext* probability_context) const override;

View File

@ -141,7 +141,7 @@ tint::Program Mutate(tint::Program program,
// Get all applicable mutations from some mutation finder. // Get all applicable mutations from some mutation finder.
const auto& mutation_finder = const auto& mutation_finder =
finders[probability_context->GetRandomIndex(finders)]; finders[probability_context->GetRandomIndex(finders)];
auto mutations = mutation_finder->FindMutations(program, node_id_map, auto mutations = mutation_finder->FindMutations(program, &node_id_map,
probability_context); probability_context);
const auto old_applied_mutations = applied_mutations; const auto old_applied_mutations = applied_mutations;

View File

@ -40,17 +40,21 @@ const ast::Node* NodeIdMap::GetNode(IdType id) const {
void NodeIdMap::Add(const ast::Node* node, IdType id) { void NodeIdMap::Add(const ast::Node* node, IdType id) {
assert(!node_to_id_.count(node) && "The node already exists in the map"); assert(!node_to_id_.count(node) && "The node already exists in the map");
assert(!id_to_node_.count(id) && "Id already exists in the map"); assert(IdIsFreshAndValid(id) && "Id already exists in the map or Id is zero");
assert(node && "`node` can't be a nullptr"); assert(node && "`node` can't be a nullptr");
assert(id && "`id` can't be equal to 0");
node_to_id_[node] = id; node_to_id_[node] = id;
id_to_node_[id] = node; id_to_node_[id] = node;
if (id >= fresh_id_) { if (id >= fresh_id_) {
fresh_id_ = id + 1; fresh_id_ = id + 1;
} }
} }
bool NodeIdMap::IdIsFreshAndValid(IdType id) {
return id && !id_to_node_.count(id);
}
NodeIdMap::IdType NodeIdMap::TakeFreshId() { NodeIdMap::IdType NodeIdMap::TakeFreshId() {
assert(fresh_id_ != 0 && "`NodeIdMap` id has overflowed"); assert(fresh_id_ != 0 && "`NodeIdMap` id has overflowed");
return fresh_id_++; return fresh_id_++;

View File

@ -67,6 +67,13 @@ class NodeIdMap {
/// @param id - may not be 0 and can't be present in this map. /// @param id - may not be 0 and can't be present in this map.
void Add(const ast::Node* node, IdType id); void Add(const ast::Node* node, IdType id);
/// @brief Returns whether the id is fresh by checking if it exists in
/// the id map and the id is not 0.
/// @param id - an id that is used to check in the map.
/// @return true the given id is fresh and valid (non-zero).
/// @return false otherwise.
bool IdIsFreshAndValid(IdType id);
/// @brief Returns an id that is guaranteed to be unoccupied in this map. /// @brief Returns an id that is guaranteed to be unoccupied in this map.
/// ///
/// This will effectively increase the counter. This means that two /// This will effectively increase the counter. This means that two