1fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard//===-- SIAssignInterpRegs.cpp - Assign interpolation registers -----------===// 2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// The LLVM Compiler Infrastructure 4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// This file is distributed under the University of Illinois Open Source 6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// License. See LICENSE.TXT for details. 7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===// 9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 10fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// This pass maps the pseudo interpolation registers to the correct physical 11fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// registers. Prior to executing a fragment shader, the GPU loads interpolation 12fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// parameters into physical registers. The specific physical register that each 13fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// interpolation parameter ends up in depends on the type of the interpolation 14fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// parameter as well as how many interpolation parameters are used by the 15fa63f976522bd4faf19249e8c9ac4d3edda498d9Tom Stellard// shader. 16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// 17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard//===----------------------------------------------------------------------===// 18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDGPU.h" 22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "AMDIL.h" 23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "SIMachineFunctionInfo.h" 24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/MachineFunctionPass.h" 25b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard#include "llvm/CodeGen/MachineInstrBuilder.h" 26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "llvm/CodeGen/MachineRegisterInfo.h" 27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardusing namespace llvm; 29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardnamespace { 31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 32bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellardclass SIAssignInterpRegsPass : public MachineFunctionPass { 33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 34bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellardprivate: 35bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard static char ID; 36bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard TargetMachine &TM; 37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 38b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard void AddLiveIn(MachineFunction * MF, MachineRegisterInfo & MRI, 39b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard unsigned physReg, unsigned virtReg); 40b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard 41bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellardpublic: 42bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard SIAssignInterpRegsPass(TargetMachine &tm) : 43bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard MachineFunctionPass(ID), TM(tm) { } 44bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard 45bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard virtual bool runOnMachineFunction(MachineFunction &MF); 46bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard 47bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard const char *getPassName() const { return "SI Assign intrpolation registers"; } 48bcfc97dbf40c256ed59c2424e0c55b845f0f2569Tom Stellard}; 49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} // End anonymous namespace 51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardchar SIAssignInterpRegsPass::ID = 0; 53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#define INTERP_VALUES 16 55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstruct interp_info { 57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard bool enabled; 58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned regs[3]; 59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned reg_count; 60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}; 61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 63a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardFunctionPass *llvm::createSIAssignInterpRegsPass(TargetMachine &tm) { 64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return new SIAssignInterpRegsPass(tm); 65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool SIAssignInterpRegsPass::runOnMachineFunction(MachineFunction &MF) 68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{ 69a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard struct interp_info InterpUse[INTERP_VALUES] = { 7176b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::PERSP_SAMPLE_I, AMDGPU::PERSP_SAMPLE_J}, 2}, 7276b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::PERSP_CENTER_I, AMDGPU::PERSP_CENTER_J}, 2}, 7376b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::PERSP_CENTROID_I, AMDGPU::PERSP_CENTROID_J}, 2}, 7476b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::PERSP_I_W, AMDGPU::PERSP_J_W, AMDGPU::PERSP_1_W}, 3}, 7576b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::LINEAR_SAMPLE_I, AMDGPU::LINEAR_SAMPLE_J}, 2}, 7676b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::LINEAR_CENTER_I, AMDGPU::LINEAR_CENTER_J}, 2}, 7776b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::LINEAR_CENTROID_I, AMDGPU::LINEAR_CENTROID_J}, 2}, 7876b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::LINE_STIPPLE_TEX_COORD}, 1}, 7976b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::POS_X_FLOAT}, 1}, 8076b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::POS_Y_FLOAT}, 1}, 8176b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::POS_Z_FLOAT}, 1}, 8276b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::POS_W_FLOAT}, 1}, 8376b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::FRONT_FACE}, 1}, 8476b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::ANCILLARY}, 1}, 8576b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::SAMPLE_COVERAGE}, 1}, 8676b44034b9b234d3db4012342f0fae677d4f10f6Tom Stellard {false, {AMDGPU::POS_FIXED_PT}, 1} 87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard }; 88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>(); 90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard MachineRegisterInfo &MRI = MF.getRegInfo(); 91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* First pass, mark the interpolation values that are used. */ 93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (unsigned interp_idx = 0; interp_idx < INTERP_VALUES; interp_idx++) { 94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (unsigned reg_idx = 0; reg_idx < InterpUse[interp_idx].reg_count; 95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard reg_idx++) { 96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard InterpUse[interp_idx].enabled = 97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard !MRI.use_empty(InterpUse[interp_idx].regs[reg_idx]); 98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 99a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 100a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard unsigned used_vgprs = 0; 102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard /* Second pass, replace with VGPRs. */ 104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (unsigned interp_idx = 0; interp_idx < INTERP_VALUES; interp_idx++) { 105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!InterpUse[interp_idx].enabled) { 106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard continue; 107a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard MFI->spi_ps_input_addr |= (1 << interp_idx); 109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard for (unsigned reg_idx = 0; reg_idx < InterpUse[interp_idx].reg_count; 111a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard reg_idx++, used_vgprs++) { 112228a6641ccddaf24a993f827af1e97379785985aTom Stellard unsigned new_reg = AMDGPU::VReg_32RegClass.getRegister(used_vgprs); 113228a6641ccddaf24a993f827af1e97379785985aTom Stellard unsigned virt_reg = MRI.createVirtualRegister(&AMDGPU::VReg_32RegClass); 114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard MRI.replaceRegWith(InterpUse[interp_idx].regs[reg_idx], virt_reg); 115b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard AddLiveIn(&MF, MRI, new_reg, virt_reg); 116a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 118a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 120a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 121b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard 122b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellardvoid SIAssignInterpRegsPass::AddLiveIn(MachineFunction * MF, 123b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard MachineRegisterInfo & MRI, 124b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard unsigned physReg, unsigned virtReg) 125b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard{ 126b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard const TargetInstrInfo * TII = TM.getInstrInfo(); 127b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard if (!MRI.isLiveIn(physReg)) { 128b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard MRI.addLiveIn(physReg, virtReg); 129b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard MF->front().addLiveIn(physReg); 130b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard BuildMI(MF->front(), MF->front().begin(), DebugLoc(), 131b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard TII->get(TargetOpcode::COPY), virtReg) 132b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard .addReg(physReg); 133b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard } else { 134b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard MRI.replaceRegWith(virtReg, MRI.getLiveInVirtReg(physReg)); 135b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard } 136b6051bc7859829588b2361da96f8e828a7fe1326Tom Stellard} 137