shader_ir: Remove the old scanner.
This commit is contained in:
		
							parent
							
								
									8af6e6a052
								
							
						
					
					
						commit
						c218ae4b02
					
				@ -22,20 +22,6 @@ using Tegra::Shader::OpCode;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Merges exit method of two parallel branches.
 | 
					 | 
				
			||||||
constexpr ExitMethod ParallelExit(ExitMethod a, ExitMethod b) {
 | 
					 | 
				
			||||||
    if (a == ExitMethod::Undetermined) {
 | 
					 | 
				
			||||||
        return b;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (b == ExitMethod::Undetermined) {
 | 
					 | 
				
			||||||
        return a;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (a == b) {
 | 
					 | 
				
			||||||
        return a;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return ExitMethod::Conditional;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Returns whether the instruction at the specified offset is a 'sched' instruction.
 | 
					 * Returns whether the instruction at the specified offset is a 'sched' instruction.
 | 
				
			||||||
 * Sched instructions always appear before a sequence of 3 instructions.
 | 
					 * Sched instructions always appear before a sequence of 3 instructions.
 | 
				
			||||||
@ -79,58 +65,6 @@ void ShaderIR::Decode() {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ExitMethod ShaderIR::Scan(u32 begin, u32 end, std::set<u32>& labels) {
 | 
					 | 
				
			||||||
    const auto [iter, inserted] =
 | 
					 | 
				
			||||||
        exit_method_map.emplace(std::make_pair(begin, end), ExitMethod::Undetermined);
 | 
					 | 
				
			||||||
    ExitMethod& exit_method = iter->second;
 | 
					 | 
				
			||||||
    if (!inserted)
 | 
					 | 
				
			||||||
        return exit_method;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (u32 offset = begin; offset != end && offset != MAX_PROGRAM_LENGTH; ++offset) {
 | 
					 | 
				
			||||||
        coverage_begin = std::min(coverage_begin, offset);
 | 
					 | 
				
			||||||
        coverage_end = std::max(coverage_end, offset + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const Instruction instr = {program_code[offset]};
 | 
					 | 
				
			||||||
        const auto opcode = OpCode::Decode(instr);
 | 
					 | 
				
			||||||
        if (!opcode)
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        switch (opcode->get().GetId()) {
 | 
					 | 
				
			||||||
        case OpCode::Id::EXIT: {
 | 
					 | 
				
			||||||
            // The EXIT instruction can be predicated, which means that the shader can conditionally
 | 
					 | 
				
			||||||
            // end on this instruction. We have to consider the case where the condition is not met
 | 
					 | 
				
			||||||
            // and check the exit method of that other basic block.
 | 
					 | 
				
			||||||
            using Tegra::Shader::Pred;
 | 
					 | 
				
			||||||
            if (instr.pred.pred_index == static_cast<u64>(Pred::UnusedIndex)) {
 | 
					 | 
				
			||||||
                return exit_method = ExitMethod::AlwaysEnd;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                const ExitMethod not_met = Scan(offset + 1, end, labels);
 | 
					 | 
				
			||||||
                return exit_method = ParallelExit(ExitMethod::AlwaysEnd, not_met);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        case OpCode::Id::BRA: {
 | 
					 | 
				
			||||||
            const u32 target = offset + instr.bra.GetBranchTarget();
 | 
					 | 
				
			||||||
            labels.insert(target);
 | 
					 | 
				
			||||||
            const ExitMethod no_jmp = Scan(offset + 1, end, labels);
 | 
					 | 
				
			||||||
            const ExitMethod jmp = Scan(target, end, labels);
 | 
					 | 
				
			||||||
            return exit_method = ParallelExit(no_jmp, jmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        case OpCode::Id::SSY:
 | 
					 | 
				
			||||||
        case OpCode::Id::PBK: {
 | 
					 | 
				
			||||||
            // The SSY and PBK use a similar encoding as the BRA instruction.
 | 
					 | 
				
			||||||
            UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
 | 
					 | 
				
			||||||
                                 "Constant buffer branching is not supported");
 | 
					 | 
				
			||||||
            const u32 target = offset + instr.bra.GetBranchTarget();
 | 
					 | 
				
			||||||
            labels.insert(target);
 | 
					 | 
				
			||||||
            // Continue scanning for an exit method.
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return exit_method = ExitMethod::AlwaysReturn;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) {
 | 
					NodeBlock ShaderIR::DecodeRange(u32 begin, u32 end) {
 | 
				
			||||||
    NodeBlock basic_block;
 | 
					    NodeBlock basic_block;
 | 
				
			||||||
    for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) {
 | 
					    for (u32 pc = begin; pc < (begin > end ? MAX_PROGRAM_LENGTH : end);) {
 | 
				
			||||||
 | 
				
			|||||||
@ -26,14 +26,6 @@ using ProgramCode = std::vector<u64>;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
constexpr u32 MAX_PROGRAM_LENGTH = 0x1000;
 | 
					constexpr u32 MAX_PROGRAM_LENGTH = 0x1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Describes the behaviour of code path of a given entry point and a return point.
 | 
					 | 
				
			||||||
enum class ExitMethod {
 | 
					 | 
				
			||||||
    Undetermined, ///< Internal value. Only occur when analyzing JMP loop.
 | 
					 | 
				
			||||||
    AlwaysReturn, ///< All code paths reach the return point.
 | 
					 | 
				
			||||||
    Conditional,  ///< Code path reaches the return point or an END instruction conditionally.
 | 
					 | 
				
			||||||
    AlwaysEnd,    ///< All code paths reach a END instruction.
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ConstBuffer {
 | 
					class ConstBuffer {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    explicit ConstBuffer(u32 max_offset, bool is_indirect)
 | 
					    explicit ConstBuffer(u32 max_offset, bool is_indirect)
 | 
				
			||||||
@ -132,8 +124,6 @@ public:
 | 
				
			|||||||
private:
 | 
					private:
 | 
				
			||||||
    void Decode();
 | 
					    void Decode();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ExitMethod Scan(u32 begin, u32 end, std::set<u32>& labels);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    NodeBlock DecodeRange(u32 begin, u32 end);
 | 
					    NodeBlock DecodeRange(u32 begin, u32 end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@ -329,7 +319,6 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    u32 coverage_begin{};
 | 
					    u32 coverage_begin{};
 | 
				
			||||||
    u32 coverage_end{};
 | 
					    u32 coverage_end{};
 | 
				
			||||||
    std::map<std::pair<u32, u32>, ExitMethod> exit_method_map;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::map<u32, NodeBlock> basic_blocks;
 | 
					    std::map<u32, NodeBlock> basic_blocks;
 | 
				
			||||||
    NodeBlock global_code;
 | 
					    NodeBlock global_code;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user