Skip to content

Commit

Permalink
Fixes #2358. Added to the reducer the ability to remove a function t… (
Browse files Browse the repository at this point in the history
…#2361)

* Fixes #2358.  Added to the reducer the ability to remove a function that is not directly called.  Factored out some code from the optimizer to help with this.
  • Loading branch information
afd authored Feb 8, 2019
1 parent 10a7def commit 34c5ac6
Show file tree
Hide file tree
Showing 14 changed files with 551 additions and 7 deletions.
1 change: 1 addition & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ SPVTOOLS_OPT_SRC_FILES := \
source/opt/dominator_tree.cpp \
source/opt/eliminate_dead_constant_pass.cpp \
source/opt/eliminate_dead_functions_pass.cpp \
source/opt/eliminate_dead_functions_util.cpp \
source/opt/feature_manager.cpp \
source/opt/flatten_decoration_pass.cpp \
source/opt/fold.cpp \
Expand Down
2 changes: 2 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,8 @@ static_library("spvtools_opt") {
"source/opt/eliminate_dead_constant_pass.h",
"source/opt/eliminate_dead_functions_pass.cpp",
"source/opt/eliminate_dead_functions_pass.h",
"source/opt/eliminate_dead_functions_util.cpp",
"source/opt/eliminate_dead_functions_util.h",
"source/opt/feature_manager.cpp",
"source/opt/feature_manager.h",
"source/opt/flatten_decoration_pass.cpp",
Expand Down
2 changes: 2 additions & 0 deletions source/opt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
dominator_tree.h
eliminate_dead_constant_pass.h
eliminate_dead_functions_pass.h
eliminate_dead_functions_util.h
feature_manager.h
flatten_decoration_pass.h
fold.h
Expand Down Expand Up @@ -131,6 +132,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
dominator_tree.cpp
eliminate_dead_constant_pass.cpp
eliminate_dead_functions_pass.cpp
eliminate_dead_functions_util.cpp
feature_manager.cpp
flatten_decoration_pass.cpp
fold.cpp
Expand Down
10 changes: 3 additions & 7 deletions source/opt/eliminate_dead_functions_pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include "source/opt/eliminate_dead_functions_pass.h"
#include "source/opt/eliminate_dead_functions_util.h"

#include <unordered_set>

Expand All @@ -36,8 +37,8 @@ Pass::Status EliminateDeadFunctionsPass::Process() {
funcIter != get_module()->end();) {
if (live_function_set.count(&*funcIter) == 0) {
modified = true;
EliminateFunction(&*funcIter);
funcIter = funcIter.Erase();
funcIter =
eliminatedeadfunctionsutil::EliminateFunction(context(), &funcIter);
} else {
++funcIter;
}
Expand All @@ -47,10 +48,5 @@ Pass::Status EliminateDeadFunctionsPass::Process() {
: Pass::Status::SuccessWithoutChange;
}

void EliminateDeadFunctionsPass::EliminateFunction(Function* func) {
// Remove all of the instruction in the function body
func->ForEachInst([this](Instruction* inst) { context()->KillInst(inst); },
true);
}
} // namespace opt
} // namespace spvtools
32 changes: 32 additions & 0 deletions source/opt/eliminate_dead_functions_util.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "eliminate_dead_functions_util.h"

namespace spvtools {
namespace opt {

namespace eliminatedeadfunctionsutil {

Module::iterator EliminateFunction(IRContext* context,
Module::iterator* func_iter) {
(*func_iter)
->ForEachInst([context](Instruction* inst) { context->KillInst(inst); },
true);
return func_iter->Erase();
}

} // namespace eliminatedeadfunctionsutil
} // namespace opt
} // namespace spvtools
36 changes: 36 additions & 0 deletions source/opt/eliminate_dead_functions_util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_UTIL_H_
#define SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_UTIL_H_

#include "source/opt/ir_context.h"

namespace spvtools {
namespace opt {

// Provides functionality for eliminating functions that are not needed, for use
// by various analyses and passes.
namespace eliminatedeadfunctionsutil {

// Removes all of the function's instructions, removes the function from the
// module, and returns the next iterator.
Module::iterator EliminateFunction(IRContext* context,
Module::iterator* func_iter);

} // namespace eliminatedeadfunctionsutil
} // namespace opt
} // namespace spvtools

