| 83 | } |
| 84 | |
| 85 | void FuzzerPassDonateModules::DonateSingleModule( |
| 86 | opt::IRContext* donor_ir_context, bool make_livesafe) { |
| 87 | // Check that the donated module has capabilities, supported by the recipient |
| 88 | // module. |
| 89 | for (const auto& capability_inst : donor_ir_context->capabilities()) { |
| 90 | auto capability = |
| 91 | static_cast<spv::Capability>(capability_inst.GetSingleWordInOperand(0)); |
| 92 | if (!GetIRContext()->get_feature_mgr()->HasCapability(capability)) { |
| 93 | return; |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | // The ids used by the donor module may very well clash with ids defined in |
| 98 | // the recipient module. Furthermore, some instructions defined in the donor |
| 99 | // module will be equivalent to instructions defined in the recipient module, |
| 100 | // and it is not always legal to re-declare equivalent instructions. For |
| 101 | // example, OpTypeVoid cannot be declared twice. |
| 102 | // |
| 103 | // To handle this, we maintain a mapping from an id used in the donor module |
| 104 | // to the corresponding id that will be used by the donated code when it |
| 105 | // appears in the recipient module. |
| 106 | // |
| 107 | // This mapping is populated in two ways: |
| 108 | // (1) by mapping a donor instruction's result id to the id of some equivalent |
| 109 | // existing instruction in the recipient (e.g. this has to be done for |
| 110 | // OpTypeVoid) |
| 111 | // (2) by mapping a donor instruction's result id to a freshly chosen id that |
| 112 | // is guaranteed to be different from any id already used by the recipient |
| 113 | // (or from any id already chosen to handle a previous donor id) |
| 114 | std::map<uint32_t, uint32_t> original_id_to_donated_id; |
| 115 | |
| 116 | HandleExternalInstructionImports(donor_ir_context, |
| 117 | &original_id_to_donated_id); |
| 118 | HandleTypesAndValues(donor_ir_context, &original_id_to_donated_id); |
| 119 | HandleFunctions(donor_ir_context, &original_id_to_donated_id, make_livesafe); |
| 120 | |
| 121 | // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3115) Handle some |
| 122 | // kinds of decoration. |
| 123 | } |
| 124 | |
| 125 | spv::StorageClass FuzzerPassDonateModules::AdaptStorageClass( |
| 126 | spv::StorageClass donor_storage_class) { |