use Pass::Run to set the context on each pass. (#1708)

Currently the IRContext is passed into the Pass::Process method. It is
then up to the individual pass to store the context into the context_
variable. This CL changes the Run method to store the context before
calling Process which no-longer receives the context as a parameter.
This commit is contained in:
dan sinclair 2018-07-12 09:08:45 -04:00 committed by GitHub
parent 4db9c789ff
commit f96b7f1cb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
103 changed files with 309 additions and 436 deletions

View File

@ -500,13 +500,6 @@ bool AggressiveDCEPass::AggressiveDCE(opt::Function* func) {
return modified;
}
void AggressiveDCEPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
// Initialize extensions whitelist
InitExtensions();
}
void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() {
// Keep all execution modes.
for (auto& exec : get_module()->execution_modes()) {
@ -706,10 +699,11 @@ bool AggressiveDCEPass::ProcessGlobalValues() {
return modified;
}
AggressiveDCEPass::AggressiveDCEPass() {}
AggressiveDCEPass::AggressiveDCEPass() = default;
Pass::Status AggressiveDCEPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status AggressiveDCEPass::Process() {
// Initialize extensions whitelist
InitExtensions();
return ProcessImpl();
}

View File

@ -43,7 +43,7 @@ class AggressiveDCEPass : public MemPass {
AggressiveDCEPass();
const char* name() const override { return "eliminate-dead-code-aggressive"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
@ -138,7 +138,6 @@ class AggressiveDCEPass : public MemPass {
// TODO(): Remove useless control constructs.
bool AggressiveDCE(opt::Function* func);
void Initialize(opt::IRContext* c);
Pass::Status ProcessImpl();
// True if current function has a call instruction contained in it

View File

@ -145,21 +145,14 @@ bool BlockMergePass::IsMerge(opt::BasicBlock* block) {
return IsMerge(block->id());
}
void BlockMergePass::Initialize(opt::IRContext* c) { InitializeProcessing(c); }
Pass::Status BlockMergePass::ProcessImpl() {
Pass::Status BlockMergePass::Process() {
// Process all entry point functions.
ProcessFunction pfn = [this](opt::Function* fp) { return MergeBlocks(fp); };
bool modified = ProcessEntryPointCallTree(pfn, get_module());
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
BlockMergePass::BlockMergePass() {}
Pass::Status BlockMergePass::Process(opt::IRContext* c) {
Initialize(c);
return ProcessImpl();
}
BlockMergePass::BlockMergePass() = default;
} // namespace opt
} // namespace spvtools

View File

@ -38,8 +38,9 @@ class BlockMergePass : public Pass {
public:
BlockMergePass();
const char* name() const override { return "merge-blocks"; }
Status Process(opt::IRContext*) override;
virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
opt::IRContext::kAnalysisInstrToBlockMapping |
opt::IRContext::kAnalysisDecorations |
@ -63,9 +64,6 @@ class BlockMergePass : public Pass {
// instruction.
bool IsMerge(opt::BasicBlock* block);
bool IsMerge(uint32_t id);
void Initialize(opt::IRContext* c);
Pass::Status ProcessImpl();
};
} // namespace opt

View File

@ -296,9 +296,7 @@ bool CCPPass::PropagateConstants(opt::Function* fp) {
return false;
}
void CCPPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
void CCPPass::Initialize() {
const_mgr_ = context()->get_constant_mgr();
// Populate the constant table with values from constant declarations in the
@ -315,8 +313,8 @@ void CCPPass::Initialize(opt::IRContext* c) {
}
}
Pass::Status CCPPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status CCPPass::Process() {
Initialize();
// Process all entry point functions.
ProcessFunction pfn = [this](opt::Function* fp) {

View File

@ -28,9 +28,11 @@ namespace opt {
class CCPPass : public MemPass {
public:
CCPPass() = default;
const char* name() const override { return "ccp"; }
Status Process(opt::IRContext* c) override;
virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
opt::IRContext::kAnalysisInstrToBlockMapping |
opt::IRContext::kAnalysisDecorations |
@ -41,7 +43,7 @@ class CCPPass : public MemPass {
private:
// Initializes the pass.
void Initialize(opt::IRContext* c);
void Initialize();
// Runs constant propagation on the given function |fp|. Returns true if any
// constants were propagated and the IR modified.

View File

@ -27,11 +27,7 @@
namespace spvtools {
namespace opt {
void CFGCleanupPass::Initialize(opt::IRContext* c) { InitializeProcessing(c); }
Pass::Status CFGCleanupPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status CFGCleanupPass::Process() {
// Process all entry point functions.
ProcessFunction pfn = [this](opt::Function* fp) { return CFGCleanup(fp); };
bool modified = ProcessReachableCallTree(pfn, context());

View File

@ -25,16 +25,13 @@ namespace opt {
class CFGCleanupPass : public MemPass {
public:
CFGCleanupPass() = default;
const char* name() const override { return "cfg-cleanup"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse;
}
private:
// Initialize the pass.
void Initialize(opt::IRContext* c);
};
} // namespace opt

View File

@ -489,9 +489,7 @@ bool CommonUniformElimPass::EliminateCommonUniform(opt::Function* func) {
return modified;
}
void CommonUniformElimPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
void CommonUniformElimPass::Initialize() {
// Clear collections.
comp2idx2inst_.clear();
@ -540,10 +538,10 @@ Pass::Status CommonUniformElimPass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
CommonUniformElimPass::CommonUniformElimPass() {}
CommonUniformElimPass::CommonUniformElimPass() = default;
Pass::Status CommonUniformElimPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status CommonUniformElimPass::Process() {
Initialize();
return ProcessImpl();
}

View File

@ -43,8 +43,9 @@ class CommonUniformElimPass : public Pass {
std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
CommonUniformElimPass();
const char* name() const override { return "eliminate-common-uniform"; }
Status Process(opt::IRContext*) override;
Status Process() override;
private:
// Returns true if |opcode| is a non-ptr access chain op
@ -184,7 +185,7 @@ class CommonUniformElimPass : public Pass {
return false;
}
void Initialize(opt::IRContext* c);
void Initialize();
Pass::Status ProcessImpl();
// Map from uniform variable id to its common load id

View File

@ -24,13 +24,11 @@ namespace opt {
using opt::Instruction;
using opt::Operand;
Pass::Status CompactIdsPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status CompactIdsPass::Process() {
bool modified = false;
std::unordered_map<uint32_t, uint32_t> result_id_mapping;
c->module()->ForEachInst(
context()->module()->ForEachInst(
[&result_id_mapping, &modified](Instruction* inst) {
auto operand = inst->begin();
while (operand != inst->end()) {
@ -64,7 +62,7 @@ Pass::Status CompactIdsPass::Process(opt::IRContext* c) {
true);
if (modified)
c->module()->SetIdBound(
context()->module()->SetIdBound(
static_cast<uint32_t>(result_id_mapping.size() + 1));
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;

View File

@ -26,7 +26,7 @@ namespace opt {
class CompactIdsPass : public Pass {
public:
const char* name() const override { return "compact-ids"; }
Status Process(opt::IRContext*) override;
Status Process() override;
// Return the mask of preserved Analyses.
opt::IRContext::Analysis GetPreservedAnalyses() override {

View File

@ -25,9 +25,7 @@ const uint32_t kCompositeExtractObjectInOperand = 0;
namespace spvtools {
namespace opt {
Pass::Status CopyPropagateArrays::Process(opt::IRContext* ctx) {
InitializeProcessing(ctx);
Pass::Status CopyPropagateArrays::Process() {
bool modified = false;
for (opt::Function& function : *get_module()) {
opt::BasicBlock* entry_bb = &*function.begin();

View File

@ -38,7 +38,7 @@ namespace opt {
class CopyPropagateArrays : public MemPass {
public:
const char* name() const override { return "copy-propagate-arrays"; }
Status Process(opt::IRContext*) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse | opt::IRContext::kAnalysisCFG |

View File

@ -371,11 +371,7 @@ bool DeadBranchElimPass::EliminateDeadBranches(opt::Function* func) {
return modified;
}
void DeadBranchElimPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
}
Pass::Status DeadBranchElimPass::ProcessImpl() {
Pass::Status DeadBranchElimPass::Process() {
// Do not process if module contains OpGroupDecorate. Additional
// support required in KillNamesAndDecorates().
// TODO(greg-lunarg): Add support for OpGroupDecorate
@ -389,12 +385,5 @@ Pass::Status DeadBranchElimPass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
DeadBranchElimPass::DeadBranchElimPass() {}
Pass::Status DeadBranchElimPass::Process(opt::IRContext* module) {
Initialize(module);
return ProcessImpl();
}
} // namespace opt
} // namespace spvtools

View File

@ -37,9 +37,10 @@ class DeadBranchElimPass : public MemPass {
using cbb_ptr = const opt::BasicBlock*;
public:
DeadBranchElimPass();
DeadBranchElimPass() = default;
const char* name() const override { return "eliminate-dead-branches"; }
Status Process(opt::IRContext* context) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
@ -128,9 +129,6 @@ class DeadBranchElimPass : public MemPass {
const std::unordered_set<opt::BasicBlock*>& unreachable_merges,
const std::unordered_map<opt::BasicBlock*, opt::BasicBlock*>&
unreachable_continues);
void Initialize(opt::IRContext* c);
Pass::Status ProcessImpl();
};
} // namespace opt

View File

@ -253,11 +253,7 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(opt::Function* func) {
return modified;
}
void DeadInsertElimPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
}
Pass::Status DeadInsertElimPass::ProcessImpl() {
Pass::Status DeadInsertElimPass::Process() {
// Process all entry point functions.
ProcessFunction pfn = [this](opt::Function* fp) {
return EliminateDeadInserts(fp);
@ -266,12 +262,5 @@ Pass::Status DeadInsertElimPass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
DeadInsertElimPass::DeadInsertElimPass() {}
Pass::Status DeadInsertElimPass::Process(opt::IRContext* c) {
Initialize(c);
return ProcessImpl();
}
} // namespace opt
} // namespace spvtools

View File

@ -35,10 +35,11 @@ namespace opt {
// See optimizer.hpp for documentation.
class DeadInsertElimPass : public MemPass {
public:
DeadInsertElimPass();
DeadInsertElimPass() = default;
const char* name() const override { return "eliminate-dead-inserts"; }
Status Process(opt::IRContext*) override;
virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
opt::IRContext::kAnalysisInstrToBlockMapping |
opt::IRContext::kAnalysisDecorations |
@ -75,9 +76,6 @@ class DeadInsertElimPass : public MemPass {
// Return true if all extensions in this module are allowed by this pass.
bool AllExtensionsSupported() const;
void Initialize(opt::IRContext* c);
Pass::Status ProcessImpl();
// Live inserts
std::unordered_set<uint32_t> liveInserts_;

View File

@ -22,14 +22,11 @@ namespace opt {
// This optimization removes global variables that are not needed because they
// are definitely not accessed.
Pass::Status DeadVariableElimination::Process(opt::IRContext* c) {
Pass::Status DeadVariableElimination::Process() {
// The algorithm will compute the reference count for every global variable.
// Anything with a reference count of 0 will then be deleted. For variables
// that might have references that are not explicit in this context, we use
// the
// value kMustKeep as the reference count.
InitializeProcessing(c);
// the value kMustKeep as the reference count.
std::vector<uint32_t> ids_to_remove;
// Get the reference count for all of the global OpVariable instructions.

View File

@ -27,7 +27,7 @@ namespace opt {
class DeadVariableElimination : public MemPass {
public:
const char* name() const override { return "dead-variable-elimination"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse;

View File

@ -26,17 +26,17 @@
namespace spvtools {
namespace opt {
Pass::Status EliminateDeadConstantPass::Process(opt::IRContext* irContext) {
Pass::Status EliminateDeadConstantPass::Process() {
std::unordered_set<opt::Instruction*> working_list;
// Traverse all the instructions to get the initial set of dead constants as
// working list and count number of real uses for constants. Uses in
// annotation instructions do not count.
std::unordered_map<opt::Instruction*, size_t> use_counts;
std::vector<opt::Instruction*> constants = irContext->GetConstants();
std::vector<opt::Instruction*> constants = context()->GetConstants();
for (auto* c : constants) {
uint32_t const_id = c->result_id();
size_t count = 0;
irContext->get_def_use_mgr()->ForEachUse(
context()->get_def_use_mgr()->ForEachUse(
const_id, [&count](opt::Instruction* user, uint32_t index) {
(void)index;
SpvOp op = user->opcode();
@ -69,7 +69,7 @@ Pass::Status EliminateDeadConstantPass::Process(opt::IRContext* irContext) {
}
uint32_t operand_id = inst->GetSingleWordInOperand(i);
opt::Instruction* def_inst =
irContext->get_def_use_mgr()->GetDef(operand_id);
context()->get_def_use_mgr()->GetDef(operand_id);
// If the use_count does not have any count for the def_inst,
// def_inst must not be a constant, and should be ignored here.
if (!use_counts.count(def_inst)) {
@ -93,7 +93,7 @@ Pass::Status EliminateDeadConstantPass::Process(opt::IRContext* irContext) {
// Turn all dead instructions and uses of them to nop
for (auto* dc : dead_consts) {
irContext->KillDef(dc->result_id());
context()->KillDef(dc->result_id());
}
return dead_consts.empty() ? Status::SuccessWithoutChange
: Status::SuccessWithChange;

View File

@ -26,7 +26,7 @@ namespace opt {
class EliminateDeadConstantPass : public Pass {
public:
const char* name() const override { return "eliminate-dead-const"; }
Status Process(opt::IRContext*) override;
Status Process() override;
};
} // namespace opt

View File

@ -20,9 +20,7 @@
namespace spvtools {
namespace opt {
Pass::Status EliminateDeadFunctionsPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status EliminateDeadFunctionsPass::Process() {
// Identify live functions first. Those that are not live
// are dead.
std::unordered_set<const opt::Function*> live_function_set;

View File

@ -27,7 +27,7 @@ namespace opt {
class EliminateDeadFunctionsPass : public MemPass {
public:
const char* name() const override { return "eliminate-dead-functions"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse;

View File

@ -29,9 +29,7 @@ using opt::Operand;
using Words = std::vector<uint32_t>;
using OrderedUsesMap = std::unordered_map<uint32_t, Words>;
Pass::Status FlattenDecorationPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status FlattenDecorationPass::Process() {
bool modified = false;
// The target Id of OpDecorationGroup instructions.

View File

@ -26,7 +26,7 @@ namespace opt {
class FlattenDecorationPass : public Pass {
public:
const char* name() const override { return "flatten-decoration"; }
Status Process(opt::IRContext*) override;
Status Process() override;
};
} // namespace opt

View File

@ -26,18 +26,7 @@
namespace spvtools {
namespace opt {
Pass::Status FoldSpecConstantOpAndCompositePass::Process(
opt::IRContext* irContext) {
Initialize(irContext);
return ProcessImpl(irContext);
}
void FoldSpecConstantOpAndCompositePass::Initialize(opt::IRContext* irContext) {
InitializeProcessing(irContext);
}
Pass::Status FoldSpecConstantOpAndCompositePass::ProcessImpl(
opt::IRContext* irContext) {
Pass::Status FoldSpecConstantOpAndCompositePass::Process() {
bool modified = false;
// Traverse through all the constant defining instructions. For Normal
// Constants whose values are determined and do not depend on OpUndef
@ -59,11 +48,11 @@ Pass::Status FoldSpecConstantOpAndCompositePass::ProcessImpl(
// the dependee Spec Constants, all its dependent constants must have been
// processed and all its dependent Spec Constants should have been folded if
// possible.
opt::Module::inst_iterator next_inst = irContext->types_values_begin();
opt::Module::inst_iterator next_inst = context()->types_values_begin();
for (opt::Module::inst_iterator inst_iter = next_inst;
// Need to re-evaluate the end iterator since we may modify the list of
// instructions in this section of the module as the process goes.
inst_iter != irContext->types_values_end(); inst_iter = next_inst) {
inst_iter != context()->types_values_end(); inst_iter = next_inst) {
++next_inst;
opt::Instruction* inst = &*inst_iter;
// Collect constant values of normal constants and process the

View File

@ -36,20 +36,13 @@ class FoldSpecConstantOpAndCompositePass : public Pass {
const char* name() const override { return "fold-spec-const-op-composite"; }
Status Process(opt::IRContext* irContext) override;
// Iterates through the types-constants-globals section of the given module,
// finds the Spec Constants defined with OpSpecConstantOp and
// OpSpecConstantComposite instructions. If the result value of those spec
// constants can be folded, fold them to their corresponding normal constants.
Status Process() override;
private:
// Initializes the type manager, def-use manager and get the maximal id used
// in the module.
void Initialize(opt::IRContext* irContext);
// The real entry of processing. Iterates through the types-constants-globals
// section of the given module, finds the Spec Constants defined with
// OpSpecConstantOp and OpSpecConstantComposite instructions. If the result
// value of those spec constants can be folded, fold them to their
// corresponding normal constants.
Status ProcessImpl(opt::IRContext* irContext);
// Processes the OpSpecConstantOp instruction pointed by the given
// instruction iterator, folds it to normal constants if possible. Returns
// true if the spec constant is folded to normal constants. New instructions

View File

@ -18,34 +18,34 @@
namespace spvtools {
namespace opt {
Pass::Status FreezeSpecConstantValuePass::Process(opt::IRContext* irContext) {
Pass::Status FreezeSpecConstantValuePass::Process() {
bool modified = false;
irContext->module()->ForEachInst(
[&modified, irContext](opt::Instruction* inst) {
switch (inst->opcode()) {
case SpvOp::SpvOpSpecConstant:
inst->SetOpcode(SpvOp::SpvOpConstant);
modified = true;
break;
case SpvOp::SpvOpSpecConstantTrue:
inst->SetOpcode(SpvOp::SpvOpConstantTrue);
modified = true;
break;
case SpvOp::SpvOpSpecConstantFalse:
inst->SetOpcode(SpvOp::SpvOpConstantFalse);
modified = true;
break;
case SpvOp::SpvOpDecorate:
if (inst->GetSingleWordInOperand(1) ==
SpvDecoration::SpvDecorationSpecId) {
irContext->KillInst(inst);
modified = true;
}
break;
default:
break;
auto ctx = context();
ctx->module()->ForEachInst([&modified, ctx](opt::Instruction* inst) {
switch (inst->opcode()) {
case SpvOp::SpvOpSpecConstant:
inst->SetOpcode(SpvOp::SpvOpConstant);
modified = true;
break;
case SpvOp::SpvOpSpecConstantTrue:
inst->SetOpcode(SpvOp::SpvOpConstantTrue);
modified = true;
break;
case SpvOp::SpvOpSpecConstantFalse:
inst->SetOpcode(SpvOp::SpvOpConstantFalse);
modified = true;
break;
case SpvOp::SpvOpDecorate:
if (inst->GetSingleWordInOperand(1) ==
SpvDecoration::SpvDecorationSpecId) {
ctx->KillInst(inst);
modified = true;
}
});
break;
default:
break;
}
});
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}

View File

@ -26,7 +26,7 @@ namespace opt {
class FreezeSpecConstantValuePass : public Pass {
public:
const char* name() const override { return "freeze-spec-const"; }
Status Process(opt::IRContext*) override;
Status Process() override;
};
} // namespace opt

View File

@ -19,9 +19,7 @@
namespace spvtools {
namespace opt {
Pass::Status IfConversion::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status IfConversion::Process() {
const ValueNumberTable& vn_table = *context()->GetValueNumberTable();
bool modified = false;
std::vector<opt::Instruction*> to_kill;

View File

@ -27,7 +27,7 @@ namespace opt {
class IfConversion : public Pass {
public:
const char* name() const override { return "if-conversion"; }
Status Process(opt::IRContext* context) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |

View File

@ -59,10 +59,6 @@ bool InlineExhaustivePass::InlineExhaustive(opt::Function* func) {
return modified;
}
void InlineExhaustivePass::Initialize(opt::IRContext* c) {
InitializeInline(c);
}
Pass::Status InlineExhaustivePass::ProcessImpl() {
// Attempt exhaustive inlining on each entry point function in module
ProcessFunction pfn = [this](opt::Function* fp) {
@ -72,10 +68,10 @@ Pass::Status InlineExhaustivePass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
InlineExhaustivePass::InlineExhaustivePass() {}
InlineExhaustivePass::InlineExhaustivePass() = default;
Pass::Status InlineExhaustivePass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status InlineExhaustivePass::Process() {
InitializeInline();
return ProcessImpl();
}

View File

@ -34,7 +34,7 @@ namespace opt {
class InlineExhaustivePass : public InlinePass {
public:
InlineExhaustivePass();
Status Process(opt::IRContext* c) override;
Status Process() override;
const char* name() const override { return "inline-entry-points-exhaustive"; }
@ -43,7 +43,7 @@ class InlineExhaustivePass : public InlinePass {
// all code that is inlined into func. Return true if func is modified.
bool InlineExhaustive(opt::Function* func);
void Initialize(opt::IRContext* c);
void Initialize();
Pass::Status ProcessImpl();
};

View File

@ -92,7 +92,7 @@ bool InlineOpaquePass::InlineOpaque(opt::Function* func) {
return modified;
}
void InlineOpaquePass::Initialize(opt::IRContext* c) { InitializeInline(c); }
void InlineOpaquePass::Initialize() { InitializeInline(); }
Pass::Status InlineOpaquePass::ProcessImpl() {
// Do opaque inlining on each function in entry point call tree
@ -101,10 +101,10 @@ Pass::Status InlineOpaquePass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
InlineOpaquePass::InlineOpaquePass() {}
InlineOpaquePass::InlineOpaquePass() = default;
Pass::Status InlineOpaquePass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status InlineOpaquePass::Process() {
Initialize();
return ProcessImpl();
}

View File

@ -34,7 +34,7 @@ namespace opt {
class InlineOpaquePass : public InlinePass {
public:
InlineOpaquePass();
Status Process(opt::IRContext* c) override;
Status Process() override;
const char* name() const override { return "inline-entry-points-opaque"; }
@ -50,7 +50,7 @@ class InlineOpaquePass : public InlinePass {
// if func is modified.
bool InlineOpaque(opt::Function* func);
void Initialize(opt::IRContext* c);
void Initialize();
Pass::Status ProcessImpl();
};

View File

@ -668,9 +668,7 @@ bool InlinePass::IsInlinableFunction(opt::Function* func) {
no_return_in_loop_.cend();
}
void InlinePass::InitializeInline(opt::IRContext* c) {
InitializeProcessing(c);
void InlinePass::InitializeInline() {
false_id_ = 0;
// clear collections

View File

@ -38,10 +38,10 @@ class InlinePass : public Pass {
using GetBlocksFunction =
std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
InlinePass();
virtual ~InlinePass() = default;
protected:
InlinePass();
// Add pointer to type to module and return resultId.
uint32_t AddPointerToType(uint32_t type_id, SpvStorageClass storage_class);
@ -157,7 +157,7 @@ class InlinePass : public Pass {
std::vector<std::unique_ptr<opt::BasicBlock>>& new_blocks);
// Initialize state for optimization of |module|
void InitializeInline(opt::IRContext* c);
void InitializeInline();
// Map from function's result id to function.
std::unordered_map<uint32_t, opt::Function*> id2function_;

View File

@ -22,15 +22,9 @@
namespace spvtools {
namespace opt {
Pass::Status LICMPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
bool modified = false;
if (c != nullptr) {
modified = ProcessIRContext();
}
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
Pass::Status LICMPass::Process() {
return ProcessIRContext() ? Status::SuccessWithChange
: Status::SuccessWithoutChange;
}
bool LICMPass::ProcessIRContext() {

View File

@ -30,7 +30,7 @@ class LICMPass : public Pass {
LICMPass() {}
const char* name() const override { return "loop-invariant-code-motion"; }
Status Process(opt::IRContext*) override;
Status Process() override;
private:
// Searches the IRContext for functions and processes each, moving invariants

View File

@ -245,9 +245,7 @@ bool LocalAccessChainConvertPass::ConvertLocalAccessChains(
return modified;
}
void LocalAccessChainConvertPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
void LocalAccessChainConvertPass::Initialize() {
// Initialize Target Variable Caches
seen_target_vars_.clear();
seen_non_target_vars_.clear();
@ -294,8 +292,8 @@ Pass::Status LocalAccessChainConvertPass::ProcessImpl() {
LocalAccessChainConvertPass::LocalAccessChainConvertPass() {}
Pass::Status LocalAccessChainConvertPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status LocalAccessChainConvertPass::Process() {
Initialize();
return ProcessImpl();
}

View File

@ -36,8 +36,9 @@ namespace opt {
class LocalAccessChainConvertPass : public MemPass {
public:
LocalAccessChainConvertPass();
const char* name() const override { return "convert-local-access-chains"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse;
@ -109,7 +110,7 @@ class LocalAccessChainConvertPass : public MemPass {
// Return true if all extensions in this module are allowed by this pass.
bool AllExtensionsSupported() const;
void Initialize(opt::IRContext* c);
void Initialize();
Pass::Status ProcessImpl();
// Variables with only supported references, ie. loads and stores using

View File

@ -19,9 +19,7 @@
namespace spvtools {
namespace opt {
Pass::Status LocalRedundancyEliminationPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status LocalRedundancyEliminationPass::Process() {
bool modified = false;
ValueNumberTable vnTable(context());

View File

@ -32,8 +32,9 @@ namespace opt {
class LocalRedundancyEliminationPass : public Pass {
public:
const char* name() const override { return "local-redundancy-elimination"; }
Status Process(opt::IRContext*) override;
virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
opt::IRContext::kAnalysisInstrToBlockMapping |
opt::IRContext::kAnalysisDecorations |

View File

@ -158,9 +158,7 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim(
return modified;
}
void LocalSingleBlockLoadStoreElimPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
void LocalSingleBlockLoadStoreElimPass::Initialize() {
// Initialize Target Type Caches
seen_target_vars_.clear();
seen_non_target_vars_.clear();
@ -204,10 +202,11 @@ Pass::Status LocalSingleBlockLoadStoreElimPass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElimPass() {}
LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElimPass() =
default;
Pass::Status LocalSingleBlockLoadStoreElimPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status LocalSingleBlockLoadStoreElimPass::Process() {
Initialize();
return ProcessImpl();
}

View File

@ -36,8 +36,9 @@ namespace opt {
class LocalSingleBlockLoadStoreElimPass : public MemPass {
public:
LocalSingleBlockLoadStoreElimPass();
const char* name() const override { return "eliminate-local-single-block"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
@ -66,7 +67,7 @@ class LocalSingleBlockLoadStoreElimPass : public MemPass {
// Return true if all extensions in this module are supported by this pass.
bool AllExtensionsSupported() const;
void Initialize(opt::IRContext* c);
void Initialize();
Pass::Status ProcessImpl();
// Map from function scope variable to a store of that variable in the

View File

@ -45,11 +45,6 @@ bool LocalSingleStoreElimPass::LocalSingleStoreElim(opt::Function* func) {
return modified;
}
void LocalSingleStoreElimPass::Initialize(opt::IRContext* irContext) {
InitializeProcessing(irContext);
InitExtensionWhiteList();
}
bool LocalSingleStoreElimPass::AllExtensionsSupported() const {
// If any extension not in whitelist, return false
for (auto& ei : get_module()->extensions()) {
@ -76,10 +71,10 @@ Pass::Status LocalSingleStoreElimPass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
LocalSingleStoreElimPass::LocalSingleStoreElimPass() {}
LocalSingleStoreElimPass::LocalSingleStoreElimPass() = default;
Pass::Status LocalSingleStoreElimPass::Process(opt::IRContext* irContext) {
Initialize(irContext);
Pass::Status LocalSingleStoreElimPass::Process() {
InitExtensionWhiteList();
return ProcessImpl();
}

View File

@ -38,8 +38,9 @@ class LocalSingleStoreElimPass : public Pass {
public:
LocalSingleStoreElimPass();
const char* name() const override { return "eliminate-local-single-store"; }
Status Process(opt::IRContext* irContext) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
@ -59,7 +60,6 @@ class LocalSingleStoreElimPass : public Pass {
// Return true if all extensions in this module are allowed by this pass.
bool AllExtensionsSupported() const;
void Initialize(opt::IRContext* irContext);
Pass::Status ProcessImpl();
// If there is a single store to |var_inst|, and it covers the entire

View File

@ -23,13 +23,6 @@
namespace spvtools {
namespace opt {
void LocalMultiStoreElimPass::Initialize(opt::IRContext* c) {
InitializeProcessing(c);
// Initialize extension whitelist
InitExtensions();
}
bool LocalMultiStoreElimPass::AllExtensionsSupported() const {
// If any extension not in whitelist, return false
for (auto& ei : get_module()->extensions()) {
@ -61,10 +54,11 @@ Pass::Status LocalMultiStoreElimPass::ProcessImpl() {
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
LocalMultiStoreElimPass::LocalMultiStoreElimPass() {}
LocalMultiStoreElimPass::LocalMultiStoreElimPass() = default;
Pass::Status LocalMultiStoreElimPass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status LocalMultiStoreElimPass::Process() {
// Initialize extension whitelist
InitExtensions();
return ProcessImpl();
}

View File

@ -41,8 +41,9 @@ class LocalMultiStoreElimPass : public MemPass {
std::function<std::vector<opt::BasicBlock*>*(const opt::BasicBlock*)>;
LocalMultiStoreElimPass();
const char* name() const override { return "eliminate-local-multi-store"; }
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
@ -56,7 +57,6 @@ class LocalMultiStoreElimPass : public MemPass {
// Return true if all extensions in this module are allowed by this pass.
bool AllExtensionsSupported() const;
void Initialize(opt::IRContext* c);
Pass::Status ProcessImpl();
// Extensions supported by this pass.

View File

@ -445,17 +445,17 @@ bool LoopFissionPass::ShouldSplitLoop(const opt::Loop& loop,
return split_criteria_(liveness);
}
Pass::Status LoopFissionPass::Process(opt::IRContext* c) {
Pass::Status LoopFissionPass::Process() {
bool changed = false;
for (opt::Function& f : *c->module()) {
for (opt::Function& f : *context()->module()) {
// We collect all the inner most loops in the function and run the loop
// splitting util on each. The reason we do this is to allow us to iterate
// over each, as creating new loops will invalidate the the loop iterator.
std::vector<opt::Loop*> inner_most_loops{};
opt::LoopDescriptor& loop_descriptor = *c->GetLoopDescriptor(&f);
opt::LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(&f);
for (opt::Loop& loop : loop_descriptor) {
if (!loop.HasChildren() && ShouldSplitLoop(loop, c)) {
if (!loop.HasChildren() && ShouldSplitLoop(loop, context())) {
inner_most_loops.push_back(&loop);
}
}
@ -465,7 +465,7 @@ Pass::Status LoopFissionPass::Process(opt::IRContext* c) {
while (!inner_most_loops.empty()) {
for (opt::Loop* loop : inner_most_loops) {
LoopFissionImpl impl{c, loop};
LoopFissionImpl impl{context(), loop};
// Group the instructions in the loop into two different sets of related
// instructions. If we can't group the instructions into the two sets
@ -477,16 +477,18 @@ Pass::Status LoopFissionPass::Process(opt::IRContext* c) {
if (impl.CanPerformSplit()) {
opt::Loop* second_loop = impl.SplitLoop();
changed = true;
c->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisLoopAnalysis);
context()->InvalidateAnalysesExceptFor(
opt::IRContext::kAnalysisLoopAnalysis);
// If the newly created loop meets the criteria to be split, split it
// again.
if (ShouldSplitLoop(*second_loop, c))
if (ShouldSplitLoop(*second_loop, context()))
new_loops_to_split.push_back(second_loop);
// If the original loop (now split) still meets the criteria to be
// split, split it again.
if (ShouldSplitLoop(*loop, c)) new_loops_to_split.push_back(loop);
if (ShouldSplitLoop(*loop, context()))
new_loops_to_split.push_back(loop);
}
}

View File

@ -57,7 +57,7 @@ class LoopFissionPass : public Pass {
const char* name() const override { return "Loop Fission"; }
Pass::Status Process(opt::IRContext* context) override;
Pass::Status Process() override;
// Checks if |loop| meets the register pressure criteria to be split.
bool ShouldSplitLoop(const opt::Loop& loop, opt::IRContext* context);

View File

@ -22,9 +22,9 @@
namespace spvtools {
namespace opt {
Pass::Status LoopFusionPass::Process(opt::IRContext* c) {
Pass::Status LoopFusionPass::Process() {
bool modified = false;
opt::Module* module = c->module();
opt::Module* module = context()->module();
// Process each function in the module
for (opt::Function& f : *module) {

View File

@ -34,7 +34,7 @@ class LoopFusionPass : public Pass {
// Processes the given |module|. Returns Status::Failure if errors occur when
// processing. Returns the corresponding Status::Success if processing is
// succesful to indicate whether changes have been made to the modue.
Status Process(opt::IRContext* c) override;
Status Process() override;
private:
// Fuse loops in |function| if compatible, legal and the fused loop won't use

View File

@ -572,11 +572,9 @@ void LoopPeeling::PeelAfter(uint32_t peel_factor) {
opt::IRContext::kAnalysisLoopAnalysis | opt::IRContext::kAnalysisCFG);
}
Pass::Status LoopPeelingPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status LoopPeelingPass::Process() {
bool modified = false;
opt::Module* module = c->module();
opt::Module* module = context()->module();
// Process each function in the module
for (opt::Function& f : *module) {

View File

@ -262,7 +262,7 @@ class LoopPeelingPass : public Pass {
// Processes the given |module|. Returns Status::Failure if errors occur when
// processing. Returns the corresponding Status::Success if processing is
// succesful to indicate whether changes have been made to the modue.
Pass::Status Process(opt::IRContext* context) override;
Pass::Status Process() override;
private:
// Describes the peeling direction.

View File

@ -1040,13 +1040,12 @@ void LoopUtils::Finalize() {
*
*/
Pass::Status LoopUnroller::Process(opt::IRContext* c) {
context_ = c;
Pass::Status LoopUnroller::Process() {
bool changed = false;
for (opt::Function& f : *c->module()) {
opt::LoopDescriptor* LD = context_->GetLoopDescriptor(&f);
for (opt::Function& f : *context()->module()) {
opt::LoopDescriptor* LD = context()->GetLoopDescriptor(&f);
for (opt::Loop& loop : *LD) {
LoopUtils loop_utils{c, &loop};
LoopUtils loop_utils{context(), &loop};
if (!loop.HasUnrollLoopControl() || !loop_utils.CanPerformUnroll()) {
continue;
}

View File

@ -27,10 +27,9 @@ class LoopUnroller : public Pass {
const char* name() const override { return "Loop unroller"; }
Status Process(opt::IRContext* context) override;
Status Process() override;
private:
opt::IRContext* context_;
bool fully_unroll_;
int unroll_factor_;
};

View File

@ -856,11 +856,9 @@ class LoopUnswitch {
} // namespace
Pass::Status LoopUnswitchPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status LoopUnswitchPass::Process() {
bool modified = false;
opt::Module* module = c->module();
opt::Module* module = context()->module();
// Process each function in the module
for (opt::Function& f : *module) {

View File

@ -31,7 +31,7 @@ class LoopUnswitchPass : public Pass {
// Processes the given |module|. Returns Status::Failure if errors occur when
// processing. Returns the corresponding Status::Success if processing is
// succesful to indicate whether changes have been made to the modue.
Pass::Status Process(opt::IRContext* context) override;
Pass::Status Process() override;
private:
bool ProcessFunction(opt::Function* f);

View File

@ -38,7 +38,6 @@ namespace opt {
// utility functions and supporting state.
class MemPass : public Pass {
public:
MemPass();
virtual ~MemPass() = default;
// Returns an undef value for the given |var_id|'s type.
@ -69,6 +68,8 @@ class MemPass : public Pass {
void CollectTargetVars(opt::Function* func);
protected:
MemPass();
// Returns true if |typeInst| is a scalar type
// or a vector or matrix
bool IsBaseTargetType(const opt::Instruction* typeInst) const;

View File

@ -23,9 +23,7 @@
namespace spvtools {
namespace opt {
Pass::Status MergeReturnPass::Process(opt::IRContext* irContext) {
InitializeProcessing(irContext);
Pass::Status MergeReturnPass::Process() {
bool modified = false;
bool is_shader =
context()->get_feature_mgr()->HasCapability(SpvCapabilityShader);

View File

@ -103,7 +103,7 @@ class MergeReturnPass : public MemPass {
final_return_block_(nullptr) {}
const char* name() const override { return "merge-return"; }
Status Process(opt::IRContext*) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
// return opt::IRContext::kAnalysisDefUse;

View File

@ -25,9 +25,7 @@ namespace opt {
class NullPass : public Pass {
public:
const char* name() const override { return "null"; }
Status Process(opt::IRContext*) override {
return Status::SuccessWithoutChange;
}
Status Process() override { return Status::SuccessWithoutChange; }
};
} // namespace opt

View File

@ -109,7 +109,10 @@ Pass::Status Pass::Run(opt::IRContext* ctx) {
}
already_run_ = true;
Pass::Status status = Process(ctx);
context_ = ctx;
Pass::Status status = Process();
context_ = nullptr;
if (status == Status::SuccessWithChange) {
ctx->InvalidateAnalysesExceptFor(GetPreservedAnalyses());
}

View File

@ -47,13 +47,6 @@ class Pass {
using ProcessFunction = std::function<bool(opt::Function*)>;
// Constructs a new pass.
//
// The constructed instance will have an empty message consumer, which just
// ignores all messages from the library. Use SetMessageConsumer() to supply
// one if messages are of concern.
Pass();
// Destructs the pass.
virtual ~Pass() = default;
@ -89,6 +82,9 @@ class Pass {
// Returns a pointer to the current module for this pass.
opt::Module* get_module() const { return context_->module(); }
// Sets the pointer to the current context for this pass.
void SetContextForTesting(IRContext* ctx) { context_ = ctx; }
// Returns a pointer to the current context for this pass.
opt::IRContext* context() const { return context_; }
@ -126,7 +122,7 @@ class Pass {
//
// It is an error if |Run| is called twice with the same instance of the pass.
// If this happens the return value will be |Failure|.
virtual Status Run(opt::IRContext* ctx) final;
Status Run(opt::IRContext* ctx);
// Returns the set of analyses that the pass is guaranteed to preserve.
virtual opt::IRContext::Analysis GetPreservedAnalyses() {
@ -137,14 +133,17 @@ class Pass {
uint32_t GetPointeeTypeId(const opt::Instruction* ptrInst) const;
protected:
// Initialize basic data structures for the pass. This sets up the def-use
// manager, module and other attributes.
virtual void InitializeProcessing(opt::IRContext* c) { context_ = c; }
// Constructs a new pass.
//
// The constructed instance will have an empty message consumer, which just
// ignores all messages from the library. Use SetMessageConsumer() to supply
// one if messages are of concern.
Pass();
// Processes the given |module|. Returns Status::Failure if errors occur when
// processing. Returns the corresponding Status::Success if processing is
// succesful to indicate whether changes are made to the module.
virtual Status Process(opt::IRContext* context) = 0;
virtual Status Process() = 0;
// Return the next available SSA id and increment it.
uint32_t TakeNextId() { return context_->TakeNextId(); }

View File

@ -24,8 +24,7 @@ const uint32_t kSpvTypePointerTypeIdInIdx = 1;
namespace spvtools {
namespace opt {
Pass::Status PrivateToLocalPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status PrivateToLocalPass::Process() {
bool modified = false;
// Private variables require the shader capability. If this is not a shader,

View File

@ -28,7 +28,8 @@ namespace opt {
class PrivateToLocalPass : public Pass {
public:
const char* name() const override { return "private-to-local"; }
Status Process(opt::IRContext*) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
opt::IRContext::kAnalysisInstrToBlockMapping |

View File

@ -29,8 +29,7 @@ const double kThreshold = 0.9;
namespace spvtools {
namespace opt {
Pass::Status ReduceLoadSize::Process(opt::IRContext* ctx) {
InitializeProcessing(ctx);
Pass::Status ReduceLoadSize::Process() {
bool modified = false;
for (auto& func : *get_module()) {

View File

@ -26,7 +26,7 @@ namespace opt {
class ReduceLoadSize : public Pass {
public:
const char* name() const override { return "reduce-load-size"; }
Status Process(opt::IRContext* irContext) override;
Status Process() override;
// Return the mask of preserved Analyses.
opt::IRContext::Analysis GetPreservedAnalyses() override {

View File

@ -19,9 +19,7 @@
namespace spvtools {
namespace opt {
Pass::Status RedundancyEliminationPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status RedundancyEliminationPass::Process() {
bool modified = false;
ValueNumberTable vnTable(context());

View File

@ -30,7 +30,7 @@ namespace opt {
class RedundancyEliminationPass : public LocalRedundancyEliminationPass {
public:
const char* name() const override { return "redundancy-elimination"; }
Status Process(opt::IRContext*) override;
Status Process() override;
protected:
// Removes for all total redundancies in the function starting at |bb|.

View File

@ -36,25 +36,24 @@ using opt::Operand;
using opt::analysis::DecorationManager;
using opt::analysis::DefUseManager;
Pass::Status RemoveDuplicatesPass::Process(opt::IRContext* ir_context) {
bool modified = RemoveDuplicateCapabilities(ir_context);
modified |= RemoveDuplicatesExtInstImports(ir_context);
modified |= RemoveDuplicateTypes(ir_context);
modified |= RemoveDuplicateDecorations(ir_context);
Pass::Status RemoveDuplicatesPass::Process() {
bool modified = RemoveDuplicateCapabilities();
modified |= RemoveDuplicatesExtInstImports();
modified |= RemoveDuplicateTypes();
modified |= RemoveDuplicateDecorations();
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
bool RemoveDuplicatesPass::RemoveDuplicateCapabilities(
opt::IRContext* ir_context) const {
bool RemoveDuplicatesPass::RemoveDuplicateCapabilities() const {
bool modified = false;
if (ir_context->capabilities().empty()) {
if (context()->capabilities().empty()) {
return modified;
}
std::unordered_set<uint32_t> capabilities;
for (auto* i = &*ir_context->capability_begin(); i;) {
for (auto* i = &*context()->capability_begin(); i;) {
auto res = capabilities.insert(i->GetSingleWordOperand(0u));
if (res.second) {
@ -62,7 +61,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateCapabilities(
i = i->NextNode();
} else {
// It's a duplicate, remove it.
i = ir_context->KillInst(i);
i = context()->KillInst(i);
modified = true;
}
}
@ -70,16 +69,15 @@ bool RemoveDuplicatesPass::RemoveDuplicateCapabilities(
return modified;
}
bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports(
opt::IRContext* ir_context) const {
bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports() const {
bool modified = false;
if (ir_context->ext_inst_imports().empty()) {
if (context()->ext_inst_imports().empty()) {
return modified;
}
std::unordered_map<std::string, SpvId> ext_inst_imports;
for (auto* i = &*ir_context->ext_inst_import_begin(); i;) {
for (auto* i = &*context()->ext_inst_import_begin(); i;) {
auto res = ext_inst_imports.emplace(
reinterpret_cast<const char*>(i->GetInOperand(0u).words.data()),
i->result_id());
@ -88,8 +86,8 @@ bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports(
i = i->NextNode();
} else {
// It's a duplicate, remove it.
ir_context->ReplaceAllUsesWith(i->result_id(), res.first->second);
i = ir_context->KillInst(i);
context()->ReplaceAllUsesWith(i->result_id(), res.first->second);
i = context()->KillInst(i);
modified = true;
}
}
@ -97,17 +95,16 @@ bool RemoveDuplicatesPass::RemoveDuplicatesExtInstImports(
return modified;
}
bool RemoveDuplicatesPass::RemoveDuplicateTypes(
opt::IRContext* ir_context) const {
bool RemoveDuplicatesPass::RemoveDuplicateTypes() const {
bool modified = false;
if (ir_context->types_values().empty()) {
if (context()->types_values().empty()) {
return modified;
}
std::vector<Instruction*> visited_types;
std::vector<Instruction*> to_delete;
for (auto* i = &*ir_context->types_values_begin(); i; i = i->NextNode()) {
for (auto* i = &*context()->types_values_begin(); i; i = i->NextNode()) {
// We only care about types.
if (!spvOpcodeGeneratesType((i->opcode())) &&
i->opcode() != SpvOpTypeForwardPointer) {
@ -119,7 +116,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes(
// TODO(dneto0): Use a trie to avoid quadratic behaviour? Extract the
// ResultIdTrie from unify_const_pass.cpp for this.
for (auto j : visited_types) {
if (AreTypesEqual(*i, *j, ir_context)) {
if (AreTypesEqual(*i, *j, context())) {
id_to_keep = j->result_id();
break;
}
@ -130,15 +127,15 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes(
visited_types.emplace_back(i);
} else {
// The same type has already been seen before, remove this one.
ir_context->KillNamesAndDecorates(i->result_id());
ir_context->ReplaceAllUsesWith(i->result_id(), id_to_keep);
context()->KillNamesAndDecorates(i->result_id());
context()->ReplaceAllUsesWith(i->result_id(), id_to_keep);
modified = true;
to_delete.emplace_back(i);
}
}
for (auto i : to_delete) {
ir_context->KillInst(i);
context()->KillInst(i);
}
return modified;
@ -153,14 +150,13 @@ bool RemoveDuplicatesPass::RemoveDuplicateTypes(
// OpGroupDecorate %1 %3
// OpGroupDecorate %2 %4
// group %2 could be removed.
bool RemoveDuplicatesPass::RemoveDuplicateDecorations(
opt::IRContext* ir_context) const {
bool RemoveDuplicatesPass::RemoveDuplicateDecorations() const {
bool modified = false;
std::vector<const Instruction*> visited_decorations;
opt::analysis::DecorationManager decoration_manager(ir_context->module());
for (auto* i = &*ir_context->annotation_begin(); i;) {
opt::analysis::DecorationManager decoration_manager(context()->module());
for (auto* i = &*context()->annotation_begin(); i;) {
// Is the current decoration equal to one of the decorations we have aready
// visited?
bool already_visited = false;
@ -180,7 +176,7 @@ bool RemoveDuplicatesPass::RemoveDuplicateDecorations(
} else {
// The same decoration has already been seen before, remove this one.
modified = true;
i = ir_context->KillInst(i);
i = context()->KillInst(i);
}
}

View File

@ -33,7 +33,8 @@ using IdDecorationsList =
class RemoveDuplicatesPass : public Pass {
public:
const char* name() const override { return "remove-duplicates"; }
Status Process(opt::IRContext*) override;
Status Process() override;
// TODO(pierremoreau): Move this function somewhere else (e.g. pass.h or
// within the type manager)
// Returns whether two types are equal, and have the same decorations.
@ -42,23 +43,22 @@ class RemoveDuplicatesPass : public Pass {
opt::IRContext* context);
private:
// Remove duplicate capabilities from the module attached to |ir_context|.
// Remove duplicate capabilities from the module
//
// Returns true if the module was modified, false otherwise.
bool RemoveDuplicateCapabilities(opt::IRContext* ir_context) const;
// Remove duplicate extended instruction imports from the module attached to
// |ir_context|.
bool RemoveDuplicateCapabilities() const;
// Remove duplicate extended instruction imports from the module
//
// Returns true if the module was modified, false otherwise.
bool RemoveDuplicatesExtInstImports(opt::IRContext* ir_context) const;
// Remove duplicate types from the module attached to |ir_context|.
bool RemoveDuplicatesExtInstImports() const;
// Remove duplicate types from the module
//
// Returns true if the module was modified, false otherwise.
bool RemoveDuplicateTypes(opt::IRContext* ir_context) const;
// Remove duplicate decorations from the module attached to |ir_context|.
bool RemoveDuplicateTypes() const;
// Remove duplicate decorations from the module
//
// Returns true if the module was modified, false otherwise.
bool RemoveDuplicateDecorations(opt::IRContext* ir_context) const;
bool RemoveDuplicateDecorations() const;
};
} // namespace opt

View File

@ -19,8 +19,7 @@
namespace spvtools {
namespace opt {
Pass::Status ReplaceInvalidOpcodePass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status ReplaceInvalidOpcodePass::Process() {
bool modified = false;
if (context()->get_feature_mgr()->HasCapability(SpvCapabilityLinkage)) {

View File

@ -27,7 +27,7 @@ namespace opt {
class ReplaceInvalidOpcodePass : public Pass {
public:
const char* name() const override { return "replace-invalid-opcodes"; }
Status Process(opt::IRContext*) override;
Status Process() override;
private:
// Returns the execution model that is used by every entry point in the

View File

@ -26,9 +26,7 @@
namespace spvtools {
namespace opt {
Pass::Status ScalarReplacementPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status ScalarReplacementPass::Process() {
Status status = Status::SuccessWithoutChange;
for (auto& f : *get_module()) {
Status functionStatus = ProcessFunction(&f);

View File

@ -43,7 +43,7 @@ class ScalarReplacementPass : public Pass {
// Attempts to scalarize all appropriate function scope variables. Returns
// SuccessWithChange if any change is made.
Status Process(opt::IRContext* c) override;
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |

View File

@ -190,10 +190,7 @@ opt::Instruction* GetSpecIdTargetFromDecorationGroup(
}
} // namespace
Pass::Status SetSpecConstantDefaultValuePass::Process(
opt::IRContext* irContext) {
InitializeProcessing(irContext);
Pass::Status SetSpecConstantDefaultValuePass::Process() {
// The operand index of decoration target in an OpDecorate instruction.
const uint32_t kTargetIdOperandIndex = 0;
// The operand index of the decoration literal in an OpDecorate instruction.
@ -216,7 +213,7 @@ Pass::Status SetSpecConstantDefaultValuePass::Process(
// is found for a spec id, the string will be parsed according to the target
// spec constant type. The parsed value will be used to replace the original
// default value of the target spec constant.
for (opt::Instruction& inst : irContext->annotations()) {
for (opt::Instruction& inst : context()->annotations()) {
// Only process 'OpDecorate SpecId' instructions
if (inst.opcode() != SpvOp::SpvOpDecorate) continue;
if (inst.NumOperands() != kOpDecorateSpecIdNumOperands) continue;

View File

@ -56,7 +56,7 @@ class SetSpecConstantDefaultValuePass : public Pass {
spec_id_to_value_bit_pattern_(std::move(default_values)) {}
const char* name() const override { return "set-spec-const-default-value"; }
Status Process(opt::IRContext*) override;
Status Process() override;
// Parses the given null-terminated C string to get a mapping from Spec Id to
// default value strings. Returns a unique pointer of the mapping from spec

View File

@ -23,8 +23,7 @@
namespace spvtools {
namespace opt {
Pass::Status SimplificationPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status SimplificationPass::Process() {
bool modified = false;
for (opt::Function& function : *get_module()) {

View File

@ -26,8 +26,9 @@ namespace opt {
class SimplificationPass : public Pass {
public:
const char* name() const override { return "simplify-instructions"; }
Status Process(opt::IRContext*) override;
virtual opt::IRContext::Analysis GetPreservedAnalyses() override {
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse |
opt::IRContext::kAnalysisInstrToBlockMapping |
opt::IRContext::kAnalysisDecorations |

View File

@ -565,11 +565,7 @@ bool SSARewriter::RewriteFunctionIntoSSA(opt::Function* fp) {
return modified;
}
void SSARewritePass::Initialize(opt::IRContext* c) { InitializeProcessing(c); }
Pass::Status SSARewritePass::Process(opt::IRContext* c) {
Initialize(c);
Pass::Status SSARewritePass::Process() {
bool modified = false;
for (auto& fn : *get_module()) {
modified |= SSARewriter(this).RewriteFunctionIntoSSA(&fn);

View File

@ -290,12 +290,9 @@ class SSARewriter {
class SSARewritePass : public MemPass {
public:
SSARewritePass() = default;
const char* name() const override { return "ssa-rewrite"; }
Status Process(opt::IRContext* c) override;
private:
// Initializes the pass.
void Initialize(opt::IRContext* c);
const char* name() const override { return "ssa-rewrite"; }
Status Process() override;
};
} // namespace opt

View File

@ -53,9 +53,7 @@ bool IsPowerOf2(uint32_t val) {
namespace spvtools {
namespace opt {
Pass::Status StrengthReductionPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status StrengthReductionPass::Process() {
// Initialize the member variables on a per module basis.
bool modified = false;
int32_type_id_ = 0;

View File

@ -27,7 +27,7 @@ namespace opt {
class StrengthReductionPass : public Pass {
public:
const char* name() const override { return "strength-reduction"; }
Status Process(opt::IRContext*) override;
Status Process() override;
private:
// Replaces multiple by power of 2 with an equivalent bit shift.

View File

@ -18,13 +18,13 @@
namespace spvtools {
namespace opt {
Pass::Status StripDebugInfoPass::Process(opt::IRContext* irContext) {
bool modified = !irContext->debugs1().empty() ||
!irContext->debugs2().empty() ||
!irContext->debugs3().empty();
irContext->debug_clear();
Pass::Status StripDebugInfoPass::Process() {
bool modified = !context()->debugs1().empty() ||
!context()->debugs2().empty() ||
!context()->debugs3().empty();
context()->debug_clear();
irContext->module()->ForEachInst([&modified](opt::Instruction* inst) {
context()->module()->ForEachInst([&modified](opt::Instruction* inst) {
modified |= !inst->dbg_line_insts().empty();
inst->dbg_line_insts().clear();
});

View File

@ -26,7 +26,7 @@ namespace opt {
class StripDebugInfoPass : public Pass {
public:
const char* name() const override { return "strip-debug"; }
Status Process(opt::IRContext* irContext) override;
Status Process() override;
};
} // namespace opt

View File

@ -24,13 +24,13 @@ namespace opt {
using opt::Instruction;
Pass::Status StripReflectInfoPass::Process(opt::IRContext* irContext) {
Pass::Status StripReflectInfoPass::Process() {
bool modified = false;
std::vector<Instruction*> to_remove;
bool other_uses_for_decorate_string = false;
for (auto& inst : irContext->module()->annotations()) {
for (auto& inst : context()->module()->annotations()) {
switch (inst.opcode()) {
case SpvOpDecorateStringGOOGLE:
if (inst.GetSingleWordInOperand(1) == SpvDecorationHlslSemanticGOOGLE) {
@ -52,7 +52,7 @@ Pass::Status StripReflectInfoPass::Process(opt::IRContext* irContext) {
}
}
for (auto& inst : irContext->module()->extensions()) {
for (auto& inst : context()->module()->extensions()) {
const char* ext_name =
reinterpret_cast<const char*>(&inst.GetInOperand(0).words[0]);
if (0 == std::strcmp(ext_name, "SPV_GOOGLE_hlsl_functionality1")) {
@ -65,7 +65,7 @@ Pass::Status StripReflectInfoPass::Process(opt::IRContext* irContext) {
for (auto* inst : to_remove) {
modified = true;
irContext->KillInst(inst);
context()->KillInst(inst);
}
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;

View File

@ -26,7 +26,7 @@ namespace opt {
class StripReflectInfoPass : public Pass {
public:
const char* name() const override { return "strip-reflect"; }
Status Process(opt::IRContext* irContext) override;
Status Process() override;
// Return the mask of preserved Analyses.
opt::IRContext::Analysis GetPreservedAnalyses() override {

View File

@ -103,8 +103,7 @@ class ResultIdTrie {
};
} // anonymous namespace
Pass::Status UnifyConstantPass::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status UnifyConstantPass::Process() {
bool modified = false;
ResultIdTrie defined_constants;

View File

@ -26,7 +26,7 @@ namespace opt {
class UnifyConstantPass : public Pass {
public:
const char* name() const override { return "unify-const"; }
Status Process(opt::IRContext*) override;
Status Process() override;
};
} // namespace opt

View File

@ -23,9 +23,7 @@ const uint32_t kInsertCompositeIdInIdx = 1;
namespace spvtools {
namespace opt {
Pass::Status VectorDCE::Process(opt::IRContext* ctx) {
InitializeProcessing(ctx);
Pass::Status VectorDCE::Process() {
bool modified = false;
for (opt::Function& function : *get_module()) {
modified |= VectorDCEFunction(&function);

View File

@ -37,15 +37,15 @@ class VectorDCE : public MemPass {
};
public:
const char* name() const override { return "vector-dce"; }
Status Process(opt::IRContext*) override;
VectorDCE() : all_components_live_(kMaxVectorSize) {
for (uint32_t i = 0; i < kMaxVectorSize; i++) {
all_components_live_.Set(i);
}
}
const char* name() const override { return "vector-dce"; }
Status Process() override;
opt::IRContext::Analysis GetPreservedAnalyses() override {
return opt::IRContext::kAnalysisDefUse | opt::IRContext::kAnalysisCFG |
opt::IRContext::kAnalysisInstrToBlockMapping |

View File

@ -20,8 +20,7 @@
namespace spvtools {
namespace opt {
Pass::Status Workaround1209::Process(opt::IRContext* c) {
InitializeProcessing(c);
Pass::Status Workaround1209::Process() {
bool modified = false;
modified = RemoveOpUnreachableInLoops();
return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange);

View File

@ -24,7 +24,7 @@ namespace opt {
class Workaround1209 : public Pass {
public:
const char* name() const override { return "workaround-1209"; }
Status Process(opt::IRContext*) override;
Status Process() override;
private:
// There is at least one driver where an OpUnreachable found in a loop is not

View File

@ -31,31 +31,40 @@ using ::testing::Each;
class DummyPassPreservesNothing : public Pass {
public:
DummyPassPreservesNothing(Status s) : Pass(), status_to_return_(s) {}
const char* name() const override { return "dummy-pass"; }
Status Process(IRContext*) override { return status_to_return_; }
Status Process() override { return status_to_return_; }
private:
Status status_to_return_;
};
class DummyPassPreservesAll : public Pass {
public:
DummyPassPreservesAll(Status s) : Pass(), status_to_return_(s) {}
const char* name() const override { return "dummy-pass"; }
Status Process(IRContext*) override { return status_to_return_; }
Status status_to_return_;
virtual Analysis GetPreservedAnalyses() override {
Status Process() override { return status_to_return_; }
Analysis GetPreservedAnalyses() override {
return Analysis(IRContext::kAnalysisEnd - 1);
}
private:
Status status_to_return_;
};
class DummyPassPreservesFirst : public Pass {
public:
DummyPassPreservesFirst(Status s) : Pass(), status_to_return_(s) {}
const char* name() const override { return "dummy-pass"; }
Status Process(IRContext*) override { return status_to_return_; }
Status Process() override { return status_to_return_; }
Analysis GetPreservedAnalyses() override { return IRContext::kAnalysisBegin; }
private:
Status status_to_return_;
virtual Analysis GetPreservedAnalyses() override {
return IRContext::kAnalysisBegin;
}
};
using IRContextTest = PassTest<::testing::Test>;

View File

@ -23,9 +23,9 @@ namespace {
class NopifyPass : public Pass {
public:
const char* name() const override { return "NopifyPass"; }
Status Process(IRContext* irContext) override {
Status Process() override {
bool modified = false;
irContext->module()->ForEachInst(
context()->module()->ForEachInst(
[&modified](Instruction* inst) {
inst->ToNop();
modified = true;

View File

@ -2922,8 +2922,9 @@ OpFunctionEnd
// Test that the loop descriptor is correctly maintained and updated by the
// pass.
LoopFissionPass loop_fission{};
loop_fission.Process(context.get());
LoopFissionPass loop_fission;
loop_fission.SetContextForTesting(context.get());
loop_fission.Process();
function = spvtest::GetFunction(module, 2);
LoopDescriptor& post_pass_descriptor = *context->GetLoopDescriptor(function);
@ -3179,8 +3180,9 @@ OpFunctionEnd
// Test that the loop descriptor is correctly maintained and updated by the
// pass.
LoopFissionPass loop_fission{};
loop_fission.Process(context.get());
LoopFissionPass loop_fission;
loop_fission.SetContextForTesting(context.get());
loop_fission.Process();
function = spvtest::GetFunction(module, 2);
LoopDescriptor& post_pass_descriptor = *context->GetLoopDescriptor(function);

View File

@ -39,12 +39,12 @@ class PartialUnrollerTestPass : public Pass {
const char* name() const override { return "Loop unroller"; }
Status Process(IRContext* context) override {
Status Process() override {
bool changed = false;
for (Function& f : *context->module()) {
LoopDescriptor& loop_descriptor = *context->GetLoopDescriptor(&f);
for (Function& f : *context()->module()) {
LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(&f);
for (auto& loop : loop_descriptor) {
LoopUtils loop_utils{context, &loop};
LoopUtils loop_utils{context(), &loop};
if (loop_utils.PartiallyUnroll(factor)) {
changed = true;
}

Some files were not shown because too many files have changed in this diff Show More