diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUUtil.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUUtil.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUUtil.cpp b/llvm/lib/Target/AMDGPU/AMDGPUUtil.cpp new file mode 100644 index 00000000000..63b359ffc14 --- /dev/null +++ b/llvm/lib/Target/AMDGPU/AMDGPUUtil.cpp @@ -0,0 +1,139 @@ +//===-- AMDGPUUtil.cpp - AMDGPU Utility functions -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Common utility functions used by hw codegen targets +// +//===----------------------------------------------------------------------===// + +#include "AMDGPUUtil.h" +#include "AMDGPURegisterInfo.h" +#include "AMDIL.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" + +using namespace llvm; + +// Some instructions act as place holders to emulate operations that the GPU +// hardware does automatically. This function can be used to check if +// an opcode falls into this category. +bool AMDGPU::isPlaceHolderOpcode(unsigned opcode) +{ + switch (opcode) { + default: return false; + case AMDGPU::RETURN: + case AMDGPU::LOAD_INPUT: + case AMDGPU::LAST: + case AMDGPU::MASK_WRITE: + case AMDGPU::RESERVE_REG: + return true; + } +} + +bool AMDGPU::isTransOp(unsigned opcode) +{ + switch(opcode) { + default: return false; + + case AMDGPU::COS_r600: + case AMDGPU::COS_eg: + case AMDGPU::MULLIT: + case AMDGPU::MUL_LIT_r600: + case AMDGPU::MUL_LIT_eg: + case AMDGPU::EXP_IEEE_r600: + case AMDGPU::EXP_IEEE_eg: + case AMDGPU::LOG_CLAMPED_r600: + case AMDGPU::LOG_IEEE_r600: + case AMDGPU::LOG_CLAMPED_eg: + case AMDGPU::LOG_IEEE_eg: + return true; + } +} + +bool AMDGPU::isTexOp(unsigned opcode) +{ + switch(opcode) { + default: return false; + case AMDGPU::TEX_LD: + case AMDGPU::TEX_GET_TEXTURE_RESINFO: + case AMDGPU::TEX_SAMPLE: + case AMDGPU::TEX_SAMPLE_C: + case AMDGPU::TEX_SAMPLE_L: + case AMDGPU::TEX_SAMPLE_C_L: + case AMDGPU::TEX_SAMPLE_LB: + case AMDGPU::TEX_SAMPLE_C_LB: + case AMDGPU::TEX_SAMPLE_G: + case AMDGPU::TEX_SAMPLE_C_G: + case AMDGPU::TEX_GET_GRADIENTS_H: + case AMDGPU::TEX_GET_GRADIENTS_V: + case AMDGPU::TEX_SET_GRADIENTS_H: + case AMDGPU::TEX_SET_GRADIENTS_V: + return true; + } +} + +bool AMDGPU::isReductionOp(unsigned opcode) +{ + switch(opcode) { + default: return false; + case AMDGPU::DOT4_r600: + case AMDGPU::DOT4_eg: + return true; + } +} + +bool AMDGPU::isCubeOp(unsigned opcode) +{ + switch(opcode) { + default: return false; + case AMDGPU::CUBE_r600: + case AMDGPU::CUBE_eg: + return true; + } +} + + +bool AMDGPU::isFCOp(unsigned opcode) +{ + switch(opcode) { + default: return false; + case AMDGPU::BREAK_LOGICALZ_f32: + case AMDGPU::BREAK_LOGICALNZ_i32: + case AMDGPU::BREAK_LOGICALZ_i32: + case AMDGPU::BREAK_LOGICALNZ_f32: + case AMDGPU::CONTINUE_LOGICALNZ_f32: + case AMDGPU::IF_LOGICALNZ_i32: + case AMDGPU::IF_LOGICALZ_f32: + case AMDGPU::ELSE: + case AMDGPU::ENDIF: + case AMDGPU::ENDLOOP: + case AMDGPU::IF_LOGICALNZ_f32: + case AMDGPU::WHILELOOP: + return true; + } +} + +void AMDGPU::utilAddLiveIn(MachineFunction * MF, + MachineRegisterInfo & MRI, + const TargetInstrInfo * TII, + unsigned physReg, unsigned virtReg) +{ + if (!MRI.isLiveIn(physReg)) { + MRI.addLiveIn(physReg, virtReg); + MF->front().addLiveIn(physReg); + BuildMI(MF->front(), MF->front().begin(), DebugLoc(), + TII->get(TargetOpcode::COPY), virtReg) + .addReg(physReg); + } else { + MRI.replaceRegWith(virtReg, MRI.getLiveInVirtReg(physReg)); + } +} |