1 // Copyright (c) 2018 The Khronos Group Inc.
2 // Copyright (c) 2018 Valve Corporation
3 // Copyright (c) 2018 LunarG Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef SOURCE_OPT_PROPAGATE_LINES_PASS_H_
18 #define SOURCE_OPT_PROPAGATE_LINES_PASS_H_
19 
20 #include "source/opt/function.h"
21 #include "source/opt/ir_context.h"
22 #include "source/opt/pass.h"
23 
24 namespace spvtools {
25 namespace opt {
26 
27 namespace {
28 
29 // Constructor Parameters
30 static const int kLinesPropagateLines = 0;
31 static const int kLinesEliminateDeadLines = 1;
32 
33 }  // anonymous namespace
34 
35 // See optimizer.hpp for documentation.
36 class ProcessLinesPass : public Pass {
37   using LineProcessFunction =
38       std::function<bool(Instruction*, uint32_t*, uint32_t*, uint32_t*)>;
39 
40  public:
41   ProcessLinesPass(uint32_t func_id);
42   ~ProcessLinesPass() override = default;
43 
name()44   const char* name() const override { return "propagate-lines"; }
45 
46   // See optimizer.hpp for this pass' user documentation.
47   Status Process() override;
48 
GetPreservedAnalyses()49   IRContext::Analysis GetPreservedAnalyses() override {
50     return IRContext::kAnalysisDefUse |
51            IRContext::kAnalysisInstrToBlockMapping |
52            IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
53            IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis |
54            IRContext::kAnalysisNameMap;
55   }
56 
57  private:
58   // If |inst| has no debug line instruction, create one with
59   // |file_id, line, col|. If |inst| has debug line instructions, set
60   // |file_id, line, col| from the last. |file_id| equals 0 indicates no line
61   // info is available. Return true if |inst| modified.
62   bool PropagateLine(Instruction* inst, uint32_t* file_id, uint32_t* line,
63                      uint32_t* col);
64 
65   // If last debug line instruction of |inst| matches |file_id, line, col|,
66   // delete all debug line instructions of |inst|. If they do not match,
67   // replace all debug line instructions of |inst| with new line instruction
68   // set from |file_id, line, col|. If |inst| has no debug line instructions,
69   // do not modify |inst|. |file_id| equals 0 indicates no line info is
70   // available. Return true if |inst| modified.
71   bool EliminateDeadLines(Instruction* inst, uint32_t* file_id, uint32_t* line,
72                           uint32_t* col);
73 
74   // Apply lpfn() to all type, constant, global variable and function
75   // instructions in their physical order.
76   bool ProcessLines();
77 
78   // A function that calls either PropagateLine or EliminateDeadLines.
79   // Initialized by the class constructor.
80   LineProcessFunction line_process_func_;
81 };
82 
83 }  // namespace opt
84 }  // namespace spvtools
85 
86 #endif  // SOURCE_OPT_PROPAGATE_LINES_PASS_H_
87