mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-26 09:41:03 +00:00
parent
efe286cd32
commit
3756b387f3
@ -41,11 +41,6 @@ namespace {
|
||||
#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) {
|
||||
@ -225,6 +220,11 @@ bool FoldInstructionInternal(ir::Instruction* inst) {
|
||||
|
||||
} // 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
|
||||
@ -612,7 +612,7 @@ ir::Instruction* FoldInstructionToConstant(
|
||||
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;
|
||||
}
|
||||
@ -649,12 +649,12 @@ ir::Instruction* FoldInstructionToConstant(
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -18,12 +18,16 @@
|
||||
#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
|
||||
|
@ -12,11 +12,12 @@
|
||||
// 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"
|
||||
|
||||
@ -470,6 +471,11 @@ bool Instruction::IsOpaqueType() const {
|
||||
}
|
||||
|
||||
bool Instruction::IsFoldable() const {
|
||||
return IsFoldableByFoldScalar() ||
|
||||
opt::GetConstantFoldingRules().HasFoldingRule(opcode());
|
||||
}
|
||||
|
||||
bool Instruction::IsFoldableByFoldScalar() const {
|
||||
if (!opt::IsFoldableOpcode(opcode())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -368,6 +368,10 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
// 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;
|
||||
|
@ -679,6 +679,32 @@ TEST_F(CCPTest, UndefInPhi) {
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user