Skip to content

Commit 5f7bbe7

Browse files
Jmangless-perron
andauthored
Remove redundant iterations from inliner passes (#6639)
Implemented in both the exhaustive/opaque inliner even though it appears the opaque one is not fully functional. In my benchmark tests I found it reduced the time needed to run the exhaustive pass by 50% on average with the shaders I was testing with. Also fixes two bugs in the opaque inliner. One is from not updating the parent of each new block and the other for debug. These could be split into another PR if desired but it's still pretty small overall. --------- Co-authored-by: Steven Perron <[email protected]>
1 parent 3a49d67 commit 5f7bbe7

2 files changed

Lines changed: 23 additions & 4 deletions

File tree

source/opt/inline_exhaustive_pass.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "source/opt/inline_exhaustive_pass.h"
1818

19+
#include <iterator>
1920
#include <utility>
2021

2122
namespace spvtools {
@@ -27,6 +28,10 @@ Pass::Status InlineExhaustivePass::InlineExhaustive(Function* func) {
2728
for (auto bi = func->begin(); bi != func->end(); ++bi) {
2829
for (auto ii = bi->begin(); ii != bi->end();) {
2930
if (IsInlinableFunctionCall(&*ii)) {
31+
// Save instruction before the call to avoid redundant re-scanning.
32+
Instruction* prev_inst =
33+
(ii == bi->begin()) ? nullptr : &*std::prev(ii);
34+
3035
// Inline call.
3136
std::vector<std::unique_ptr<BasicBlock>> newBlocks;
3237
std::vector<std::unique_ptr<Instruction>> newVars;
@@ -47,8 +52,8 @@ Pass::Status InlineExhaustivePass::InlineExhaustive(Function* func) {
4752
// Insert new function variables.
4853
if (newVars.size() > 0)
4954
func->begin()->begin().InsertBefore(std::move(newVars));
50-
// Restart inlining at beginning of calling block.
51-
ii = bi->begin();
55+
// Restart inlining at the first instruction of the inlined code.
56+
ii = prev_inst ? ++InstructionList::iterator(prev_inst) : bi->begin();
5257
modified = true;
5358
} else {
5459
++ii;

source/opt/inline_opaque_pass.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "source/opt/inline_opaque_pass.h"
1818

19+
#include <iterator>
1920
#include <utility>
2021

2122
namespace spvtools {
@@ -67,6 +68,10 @@ Pass::Status InlineOpaquePass::InlineOpaque(Function* func) {
6768
for (auto bi = func->begin(); bi != func->end(); ++bi) {
6869
for (auto ii = bi->begin(); ii != bi->end();) {
6970
if (IsInlinableFunctionCall(&*ii) && HasOpaqueArgsOrReturn(&*ii)) {
71+
// Save instruction before the call to avoid redundant re-scanning.
72+
Instruction* prev_inst =
73+
(ii == bi->begin()) ? nullptr : &*std::prev(ii);
74+
7075
// Inline call.
7176
std::vector<std::unique_ptr<BasicBlock>> newBlocks;
7277
std::vector<std::unique_ptr<Instruction>> newVars;
@@ -79,18 +84,27 @@ Pass::Status InlineOpaquePass::InlineOpaque(Function* func) {
7984
if (newBlocks.size() > 1) UpdateSucceedingPhis(newBlocks);
8085
// Replace old calling block with new block(s).
8186
bi = bi.Erase();
87+
88+
for (auto& bb : newBlocks) {
89+
bb->SetParent(func);
90+
}
8291
bi = bi.InsertBefore(&newBlocks);
8392
// Insert new function variables.
8493
if (newVars.size() > 0)
8594
func->begin()->begin().InsertBefore(std::move(newVars));
86-
// Restart inlining at beginning of calling block.
87-
ii = bi->begin();
95+
// Restart inlining at the first instruction of the inlined code.
96+
ii = prev_inst ? ++InstructionList::iterator(prev_inst) : bi->begin();
8897
modified = true;
8998
} else {
9099
++ii;
91100
}
92101
}
93102
}
103+
104+
if (modified) {
105+
FixDebugDeclares(func);
106+
}
107+
94108
return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);
95109
}
96110

0 commit comments

Comments
 (0)