#endif // SOURCE_OPT_ELIMINATE_DEAD_FUNCTIONS_UTIL_H_
4 changes: 4 additions & 0 deletions source/reduce/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ set(SPIRV_TOOLS_REDUCE_SOURCES
reduction_pass.h
reduction_util.h
remove_instruction_reduction_opportunity.h
remove_function_reduction_opportunity.h
remove_function_reduction_opportunity_finder.h
remove_opname_instruction_reduction_opportunity_finder.h
remove_unreferenced_instruction_reduction_opportunity_finder.h
structured_loop_to_selection_reduction_opportunity.h
Expand All @@ -41,6 +43,8 @@ set(SPIRV_TOOLS_REDUCE_SOURCES
reduction_opportunity.cpp
reduction_pass.cpp
reduction_util.cpp
remove_function_reduction_opportunity.cpp
remove_function_reduction_opportunity_finder.cpp
remove_instruction_reduction_opportunity.cpp
remove_unreferenced_instruction_reduction_opportunity_finder.cpp
remove_opname_instruction_reduction_opportunity_finder.cpp
Expand Down
40 changes: 40 additions & 0 deletions source/reduce/remove_function_reduction_opportunity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "remove_function_reduction_opportunity.h"
#include "source/opt/eliminate_dead_functions_util.h"

namespace spvtools {
namespace reduce {

bool RemoveFunctionReductionOpportunity::PreconditionHolds() {
// Removing one function cannot influence whether another function can be
// removed.
return true;
}

void RemoveFunctionReductionOpportunity::Apply() {
for (opt::Module::iterator function_it = context_->module()->begin();
function_it != context_->module()->end(); ++function_it) {
if (&*function_it == function_) {
opt::eliminatedeadfunctionsutil::EliminateFunction(context_,
&function_it);
return;
}
}
assert(0 && "Function to be removed was not found.");
}

} // namespace reduce
} // namespace spvtools
49 changes: 49 additions & 0 deletions source/reduce/remove_function_reduction_opportunity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_H_
#define SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_H_

#include "reduction_opportunity.h"
#include "source/opt/function.h"

namespace spvtools {
namespace reduce {

// An opportunity to remove an unreferenced function.
class RemoveFunctionReductionOpportunity : public ReductionOpportunity {
public:
// Creates an opportunity to remove |function| from the module represented by
// |context|.
RemoveFunctionReductionOpportunity(opt::IRContext* context,
opt::Function* function)
: context_(context), function_(function) {}

bool PreconditionHolds() override;

protected:
void Apply() override;

private:
// The IR context for the module under analysis.
opt::IRContext* context_;

// The function that can be removed.
opt::Function* function_;
};

} // namespace reduce
} // namespace spvtools

#endif // SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_H_
42 changes: 42 additions & 0 deletions source/reduce/remove_function_reduction_opportunity_finder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "remove_function_reduction_opportunity_finder.h"
#include "remove_function_reduction_opportunity.h"

namespace spvtools {
namespace reduce {

std::vector<std::unique_ptr<ReductionOpportunity>>
RemoveFunctionReductionOpportunityFinder::GetAvailableOpportunities(
opt::IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
// Consider each function.
for (auto& function : *context->module()) {
if (context->get_def_use_mgr()->NumUses(function.result_id()) > 0) {
// If the function is referenced, ignore it.
continue;
}
result.push_back(
MakeUnique<RemoveFunctionReductionOpportunity>(context, &function));
}
return result;
}

std::string RemoveFunctionReductionOpportunityFinder::GetName() const {
return "RemoveFunctionReductionOpportunityFinder";
}

} // namespace reduce
} // namespace spvtools
42 changes: 42 additions & 0 deletions source/reduce/remove_function_reduction_opportunity_finder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_FINDER_H_
#define SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_FINDER_H_

#include "source/reduce/reduction_opportunity_finder.h"

namespace spvtools {
namespace reduce {

// A finder of opportunities to remove unreferenced functions.
class RemoveFunctionReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
RemoveFunctionReductionOpportunityFinder() = default;

~RemoveFunctionReductionOpportunityFinder() override = default;

std::string GetName() const final;

std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

private:
};

} // namespace reduce
} // namespace spvtools

#endif // SOURCE_REDUCE_REMOVE_FUNCTION_REDUCTION_OPPORTUNITY_FINDER_H_
1 change: 1 addition & 0 deletions test/reduce/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ add_spvtools_unittest(TARGET reduce
reduce_test_util.cpp
reduce_test_util.h
reducer_test.cpp
remove_function_test.cpp
remove_opname_instruction_test.cpp
remove_unreferenced_instruction_test.cpp
structured_loop_to_selection_test.cpp
Expand Down
Loading

0 comments on commit 34c5ac6

Please sign in to comment.