ir_context.h 44 KB

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