ir_context.h 47 KB

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