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

Function FactorAddSubMuls

source/opt/folding_rules.cpp:1590–1637  ·  view source on GitHub ↗

Perform the following factoring identity, handling all operand order combinations: (a * b) + (a * c) = a * (b + c) (a * b) - (a * c) = a * (b - c)

Source from the content-addressed store, hash-verified

1588// (a * b) + (a * c) = a * (b + c)
1589// (a * b) - (a * c) = a * (b - c)
1590FoldingRule FactorAddSubMuls() {
1591 return [](IRContext* context, Instruction* inst,
1592 const std::vector<const analysis::Constant*>&) {
1593 assert(inst->opcode() == spv::Op::OpFAdd ||
1594 inst->opcode() == spv::Op::OpFSub ||
1595 inst->opcode() == spv::Op::OpIAdd ||
1596 inst->opcode() == spv::Op::OpISub);
1597 const analysis::Type* type =
1598 context->get_type_mgr()->GetType(inst->type_id());
1599 bool uses_float = HasFloatingPoint(type);
1600 if (uses_float && !inst->IsFloatingPointFoldingAllowed()) return false;
1601
1602 analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
1603 uint32_t add_op0 = inst->GetSingleWordInOperand(0);
1604 Instruction* add_op0_inst = def_use_mgr->GetDef(add_op0);
1605 if (add_op0_inst->opcode() != spv::Op::OpFMul &&
1606 add_op0_inst->opcode() != spv::Op::OpIMul)
1607 return false;
1608 uint32_t add_op1 = inst->GetSingleWordInOperand(1);
1609 Instruction* add_op1_inst = def_use_mgr->GetDef(add_op1);
1610 if (add_op1_inst->opcode() != spv::Op::OpFMul &&
1611 add_op1_inst->opcode() != spv::Op::OpIMul)
1612 return false;
1613
1614 // Only perform this optimization if both of the muls only have one use.
1615 // Otherwise this is a deoptimization in size and performance.
1616 if (def_use_mgr->NumUses(add_op0_inst) > 1) return false;
1617 if (def_use_mgr->NumUses(add_op1_inst) > 1) return false;
1618
1619 if (add_op0_inst->opcode() == spv::Op::OpFMul &&
1620 (!add_op0_inst->IsFloatingPointFoldingAllowed() ||
1621 !add_op1_inst->IsFloatingPointFoldingAllowed()))
1622 return false;
1623
1624 for (int i = 0; i < 2; i++) {
1625 for (int j = 0; j < 2; j++) {
1626 // Check if operand i in add_op0_inst matches operand j in add_op1_inst.
1627 if (FactorAddSubMulsOpnds(add_op0_inst->GetSingleWordInOperand(i),
1628 add_op0_inst->GetSingleWordInOperand(1 - i),
1629 add_op1_inst->GetSingleWordInOperand(j),
1630 add_op1_inst->GetSingleWordInOperand(1 - j),
1631 inst))
1632 return true;
1633 }
1634 }
1635 return false;
1636 };
1637}
1638
1639// Reassociate integer instructions where both operands share the same opcode
1640// and both source instructions contain a constant.

Callers 1

AddFoldingRulesMethod · 0.85

Calls 11

FactorAddSubMulsOpndsFunction · 0.85
get_type_mgrMethod · 0.80
NumUsesMethod · 0.80
HasFloatingPointFunction · 0.70
opcodeMethod · 0.45
GetTypeMethod · 0.45
type_idMethod · 0.45
get_def_use_mgrMethod · 0.45
GetDefMethod · 0.45

Tested by

no test coverage detected