linker.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. // Copyright (c) 2017 Pierre Moreau
  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. #include "spirv-tools/linker.hpp"
  15. #include <algorithm>
  16. #include <cstdio>
  17. #include <cstring>
  18. #include <iostream>
  19. #include <memory>
  20. #include <numeric>
  21. #include <string>
  22. #include <unordered_map>
  23. #include <unordered_set>
  24. #include <utility>
  25. #include <vector>
  26. #include "source/assembly_grammar.h"
  27. #include "source/diagnostic.h"
  28. #include "source/opt/build_module.h"
  29. #include "source/opt/compact_ids_pass.h"
  30. #include "source/opt/decoration_manager.h"
  31. #include "source/opt/ir_builder.h"
  32. #include "source/opt/ir_loader.h"
  33. #include "source/opt/pass_manager.h"
  34. #include "source/opt/remove_duplicates_pass.h"
  35. #include "source/opt/remove_unused_interface_variables_pass.h"
  36. #include "source/opt/type_manager.h"
  37. #include "source/spirv_constant.h"
  38. #include "source/spirv_target_env.h"
  39. #include "source/util/make_unique.h"
  40. #include "source/util/string_utils.h"
  41. #include "spirv-tools/libspirv.hpp"
  42. namespace spvtools {
  43. namespace {
  44. using opt::Instruction;
  45. using opt::InstructionBuilder;
  46. using opt::IRContext;
  47. using opt::Module;
  48. using opt::PassManager;
  49. using opt::RemoveDuplicatesPass;
  50. using opt::analysis::DecorationManager;
  51. using opt::analysis::DefUseManager;
  52. using opt::analysis::Function;
  53. using opt::analysis::Type;
  54. using opt::analysis::TypeManager;
  55. // Stores various information about an imported or exported symbol.
  56. struct LinkageSymbolInfo {
  57. spv::Id id; // ID of the symbol
  58. spv::Id type_id; // ID of the type of the symbol
  59. std::string name; // unique name defining the symbol and used for matching
  60. // imports and exports together
  61. std::vector<spv::Id> parameter_ids; // ID of the parameters of the symbol, if
  62. // it is a function
  63. };
  64. struct LinkageEntry {
  65. LinkageSymbolInfo imported_symbol;
  66. LinkageSymbolInfo exported_symbol;
  67. LinkageEntry(const LinkageSymbolInfo& import_info,
  68. const LinkageSymbolInfo& export_info)
  69. : imported_symbol(import_info), exported_symbol(export_info) {}
  70. };
  71. using LinkageTable = std::vector<LinkageEntry>;
  72. // Shifts the IDs used in each binary of |modules| so that they occupy a
  73. // disjoint range from the other binaries, and compute the new ID bound which
  74. // is returned in |max_id_bound|.
  75. //
  76. // Both |modules| and |max_id_bound| should not be null, and |modules| should
  77. // not be empty either. Furthermore |modules| should not contain any null
  78. // pointers.
  79. spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
  80. std::vector<opt::Module*>* modules,
  81. uint32_t* max_id_bound);
  82. // Generates the header for the linked module and returns it in |header|.
  83. //
  84. // |header| should not be null, |modules| should not be empty and pointers
  85. // should be non-null. |max_id_bound| should be strictly greater than 0.
  86. spv_result_t GenerateHeader(const MessageConsumer& consumer,
  87. const std::vector<opt::Module*>& modules,
  88. uint32_t max_id_bound, opt::ModuleHeader* header,
  89. const LinkerOptions& options);
  90. // Merge all the modules from |in_modules| into a single module owned by
  91. // |linked_context|.
  92. //
  93. // |linked_context| should not be null.
  94. spv_result_t MergeModules(const MessageConsumer& consumer,
  95. const std::vector<Module*>& in_modules,
  96. const AssemblyGrammar& grammar,
  97. IRContext* linked_context);
  98. // Compute all pairs of import and export and return it in |linkings_to_do|.
  99. //
  100. // |linkings_to_do should not be null. Built-in symbols will be ignored.
  101. //
  102. // TODO(pierremoreau): Linkage attributes applied by a group decoration are
  103. // currently not handled. (You could have a group being
  104. // applied to a single ID.)
  105. // TODO(pierremoreau): What should be the proper behaviour with built-in
  106. // symbols?
  107. spv_result_t GetImportExportPairs(const MessageConsumer& consumer,
  108. const opt::IRContext& linked_context,
  109. const DefUseManager& def_use_manager,
  110. const DecorationManager& decoration_manager,
  111. bool allow_partial_linkage,
  112. LinkageTable* linkings_to_do);
  113. // Checks that for each pair of import and export, the import and export have
  114. // the same type as well as the same decorations.
  115. //
  116. // TODO(pierremoreau): Decorations on functions parameters are currently not
  117. // checked.
  118. spv_result_t CheckImportExportCompatibility(const MessageConsumer& consumer,
  119. const LinkageTable& linkings_to_do,
  120. bool allow_ptr_type_mismatch,
  121. opt::IRContext* context);
  122. // Remove linkage specific instructions, such as prototypes of imported
  123. // functions, declarations of imported variables, import (and export if
  124. // necessary) linkage attributes.
  125. //
  126. // |linked_context| and |decoration_manager| should not be null, and the
  127. // 'RemoveDuplicatePass' should be run first.
  128. //
  129. // TODO(pierremoreau): Linkage attributes applied by a group decoration are
  130. // currently not handled. (You could have a group being
  131. // applied to a single ID.)
  132. spv_result_t RemoveLinkageSpecificInstructions(
  133. const MessageConsumer& consumer, const LinkerOptions& options,
  134. const LinkageTable& linkings_to_do, DecorationManager* decoration_manager,
  135. opt::IRContext* linked_context);
  136. // Verify that the unique ids of each instruction in |linked_context| (i.e. the
  137. // merged module) are truly unique. Does not check the validity of other ids
  138. spv_result_t VerifyIds(const MessageConsumer& consumer,
  139. opt::IRContext* linked_context);
  140. // Verify that the universal limits are not crossed, and warn the user
  141. // otherwise.
  142. //
  143. // TODO(pierremoreau):
  144. // - Verify against the limits of the environment (e.g. Vulkan limits if
  145. // consuming vulkan1.x)
  146. spv_result_t VerifyLimits(const MessageConsumer& consumer,
  147. const opt::IRContext& linked_context);
  148. spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
  149. std::vector<opt::Module*>* modules,
  150. uint32_t* max_id_bound) {
  151. spv_position_t position = {};
  152. if (modules == nullptr)
  153. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  154. << "|modules| of ShiftIdsInModules should not be null.";
  155. if (modules->empty())
  156. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  157. << "|modules| of ShiftIdsInModules should not be empty.";
  158. if (max_id_bound == nullptr)
  159. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  160. << "|max_id_bound| of ShiftIdsInModules should not be null.";
  161. const size_t id_bound =
  162. std::accumulate(modules->begin(), modules->end(), static_cast<size_t>(1),
  163. [](const size_t& accumulation, opt::Module* module) {
  164. return accumulation + module->IdBound() - 1u;
  165. });
  166. if (id_bound > std::numeric_limits<uint32_t>::max())
  167. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  168. << "Too many IDs (" << id_bound
  169. << "): combining all modules would overflow the 32-bit word of the "
  170. "SPIR-V header.";
  171. *max_id_bound = static_cast<uint32_t>(id_bound);
  172. uint32_t id_offset = modules->front()->IdBound() - 1u;
  173. for (auto module_iter = modules->begin() + 1; module_iter != modules->end();
  174. ++module_iter) {
  175. Module* module = *module_iter;
  176. module->ForEachInst([&id_offset](Instruction* insn) {
  177. insn->ForEachId([&id_offset](uint32_t* id) { *id += id_offset; });
  178. });
  179. id_offset += module->IdBound() - 1u;
  180. // Invalidate the DefUseManager
  181. module->context()->InvalidateAnalyses(opt::IRContext::kAnalysisDefUse);
  182. }
  183. return SPV_SUCCESS;
  184. }
  185. spv_result_t GenerateHeader(const MessageConsumer& consumer,
  186. const std::vector<opt::Module*>& modules,
  187. uint32_t max_id_bound, opt::ModuleHeader* header,
  188. const LinkerOptions& options) {
  189. spv_position_t position = {};
  190. if (modules.empty())
  191. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  192. << "|modules| of GenerateHeader should not be empty.";
  193. if (max_id_bound == 0u)
  194. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  195. << "|max_id_bound| of GenerateHeader should not be null.";
  196. uint32_t linked_version = modules.front()->version();
  197. for (std::size_t i = 1; i < modules.size(); ++i) {
  198. const uint32_t module_version = modules[i]->version();
  199. if (options.GetUseHighestVersion()) {
  200. linked_version = std::max(linked_version, module_version);
  201. } else if (module_version != linked_version) {
  202. return DiagnosticStream({0, 0, 1}, consumer, "", SPV_ERROR_INTERNAL)
  203. << "Conflicting SPIR-V versions: "
  204. << SPV_SPIRV_VERSION_MAJOR_PART(linked_version) << "."
  205. << SPV_SPIRV_VERSION_MINOR_PART(linked_version)
  206. << " (input modules 1 through " << i << ") vs "
  207. << SPV_SPIRV_VERSION_MAJOR_PART(module_version) << "."
  208. << SPV_SPIRV_VERSION_MINOR_PART(module_version)
  209. << " (input module " << (i + 1) << ").";
  210. }
  211. }
  212. header->magic_number = spv::MagicNumber;
  213. header->version = linked_version;
  214. header->generator = SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_LINKER, 0);
  215. header->bound = max_id_bound;
  216. header->schema = 0u;
  217. return SPV_SUCCESS;
  218. }
  219. spv_result_t MergeModules(const MessageConsumer& consumer,
  220. const std::vector<Module*>& input_modules,
  221. const AssemblyGrammar& grammar,
  222. IRContext* linked_context) {
  223. spv_position_t position = {};
  224. if (linked_context == nullptr)
  225. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  226. << "|linked_module| of MergeModules should not be null.";
  227. Module* linked_module = linked_context->module();
  228. if (input_modules.empty()) return SPV_SUCCESS;
  229. for (const auto& module : input_modules)
  230. for (const auto& inst : module->capabilities())
  231. linked_module->AddCapability(
  232. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  233. for (const auto& module : input_modules)
  234. for (const auto& inst : module->extensions())
  235. linked_module->AddExtension(
  236. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  237. for (const auto& module : input_modules)
  238. for (const auto& inst : module->ext_inst_imports())
  239. linked_module->AddExtInstImport(
  240. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  241. const Instruction* linked_memory_model_inst =
  242. input_modules.front()->GetMemoryModel();
  243. if (linked_memory_model_inst == nullptr) {
  244. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  245. << "Input module 1 is lacking an OpMemoryModel instruction.";
  246. }
  247. const uint32_t linked_addressing_model =
  248. linked_memory_model_inst->GetSingleWordOperand(0u);
  249. const uint32_t linked_memory_model =
  250. linked_memory_model_inst->GetSingleWordOperand(1u);
  251. for (std::size_t i = 1; i < input_modules.size(); ++i) {
  252. const Module* module = input_modules[i];
  253. const Instruction* memory_model_inst = module->GetMemoryModel();
  254. if (memory_model_inst == nullptr)
  255. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  256. << "Input module " << (i + 1)
  257. << " is lacking an OpMemoryModel instruction.";
  258. const uint32_t module_addressing_model =
  259. memory_model_inst->GetSingleWordOperand(0u);
  260. if (module_addressing_model != linked_addressing_model) {
  261. spv_operand_desc linked_desc = nullptr, module_desc = nullptr;
  262. grammar.lookupOperand(SPV_OPERAND_TYPE_ADDRESSING_MODEL,
  263. linked_addressing_model, &linked_desc);
  264. grammar.lookupOperand(SPV_OPERAND_TYPE_ADDRESSING_MODEL,
  265. module_addressing_model, &module_desc);
  266. return DiagnosticStream(position, consumer, "", SPV_ERROR_INTERNAL)
  267. << "Conflicting addressing models: " << linked_desc->name
  268. << " (input modules 1 through " << i << ") vs "
  269. << module_desc->name << " (input module " << (i + 1) << ").";
  270. }
  271. const uint32_t module_memory_model =
  272. memory_model_inst->GetSingleWordOperand(1u);
  273. if (module_memory_model != linked_memory_model) {
  274. spv_operand_desc linked_desc = nullptr, module_desc = nullptr;
  275. grammar.lookupOperand(SPV_OPERAND_TYPE_MEMORY_MODEL, linked_memory_model,
  276. &linked_desc);
  277. grammar.lookupOperand(SPV_OPERAND_TYPE_MEMORY_MODEL, module_memory_model,
  278. &module_desc);
  279. return DiagnosticStream(position, consumer, "", SPV_ERROR_INTERNAL)
  280. << "Conflicting memory models: " << linked_desc->name
  281. << " (input modules 1 through " << i << ") vs "
  282. << module_desc->name << " (input module " << (i + 1) << ").";
  283. }
  284. }
  285. linked_module->SetMemoryModel(std::unique_ptr<Instruction>(
  286. linked_memory_model_inst->Clone(linked_context)));
  287. std::vector<std::pair<uint32_t, std::string>> entry_points;
  288. for (const auto& module : input_modules)
  289. for (const auto& inst : module->entry_points()) {
  290. const uint32_t model = inst.GetSingleWordInOperand(0);
  291. const std::string name = inst.GetInOperand(2).AsString();
  292. const auto i = std::find_if(
  293. entry_points.begin(), entry_points.end(),
  294. [model, name](const std::pair<uint32_t, std::string>& v) {
  295. return v.first == model && v.second == name;
  296. });
  297. if (i != entry_points.end()) {
  298. spv_operand_desc desc = nullptr;
  299. grammar.lookupOperand(SPV_OPERAND_TYPE_EXECUTION_MODEL, model, &desc);
  300. return DiagnosticStream(position, consumer, "", SPV_ERROR_INTERNAL)
  301. << "The entry point \"" << name << "\", with execution model "
  302. << desc->name << ", was already defined.";
  303. }
  304. linked_module->AddEntryPoint(
  305. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  306. entry_points.emplace_back(model, name);
  307. }
  308. for (const auto& module : input_modules)
  309. for (const auto& inst : module->execution_modes())
  310. linked_module->AddExecutionMode(
  311. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  312. for (const auto& module : input_modules)
  313. for (const auto& inst : module->debugs1())
  314. linked_module->AddDebug1Inst(
  315. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  316. for (const auto& module : input_modules)
  317. for (const auto& inst : module->debugs2())
  318. linked_module->AddDebug2Inst(
  319. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  320. for (const auto& module : input_modules)
  321. for (const auto& inst : module->debugs3())
  322. linked_module->AddDebug3Inst(
  323. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  324. for (const auto& module : input_modules)
  325. for (const auto& inst : module->ext_inst_debuginfo())
  326. linked_module->AddExtInstDebugInfo(
  327. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  328. // If the generated module uses SPIR-V 1.1 or higher, add an
  329. // OpModuleProcessed instruction about the linking step.
  330. if (linked_module->version() >= SPV_SPIRV_VERSION_WORD(1, 1)) {
  331. const std::string processed_string("Linked by SPIR-V Tools Linker");
  332. std::vector<uint32_t> processed_words =
  333. spvtools::utils::MakeVector(processed_string);
  334. linked_module->AddDebug3Inst(std::unique_ptr<Instruction>(
  335. new Instruction(linked_context, spv::Op::OpModuleProcessed, 0u, 0u,
  336. {{SPV_OPERAND_TYPE_LITERAL_STRING, processed_words}})));
  337. }
  338. for (const auto& module : input_modules)
  339. for (const auto& inst : module->annotations())
  340. linked_module->AddAnnotationInst(
  341. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  342. // TODO(pierremoreau): Since the modules have not been validate, should we
  343. // expect spv::StorageClass::Function variables outside
  344. // functions?
  345. for (const auto& module : input_modules) {
  346. for (const auto& inst : module->types_values()) {
  347. linked_module->AddType(
  348. std::unique_ptr<Instruction>(inst.Clone(linked_context)));
  349. }
  350. }
  351. // Process functions and their basic blocks
  352. for (const auto& module : input_modules) {
  353. for (const auto& func : *module) {
  354. std::unique_ptr<opt::Function> cloned_func(func.Clone(linked_context));
  355. linked_module->AddFunction(std::move(cloned_func));
  356. }
  357. }
  358. return SPV_SUCCESS;
  359. }
  360. spv_result_t GetImportExportPairs(const MessageConsumer& consumer,
  361. const opt::IRContext& linked_context,
  362. const DefUseManager& def_use_manager,
  363. const DecorationManager& decoration_manager,
  364. bool allow_partial_linkage,
  365. LinkageTable* linkings_to_do) {
  366. spv_position_t position = {};
  367. if (linkings_to_do == nullptr)
  368. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  369. << "|linkings_to_do| of GetImportExportPairs should not be empty.";
  370. std::vector<LinkageSymbolInfo> imports;
  371. std::unordered_map<std::string, std::vector<LinkageSymbolInfo>> exports;
  372. std::unordered_map<std::string, LinkageSymbolInfo> linkonce;
  373. // Figure out the imports and exports
  374. for (const auto& decoration : linked_context.annotations()) {
  375. if (decoration.opcode() != spv::Op::OpDecorate ||
  376. spv::Decoration(decoration.GetSingleWordInOperand(1u)) !=
  377. spv::Decoration::LinkageAttributes)
  378. continue;
  379. const spv::Id id = decoration.GetSingleWordInOperand(0u);
  380. // Ignore if the targeted symbol is a built-in
  381. bool is_built_in = false;
  382. for (const auto& id_decoration :
  383. decoration_manager.GetDecorationsFor(id, false)) {
  384. if (spv::Decoration(id_decoration->GetSingleWordInOperand(1u)) ==
  385. spv::Decoration::BuiltIn) {
  386. is_built_in = true;
  387. break;
  388. }
  389. }
  390. if (is_built_in) {
  391. continue;
  392. }
  393. const uint32_t type = decoration.GetSingleWordInOperand(3u);
  394. LinkageSymbolInfo symbol_info;
  395. symbol_info.name = decoration.GetInOperand(2u).AsString();
  396. symbol_info.id = id;
  397. symbol_info.type_id = 0u;
  398. // Retrieve the type of the current symbol. This information will be used
  399. // when checking that the imported and exported symbols have the same
  400. // types.
  401. const Instruction* def_inst = def_use_manager.GetDef(id);
  402. if (def_inst == nullptr)
  403. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  404. << "ID " << id << " is never defined:\n";
  405. if (def_inst->opcode() == spv::Op::OpVariable) {
  406. symbol_info.type_id = def_inst->type_id();
  407. } else if (def_inst->opcode() == spv::Op::OpFunction) {
  408. symbol_info.type_id = def_inst->GetSingleWordInOperand(1u);
  409. // range-based for loop calls begin()/end(), but never cbegin()/cend(),
  410. // which will not work here.
  411. for (auto func_iter = linked_context.module()->cbegin();
  412. func_iter != linked_context.module()->cend(); ++func_iter) {
  413. if (func_iter->result_id() != id) continue;
  414. func_iter->ForEachParam([&symbol_info](const Instruction* inst) {
  415. symbol_info.parameter_ids.push_back(inst->result_id());
  416. });
  417. }
  418. } else {
  419. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  420. << "Only global variables and functions can be decorated using"
  421. << " LinkageAttributes; " << id << " is neither of them.\n";
  422. }
  423. if (spv::LinkageType(type) == spv::LinkageType::Import) {
  424. imports.push_back(symbol_info);
  425. } else if (spv::LinkageType(type) == spv::LinkageType::Export) {
  426. exports[symbol_info.name].push_back(symbol_info);
  427. } else if (spv::LinkageType(type) == spv::LinkageType::LinkOnceODR) {
  428. if (linkonce.find(symbol_info.name) == linkonce.end())
  429. linkonce[symbol_info.name] = symbol_info;
  430. }
  431. }
  432. for (const auto& possible_export : linkonce) {
  433. if (exports.find(possible_export.first) == exports.end())
  434. exports[possible_export.first].push_back(possible_export.second);
  435. else
  436. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  437. << "Combination of Export and LinkOnceODR is not allowed, found "
  438. "for \""
  439. << possible_export.second.name << "\".";
  440. }
  441. // Find the import/export pairs
  442. for (const auto& import : imports) {
  443. std::vector<LinkageSymbolInfo> possible_exports;
  444. const auto& exp = exports.find(import.name);
  445. if (exp != exports.end()) possible_exports = exp->second;
  446. if (possible_exports.empty() && !allow_partial_linkage)
  447. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  448. << "Unresolved external reference to \"" << import.name << "\".";
  449. else if (possible_exports.size() > 1u)
  450. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  451. << "Too many external references, " << possible_exports.size()
  452. << ", were found for \"" << import.name << "\".";
  453. if (!possible_exports.empty())
  454. linkings_to_do->emplace_back(import, possible_exports.front());
  455. }
  456. return SPV_SUCCESS;
  457. }
  458. spv_result_t CheckImportExportCompatibility(const MessageConsumer& consumer,
  459. const LinkageTable& linkings_to_do,
  460. bool allow_ptr_type_mismatch,
  461. opt::IRContext* context) {
  462. spv_position_t position = {};
  463. // Ensure the import and export types are the same.
  464. const DecorationManager& decoration_manager = *context->get_decoration_mgr();
  465. const TypeManager& type_manager = *context->get_type_mgr();
  466. for (const auto& linking_entry : linkings_to_do) {
  467. Type* imported_symbol_type =
  468. type_manager.GetType(linking_entry.imported_symbol.type_id);
  469. Type* exported_symbol_type =
  470. type_manager.GetType(linking_entry.exported_symbol.type_id);
  471. if (!(*imported_symbol_type == *exported_symbol_type)) {
  472. Function* imported_symbol_type_func = imported_symbol_type->AsFunction();
  473. Function* exported_symbol_type_func = exported_symbol_type->AsFunction();
  474. if (imported_symbol_type_func && exported_symbol_type_func) {
  475. const auto& imported_params = imported_symbol_type_func->param_types();
  476. const auto& exported_params = exported_symbol_type_func->param_types();
  477. // allow_ptr_type_mismatch allows linking functions where the pointer
  478. // type of arguments doesn't match. Everything else still needs to be
  479. // equal. This is to workaround LLVM-17+ not having typed pointers and
  480. // generated SPIR-Vs not knowing the actual pointer types in some cases.
  481. if (allow_ptr_type_mismatch &&
  482. imported_params.size() == exported_params.size()) {
  483. bool correct = true;
  484. for (size_t i = 0; i < imported_params.size(); i++) {
  485. const auto& imported_param = imported_params[i];
  486. const auto& exported_param = exported_params[i];
  487. if (!imported_param->IsSame(exported_param) &&
  488. (imported_param->kind() != Type::kPointer ||
  489. exported_param->kind() != Type::kPointer)) {
  490. correct = false;
  491. break;
  492. }
  493. }
  494. if (correct) continue;
  495. }
  496. }
  497. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  498. << "Type mismatch on symbol \""
  499. << linking_entry.imported_symbol.name
  500. << "\" between imported variable/function %"
  501. << linking_entry.imported_symbol.id
  502. << " and exported variable/function %"
  503. << linking_entry.exported_symbol.id << ".";
  504. }
  505. }
  506. // Ensure the import and export decorations are similar
  507. for (const auto& linking_entry : linkings_to_do) {
  508. if (!decoration_manager.HaveTheSameDecorations(
  509. linking_entry.imported_symbol.id, linking_entry.exported_symbol.id))
  510. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  511. << "Decorations mismatch on symbol \""
  512. << linking_entry.imported_symbol.name
  513. << "\" between imported variable/function %"
  514. << linking_entry.imported_symbol.id
  515. << " and exported variable/function %"
  516. << linking_entry.exported_symbol.id << ".";
  517. // TODO(pierremoreau): Decorations on function parameters should probably
  518. // match, except for FuncParamAttr if I understand the
  519. // spec correctly.
  520. // TODO(pierremoreau): Decorations on the function return type should
  521. // match, except for FuncParamAttr.
  522. }
  523. return SPV_SUCCESS;
  524. }
  525. spv_result_t RemoveLinkageSpecificInstructions(
  526. const MessageConsumer& consumer, const LinkerOptions& options,
  527. const LinkageTable& linkings_to_do, DecorationManager* decoration_manager,
  528. opt::IRContext* linked_context) {
  529. spv_position_t position = {};
  530. if (decoration_manager == nullptr)
  531. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  532. << "|decoration_manager| of RemoveLinkageSpecificInstructions "
  533. "should not be empty.";
  534. if (linked_context == nullptr)
  535. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
  536. << "|linked_module| of RemoveLinkageSpecificInstructions should not "
  537. "be empty.";
  538. // TODO(pierremoreau): Remove FuncParamAttr decorations of imported
  539. // functions' return type.
  540. // Remove prototypes of imported functions
  541. for (const auto& linking_entry : linkings_to_do) {
  542. for (auto func_iter = linked_context->module()->begin();
  543. func_iter != linked_context->module()->end();) {
  544. if (func_iter->result_id() == linking_entry.imported_symbol.id)
  545. func_iter = func_iter.Erase();
  546. else
  547. ++func_iter;
  548. }
  549. }
  550. // Remove declarations of imported variables
  551. for (const auto& linking_entry : linkings_to_do) {
  552. auto next = linked_context->types_values_begin();
  553. for (auto inst = next; inst != linked_context->types_values_end();
  554. inst = next) {
  555. ++next;
  556. if (inst->result_id() == linking_entry.imported_symbol.id) {
  557. linked_context->KillInst(&*inst);
  558. }
  559. }
  560. }
  561. // If partial linkage is allowed, we need an efficient way to check whether
  562. // an imported ID had a corresponding export symbol. As uses of the imported
  563. // symbol have already been replaced by the exported symbol, use the exported
  564. // symbol ID.
  565. // TODO(pierremoreau): This will not work if the decoration is applied
  566. // through a group, but the linker does not support that
  567. // either.
  568. std::unordered_set<spv::Id> imports;
  569. if (options.GetAllowPartialLinkage()) {
  570. imports.reserve(linkings_to_do.size());
  571. for (const auto& linking_entry : linkings_to_do)
  572. imports.emplace(linking_entry.exported_symbol.id);
  573. }
  574. // Remove import linkage attributes
  575. auto next = linked_context->annotation_begin();
  576. for (auto inst = next; inst != linked_context->annotation_end();
  577. inst = next) {
  578. ++next;
  579. // If this is an import annotation:
  580. // * if we do not allow partial linkage, remove all import annotations;
  581. // * otherwise, remove the annotation only if there was a corresponding
  582. // export.
  583. if (inst->opcode() == spv::Op::OpDecorate &&
  584. spv::Decoration(inst->GetSingleWordOperand(1u)) ==
  585. spv::Decoration::LinkageAttributes &&
  586. spv::LinkageType(inst->GetSingleWordOperand(3u)) ==
  587. spv::LinkageType::Import &&
  588. (!options.GetAllowPartialLinkage() ||
  589. imports.find(inst->GetSingleWordOperand(0u)) != imports.end())) {
  590. linked_context->KillInst(&*inst);
  591. }
  592. }
  593. // Remove export linkage attributes if making an executable
  594. if (!options.GetCreateLibrary()) {
  595. next = linked_context->annotation_begin();
  596. for (auto inst = next; inst != linked_context->annotation_end();
  597. inst = next) {
  598. ++next;
  599. if (inst->opcode() == spv::Op::OpDecorate &&
  600. spv::Decoration(inst->GetSingleWordOperand(1u)) ==
  601. spv::Decoration::LinkageAttributes &&
  602. (spv::LinkageType(inst->GetSingleWordOperand(3u)) ==
  603. spv::LinkageType::Export ||
  604. spv::LinkageType(inst->GetSingleWordOperand(3u)) ==
  605. spv::LinkageType::LinkOnceODR)) {
  606. linked_context->KillInst(&*inst);
  607. }
  608. }
  609. }
  610. // Remove Linkage capability if making an executable and partial linkage is
  611. // not allowed
  612. if (!options.GetCreateLibrary() && !options.GetAllowPartialLinkage()) {
  613. for (auto& inst : linked_context->capabilities())
  614. if (spv::Capability(inst.GetSingleWordInOperand(0u)) ==
  615. spv::Capability::Linkage) {
  616. linked_context->KillInst(&inst);
  617. // The RemoveDuplicatesPass did remove duplicated capabilities, so we
  618. // now there aren’t more spv::Capability::Linkage further down.
  619. break;
  620. }
  621. }
  622. return SPV_SUCCESS;
  623. }
  624. spv_result_t VerifyIds(const MessageConsumer& consumer,
  625. opt::IRContext* linked_context) {
  626. std::unordered_set<uint32_t> ids;
  627. bool ok = true;
  628. linked_context->module()->ForEachInst(
  629. [&ids, &ok](const opt::Instruction* inst) {
  630. ok &= ids.insert(inst->unique_id()).second;
  631. });
  632. if (!ok) {
  633. consumer(SPV_MSG_INTERNAL_ERROR, "", {}, "Non-unique id in merged module");
  634. return SPV_ERROR_INVALID_ID;
  635. }
  636. return SPV_SUCCESS;
  637. }
  638. spv_result_t VerifyLimits(const MessageConsumer& consumer,
  639. const opt::IRContext& linked_context) {
  640. spv_position_t position = {};
  641. const uint32_t max_id_bound = linked_context.module()->id_bound();
  642. if (max_id_bound >= SPV_LIMIT_RESULT_ID_BOUND)
  643. DiagnosticStream({0u, 0u, 4u}, consumer, "", SPV_WARNING)
  644. << "The minimum limit of IDs, " << (SPV_LIMIT_RESULT_ID_BOUND - 1)
  645. << ", was exceeded:"
  646. << " " << max_id_bound << " is the current ID bound.\n"
  647. << "The resulting module might not be supported by all "
  648. "implementations.";
  649. size_t num_global_values = 0u;
  650. for (const auto& inst : linked_context.module()->types_values()) {
  651. num_global_values += inst.opcode() == spv::Op::OpVariable;
  652. }
  653. if (num_global_values >= SPV_LIMIT_GLOBAL_VARIABLES_MAX)
  654. DiagnosticStream(position, consumer, "", SPV_WARNING)
  655. << "The minimum limit of global values, "
  656. << (SPV_LIMIT_GLOBAL_VARIABLES_MAX - 1) << ", was exceeded;"
  657. << " " << num_global_values << " global values were found.\n"
  658. << "The resulting module might not be supported by all "
  659. "implementations.";
  660. return SPV_SUCCESS;
  661. }
  662. spv_result_t FixFunctionCallTypes(opt::IRContext& context,
  663. const LinkageTable& linkings) {
  664. auto mod = context.module();
  665. const auto type_manager = context.get_type_mgr();
  666. const auto def_use_mgr = context.get_def_use_mgr();
  667. for (auto& func : *mod) {
  668. func.ForEachInst([&](Instruction* inst) {
  669. if (inst->opcode() != spv::Op::OpFunctionCall) return;
  670. opt::Operand& target = inst->GetInOperand(0);
  671. // only fix calls to imported functions
  672. auto linking = std::find_if(
  673. linkings.begin(), linkings.end(), [&](const auto& entry) {
  674. return entry.exported_symbol.id == target.AsId();
  675. });
  676. if (linking == linkings.end()) return;
  677. auto builder = InstructionBuilder(&context, inst);
  678. for (uint32_t i = 1; i < inst->NumInOperands(); ++i) {
  679. auto exported_func_param =
  680. def_use_mgr->GetDef(linking->exported_symbol.parameter_ids[i - 1]);
  681. const Type* target_type =
  682. type_manager->GetType(exported_func_param->type_id());
  683. if (target_type->kind() != Type::kPointer) continue;
  684. opt::Operand& arg = inst->GetInOperand(i);
  685. const Type* param_type =
  686. type_manager->GetType(def_use_mgr->GetDef(arg.AsId())->type_id());
  687. // No need to cast if it already matches
  688. if (*param_type == *target_type) continue;
  689. auto new_id = context.TakeNextId();
  690. // cast to the expected pointer type
  691. builder.AddInstruction(MakeUnique<opt::Instruction>(
  692. &context, spv::Op::OpBitcast, exported_func_param->type_id(),
  693. new_id,
  694. opt::Instruction::OperandList(
  695. {{SPV_OPERAND_TYPE_ID, {arg.AsId()}}})));
  696. inst->SetInOperand(i, {new_id});
  697. }
  698. });
  699. }
  700. context.InvalidateAnalyses(opt::IRContext::kAnalysisDefUse |
  701. opt::IRContext::kAnalysisInstrToBlockMapping);
  702. return SPV_SUCCESS;
  703. }
  704. } // namespace
  705. spv_result_t Link(const Context& context,
  706. const std::vector<std::vector<uint32_t>>& binaries,
  707. std::vector<uint32_t>* linked_binary,
  708. const LinkerOptions& options) {
  709. std::vector<const uint32_t*> binary_ptrs;
  710. binary_ptrs.reserve(binaries.size());
  711. std::vector<size_t> binary_sizes;
  712. binary_sizes.reserve(binaries.size());
  713. for (const auto& binary : binaries) {
  714. binary_ptrs.push_back(binary.data());
  715. binary_sizes.push_back(binary.size());
  716. }
  717. return Link(context, binary_ptrs.data(), binary_sizes.data(), binaries.size(),
  718. linked_binary, options);
  719. }
  720. spv_result_t Link(const Context& context, const uint32_t* const* binaries,
  721. const size_t* binary_sizes, size_t num_binaries,
  722. std::vector<uint32_t>* linked_binary,
  723. const LinkerOptions& options) {
  724. spv_position_t position = {};
  725. const spv_context& c_context = context.CContext();
  726. const MessageConsumer& consumer = c_context->consumer;
  727. linked_binary->clear();
  728. if (num_binaries == 0u)
  729. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  730. << "No modules were given.";
  731. std::vector<std::unique_ptr<IRContext>> ir_contexts;
  732. std::vector<Module*> modules;
  733. modules.reserve(num_binaries);
  734. for (size_t i = 0u; i < num_binaries; ++i) {
  735. const uint32_t schema = binaries[i][4u];
  736. if (schema != 0u) {
  737. position.index = 4u;
  738. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  739. << "Schema is non-zero for module " << i + 1 << ".";
  740. }
  741. std::unique_ptr<IRContext> ir_context = BuildModule(
  742. c_context->target_env, consumer, binaries[i], binary_sizes[i]);
  743. if (ir_context == nullptr)
  744. return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_BINARY)
  745. << "Failed to build module " << i + 1 << " out of " << num_binaries
  746. << ".";
  747. modules.push_back(ir_context->module());
  748. ir_contexts.push_back(std::move(ir_context));
  749. }
  750. // Phase 1: Shift the IDs used in each binary so that they occupy a disjoint
  751. // range from the other binaries, and compute the new ID bound.
  752. uint32_t max_id_bound = 0u;
  753. spv_result_t res = ShiftIdsInModules(consumer, &modules, &max_id_bound);
  754. if (res != SPV_SUCCESS) return res;
  755. // Phase 2: Generate the header
  756. opt::ModuleHeader header;
  757. res = GenerateHeader(consumer, modules, max_id_bound, &header, options);
  758. if (res != SPV_SUCCESS) return res;
  759. IRContext linked_context(c_context->target_env, consumer);
  760. linked_context.module()->SetHeader(header);
  761. // Phase 3: Merge all the binaries into a single one.
  762. AssemblyGrammar grammar(c_context);
  763. res = MergeModules(consumer, modules, grammar, &linked_context);
  764. if (res != SPV_SUCCESS) return res;
  765. if (options.GetVerifyIds()) {
  766. res = VerifyIds(consumer, &linked_context);
  767. if (res != SPV_SUCCESS) return res;
  768. }
  769. // Phase 4: Remove duplicates
  770. PassManager manager;
  771. manager.SetMessageConsumer(consumer);
  772. manager.AddPass<RemoveDuplicatesPass>();
  773. opt::Pass::Status pass_res = manager.Run(&linked_context);
  774. if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA;
  775. // Phase 5: Find the import/export pairs
  776. LinkageTable linkings_to_do;
  777. res = GetImportExportPairs(consumer, linked_context,
  778. *linked_context.get_def_use_mgr(),
  779. *linked_context.get_decoration_mgr(),
  780. options.GetAllowPartialLinkage(), &linkings_to_do);
  781. if (res != SPV_SUCCESS) return res;
  782. // Phase 6: Ensure the import and export have the same types and decorations.
  783. res = CheckImportExportCompatibility(consumer, linkings_to_do,
  784. options.GetAllowPtrTypeMismatch(),
  785. &linked_context);
  786. if (res != SPV_SUCCESS) return res;
  787. // Phase 7: Remove all names and decorations of import variables/functions
  788. for (const auto& linking_entry : linkings_to_do) {
  789. linked_context.KillNamesAndDecorates(linking_entry.imported_symbol.id);
  790. for (const auto parameter_id :
  791. linking_entry.imported_symbol.parameter_ids) {
  792. linked_context.KillNamesAndDecorates(parameter_id);
  793. }
  794. }
  795. // Phase 8: Rematch import variables/functions to export variables/functions
  796. for (const auto& linking_entry : linkings_to_do) {
  797. linked_context.ReplaceAllUsesWith(linking_entry.imported_symbol.id,
  798. linking_entry.exported_symbol.id);
  799. }
  800. // Phase 9: Remove linkage specific instructions, such as import/export
  801. // attributes, linkage capability, etc. if applicable
  802. res = RemoveLinkageSpecificInstructions(consumer, options, linkings_to_do,
  803. linked_context.get_decoration_mgr(),
  804. &linked_context);
  805. if (res != SPV_SUCCESS) return res;
  806. // Phase 10: Optionally fix function call types
  807. if (options.GetAllowPtrTypeMismatch()) {
  808. res = FixFunctionCallTypes(linked_context, linkings_to_do);
  809. if (res != SPV_SUCCESS) return res;
  810. }
  811. // Phase 11: Compact the IDs used in the module
  812. manager.AddPass<opt::CompactIdsPass>();
  813. pass_res = manager.Run(&linked_context);
  814. if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA;
  815. // Phase 12: Recompute EntryPoint variables
  816. manager.AddPass<opt::RemoveUnusedInterfaceVariablesPass>();
  817. pass_res = manager.Run(&linked_context);
  818. if (pass_res == opt::Pass::Status::Failure) return SPV_ERROR_INVALID_DATA;
  819. // Phase 13: Warn if SPIR-V limits were exceeded
  820. res = VerifyLimits(consumer, linked_context);
  821. if (res != SPV_SUCCESS) return res;
  822. // Phase 14: Output the module
  823. linked_context.module()->ToBinary(linked_binary, true);
  824. return SPV_SUCCESS;
  825. }
  826. } // namespace spvtools