mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 06:46:40 +08:00 
			
		
		
		
	glasm: Fix usage counting on phi nodes
This commit is contained in:
		
							parent
							
								
									4017928213
								
							
						
					
					
						commit
						9fbfe7d676
					
				| @ -178,6 +178,10 @@ void EmitInst(EmitContext& ctx, IR::Inst* inst) { | |||||||
|     throw LogicError("Invalid opcode {}", inst->GetOpcode()); |     throw LogicError("Invalid opcode {}", inst->GetOpcode()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool IsReference(IR::Inst& inst) { | ||||||
|  |     return inst.GetOpcode() == IR::Opcode::Reference; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Precolor(EmitContext& ctx, const IR::Program& program) { | void Precolor(EmitContext& ctx, const IR::Program& program) { | ||||||
|     for (IR::Block* const block : program.blocks) { |     for (IR::Block* const block : program.blocks) { | ||||||
|         for (IR::Inst& phi : block->Instructions() | std::views::take_while(IR::IsPhi)) { |         for (IR::Inst& phi : block->Instructions() | std::views::take_while(IR::IsPhi)) { | ||||||
| @ -194,11 +198,13 @@ void Precolor(EmitContext& ctx, const IR::Program& program) { | |||||||
|             default: |             default: | ||||||
|                 throw NotImplementedException("Phi node type {}", phi.Type()); |                 throw NotImplementedException("Phi node type {}", phi.Type()); | ||||||
|             } |             } | ||||||
|  |             // Insert phi moves before references to avoid overwritting them
 | ||||||
|             const size_t num_args{phi.NumArgs()}; |             const size_t num_args{phi.NumArgs()}; | ||||||
|             for (size_t i = 0; i < num_args; ++i) { |             for (size_t i = 0; i < num_args; ++i) { | ||||||
|                 IR::IREmitter{*phi.PhiBlock(i)}.PhiMove(phi, phi.Arg(i)); |                 IR::Block& phi_block{*phi.PhiBlock(i)}; | ||||||
|  |                 auto it{std::find_if_not(phi_block.rbegin(), phi_block.rend(), IsReference).base()}; | ||||||
|  |                 IR::IREmitter{phi_block, it}.PhiMove(phi, phi.Arg(i)); | ||||||
|             } |             } | ||||||
|             // Add reference to the phi node on the phi predecessor to avoid overwritting it
 |  | ||||||
|             for (size_t i = 0; i < num_args; ++i) { |             for (size_t i = 0; i < num_args; ++i) { | ||||||
|                 IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi}); |                 IR::IREmitter{*phi.PhiBlock(i)}.Reference(IR::Value{&phi}); | ||||||
|             } |             } | ||||||
| @ -237,7 +243,7 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) { | |||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 ctx.Add("MOV.S.CC RC,{};" |                 ctx.Add("MOV.S.CC RC,{};" | ||||||
|                         "BRK (EQ.x);" |                         "BRK(EQ.x);" | ||||||
|                         "ENDREP;", |                         "ENDREP;", | ||||||
|                         eval(node.data.repeat.cond)); |                         eval(node.data.repeat.cond)); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& inst); | |||||||
| void EmitVoid(EmitContext& ctx); | void EmitVoid(EmitContext& ctx); | ||||||
| void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | ||||||
| void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | ||||||
| void EmitReference(EmitContext&); | void EmitReference(EmitContext&, const IR::Value& value); | ||||||
| void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | ||||||
| void EmitJoin(EmitContext& ctx); | void EmitJoin(EmitContext& ctx); | ||||||
| void EmitDemoteToHelperInvocation(EmitContext& ctx); | void EmitDemoteToHelperInvocation(EmitContext& ctx); | ||||||
|  | |||||||
| @ -17,18 +17,26 @@ namespace Shader::Backend::GLASM { | |||||||
| 
 | 
 | ||||||
| #define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__) | #define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__) | ||||||
| 
 | 
 | ||||||
| void EmitPhi(EmitContext&, IR::Inst&) {} | void EmitPhi(EmitContext& ctx, IR::Inst& inst) { | ||||||
|  |     const size_t num_args{inst.NumArgs()}; | ||||||
|  |     for (size_t i = 0; i < num_args; ++i) { | ||||||
|  |         ctx.reg_alloc.Consume(inst.Arg(i)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void EmitVoid(EmitContext&) {} | void EmitVoid(EmitContext&) {} | ||||||
| 
 | 
 | ||||||
| void EmitReference(EmitContext&) {} | void EmitReference(EmitContext& ctx, const IR::Value& value) { | ||||||
|  |     ctx.reg_alloc.Consume(value); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) { | void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value) { | ||||||
|  |     const Register phi_reg{ctx.reg_alloc.Consume(phi)}; | ||||||
|  |     const Value eval_value{ctx.reg_alloc.Consume(value)}; | ||||||
|  | 
 | ||||||
|     if (phi == value) { |     if (phi == value) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     const Register phi_reg{ctx.reg_alloc.Consume(phi)}; |  | ||||||
|     const Value eval_value{ctx.reg_alloc.Consume(value)}; |  | ||||||
|     switch (phi.Inst()->Flags<IR::Type>()) { |     switch (phi.Inst()->Flags<IR::Type>()) { | ||||||
|     case IR::Type::U1: |     case IR::Type::U1: | ||||||
|     case IR::Type::U32: |     case IR::Type::U32: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user