#define UINT32_MAX 0xffffffff /* 4294967295U */
#endif
-const ConstantFoldingRules& GetConstantFoldingRules() {
- static ConstantFoldingRules* rules = new ConstantFoldingRules();
- return *rules;
-}
-
// Returns the single-word result from performing the given unary operation on
// the operand value which is passed in as a 32-bit word.
uint32_t UnaryOperate(SpvOp opcode, uint32_t operand) {
} // namespace
+const ConstantFoldingRules& GetConstantFoldingRules() {
+ static ConstantFoldingRules* rules = new ConstantFoldingRules();
+ return *rules;
+}
+
// Returns the result of performing an operation on scalar constant operands.
// This function extracts the operand values as 32 bit words and returns the
// result in 32 bit word. Scalar constants with longer than 32-bit width are
ir::IRContext* context = inst->context();
analysis::ConstantManager* const_mgr = context->get_constant_mgr();
- if (!inst->IsFoldable() &&
+ if (!inst->IsFoldableByFoldScalar() &&
!GetConstantFoldingRules().HasFoldingRule(inst->opcode())) {
return nullptr;
}
uint32_t result_val = 0;
bool successful = false;
// If all parameters are constant, fold the instruction to a constant.
- if (!missing_constants && inst->IsFoldable()) {
+ if (!missing_constants && inst->IsFoldableByFoldScalar()) {
result_val = FoldScalars(inst->opcode(), constants);
successful = true;
}
- if (!successful && inst->IsFoldable()) {
+ if (!successful && inst->IsFoldableByFoldScalar()) {
successful = FoldIntegerOpToConstant(inst, id_map, &result_val);
}
#include <cstdint>
#include <vector>
+#include "const_folding_rules.h"
#include "constants.h"
#include "def_use_manager.h"
namespace spvtools {
namespace opt {
+// Returns a reference to the ConstnatFoldingRules instance.
+const ConstantFoldingRules& GetConstantFoldingRules();
+
// Returns the result of folding a scalar instruction with the given |opcode|
// and |operands|. Each entry in |operands| is a pointer to an
// analysis::Constant instance, which should've been created with the constant
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "instruction.h"
+
#include <initializer_list>
#include "disassemble.h"
#include "fold.h"
-#include "instruction.h"
#include "ir_context.h"
#include "reflect.h"
}
bool Instruction::IsFoldable() const {
+ return IsFoldableByFoldScalar() ||
+ opt::GetConstantFoldingRules().HasFoldingRule(opcode());
+}
+
+bool Instruction::IsFoldableByFoldScalar() const {
if (!opt::IsFoldableOpcode(opcode())) {
return false;
}
// constant value.
bool IsFoldable() const;
+ // Returns true if |this| is an instruction which could be folded into a
+ // constant value by |FoldScalar|.
+ bool IsFoldableByFoldScalar() const;
+
inline bool operator==(const Instruction&) const;
inline bool operator!=(const Instruction&) const;
inline bool operator<(const Instruction&) const;
SinglePassRunAndMatch<opt::CCPPass>(text, true);
}
+
+// Just test to make sure the constant fold rules are being used. Will rely on
+// the folding test for specific testing of specific rules.
+TEST_F(CCPTest, UseConstantFoldingRules) {
+ const std::string text = R"(
+; CHECK: [[float1:%\w+]] = OpConstant {{%\w+}} 1
+; CHECK: OpReturnValue [[float1]]
+ OpCapability Shader
+ OpCapability Linkage
+ OpMemoryModel Logical GLSL450
+ OpDecorate %1 LinkageAttributes "func" Export
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %float = OpTypeFloat 32
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %8 = OpTypeFunction %float
+ %1 = OpFunction %float None %8
+ %10 = OpLabel
+ %17 = OpFAdd %float %float_0 %float_1
+ OpReturnValue %17
+ OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::CCPPass>(text, true);
+}
#endif
} // namespace