blob: 663a77f264530ba97a83a70d8030858d32bcce41 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
//===-- AMDGPUUtil.cpp - TODO: Add brief description -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// TODO: Add full description
//
//===----------------------------------------------------------------------===//
#include "AMDGPUUtil.h"
#include "AMDGPURegisterInfo.h"
#include "AMDIL.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/ErrorHandling.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 llvm::isPlaceHolderOpcode(unsigned opcode)
{
switch (opcode) {
default: return false;
case AMDIL::EXPORT_REG:
case AMDIL::RETURN:
case AMDIL::LOAD_INPUT:
case AMDIL::LAST:
case AMDIL::MASK_WRITE:
case AMDIL::RESERVE_REG:
return true;
}
}
bool llvm::isTransOp(unsigned opcode)
{
switch(opcode) {
default: return false;
case AMDIL::COS_f32:
case AMDIL::COS_r600:
case AMDIL::COS_eg:
case AMDIL::RSQ_f32:
case AMDIL::FTOI:
case AMDIL::ITOF:
case AMDIL::MULLIT:
case AMDIL::MUL_LIT_r600:
case AMDIL::MUL_LIT_eg:
case AMDIL::SHR_i32:
case AMDIL::SIN_f32:
case AMDIL::EXP_f32:
case AMDIL::EXP_IEEE_r600:
case AMDIL::EXP_IEEE_eg:
case AMDIL::LOG_CLAMPED_r600:
case AMDIL::LOG_IEEE_r600:
case AMDIL::LOG_CLAMPED_eg:
case AMDIL::LOG_IEEE_eg:
case AMDIL::LOG_f32:
return true;
}
}
bool llvm::isTexOp(unsigned opcode)
{
switch(opcode) {
default: return false;
case AMDIL::TEX_SAMPLE:
case AMDIL::TEX_SAMPLE_C:
case AMDIL::TEX_SAMPLE_L:
case AMDIL::TEX_SAMPLE_C_L:
case AMDIL::TEX_SAMPLE_LB:
case AMDIL::TEX_SAMPLE_C_LB:
case AMDIL::TEX_SAMPLE_G:
case AMDIL::TEX_SAMPLE_C_G:
return true;
}
}
bool llvm::isReductionOp(unsigned opcode)
{
switch(opcode) {
default: return false;
case AMDIL::DOT4_r600:
case AMDIL::DOT4_eg:
return true;
}
}
bool llvm::isFCOp(unsigned opcode)
{
switch(opcode) {
default: return false;
case AMDIL::BREAK_LOGICALZ_f32:
case AMDIL::BREAK_LOGICALNZ_i32:
case AMDIL::BREAK_LOGICALZ_i32:
case AMDIL::CONTINUE_LOGICALNZ_f32:
case AMDIL::IF_LOGICALNZ_i32:
case AMDIL::IF_LOGICALZ_f32:
case AMDIL::ELSE:
case AMDIL::ENDIF:
case AMDIL::ENDLOOP:
case AMDIL::IF_LOGICALNZ_f32:
case AMDIL::WHILELOOP:
return true;
}
}
void AMDGPU::utilAddLiveIn(MachineFunction * MF, MachineRegisterInfo & MRI,
const struct 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));
}
}
|