MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / MergeMulMulArithmetic

Function MergeMulMulArithmetic

source/opt/folding_rules.cpp:755–802  ·  view source on GitHub ↗

Merges consecutive multiplies where each contains one constant operand. Cases: 2 * (x * 2) = x * 4 2 * (2 * x) = x * 4 (x * 2) * 2 = x * 4 (2 * x) * 2 = x * 4

Source from the content-addressed store, hash-verified

753// (x * 2) * 2 = x * 4
754// (2 * x) * 2 = x * 4
755FoldingRule MergeMulMulArithmetic() {
756 return [](IRContext* context, Instruction* inst,
757 const std::vector<const analysis::Constant*>& constants) {
758 assert(inst->opcode() == spv::Op::OpFMul ||
759 inst->opcode() == spv::Op::OpIMul);
760 analysis::ConstantManager* const_mgr = context->get_constant_mgr();
761 const analysis::Type* type =
762 context->get_type_mgr()->GetType(inst->type_id());
763
764 if (type->IsCooperativeMatrix()) {
765 return false;
766 }
767
768 if (HasFloatingPoint(type) && !inst->IsFloatingPointFoldingAllowed())
769 return false;
770
771 uint32_t width = ElementWidth(type);
772 if (width != 32 && width != 64) return false;
773
774 // Determine the constant input and the variable input in |inst|.
775 const analysis::Constant* const_input1 = ConstInput(constants);
776 if (!const_input1) return false;
777 Instruction* other_inst = NonConstInput(context, constants[0], inst);
778 if (HasFloatingPoint(type) && !other_inst->IsFloatingPointFoldingAllowed())
779 return false;
780
781 if (other_inst->opcode() == inst->opcode()) {
782 std::vector<const analysis::Constant*> other_constants =
783 const_mgr->GetOperandConstants(other_inst);
784 const analysis::Constant* const_input2 = ConstInput(other_constants);
785 if (!const_input2) return false;
786
787 bool other_first_is_variable = other_constants[0] == nullptr;
788 uint32_t merged_id = PerformOperation(const_mgr, inst->opcode(),
789 const_input1, const_input2);
790 if (merged_id == 0) return false;
791
792 uint32_t non_const_id = other_first_is_variable
793 ? other_inst->GetSingleWordInOperand(0u)
794 : other_inst->GetSingleWordInOperand(1u);
795 inst->SetInOperands({{SPV_OPERAND_TYPE_ID, {non_const_id}},
796 {SPV_OPERAND_TYPE_ID, {merged_id}}});
797 return true;
798 }
799
800 return false;
801 };
802}
803
804// Merges divides into subsequent multiplies if each instruction contains one
805// constant operand. Does not support integer operations.

Callers 1

AddFoldingRulesMethod · 0.85

Calls 15

ElementWidthFunction · 0.85
ConstInputFunction · 0.85
NonConstInputFunction · 0.85
PerformOperationFunction · 0.85
get_constant_mgrMethod · 0.80
get_type_mgrMethod · 0.80
IsCooperativeMatrixMethod · 0.80
GetOperandConstantsMethod · 0.80
SetInOperandsMethod · 0.80
HasFloatingPointFunction · 0.70

Tested by

no test coverage detected