• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SOURCE_OPT_IR_CONTEXT_H_
16 #define SOURCE_OPT_IR_CONTEXT_H_
17 
18 #include <algorithm>
19 #include <iostream>
20 #include <limits>
21 #include <map>
22 #include <memory>
23 #include <queue>
24 #include <unordered_map>
25 #include <unordered_set>
26 #include <utility>
27 #include <vector>
28 
29 #include "source/assembly_grammar.h"
30 #include "source/enum_string_mapping.h"
31 #include "source/opt/cfg.h"
32 #include "source/opt/constants.h"
33 #include "source/opt/debug_info_manager.h"
34 #include "source/opt/decoration_manager.h"
35 #include "source/opt/def_use_manager.h"
36 #include "source/opt/dominator_analysis.h"
37 #include "source/opt/feature_manager.h"
38 #include "source/opt/fold.h"
39 #include "source/opt/liveness.h"
40 #include "source/opt/loop_descriptor.h"
41 #include "source/opt/module.h"
42 #include "source/opt/register_pressure.h"
43 #include "source/opt/scalar_analysis.h"
44 #include "source/opt/struct_cfg_analysis.h"
45 #include "source/opt/type_manager.h"
46 #include "source/opt/value_number_table.h"
47 #include "source/util/make_unique.h"
48 #include "source/util/string_utils.h"
49 
50 namespace spvtools {
51 namespace opt {
52 
53 class IRContext {
54  public:
55   // Available analyses.
56   //
57   // When adding a new analysis:
58   //
59   // 1. Enum values should be powers of 2. These are cast into uint32_t
60   //    bitmasks, so we can have at most 31 analyses represented.
61   //
62   // 2. Make sure it gets invalidated or preserved by IRContext methods that add
63   //    or remove IR elements (e.g., KillDef, KillInst, ReplaceAllUsesWith).
64   //
65   // 3. Add handling code in BuildInvalidAnalyses and InvalidateAnalyses
66   enum Analysis {
67     kAnalysisNone = 0 << 0,
68     kAnalysisBegin = 1 << 0,
69     kAnalysisDefUse = kAnalysisBegin,
70     kAnalysisInstrToBlockMapping = 1 << 1,
71     kAnalysisDecorations = 1 << 2,
72     kAnalysisCombinators = 1 << 3,
73     kAnalysisCFG = 1 << 4,
74     kAnalysisDominatorAnalysis = 1 << 5,
75     kAnalysisLoopAnalysis = 1 << 6,
76     kAnalysisNameMap = 1 << 7,
77     kAnalysisScalarEvolution = 1 << 8,
78     kAnalysisRegisterPressure = 1 << 9,
79     kAnalysisValueNumberTable = 1 << 10,
80     kAnalysisStructuredCFG = 1 << 11,
81     kAnalysisBuiltinVarId = 1 << 12,
82     kAnalysisIdToFuncMapping = 1 << 13,
83     kAnalysisConstants = 1 << 14,
84     kAnalysisTypes = 1 << 15,
85     kAnalysisDebugInfo = 1 << 16,
86     kAnalysisLiveness = 1 << 17,
87     kAnalysisEnd = 1 << 17
88   };
89 
90   using ProcessFunction = std::function<bool(Function*)>;
91 
92   friend inline Analysis operator|(Analysis lhs, Analysis rhs);
93   friend inline Analysis& operator|=(Analysis& lhs, Analysis rhs);
94   friend inline Analysis operator<<(Analysis a, int shift);
95   friend inline Analysis& operator<<=(Analysis& a, int shift);
96 
97   // Creates an |IRContext| that contains an owned |Module|
IRContext(spv_target_env env,MessageConsumer c)98   IRContext(spv_target_env env, MessageConsumer c)
99       : syntax_context_(spvContextCreate(env)),
100         grammar_(syntax_context_),
101         unique_id_(0),
102         module_(new Module()),
103         consumer_(std::move(c)),
104         def_use_mgr_(nullptr),
105         feature_mgr_(nullptr),
106         valid_analyses_(kAnalysisNone),
107         constant_mgr_(nullptr),
108         type_mgr_(nullptr),
109         id_to_name_(nullptr),
110         max_id_bound_(kDefaultMaxIdBound),
111         preserve_bindings_(false),
112         preserve_spec_constants_(false) {
113     SetContextMessageConsumer(syntax_context_, consumer_);
114     module_->SetContext(this);
115   }
116 
IRContext(spv_target_env env,std::unique_ptr<Module> && m,MessageConsumer c)117   IRContext(spv_target_env env, std::unique_ptr<Module>&& m, MessageConsumer c)
118       : syntax_context_(spvContextCreate(env)),
119         grammar_(syntax_context_),
120         unique_id_(0),
121         module_(std::move(m)),
122         consumer_(std::move(c)),
123         def_use_mgr_(nullptr),
124         feature_mgr_(nullptr),
125         valid_analyses_(kAnalysisNone),
126         type_mgr_(nullptr),
127         id_to_name_(nullptr),
128         max_id_bound_(kDefaultMaxIdBound),
129         preserve_bindings_(false),
130         preserve_spec_constants_(false) {
131     SetContextMessageConsumer(syntax_context_, consumer_);
132     module_->SetContext(this);
133     InitializeCombinators();
134   }
135 
~IRContext()136   ~IRContext() { spvContextDestroy(syntax_context_); }
137 
module()138   Module* module() const { return module_.get(); }
139 
140   // Returns a vector of pointers to constant-creation instructions in this
141   // context.
142   inline std::vector<Instruction*> GetConstants();
143   inline std::vector<const Instruction*> GetConstants() const;
144 
145   // Iterators for annotation instructions contained in this context.
146   inline Module::inst_iterator annotation_begin();
147   inline Module::inst_iterator annotation_end();
148   inline IteratorRange<Module::inst_iterator> annotations();
149   inline IteratorRange<Module::const_inst_iterator> annotations() const;
150 
151   // Iterators for capabilities instructions contained in this module.
152   inline Module::inst_iterator capability_begin();
153   inline Module::inst_iterator capability_end();
154   inline IteratorRange<Module::inst_iterator> capabilities();
155   inline IteratorRange<Module::const_inst_iterator> capabilities() const;
156 
157   // Iterators for extensions instructions contained in this module.
158   inline Module::inst_iterator extension_begin();
159   inline Module::inst_iterator extension_end();
160   inline IteratorRange<Module::inst_iterator> extensions();
161   inline IteratorRange<Module::const_inst_iterator> extensions() const;
162 
163   // Iterators for types, constants and global variables instructions.
164   inline Module::inst_iterator types_values_begin();
165   inline Module::inst_iterator types_values_end();
166   inline IteratorRange<Module::inst_iterator> types_values();
167   inline IteratorRange<Module::const_inst_iterator> types_values() const;
168 
169   // Iterators for ext_inst import instructions contained in this module.
170   inline Module::inst_iterator ext_inst_import_begin();
171   inline Module::inst_iterator ext_inst_import_end();
172   inline IteratorRange<Module::inst_iterator> ext_inst_imports();
173   inline IteratorRange<Module::const_inst_iterator> ext_inst_imports() const;
174 
175   // There are several kinds of debug instructions, according to where they can
176   // appear in the logical layout of a module:
177   //  - Section 7a:  OpString, OpSourceExtension, OpSource, OpSourceContinued
178   //  - Section 7b:  OpName, OpMemberName
179   //  - Section 7c:  OpModuleProcessed
180   //  - Mostly anywhere: OpLine and OpNoLine
181   //
182 
183   // Iterators for debug 1 instructions (excluding OpLine & OpNoLine) contained
184   // in this module.  These are for layout section 7a.
185   inline Module::inst_iterator debug1_begin();
186   inline Module::inst_iterator debug1_end();
187   inline IteratorRange<Module::inst_iterator> debugs1();
188   inline IteratorRange<Module::const_inst_iterator> debugs1() const;
189 
190   // Iterators for debug 2 instructions (excluding OpLine & OpNoLine) contained
191   // in this module.  These are for layout section 7b.
192   inline Module::inst_iterator debug2_begin();
193   inline Module::inst_iterator debug2_end();
194   inline IteratorRange<Module::inst_iterator> debugs2();
195   inline IteratorRange<Module::const_inst_iterator> debugs2() const;
196 
197   // Iterators for debug 3 instructions (excluding OpLine & OpNoLine) contained
198   // in this module.  These are for layout section 7c.
199   inline Module::inst_iterator debug3_begin();
200   inline Module::inst_iterator debug3_end();
201   inline IteratorRange<Module::inst_iterator> debugs3();
202   inline IteratorRange<Module::const_inst_iterator> debugs3() const;
203 
204   // Iterators for debug info instructions (excluding OpLine & OpNoLine)
205   // contained in this module.  These are OpExtInst for DebugInfo extension
206   // placed between section 9 and 10.
207   inline Module::inst_iterator ext_inst_debuginfo_begin();
208   inline Module::inst_iterator ext_inst_debuginfo_end();
209   inline IteratorRange<Module::inst_iterator> ext_inst_debuginfo();
210   inline IteratorRange<Module::const_inst_iterator> ext_inst_debuginfo() const;
211 
212   // Add |capability| to the module, if it is not already enabled.
213   inline void AddCapability(spv::Capability capability);
214   // Appends a capability instruction to this module.
215   inline void AddCapability(std::unique_ptr<Instruction>&& c);
216   // Removes instruction declaring `capability` from this module.
217   // Returns true if the capability was removed, false otherwise.
218   bool RemoveCapability(spv::Capability capability);
219 
220   // Appends an extension instruction to this module.
221   inline void AddExtension(const std::string& ext_name);
222   inline void AddExtension(std::unique_ptr<Instruction>&& e);
223   // Removes instruction declaring `extension` from this module.
224   // Returns true if the extension was removed, false otherwise.
225   bool RemoveExtension(Extension extension);
226 
227   // Appends an extended instruction set instruction to this module.
228   inline void AddExtInstImport(const std::string& name);
229   inline void AddExtInstImport(std::unique_ptr<Instruction>&& e);
230   // Set the memory model for this module.
231   inline void SetMemoryModel(std::unique_ptr<Instruction>&& m);
232   // Appends an entry point instruction to this module.
233   inline void AddEntryPoint(std::unique_ptr<Instruction>&& e);
234   // Appends an execution mode instruction to this module.
235   inline void AddExecutionMode(std::unique_ptr<Instruction>&& e);
236   // Appends a debug 1 instruction (excluding OpLine & OpNoLine) to this module.
237   // "debug 1" instructions are the ones in layout section 7.a), see section
238   // 2.4 Logical Layout of a Module from the SPIR-V specification.
239   inline void AddDebug1Inst(std::unique_ptr<Instruction>&& d);
240   // Appends a debug 2 instruction (excluding OpLine & OpNoLine) to this module.
241   // "debug 2" instructions are the ones in layout section 7.b), see section
242   // 2.4 Logical Layout of a Module from the SPIR-V specification.
243   inline void AddDebug2Inst(std::unique_ptr<Instruction>&& d);
244   // Appends a debug 3 instruction (OpModuleProcessed) to this module.
245   // This is due to decision by the SPIR Working Group, pending publication.
246   inline void AddDebug3Inst(std::unique_ptr<Instruction>&& d);
247   // Appends a OpExtInst for DebugInfo to this module.
248   inline void AddExtInstDebugInfo(std::unique_ptr<Instruction>&& d);
249   // Appends an annotation instruction to this module.
250   inline void AddAnnotationInst(std::unique_ptr<Instruction>&& a);
251   // Appends a type-declaration instruction to this module.
252   inline void AddType(std::unique_ptr<Instruction>&& t);
253   // Appends a constant, global variable, or OpUndef instruction to this module.
254   inline void AddGlobalValue(std::unique_ptr<Instruction>&& v);
255   // Prepends a function declaration to this module.
256   inline void AddFunctionDeclaration(std::unique_ptr<Function>&& f);
257   // Appends a function to this module.
258   inline void AddFunction(std::unique_ptr<Function>&& f);
259 
260   // Returns a pointer to a def-use manager.  If the def-use manager is
261   // invalid, it is rebuilt first.
get_def_use_mgr()262   analysis::DefUseManager* get_def_use_mgr() {
263     if (!AreAnalysesValid(kAnalysisDefUse)) {
264       BuildDefUseManager();
265     }
266     return def_use_mgr_.get();
267   }
268 
269   // Returns a pointer to a liveness manager.  If the liveness manager is
270   // invalid, it is rebuilt first.
get_liveness_mgr()271   analysis::LivenessManager* get_liveness_mgr() {
272     if (!AreAnalysesValid(kAnalysisLiveness)) {
273       BuildLivenessManager();
274     }
275     return liveness_mgr_.get();
276   }
277 
278   // Returns a pointer to a value number table.  If the liveness analysis is
279   // invalid, it is rebuilt first.
GetValueNumberTable()280   ValueNumberTable* GetValueNumberTable() {
281     if (!AreAnalysesValid(kAnalysisValueNumberTable)) {
282       BuildValueNumberTable();
283     }
284     return vn_table_.get();
285   }
286 
287   // Returns a pointer to a StructuredCFGAnalysis.  If the analysis is invalid,
288   // it is rebuilt first.
GetStructuredCFGAnalysis()289   StructuredCFGAnalysis* GetStructuredCFGAnalysis() {
290     if (!AreAnalysesValid(kAnalysisStructuredCFG)) {
291       BuildStructuredCFGAnalysis();
292     }
293     return struct_cfg_analysis_.get();
294   }
295 
296   // Returns a pointer to a liveness analysis.  If the liveness analysis is
297   // invalid, it is rebuilt first.
GetLivenessAnalysis()298   LivenessAnalysis* GetLivenessAnalysis() {
299     if (!AreAnalysesValid(kAnalysisRegisterPressure)) {
300       BuildRegPressureAnalysis();
301     }
302     return reg_pressure_.get();
303   }
304 
305   // Returns the basic block for instruction |instr|. Re-builds the instruction
306   // block map, if needed.
get_instr_block(Instruction * instr)307   BasicBlock* get_instr_block(Instruction* instr) {
308     if (!AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
309       BuildInstrToBlockMapping();
310     }
311     auto entry = instr_to_block_.find(instr);
312     return (entry != instr_to_block_.end()) ? entry->second : nullptr;
313   }
314 
315   // Returns the basic block for |id|. Re-builds the instruction block map, if
316   // needed.
317   //
318   // |id| must be a registered definition.
get_instr_block(uint32_t id)319   BasicBlock* get_instr_block(uint32_t id) {
320     Instruction* def = get_def_use_mgr()->GetDef(id);
321     return get_instr_block(def);
322   }
323 
324   // Sets the basic block for |inst|. Re-builds the mapping if it has become
325   // invalid.
set_instr_block(Instruction * inst,BasicBlock * block)326   void set_instr_block(Instruction* inst, BasicBlock* block) {
327     if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
328       instr_to_block_[inst] = block;
329     }
330   }
331 
332   // Returns a pointer the decoration manager.  If the decoration manager is
333   // invalid, it is rebuilt first.
get_decoration_mgr()334   analysis::DecorationManager* get_decoration_mgr() {
335     if (!AreAnalysesValid(kAnalysisDecorations)) {
336       BuildDecorationManager();
337     }
338     return decoration_mgr_.get();
339   }
340 
341   // Returns a pointer to the constant manager.  If no constant manager has been
342   // created yet, it creates one.  NOTE: Once created, the constant manager
343   // remains active and it is never re-built.
get_constant_mgr()344   analysis::ConstantManager* get_constant_mgr() {
345     if (!AreAnalysesValid(kAnalysisConstants)) {
346       BuildConstantManager();
347     }
348     return constant_mgr_.get();
349   }
350 
351   // Returns a pointer to the type manager.  If no type manager has been created
352   // yet, it creates one. NOTE: Once created, the type manager remains active it
353   // is never re-built.
get_type_mgr()354   analysis::TypeManager* get_type_mgr() {
355     if (!AreAnalysesValid(kAnalysisTypes)) {
356       BuildTypeManager();
357     }
358     return type_mgr_.get();
359   }
360 
361   // Returns a pointer to the debug information manager.  If no debug
362   // information manager has been created yet, it creates one.
363   // NOTE: Once created, the debug information manager remains active
364   // it is never re-built.
get_debug_info_mgr()365   analysis::DebugInfoManager* get_debug_info_mgr() {
366     if (!AreAnalysesValid(kAnalysisDebugInfo)) {
367       BuildDebugInfoManager();
368     }
369     return debug_info_mgr_.get();
370   }
371 
372   // Returns a pointer to the scalar evolution analysis. If it is invalid it
373   // will be rebuilt first.
GetScalarEvolutionAnalysis()374   ScalarEvolutionAnalysis* GetScalarEvolutionAnalysis() {
375     if (!AreAnalysesValid(kAnalysisScalarEvolution)) {
376       BuildScalarEvolutionAnalysis();
377     }
378     return scalar_evolution_analysis_.get();
379   }
380 
381   // Build the map from the ids to the OpName and OpMemberName instruction
382   // associated with it.
383   inline void BuildIdToNameMap();
384 
385   // Returns a range of instrucions that contain all of the OpName and
386   // OpMemberNames associated with the given id.
387   inline IteratorRange<std::multimap<uint32_t, Instruction*>::iterator>
388   GetNames(uint32_t id);
389 
390   // Returns an OpMemberName instruction that targets |struct_type_id| at
391   // index |index|. Returns nullptr if no such instruction exists.
392   // While the SPIR-V spec does not prohibit having multiple OpMemberName
393   // instructions for the same structure member, it is hard to imagine a member
394   // having more than one name. This method returns the first one it finds.
395   inline Instruction* GetMemberName(uint32_t struct_type_id, uint32_t index);
396 
397   // Copy names from |old_id| to |new_id|. Only copy member name if index is
398   // less than |max_member_index|.
399   inline void CloneNames(const uint32_t old_id, const uint32_t new_id,
400                          const uint32_t max_member_index = UINT32_MAX);
401 
402   // Sets the message consumer to the given |consumer|. |consumer| which will be
403   // invoked every time there is a message to be communicated to the outside.
SetMessageConsumer(MessageConsumer c)404   void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); }
405 
406   // Returns the reference to the message consumer for this pass.
consumer()407   const MessageConsumer& consumer() const { return consumer_; }
408 
409   // Rebuilds the analyses in |set| that are invalid.
410   void BuildInvalidAnalyses(Analysis set);
411 
412   // Invalidates all of the analyses except for those in |preserved_analyses|.
413   void InvalidateAnalysesExceptFor(Analysis preserved_analyses);
414 
415   // Invalidates the analyses marked in |analyses_to_invalidate|.
416   void InvalidateAnalyses(Analysis analyses_to_invalidate);
417 
418   // Deletes the instruction defining the given |id|. Returns true on
419   // success, false if the given |id| is not defined at all. This method also
420   // erases the name, decorations, and definition of |id|.
421   //
422   // Pointers and iterators pointing to the deleted instructions become invalid.
423   // However other pointers and iterators are still valid.
424   bool KillDef(uint32_t id);
425 
426   // Deletes the given instruction |inst|. This method erases the
427   // information of the given instruction's uses of its operands. If |inst|
428   // defines a result id, its name and decorations will also be deleted.
429   //
430   // Pointer and iterator pointing to the deleted instructions become invalid.
431   // However other pointers and iterators are still valid.
432   //
433   // Note that if an instruction is not in an instruction list, the memory may
434   // not be safe to delete, so the instruction is turned into a OpNop instead.
435   // This can happen with OpLabel.
436   //
437   // Returns a pointer to the instruction after |inst| or |nullptr| if no such
438   // instruction exists.
439   Instruction* KillInst(Instruction* inst);
440 
441   // Deletes all the instruction in the range [`begin`; `end`[, for which the
442   // unary predicate `condition` returned true.
443   // Returns true if at least one instruction was removed, false otherwise.
444   //
445   // Pointer and iterator pointing to the deleted instructions become invalid.
446   // However other pointers and iterators are still valid.
447   bool KillInstructionIf(Module::inst_iterator begin, Module::inst_iterator end,
448                          std::function<bool(Instruction*)> condition);
449 
450   // Collects the non-semantic instruction tree that uses |inst|'s result id
451   // to be killed later.
452   void CollectNonSemanticTree(Instruction* inst,
453                               std::unordered_set<Instruction*>* to_kill);
454 
455   // Collect function reachable from |entryId|, returns |funcs|
456   void CollectCallTreeFromRoots(unsigned entryId,
457                                 std::unordered_set<uint32_t>* funcs);
458 
459   // Returns true if all of the given analyses are valid.
AreAnalysesValid(Analysis set)460   bool AreAnalysesValid(Analysis set) { return (set & valid_analyses_) == set; }
461 
462   // Replaces all uses of |before| id with |after| id. Returns true if any
463   // replacement happens. This method does not kill the definition of the
464   // |before| id. If |after| is the same as |before|, does nothing and returns
465   // false.
466   //
467   // |before| and |after| must be registered definitions in the DefUseManager.
468   bool ReplaceAllUsesWith(uint32_t before, uint32_t after);
469 
470   // Replace all uses of |before| id with |after| id if those uses
471   // (instruction) return true for |predicate|. Returns true if
472   // any replacement happens. This method does not kill the definition of the
473   // |before| id. If |after| is the same as |before|, does nothing and return
474   // false.
475   bool ReplaceAllUsesWithPredicate(
476       uint32_t before, uint32_t after,
477       const std::function<bool(Instruction*)>& predicate);
478 
479   // Returns true if all of the analyses that are suppose to be valid are
480   // actually valid.
481   bool IsConsistent();
482 
483   // The IRContext will look at the def and uses of |inst| and update any valid
484   // analyses will be updated accordingly.
485   inline void AnalyzeDefUse(Instruction* inst);
486 
487   // Informs the IRContext that the uses of |inst| are going to change, and that
488   // is should forget everything it know about the current uses.  Any valid
489   // analyses will be updated accordingly.
490   void ForgetUses(Instruction* inst);
491 
492   // The IRContext will look at the uses of |inst| and update any valid analyses
493   // will be updated accordingly.
494   void AnalyzeUses(Instruction* inst);
495 
496   // Kill all name and decorate ops targeting |id|.
497   void KillNamesAndDecorates(uint32_t id);
498 
499   // Kill all name and decorate ops targeting the result id of |inst|.
500   void KillNamesAndDecorates(Instruction* inst);
501 
502   // Change operands of debug instruction to DebugInfoNone.
503   void KillOperandFromDebugInstructions(Instruction* inst);
504 
505   // Returns the next unique id for use by an instruction.
TakeNextUniqueId()506   inline uint32_t TakeNextUniqueId() {
507     assert(unique_id_ != std::numeric_limits<uint32_t>::max());
508 
509     // Skip zero.
510     return ++unique_id_;
511   }
512 
513   // Returns true if |inst| is a combinator in the current context.
514   // |combinator_ops_| is built if it has not been already.
IsCombinatorInstruction(const Instruction * inst)515   inline bool IsCombinatorInstruction(const Instruction* inst) {
516     if (!AreAnalysesValid(kAnalysisCombinators)) {
517       InitializeCombinators();
518     }
519     constexpr uint32_t kExtInstSetIdInIndx = 0;
520     constexpr uint32_t kExtInstInstructionInIndx = 1;
521 
522     if (inst->opcode() != spv::Op::OpExtInst) {
523       return combinator_ops_[0].count(uint32_t(inst->opcode())) != 0;
524     } else {
525       uint32_t set = inst->GetSingleWordInOperand(kExtInstSetIdInIndx);
526       auto op = inst->GetSingleWordInOperand(kExtInstInstructionInIndx);
527       return combinator_ops_[set].count(op) != 0;
528     }
529   }
530 
531   // Returns a pointer to the CFG for all the functions in |module_|.
cfg()532   CFG* cfg() {
533     if (!AreAnalysesValid(kAnalysisCFG)) {
534       BuildCFG();
535     }
536     return cfg_.get();
537   }
538 
539   // Gets the loop descriptor for function |f|.
540   LoopDescriptor* GetLoopDescriptor(const Function* f);
541 
542   // Gets the dominator analysis for function |f|.
543   DominatorAnalysis* GetDominatorAnalysis(const Function* f);
544 
545   // Gets the postdominator analysis for function |f|.
546   PostDominatorAnalysis* GetPostDominatorAnalysis(const Function* f);
547 
548   // Remove the dominator tree of |f| from the cache.
RemoveDominatorAnalysis(const Function * f)549   inline void RemoveDominatorAnalysis(const Function* f) {
550     dominator_trees_.erase(f);
551   }
552 
553   // Remove the postdominator tree of |f| from the cache.
RemovePostDominatorAnalysis(const Function * f)554   inline void RemovePostDominatorAnalysis(const Function* f) {
555     post_dominator_trees_.erase(f);
556   }
557 
558   // Return the next available SSA id and increment it.  Returns 0 if the
559   // maximum SSA id has been reached.
TakeNextId()560   inline uint32_t TakeNextId() {
561     uint32_t next_id = module()->TakeNextIdBound();
562     if (next_id == 0) {
563       if (consumer()) {
564         std::string message = "ID overflow. Try running compact-ids.";
565         consumer()(SPV_MSG_ERROR, "", {0, 0, 0}, message.c_str());
566       }
567 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
568       // If TakeNextId returns 0, it is very likely that execution will
569       // subsequently fail. Such failures are false alarms from a fuzzing point
570       // of view: they are due to the fact that too many ids were used, rather
571       // than being due to an actual bug. Thus, during a fuzzing build, it is
572       // preferable to bail out when ID overflow occurs.
573       //
574       // A zero exit code is returned here because a non-zero code would cause
575       // ClusterFuzz/OSS-Fuzz to regard the termination as a crash, and spurious
576       // crash reports is what this guard aims to avoid.
577       exit(0);
578 #endif
579     }
580     return next_id;
581   }
582 
get_feature_mgr()583   FeatureManager* get_feature_mgr() {
584     if (!feature_mgr_.get()) {
585       AnalyzeFeatures();
586     }
587     return feature_mgr_.get();
588   }
589 
ResetFeatureManager()590   void ResetFeatureManager() { feature_mgr_.reset(nullptr); }
591 
592   // Returns the grammar for this context.
grammar()593   const AssemblyGrammar& grammar() const { return grammar_; }
594 
595   // If |inst| has not yet been analysed by the def-use manager, then analyse
596   // its definitions and uses.
597   inline void UpdateDefUse(Instruction* inst);
598 
get_instruction_folder()599   const InstructionFolder& get_instruction_folder() {
600     if (!inst_folder_) {
601       inst_folder_ = MakeUnique<InstructionFolder>(this);
602     }
603     return *inst_folder_;
604   }
605 
max_id_bound()606   uint32_t max_id_bound() const { return max_id_bound_; }
set_max_id_bound(uint32_t new_bound)607   void set_max_id_bound(uint32_t new_bound) { max_id_bound_ = new_bound; }
608 
preserve_bindings()609   bool preserve_bindings() const { return preserve_bindings_; }
set_preserve_bindings(bool should_preserve_bindings)610   void set_preserve_bindings(bool should_preserve_bindings) {
611     preserve_bindings_ = should_preserve_bindings;
612   }
613 
preserve_spec_constants()614   bool preserve_spec_constants() const { return preserve_spec_constants_; }
set_preserve_spec_constants(bool should_preserve_spec_constants)615   void set_preserve_spec_constants(bool should_preserve_spec_constants) {
616     preserve_spec_constants_ = should_preserve_spec_constants;
617   }
618 
619   // Return id of input variable only decorated with |builtin|, if in module.
620   // Create variable and return its id otherwise. If builtin not currently
621   // supported, return 0.
622   uint32_t GetBuiltinInputVarId(uint32_t builtin);
623 
624   // Returns the function whose id is |id|, if one exists.  Returns |nullptr|
625   // otherwise.
GetFunction(uint32_t id)626   Function* GetFunction(uint32_t id) {
627     if (!AreAnalysesValid(kAnalysisIdToFuncMapping)) {
628       BuildIdToFuncMapping();
629     }
630     auto entry = id_to_func_.find(id);
631     return (entry != id_to_func_.end()) ? entry->second : nullptr;
632   }
633 
GetFunction(Instruction * inst)634   Function* GetFunction(Instruction* inst) {
635     if (inst->opcode() != spv::Op::OpFunction) {
636       return nullptr;
637     }
638     return GetFunction(inst->result_id());
639   }
640 
641   // Add to |todo| all ids of functions called directly from |func|.
642   void AddCalls(const Function* func, std::queue<uint32_t>* todo);
643 
644   // Applies |pfn| to every function in the call trees that are rooted at the
645   // entry points.  Returns true if any call |pfn| returns true.  By convention
646   // |pfn| should return true if it modified the module.
647   bool ProcessEntryPointCallTree(ProcessFunction& pfn);
648 
649   // Applies |pfn| to every function in the call trees rooted at the entry
650   // points and exported functions.  Returns true if any call |pfn| returns
651   // true.  By convention |pfn| should return true if it modified the module.
652   bool ProcessReachableCallTree(ProcessFunction& pfn);
653 
654   // Applies |pfn| to every function in the call trees rooted at the elements of
655   // |roots|.  Returns true if any call to |pfn| returns true.  By convention
656   // |pfn| should return true if it modified the module.  After returning
657   // |roots| will be empty.
658   bool ProcessCallTreeFromRoots(ProcessFunction& pfn,
659                                 std::queue<uint32_t>* roots);
660 
661   // Emits a error message to the message consumer indicating the error
662   // described by |message| occurred in |inst|.
663   void EmitErrorMessage(std::string message, Instruction* inst);
664 
665   // Returns true if and only if there is a path to |bb| from the entry block of
666   // the function that contains |bb|.
667   bool IsReachable(const opt::BasicBlock& bb);
668 
669   // Return the stage of the module. Will generate error if entry points don't
670   // all have the same stage.
671   spv::ExecutionModel GetStage();
672 
673   // Returns true of the current target environment is at least that of the
674   // given environment.
IsTargetEnvAtLeast(spv_target_env env)675   bool IsTargetEnvAtLeast(spv_target_env env) {
676     // A bit of a hack. We assume that the target environments are appended to
677     // the enum, so that there is an appropriate order.
678     return syntax_context_->target_env >= env;
679   }
680 
681   // Return the target environment for the current context.
GetTargetEnv()682   spv_target_env GetTargetEnv() const { return syntax_context_->target_env; }
683 
684  private:
685   // Builds the def-use manager from scratch, even if it was already valid.
BuildDefUseManager()686   void BuildDefUseManager() {
687     def_use_mgr_ = MakeUnique<analysis::DefUseManager>(module());
688     valid_analyses_ = valid_analyses_ | kAnalysisDefUse;
689   }
690 
691   // Builds the liveness manager from scratch, even if it was already valid.
BuildLivenessManager()692   void BuildLivenessManager() {
693     liveness_mgr_ = MakeUnique<analysis::LivenessManager>(this);
694     valid_analyses_ = valid_analyses_ | kAnalysisLiveness;
695   }
696 
697   // Builds the instruction-block map for the whole module.
BuildInstrToBlockMapping()698   void BuildInstrToBlockMapping() {
699     instr_to_block_.clear();
700     for (auto& fn : *module_) {
701       for (auto& block : fn) {
702         block.ForEachInst([this, &block](Instruction* inst) {
703           instr_to_block_[inst] = &block;
704         });
705       }
706     }
707     valid_analyses_ = valid_analyses_ | kAnalysisInstrToBlockMapping;
708   }
709 
710   // Builds the instruction-function map for the whole module.
BuildIdToFuncMapping()711   void BuildIdToFuncMapping() {
712     id_to_func_.clear();
713     for (auto& fn : *module_) {
714       id_to_func_[fn.result_id()] = &fn;
715     }
716     valid_analyses_ = valid_analyses_ | kAnalysisIdToFuncMapping;
717   }
718 
BuildDecorationManager()719   void BuildDecorationManager() {
720     decoration_mgr_ = MakeUnique<analysis::DecorationManager>(module());
721     valid_analyses_ = valid_analyses_ | kAnalysisDecorations;
722   }
723 
BuildCFG()724   void BuildCFG() {
725     cfg_ = MakeUnique<CFG>(module());
726     valid_analyses_ = valid_analyses_ | kAnalysisCFG;
727   }
728 
BuildScalarEvolutionAnalysis()729   void BuildScalarEvolutionAnalysis() {
730     scalar_evolution_analysis_ = MakeUnique<ScalarEvolutionAnalysis>(this);
731     valid_analyses_ = valid_analyses_ | kAnalysisScalarEvolution;
732   }
733 
734   // Builds the liveness analysis from scratch, even if it was already valid.
BuildRegPressureAnalysis()735   void BuildRegPressureAnalysis() {
736     reg_pressure_ = MakeUnique<LivenessAnalysis>(this);
737     valid_analyses_ = valid_analyses_ | kAnalysisRegisterPressure;
738   }
739 
740   // Builds the value number table analysis from scratch, even if it was already
741   // valid.
BuildValueNumberTable()742   void BuildValueNumberTable() {
743     vn_table_ = MakeUnique<ValueNumberTable>(this);
744     valid_analyses_ = valid_analyses_ | kAnalysisValueNumberTable;
745   }
746 
747   // Builds the structured CFG analysis from scratch, even if it was already
748   // valid.
BuildStructuredCFGAnalysis()749   void BuildStructuredCFGAnalysis() {
750     struct_cfg_analysis_ = MakeUnique<StructuredCFGAnalysis>(this);
751     valid_analyses_ = valid_analyses_ | kAnalysisStructuredCFG;
752   }
753 
754   // Builds the constant manager from scratch, even if it was already
755   // valid.
BuildConstantManager()756   void BuildConstantManager() {
757     constant_mgr_ = MakeUnique<analysis::ConstantManager>(this);
758     valid_analyses_ = valid_analyses_ | kAnalysisConstants;
759   }
760 
761   // Builds the type manager from scratch, even if it was already
762   // valid.
BuildTypeManager()763   void BuildTypeManager() {
764     type_mgr_ = MakeUnique<analysis::TypeManager>(consumer(), this);
765     valid_analyses_ = valid_analyses_ | kAnalysisTypes;
766   }
767 
768   // Builds the debug information manager from scratch, even if it was
769   // already valid.
BuildDebugInfoManager()770   void BuildDebugInfoManager() {
771     debug_info_mgr_ = MakeUnique<analysis::DebugInfoManager>(this);
772     valid_analyses_ = valid_analyses_ | kAnalysisDebugInfo;
773   }
774 
775   // Removes all computed dominator and post-dominator trees. This will force
776   // the context to rebuild the trees on demand.
ResetDominatorAnalysis()777   void ResetDominatorAnalysis() {
778     // Clear the cache.
779     dominator_trees_.clear();
780     post_dominator_trees_.clear();
781     valid_analyses_ = valid_analyses_ | kAnalysisDominatorAnalysis;
782   }
783 
784   // Removes all computed loop descriptors.
ResetLoopAnalysis()785   void ResetLoopAnalysis() {
786     // Clear the cache.
787     loop_descriptors_.clear();
788     valid_analyses_ = valid_analyses_ | kAnalysisLoopAnalysis;
789   }
790 
791   // Removes all computed loop descriptors.
ResetBuiltinAnalysis()792   void ResetBuiltinAnalysis() {
793     // Clear the cache.
794     builtin_var_id_map_.clear();
795     valid_analyses_ = valid_analyses_ | kAnalysisBuiltinVarId;
796   }
797 
798   // Analyzes the features in the owned module. Builds the manager if required.
AnalyzeFeatures()799   void AnalyzeFeatures() {
800     feature_mgr_ =
801         std::unique_ptr<FeatureManager>(new FeatureManager(grammar_));
802     feature_mgr_->Analyze(module());
803   }
804 
805   // Scans a module looking for it capabilities, and initializes combinator_ops_
806   // accordingly.
807   void InitializeCombinators();
808 
809   // Add the combinator opcode for the given capability to combinator_ops_.
810   void AddCombinatorsForCapability(uint32_t capability);
811 
812   // Add the combinator opcode for the given extension to combinator_ops_.
813   void AddCombinatorsForExtension(Instruction* extension);
814 
815   // Remove |inst| from |id_to_name_| if it is in map.
816   void RemoveFromIdToName(const Instruction* inst);
817 
818   // Returns true if it is suppose to be valid but it is incorrect.  Returns
819   // true if the cfg is invalidated.
820   bool CheckCFG();
821 
822   // Return id of input variable only decorated with |builtin|, if in module.
823   // Return 0 otherwise.
824   uint32_t FindBuiltinInputVar(uint32_t builtin);
825 
826   // Add |var_id| to all entry points in module.
827   void AddVarToEntryPoints(uint32_t var_id);
828 
829   // The SPIR-V syntax context containing grammar tables for opcodes and
830   // operands.
831   spv_context syntax_context_;
832 
833   // Auxiliary object for querying SPIR-V grammar facts.
834   AssemblyGrammar grammar_;
835 
836   // An unique identifier for instructions in |module_|. Can be used to order
837   // instructions in a container.
838   //
839   // This member is initialized to 0, but always issues this value plus one.
840   // Therefore, 0 is not a valid unique id for an instruction.
841   uint32_t unique_id_;
842 
843   // The module being processed within this IR context.
844   std::unique_ptr<Module> module_;
845 
846   // A message consumer for diagnostics.
847   MessageConsumer consumer_;
848 
849   // The def-use manager for |module_|.
850   std::unique_ptr<analysis::DefUseManager> def_use_mgr_;
851 
852   // The instruction decoration manager for |module_|.
853   std::unique_ptr<analysis::DecorationManager> decoration_mgr_;
854 
855   // The feature manager for |module_|.
856   std::unique_ptr<FeatureManager> feature_mgr_;
857 
858   // A map from instructions to the basic block they belong to. This mapping is
859   // built on-demand when get_instr_block() is called.
860   //
861   // NOTE: Do not traverse this map. Ever. Use the function and basic block
862   // iterators to traverse instructions.
863   std::unordered_map<Instruction*, BasicBlock*> instr_to_block_;
864 
865   // A map from ids to the function they define. This mapping is
866   // built on-demand when GetFunction() is called.
867   //
868   // NOTE: Do not traverse this map. Ever. Use the function and basic block
869   // iterators to traverse instructions.
870   std::unordered_map<uint32_t, Function*> id_to_func_;
871 
872   // A bitset indicating which analyzes are currently valid.
873   Analysis valid_analyses_;
874 
875   // Opcodes of shader capability core executable instructions
876   // without side-effect.
877   std::unordered_map<uint32_t, std::unordered_set<uint32_t>> combinator_ops_;
878 
879   // Opcodes of shader capability core executable instructions
880   // without side-effect.
881   std::unordered_map<uint32_t, uint32_t> builtin_var_id_map_;
882 
883   // The CFG for all the functions in |module_|.
884   std::unique_ptr<CFG> cfg_;
885 
886   // Each function in the module will create its own dominator tree. We cache
887   // the result so it doesn't need to be rebuilt each time.
888   std::map<const Function*, DominatorAnalysis> dominator_trees_;
889   std::map<const Function*, PostDominatorAnalysis> post_dominator_trees_;
890 
891   // Cache of loop descriptors for each function.
892   std::unordered_map<const Function*, LoopDescriptor> loop_descriptors_;
893 
894   // Constant manager for |module_|.
895   std::unique_ptr<analysis::ConstantManager> constant_mgr_;
896 
897   // Type manager for |module_|.
898   std::unique_ptr<analysis::TypeManager> type_mgr_;
899 
900   // Debug information manager for |module_|.
901   std::unique_ptr<analysis::DebugInfoManager> debug_info_mgr_;
902 
903   // A map from an id to its corresponding OpName and OpMemberName instructions.
904   std::unique_ptr<std::multimap<uint32_t, Instruction*>> id_to_name_;
905 
906   // The cache scalar evolution analysis node.
907   std::unique_ptr<ScalarEvolutionAnalysis> scalar_evolution_analysis_;
908 
909   // The liveness analysis |module_|.
910   std::unique_ptr<LivenessAnalysis> reg_pressure_;
911 
912   std::unique_ptr<ValueNumberTable> vn_table_;
913 
914   std::unique_ptr<InstructionFolder> inst_folder_;
915 
916   std::unique_ptr<StructuredCFGAnalysis> struct_cfg_analysis_;
917 
918   // The liveness manager for |module_|.
919   std::unique_ptr<analysis::LivenessManager> liveness_mgr_;
920 
921   // The maximum legal value for the id bound.
922   uint32_t max_id_bound_;
923 
924   // Whether all bindings within |module_| should be preserved.
925   bool preserve_bindings_;
926 
927   // Whether all specialization constants within |module_|
928   // should be preserved.
929   bool preserve_spec_constants_;
930 };
931 
932 inline IRContext::Analysis operator|(IRContext::Analysis lhs,
933                                      IRContext::Analysis rhs) {
934   return static_cast<IRContext::Analysis>(static_cast<int>(lhs) |
935                                           static_cast<int>(rhs));
936 }
937 
938 inline IRContext::Analysis& operator|=(IRContext::Analysis& lhs,
939                                        IRContext::Analysis rhs) {
940   lhs = lhs | rhs;
941   return lhs;
942 }
943 
944 inline IRContext::Analysis operator<<(IRContext::Analysis a, int shift) {
945   return static_cast<IRContext::Analysis>(static_cast<int>(a) << shift);
946 }
947 
948 inline IRContext::Analysis& operator<<=(IRContext::Analysis& a, int shift) {
949   a = static_cast<IRContext::Analysis>(static_cast<int>(a) << shift);
950   return a;
951 }
952 
GetConstants()953 std::vector<Instruction*> IRContext::GetConstants() {
954   return module()->GetConstants();
955 }
956 
GetConstants()957 std::vector<const Instruction*> IRContext::GetConstants() const {
958   return ((const Module*)module())->GetConstants();
959 }
960 
annotation_begin()961 Module::inst_iterator IRContext::annotation_begin() {
962   return module()->annotation_begin();
963 }
964 
annotation_end()965 Module::inst_iterator IRContext::annotation_end() {
966   return module()->annotation_end();
967 }
968 
annotations()969 IteratorRange<Module::inst_iterator> IRContext::annotations() {
970   return module_->annotations();
971 }
972 
annotations()973 IteratorRange<Module::const_inst_iterator> IRContext::annotations() const {
974   return ((const Module*)module_.get())->annotations();
975 }
976 
capability_begin()977 Module::inst_iterator IRContext::capability_begin() {
978   return module()->capability_begin();
979 }
980 
capability_end()981 Module::inst_iterator IRContext::capability_end() {
982   return module()->capability_end();
983 }
984 
capabilities()985 IteratorRange<Module::inst_iterator> IRContext::capabilities() {
986   return module()->capabilities();
987 }
988 
capabilities()989 IteratorRange<Module::const_inst_iterator> IRContext::capabilities() const {
990   return ((const Module*)module())->capabilities();
991 }
992 
extension_begin()993 Module::inst_iterator IRContext::extension_begin() {
994   return module()->extension_begin();
995 }
996 
extension_end()997 Module::inst_iterator IRContext::extension_end() {
998   return module()->extension_end();
999 }
1000 
extensions()1001 IteratorRange<Module::inst_iterator> IRContext::extensions() {
1002   return module()->extensions();
1003 }
1004 
extensions()1005 IteratorRange<Module::const_inst_iterator> IRContext::extensions() const {
1006   return ((const Module*)module())->extensions();
1007 }
1008 
types_values_begin()1009 Module::inst_iterator IRContext::types_values_begin() {
1010   return module()->types_values_begin();
1011 }
1012 
types_values_end()1013 Module::inst_iterator IRContext::types_values_end() {
1014   return module()->types_values_end();
1015 }
1016 
types_values()1017 IteratorRange<Module::inst_iterator> IRContext::types_values() {
1018   return module()->types_values();
1019 }
1020 
types_values()1021 IteratorRange<Module::const_inst_iterator> IRContext::types_values() const {
1022   return ((const Module*)module_.get())->types_values();
1023 }
1024 
ext_inst_import_begin()1025 Module::inst_iterator IRContext::ext_inst_import_begin() {
1026   return module()->ext_inst_import_begin();
1027 }
1028 
ext_inst_import_end()1029 Module::inst_iterator IRContext::ext_inst_import_end() {
1030   return module()->ext_inst_import_end();
1031 }
1032 
ext_inst_imports()1033 IteratorRange<Module::inst_iterator> IRContext::ext_inst_imports() {
1034   return module()->ext_inst_imports();
1035 }
1036 
ext_inst_imports()1037 IteratorRange<Module::const_inst_iterator> IRContext::ext_inst_imports() const {
1038   return ((const Module*)module_.get())->ext_inst_imports();
1039 }
1040 
debug1_begin()1041 Module::inst_iterator IRContext::debug1_begin() {
1042   return module()->debug1_begin();
1043 }
1044 
debug1_end()1045 Module::inst_iterator IRContext::debug1_end() { return module()->debug1_end(); }
1046 
debugs1()1047 IteratorRange<Module::inst_iterator> IRContext::debugs1() {
1048   return module()->debugs1();
1049 }
1050 
debugs1()1051 IteratorRange<Module::const_inst_iterator> IRContext::debugs1() const {
1052   return ((const Module*)module_.get())->debugs1();
1053 }
1054 
debug2_begin()1055 Module::inst_iterator IRContext::debug2_begin() {
1056   return module()->debug2_begin();
1057 }
debug2_end()1058 Module::inst_iterator IRContext::debug2_end() { return module()->debug2_end(); }
1059 
debugs2()1060 IteratorRange<Module::inst_iterator> IRContext::debugs2() {
1061   return module()->debugs2();
1062 }
1063 
debugs2()1064 IteratorRange<Module::const_inst_iterator> IRContext::debugs2() const {
1065   return ((const Module*)module_.get())->debugs2();
1066 }
1067 
debug3_begin()1068 Module::inst_iterator IRContext::debug3_begin() {
1069   return module()->debug3_begin();
1070 }
1071 
debug3_end()1072 Module::inst_iterator IRContext::debug3_end() { return module()->debug3_end(); }
1073 
debugs3()1074 IteratorRange<Module::inst_iterator> IRContext::debugs3() {
1075   return module()->debugs3();
1076 }
1077 
debugs3()1078 IteratorRange<Module::const_inst_iterator> IRContext::debugs3() const {
1079   return ((const Module*)module_.get())->debugs3();
1080 }
1081 
ext_inst_debuginfo_begin()1082 Module::inst_iterator IRContext::ext_inst_debuginfo_begin() {
1083   return module()->ext_inst_debuginfo_begin();
1084 }
1085 
ext_inst_debuginfo_end()1086 Module::inst_iterator IRContext::ext_inst_debuginfo_end() {
1087   return module()->ext_inst_debuginfo_end();
1088 }
1089 
ext_inst_debuginfo()1090 IteratorRange<Module::inst_iterator> IRContext::ext_inst_debuginfo() {
1091   return module()->ext_inst_debuginfo();
1092 }
1093 
ext_inst_debuginfo()1094 IteratorRange<Module::const_inst_iterator> IRContext::ext_inst_debuginfo()
1095     const {
1096   return ((const Module*)module_.get())->ext_inst_debuginfo();
1097 }
1098 
AddCapability(spv::Capability capability)1099 void IRContext::AddCapability(spv::Capability capability) {
1100   if (!get_feature_mgr()->HasCapability(capability)) {
1101     std::unique_ptr<Instruction> capability_inst(new Instruction(
1102         this, spv::Op::OpCapability, 0, 0,
1103         {{SPV_OPERAND_TYPE_CAPABILITY, {static_cast<uint32_t>(capability)}}}));
1104     AddCapability(std::move(capability_inst));
1105   }
1106 }
1107 
AddCapability(std::unique_ptr<Instruction> && c)1108 void IRContext::AddCapability(std::unique_ptr<Instruction>&& c) {
1109   AddCombinatorsForCapability(c->GetSingleWordInOperand(0));
1110   if (feature_mgr_ != nullptr) {
1111     feature_mgr_->AddCapability(
1112         static_cast<spv::Capability>(c->GetSingleWordInOperand(0)));
1113   }
1114   if (AreAnalysesValid(kAnalysisDefUse)) {
1115     get_def_use_mgr()->AnalyzeInstDefUse(c.get());
1116   }
1117   module()->AddCapability(std::move(c));
1118 }
1119 
AddExtension(const std::string & ext_name)1120 void IRContext::AddExtension(const std::string& ext_name) {
1121   std::vector<uint32_t> ext_words = spvtools::utils::MakeVector(ext_name);
1122   AddExtension(std::unique_ptr<Instruction>(
1123       new Instruction(this, spv::Op::OpExtension, 0u, 0u,
1124                       {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}})));
1125 }
1126 
AddExtension(std::unique_ptr<Instruction> && e)1127 void IRContext::AddExtension(std::unique_ptr<Instruction>&& e) {
1128   if (AreAnalysesValid(kAnalysisDefUse)) {
1129     get_def_use_mgr()->AnalyzeInstDefUse(e.get());
1130   }
1131   if (feature_mgr_ != nullptr) {
1132     feature_mgr_->AddExtension(&*e);
1133   }
1134   module()->AddExtension(std::move(e));
1135 }
1136 
AddExtInstImport(const std::string & name)1137 void IRContext::AddExtInstImport(const std::string& name) {
1138   std::vector<uint32_t> ext_words = spvtools::utils::MakeVector(name);
1139   AddExtInstImport(std::unique_ptr<Instruction>(
1140       new Instruction(this, spv::Op::OpExtInstImport, 0u, TakeNextId(),
1141                       {{SPV_OPERAND_TYPE_LITERAL_STRING, ext_words}})));
1142 }
1143 
AddExtInstImport(std::unique_ptr<Instruction> && e)1144 void IRContext::AddExtInstImport(std::unique_ptr<Instruction>&& e) {
1145   AddCombinatorsForExtension(e.get());
1146   if (AreAnalysesValid(kAnalysisDefUse)) {
1147     get_def_use_mgr()->AnalyzeInstDefUse(e.get());
1148   }
1149   module()->AddExtInstImport(std::move(e));
1150   if (feature_mgr_ != nullptr) {
1151     feature_mgr_->AddExtInstImportIds(module());
1152   }
1153 }
1154 
SetMemoryModel(std::unique_ptr<Instruction> && m)1155 void IRContext::SetMemoryModel(std::unique_ptr<Instruction>&& m) {
1156   module()->SetMemoryModel(std::move(m));
1157 }
1158 
AddEntryPoint(std::unique_ptr<Instruction> && e)1159 void IRContext::AddEntryPoint(std::unique_ptr<Instruction>&& e) {
1160   module()->AddEntryPoint(std::move(e));
1161 }
1162 
AddExecutionMode(std::unique_ptr<Instruction> && e)1163 void IRContext::AddExecutionMode(std::unique_ptr<Instruction>&& e) {
1164   module()->AddExecutionMode(std::move(e));
1165 }
1166 
AddDebug1Inst(std::unique_ptr<Instruction> && d)1167 void IRContext::AddDebug1Inst(std::unique_ptr<Instruction>&& d) {
1168   module()->AddDebug1Inst(std::move(d));
1169 }
1170 
AddDebug2Inst(std::unique_ptr<Instruction> && d)1171 void IRContext::AddDebug2Inst(std::unique_ptr<Instruction>&& d) {
1172   if (AreAnalysesValid(kAnalysisNameMap)) {
1173     if (d->opcode() == spv::Op::OpName ||
1174         d->opcode() == spv::Op::OpMemberName) {
1175       // OpName and OpMemberName do not have result-ids. The target of the
1176       // instruction is at InOperand index 0.
1177       id_to_name_->insert({d->GetSingleWordInOperand(0), d.get()});
1178     }
1179   }
1180   if (AreAnalysesValid(kAnalysisDefUse)) {
1181     get_def_use_mgr()->AnalyzeInstDefUse(d.get());
1182   }
1183   module()->AddDebug2Inst(std::move(d));
1184 }
1185 
AddDebug3Inst(std::unique_ptr<Instruction> && d)1186 void IRContext::AddDebug3Inst(std::unique_ptr<Instruction>&& d) {
1187   module()->AddDebug3Inst(std::move(d));
1188 }
1189 
AddExtInstDebugInfo(std::unique_ptr<Instruction> && d)1190 void IRContext::AddExtInstDebugInfo(std::unique_ptr<Instruction>&& d) {
1191   module()->AddExtInstDebugInfo(std::move(d));
1192 }
1193 
AddAnnotationInst(std::unique_ptr<Instruction> && a)1194 void IRContext::AddAnnotationInst(std::unique_ptr<Instruction>&& a) {
1195   if (AreAnalysesValid(kAnalysisDecorations)) {
1196     get_decoration_mgr()->AddDecoration(a.get());
1197   }
1198   if (AreAnalysesValid(kAnalysisDefUse)) {
1199     get_def_use_mgr()->AnalyzeInstDefUse(a.get());
1200   }
1201   module()->AddAnnotationInst(std::move(a));
1202 }
1203 
AddType(std::unique_ptr<Instruction> && t)1204 void IRContext::AddType(std::unique_ptr<Instruction>&& t) {
1205   module()->AddType(std::move(t));
1206   if (AreAnalysesValid(kAnalysisDefUse)) {
1207     get_def_use_mgr()->AnalyzeInstDefUse(&*(--types_values_end()));
1208   }
1209 }
1210 
AddGlobalValue(std::unique_ptr<Instruction> && v)1211 void IRContext::AddGlobalValue(std::unique_ptr<Instruction>&& v) {
1212   if (AreAnalysesValid(kAnalysisDefUse)) {
1213     get_def_use_mgr()->AnalyzeInstDefUse(&*v);
1214   }
1215   module()->AddGlobalValue(std::move(v));
1216 }
1217 
AddFunctionDeclaration(std::unique_ptr<Function> && f)1218 void IRContext::AddFunctionDeclaration(std::unique_ptr<Function>&& f) {
1219   module()->AddFunctionDeclaration(std::move(f));
1220 }
1221 
AddFunction(std::unique_ptr<Function> && f)1222 void IRContext::AddFunction(std::unique_ptr<Function>&& f) {
1223   module()->AddFunction(std::move(f));
1224 }
1225 
AnalyzeDefUse(Instruction * inst)1226 void IRContext::AnalyzeDefUse(Instruction* inst) {
1227   if (AreAnalysesValid(kAnalysisDefUse)) {
1228     get_def_use_mgr()->AnalyzeInstDefUse(inst);
1229   }
1230 }
1231 
UpdateDefUse(Instruction * inst)1232 void IRContext::UpdateDefUse(Instruction* inst) {
1233   if (AreAnalysesValid(kAnalysisDefUse)) {
1234     get_def_use_mgr()->UpdateDefUse(inst);
1235   }
1236 }
1237 
BuildIdToNameMap()1238 void IRContext::BuildIdToNameMap() {
1239   id_to_name_ = MakeUnique<std::multimap<uint32_t, Instruction*>>();
1240   for (Instruction& debug_inst : debugs2()) {
1241     if (debug_inst.opcode() == spv::Op::OpMemberName ||
1242         debug_inst.opcode() == spv::Op::OpName) {
1243       id_to_name_->insert({debug_inst.GetSingleWordInOperand(0), &debug_inst});
1244     }
1245   }
1246   valid_analyses_ = valid_analyses_ | kAnalysisNameMap;
1247 }
1248 
1249 IteratorRange<std::multimap<uint32_t, Instruction*>::iterator>
GetNames(uint32_t id)1250 IRContext::GetNames(uint32_t id) {
1251   if (!AreAnalysesValid(kAnalysisNameMap)) {
1252     BuildIdToNameMap();
1253   }
1254   auto result = id_to_name_->equal_range(id);
1255   return make_range(std::move(result.first), std::move(result.second));
1256 }
1257 
GetMemberName(uint32_t struct_type_id,uint32_t index)1258 Instruction* IRContext::GetMemberName(uint32_t struct_type_id, uint32_t index) {
1259   if (!AreAnalysesValid(kAnalysisNameMap)) {
1260     BuildIdToNameMap();
1261   }
1262   auto result = id_to_name_->equal_range(struct_type_id);
1263   for (auto i = result.first; i != result.second; ++i) {
1264     auto* name_instr = i->second;
1265     if (name_instr->opcode() == spv::Op::OpMemberName &&
1266         name_instr->GetSingleWordInOperand(1) == index) {
1267       return name_instr;
1268     }
1269   }
1270   return nullptr;
1271 }
1272 
CloneNames(const uint32_t old_id,const uint32_t new_id,const uint32_t max_member_index)1273 void IRContext::CloneNames(const uint32_t old_id, const uint32_t new_id,
1274                            const uint32_t max_member_index) {
1275   std::vector<std::unique_ptr<Instruction>> names_to_add;
1276   auto names = GetNames(old_id);
1277   for (auto n : names) {
1278     Instruction* old_name_inst = n.second;
1279     if (old_name_inst->opcode() == spv::Op::OpMemberName) {
1280       auto midx = old_name_inst->GetSingleWordInOperand(1);
1281       if (midx >= max_member_index) continue;
1282     }
1283     std::unique_ptr<Instruction> new_name_inst(old_name_inst->Clone(this));
1284     new_name_inst->SetInOperand(0, {new_id});
1285     names_to_add.push_back(std::move(new_name_inst));
1286   }
1287   // We can't add the new names when we are iterating over name range above.
1288   // We can add all the new names now.
1289   for (auto& new_name : names_to_add) AddDebug2Inst(std::move(new_name));
1290 }
1291 
1292 }  // namespace opt
1293 }  // namespace spvtools
1294 
1295 #endif  // SOURCE_OPT_IR_CONTEXT_H_
1296