radeon/llvm: Remove IOExpansion files

This commit is contained in:
Tom Stellard
2012-04-24 21:15:11 -04:00
parent 4b11f4321b
commit ba9bd41880
15 changed files with 0 additions and 4048 deletions
@@ -174,7 +174,6 @@ bool AMDGPUPassConfig::addPreEmitPass() {
PM.add(createSIPropagateImmReadsPass(*TM));
}
PM.add(createAMDILIOExpansion(*TM));
return false;
}
-2
View File
@@ -112,8 +112,6 @@ FunctionPass*
createAMDILCFGStructurizerPass(TargetMachine &TM AMDIL_OPT_LEVEL_DECL);
FunctionPass*
createAMDILLiteralManager(TargetMachine &TM AMDIL_OPT_LEVEL_DECL);
FunctionPass*
createAMDILIOExpansion(TargetMachine &TM AMDIL_OPT_LEVEL_DECL);
extern Target TheAMDILTarget;
extern Target TheAMDGPUTarget;
@@ -1,723 +0,0 @@
//===-- AMDIL789IOExpansion.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.
//
//==-----------------------------------------------------------------------===//
//
// @file AMDIL789IOExpansion.cpp
// @details Implementation of the IO expansion class for 789 devices.
//
#include "AMDILCompilerErrors.h"
#include "AMDILCompilerWarnings.h"
#include "AMDILDevices.h"
#include "AMDILGlobalManager.h"
#include "AMDILIOExpansion.h"
#include "AMDILKernelManager.h"
#include "AMDILMachineFunctionInfo.h"
#include "AMDILTargetMachine.h"
#include "AMDILUtilityFunctions.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Value.h"
using namespace llvm;
AMDIL789IOExpansion::AMDIL789IOExpansion(TargetMachine &tm
AMDIL_OPT_LEVEL_DECL)
: AMDILIOExpansion(tm AMDIL_OPT_LEVEL_VAR)
{
}
AMDIL789IOExpansion::~AMDIL789IOExpansion() {
}
const char *AMDIL789IOExpansion::getPassName() const
{
return "AMDIL 789 IO Expansion Pass";
}
// This code produces the following pseudo-IL:
// mov r1007, $src.y000
// cmov_logical r1007.x___, $flag.yyyy, r1007.xxxx, $src.xxxx
// mov r1006, $src.z000
// cmov_logical r1007.x___, $flag.zzzz, r1006.xxxx, r1007.xxxx
// mov r1006, $src.w000
// cmov_logical $dst.x___, $flag.wwww, r1006.xxxx, r1007.xxxx
void
AMDIL789IOExpansion::emitComponentExtract(MachineInstr *MI,
unsigned flag, unsigned src, unsigned dst, bool before)
{
MachineBasicBlock::iterator I = *MI;
DebugLoc DL = MI->getDebugLoc();
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VEXTRACT_v4i32), AMDIL::R1007)
.addReg(src)
.addImm(2);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_Y_i32), AMDIL::R1007)
.addReg(flag)
.addReg(AMDIL::R1007)
.addReg(src);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VEXTRACT_v4i32), AMDIL::R1006)
.addReg(src)
.addImm(3);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_Z_i32), AMDIL::R1007)
.addReg(flag)
.addReg(AMDIL::R1006)
.addReg(AMDIL::R1007);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VEXTRACT_v4i32), AMDIL::R1006)
.addReg(src)
.addImm(4);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_W_i32), dst)
.addReg(flag)
.addReg(AMDIL::R1006)
.addReg(AMDIL::R1007);
}
// We have a 128 bit load but a 8/16/32bit value, so we need to
// select the correct component and make sure that the correct
// bits are selected. For the 8 and 16 bit cases we need to
// extract from the component the correct bits and for 32 bits
// we just need to select the correct component.
void
AMDIL789IOExpansion::emitDataLoadSelect(MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
DebugLoc DL = MI->getDebugLoc();
emitComponentExtract(MI, AMDIL::R1008, AMDIL::R1011, AMDIL::R1011, false);
if (getMemorySize(MI) == 1) {
// This produces the following pseudo-IL:
// iand r1006.x___, r1010.xxxx, l14.xxxx
// mov r1006, r1006.xxxx
// iadd r1006, r1006, {0, -1, 2, 3}
// ieq r1008, r1006, 0
// mov r1011, r1011.xxxx
// ishr r1011, r1011, {0, 8, 16, 24}
// mov r1007, r1011.y000
// cmov_logical r1007.x___, r1008.yyyy, r1007.xxxx, r1011.xxxx
// mov r1006, r1011.z000
// cmov_logical r1007.x___, r1008.zzzz, r1006.xxxx, r1007.xxxx
// mov r1006, r1011.w000
// cmov_logical r1011.x___, r1008.wwww, r1006.xxxx, r1007.xxxx
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1006)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1006)
.addReg(AMDIL::R1006);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1006)
.addReg(AMDIL::R1006)
.addImm(mMFI->addi128Literal(0xFFFFFFFFULL << 32,
(0xFFFFFFFEULL | (0xFFFFFFFDULL << 32))));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::IEQ_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1006)
.addImm(mMFI->addi32Literal(0));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHRVEC_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi128Literal(8ULL << 32, 16ULL | (24ULL << 32)));
emitComponentExtract(MI, AMDIL::R1008, AMDIL::R1011, AMDIL::R1011, false);
} else if (getMemorySize(MI) == 2) {
// This produces the following pseudo-IL:
// ishr r1007.x___, r1010.xxxx, 1
// iand r1008.x___, r1007.xxxx, 1
// ishr r1007.x___, r1011.xxxx, 16
// cmov_logical r1011.x___, r1008.xxxx, r1007.xxxx, r1011.xxxx
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1007)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(1));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1007)
.addImm(mMFI->addi32Literal(1));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1011)
.addReg(AMDIL::R1008)
.addReg(AMDIL::R1007)
.addReg(AMDIL::R1011);
}
}
// This function does address calculations modifications to load from a vector
// register type instead of a dword addressed load.
void
AMDIL789IOExpansion::emitVectorAddressCalc(MachineInstr *MI, bool is32bit, bool needsSelect)
{
MachineBasicBlock::iterator I = *MI;
DebugLoc DL = MI->getDebugLoc();
// This produces the following pseudo-IL:
// ishr r1007.x___, r1010.xxxx, (is32bit) ? 2 : 3
// iand r1008.x___, r1007.xxxx, (is32bit) ? 3 : 1
// ishr r1007.x___, r1007.xxxx, (is32bit) ? 2 : 1
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1007)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal((is32bit) ? 0x2 : 3));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1007)
.addImm(mMFI->addi32Literal((is32bit) ? 3 : 1));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1007)
.addReg(AMDIL::R1007)
.addImm(mMFI->addi32Literal((is32bit) ? 2 : 1));
if (needsSelect) {
// If the component selection is required, the following
// pseudo-IL is produced.
// mov r1008, r1008.xxxx
// iadd r1008, r1008, (is32bit) ? {0, -1, -2, -3} : {0, 0, -1, -1}
// ieq r1008, r1008, 0
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi128Literal((is32bit) ? 0xFFFFFFFFULL << 32 : 0ULL,
(is32bit) ? 0xFFFFFFFEULL | (0xFFFFFFFDULL << 32) :
-1ULL));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::IEQ_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(0));
}
}
// This function emits a switch statement and writes 32bit/64bit
// value to a 128bit vector register type.
void
AMDIL789IOExpansion::emitVectorSwitchWrite(MachineInstr *MI, bool is32bit)
{
MachineBasicBlock::iterator I = *MI;
uint32_t xID = getPointerID(MI);
assert(xID && "Found a scratch store that was incorrectly marked as zero ID!\n");
// This section generates the following pseudo-IL:
// switch r1008.x
// default
// mov x1[r1007.x].(is32bit) ? x___ : xy__, r1011.x{y}
// break
// case 1
// mov x1[r1007.x].(is32bit) ? _y__ : __zw, r1011.x{yxy}
// break
// if is32bit is true, case 2 and 3 are emitted.
// case 2
// mov x1[r1007.x].__z_, r1011.x
// break
// case 3
// mov x1[r1007.x].___w, r1011.x
// break
// endswitch
DebugLoc DL;
BuildMI(*mBB, I, MI->getDebugLoc(), mTII->get(AMDIL::SWITCH))
.addReg(AMDIL::R1008);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::DEFAULT));
BuildMI(*mBB, I, DL,
mTII->get((is32bit) ? AMDIL::SCRATCHSTORE_X : AMDIL::SCRATCHSTORE_XY)
, AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(xID);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BREAK));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CASE)).addImm(1);
BuildMI(*mBB, I, DL,
mTII->get((is32bit) ? AMDIL::SCRATCHSTORE_Y : AMDIL::SCRATCHSTORE_ZW), AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(xID);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BREAK));
if (is32bit) {
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CASE)).addImm(2);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHSTORE_Z), AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(xID);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BREAK));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CASE)).addImm(3);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHSTORE_W), AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(xID);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BREAK));
}
BuildMI(*mBB, I, DL, mTII->get(AMDIL::ENDSWITCH));
}
void
AMDIL789IOExpansion::expandPrivateLoad(MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
bool HWPrivate = mSTM->device()->usesHardware(AMDILDeviceInfo::PrivateMem);
if (!HWPrivate || mSTM->device()->isSupported(AMDILDeviceInfo::PrivateUAV)) {
return expandGlobalLoad(MI);
}
if (!mMFI->usesMem(AMDILDevice::SCRATCH_ID)
&& mKM->isKernel()) {
mMFI->addErrorMsg(amd::CompilerErrorMessage[MEMOP_NO_ALLOCATION]);
}
uint32_t xID = getPointerID(MI);
assert(xID && "Found a scratch load that was incorrectly marked as zero ID!\n");
if (!xID) {
xID = mSTM->device()->getResourceID(AMDILDevice::SCRATCH_ID);
mMFI->addErrorMsg(amd::CompilerWarningMessage[RECOVERABLE_ERROR]);
}
DebugLoc DL;
// These instructions go before the current MI.
expandLoadStartCode(MI);
switch (getMemorySize(MI)) {
default:
// Since the private register is a 128 bit aligned, we have to align the address
// first, since our source address is 32bit aligned and then load the data.
// This produces the following pseudo-IL:
// ishr r1010.x___, r1010.xxxx, 4
// mov r1011, x1[r1010.x]
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SHR_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(4));
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(xID);
break;
case 1:
case 2:
case 4:
emitVectorAddressCalc(MI, true, true);
// This produces the following pseudo-IL:
// mov r1011, x1[r1007.x]
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHLOAD), AMDIL::R1011)
.addReg(AMDIL::R1007)
.addImm(xID);
// These instructions go after the current MI.
emitDataLoadSelect(MI);
break;
case 8:
emitVectorAddressCalc(MI, false, true);
// This produces the following pseudo-IL:
// mov r1011, x1[r1007.x]
// mov r1007, r1011.zw00
// cmov_logical r1011.xy__, r1008.xxxx, r1011.xy, r1007.zw
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHLOAD), AMDIL::R1011)
.addReg(AMDIL::R1007)
.addImm(xID);
// These instructions go after the current MI.
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::VEXTRACT_v2i64), AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(2);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::CMOVLOG_i64), AMDIL::R1011)
.addReg(AMDIL::R1008)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1007);
break;
}
expandPackedData(MI);
expandExtendLoad(MI);
BuildMI(*mBB, I, MI->getDebugLoc(),
mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)),
MI->getOperand(0).getReg())
.addReg(AMDIL::R1011);
}
void
AMDIL789IOExpansion::expandConstantLoad(MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
if (!isHardwareInst(MI) || MI->memoperands_empty()) {
return expandGlobalLoad(MI);
}
uint32_t cID = getPointerID(MI);
if (cID < 2) {
return expandGlobalLoad(MI);
}
if (!mMFI->usesMem(AMDILDevice::CONSTANT_ID)
&& mKM->isKernel()) {
mMFI->addErrorMsg(amd::CompilerErrorMessage[MEMOP_NO_ALLOCATION]);
}
DebugLoc DL;
// These instructions go before the current MI.
expandLoadStartCode(MI);
switch (getMemorySize(MI)) {
default:
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SHR_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(4));
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::CBLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(cID);
break;
case 1:
case 2:
case 4:
emitVectorAddressCalc(MI, true, true);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::CBLOAD), AMDIL::R1011)
.addReg(AMDIL::R1007)
.addImm(cID);
// These instructions go after the current MI.
emitDataLoadSelect(MI);
break;
case 8:
emitVectorAddressCalc(MI, false, true);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::CBLOAD), AMDIL::R1011)
.addReg(AMDIL::R1007)
.addImm(cID);
// These instructions go after the current MI.
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::VEXTRACT_v2i64), AMDIL::R1007)
.addReg(AMDIL::R1011)
.addImm(2);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::VCREATE_v2i32), AMDIL::R1008)
.addReg(AMDIL::R1008);
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::CMOVLOG_i64), AMDIL::R1011)
.addReg(AMDIL::R1008)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1007);
break;
}
expandPackedData(MI);
expandExtendLoad(MI);
BuildMI(*mBB, I, MI->getDebugLoc(),
mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)),
MI->getOperand(0).getReg())
.addReg(AMDIL::R1011);
MI->getOperand(0).setReg(AMDIL::R1011);
}
void
AMDIL789IOExpansion::expandConstantPoolLoad(MachineInstr *MI)
{
if (!isStaticCPLoad(MI)) {
return expandConstantLoad(MI);
} else {
uint32_t idx = MI->getOperand(1).getIndex();
const MachineConstantPool *MCP = MI->getParent()->getParent()
->getConstantPool();
const std::vector<MachineConstantPoolEntry> &consts
= MCP->getConstants();
const Constant *C = consts[idx].Val.ConstVal;
emitCPInst(MI, C, mKM, 0, isExtendLoad(MI));
}
}
void
AMDIL789IOExpansion::expandPrivateStore(MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
bool HWPrivate = mSTM->device()->usesHardware(AMDILDeviceInfo::PrivateMem);
if (!HWPrivate || mSTM->device()->isSupported(AMDILDeviceInfo::PrivateUAV)) {
return expandGlobalStore(MI);
}
if (!mMFI->usesMem(AMDILDevice::SCRATCH_ID)
&& mKM->isKernel()) {
mMFI->addErrorMsg(amd::CompilerErrorMessage[MEMOP_NO_ALLOCATION]);
}
uint32_t xID = getPointerID(MI);
assert(xID && "Found a scratch store that was incorrectly marked as zero ID!\n");
if (!xID) {
xID = mSTM->device()->getResourceID(AMDILDevice::SCRATCH_ID);
mMFI->addErrorMsg(amd::CompilerWarningMessage[RECOVERABLE_ERROR]);
}
DebugLoc DL;
// These instructions go before the current MI.
expandStoreSetupCode(MI);
switch (getMemorySize(MI)) {
default:
// This section generates the following pseudo-IL:
// ishr r1010.x___, r1010.xxxx, 4
// mov x1[r1010.x], r1011
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SHR_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(4));
BuildMI(*mBB, I, MI->getDebugLoc(),
mTII->get(AMDIL::SCRATCHSTORE), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(xID);
break;
case 1:
emitVectorAddressCalc(MI, true, true);
// This section generates the following pseudo-IL:
// mov r1002, x1[r1007.x]
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHLOAD), AMDIL::R1002)
.addReg(AMDIL::R1007)
.addImm(xID);
emitComponentExtract(MI, AMDIL::R1008, AMDIL::R1002, AMDIL::R1002, true);
// This section generates the following pseudo-IL:
// iand r1003.x, r1010.x, 3
// mov r1003, r1003.xxxx
// iadd r1000, r1003, {0, -1, -2, -3}
// ieq r1000, r1000, 0
// mov r1002, r1002.xxxx
// ishr r1002, r1002, {0, 8, 16, 24}
// mov r1011, r1011.xxxx
// cmov_logical r1002, r1000, r1011, r1002
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1003)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1003)
.addReg(AMDIL::R1003);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1001)
.addReg(AMDIL::R1003)
.addImm(mMFI->addi128Literal(0xFFFFFFFFULL << 32,
(0xFFFFFFFEULL | (0xFFFFFFFDULL << 32))));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::IEQ_v4i32), AMDIL::R1001)
.addReg(AMDIL::R1001)
.addImm(mMFI->addi32Literal(0));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1002)
.addReg(AMDIL::R1002);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHRVEC_v4i32), AMDIL::R1002)
.addReg(AMDIL::R1002)
.addImm(mMFI->addi128Literal(8ULL << 32, 16ULL | (24ULL << 32)));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_v4i32), AMDIL::R1002)
.addReg(AMDIL::R1001)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1002);
if (mSTM->device()->getGeneration() == AMDILDeviceInfo::HD4XXX) {
// This section generates the following pseudo-IL:
// iand r1002, r1002, 0xFF
// ishl r1002, r1002, {0, 8, 16, 24}
// ior r1002.xy, r1002.xy, r1002.zw
// ior r1011.x, r1002.x, r1002.y
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_v4i32), AMDIL::R1002)
.addReg(AMDIL::R1002)
.addImm(mMFI->addi32Literal(0xFF));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHL_v4i32), AMDIL::R1002)
.addReg(AMDIL::R1002)
.addImm(mMFI->addi128Literal(8ULL << 32, 16ULL | (24ULL << 32)));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v2i64), AMDIL::R1002)
.addReg(AMDIL::R1002).addReg(AMDIL::R1002);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1002).addReg(AMDIL::R1002);
} else {
// This section generates the following pseudo-IL:
// mov r1001.xy, r1002.yw
// mov r1002.xy, r1002.xz
// ubit_insert r1002.xy, 8, 8, r1001.xy, r1002.xy
// mov r1001.x, r1002.y
// ubit_insert r1011.x, 16, 16, r1002.y, r1002.x
BuildMI(*mBB, I, DL, mTII->get(AMDIL::LHI_v2i64), AMDIL::R1001)
.addReg(AMDIL::R1002);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::LLO_v2i64), AMDIL::R1002)
.addReg(AMDIL::R1002);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::UBIT_INSERT_v2i32), AMDIL::R1002)
.addImm(mMFI->addi32Literal(8))
.addImm(mMFI->addi32Literal(8))
.addReg(AMDIL::R1001)
.addReg(AMDIL::R1002);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::LHI), AMDIL::R1001)
.addReg(AMDIL::R1002);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::UBIT_INSERT_i32), AMDIL::R1011)
.addImm(mMFI->addi32Literal(16))
.addImm(mMFI->addi32Literal(16))
.addReg(AMDIL::R1001)
.addReg(AMDIL::R1002);
}
emitVectorAddressCalc(MI, true, false);
emitVectorSwitchWrite(MI, true);
break;
case 2:
emitVectorAddressCalc(MI, true, true);
// This section generates the following pseudo-IL:
// mov r1002, x1[r1007.x]
BuildMI(*mBB, I, DL,
mTII->get(AMDIL::SCRATCHLOAD), AMDIL::R1002)
.addReg(AMDIL::R1007)
.addImm(xID);
emitComponentExtract(MI, AMDIL::R1008, AMDIL::R1002, AMDIL::R1002, true);
// This section generates the following pseudo-IL:
// ishr r1003.x, r1010.x, 1
// iand r1003.x, r1003.x, 1
// ishr r1001.x, r1002.x, 16
// cmov_logical r1002.x, r1003.x, r1002.x, r1011.x
// cmov_logical r1001.x, r1003.x, r1011.x, r1001.x
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1003)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(1));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1003)
.addReg(AMDIL::R1003)
.addImm(mMFI->addi32Literal(1));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1001)
.addReg(AMDIL::R1002)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1002)
.addReg(AMDIL::R1003)
.addReg(AMDIL::R1002)
.addReg(AMDIL::R1011);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1001)
.addReg(AMDIL::R1003)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1001);
if (mSTM->device()->getGeneration() == AMDILDeviceInfo::HD4XXX) {
// This section generates the following pseudo-IL:
// iand r1002.x, r1002.x, 0xFFFF
// iand r1001.x, r1001.x, 0xFFFF
// ishl r1001.x, r1002.x, 16
// ior r1011.x, r1002.x, r1001.x
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1002)
.addReg(AMDIL::R1002)
.addImm(mMFI->addi32Literal(0xFFFF));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1001)
.addReg(AMDIL::R1001)
.addImm(mMFI->addi32Literal(0xFFFF));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1001)
.addReg(AMDIL::R1001)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_OR_i32), AMDIL::R1011)
.addReg(AMDIL::R1002).addReg(AMDIL::R1001);
} else {
// This section generates the following pseudo-IL:
// ubit_insert r1011.x, 16, 16, r1001.y, r1002.x
BuildMI(*mBB, I, DL, mTII->get(AMDIL::UBIT_INSERT_i32), AMDIL::R1011)
.addImm(mMFI->addi32Literal(16))
.addImm(mMFI->addi32Literal(16))
.addReg(AMDIL::R1001)
.addReg(AMDIL::R1002);
}
emitVectorAddressCalc(MI, true, false);
emitVectorSwitchWrite(MI, true);
break;
case 4:
emitVectorAddressCalc(MI, true, false);
emitVectorSwitchWrite(MI, true);
break;
case 8:
emitVectorAddressCalc(MI, false, false);
emitVectorSwitchWrite(MI, false);
break;
};
}
void
AMDIL789IOExpansion::expandStoreSetupCode(MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
DebugLoc DL;
if (MI->getOperand(0).isUndef()) {
BuildMI(*mBB, I, DL, mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)), AMDIL::R1011)
.addImm(mMFI->addi32Literal(0));
} else {
BuildMI(*mBB, I, DL, mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)), AMDIL::R1011)
.addReg(MI->getOperand(0).getReg());
}
expandTruncData(MI);
if (MI->getOperand(2).isReg()) {
BuildMI(*mBB, I, DL, mTII->get(AMDIL::ADD_i32), AMDIL::R1010)
.addReg(MI->getOperand(1).getReg())
.addReg(MI->getOperand(2).getReg());
} else {
BuildMI(*mBB, I, DL, mTII->get(AMDIL::MOVE_i32), AMDIL::R1010)
.addReg(MI->getOperand(1).getReg());
}
expandAddressCalc(MI);
expandPackedData(MI);
}
void
AMDIL789IOExpansion::expandPackedData(MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
if (!isPackedData(MI)) {
return;
}
DebugLoc DL;
// If we have packed data, then the shift size is no longer
// the same as the load size and we need to adjust accordingly
switch(getPackedID(MI)) {
default:
break;
case PACK_V2I8:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi64Literal(0xFFULL | (0xFFULL << 32)));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHL_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011).addImm(mMFI->addi64Literal(8ULL << 32));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1011);
}
break;
case PACK_V4I8:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(0xFF));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHL_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi128Literal(8ULL << 32, (16ULL | (24ULL << 32))));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v2i64), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1011);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1011);
}
break;
case PACK_V2I16:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(0xFFFF));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHL_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi64Literal(16ULL << 32));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1011);
}
break;
case PACK_V4I16:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::BINARY_AND_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(0xFFFF));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::SHL_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi64Literal(16ULL << 32));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::HILO_BITOR_v4i16), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1011);
}
break;
case UNPACK_V2I8:
BuildMI(*mBB, I, DL, mTII->get(AMDIL::USHRVEC_i32), AMDIL::R1012)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(8));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::LCREATE), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1012);
break;
case UNPACK_V4I8:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::VCREATE_v4i8), AMDIL::R1011)
.addReg(AMDIL::R1011);
BuildMI(*mBB, I, DL, mTII->get(AMDIL::USHRVEC_v4i8), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi128Literal(8ULL << 32, (16ULL | (24ULL << 32))));
}
break;
case UNPACK_V2I16:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::USHRVEC_i32), AMDIL::R1012)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::LCREATE), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1012);
}
break;
case UNPACK_V4I16:
{
BuildMI(*mBB, I, DL, mTII->get(AMDIL::USHRVEC_v2i32), AMDIL::R1012)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, I, DL, mTII->get(AMDIL::LCREATE_v2i64), AMDIL::R1011)
.addReg(AMDIL::R1011).addReg(AMDIL::R1012);
}
break;
};
}
@@ -11,7 +11,6 @@
#include "AMDIL7XXAsmPrinter.h"
#endif
#include "AMDILDevice.h"
#include "AMDILIOExpansion.h"
using namespace llvm;
@@ -92,13 +91,6 @@ uint32_t AMDIL7XXDevice::getMaxNumUAVs() const
return 1;
}
FunctionPass*
AMDIL7XXDevice::getIOExpansion(
TargetMachine& TM AMDIL_OPT_LEVEL_DECL) const
{
return new AMDIL7XXIOExpansion(TM AMDIL_OPT_LEVEL_VAR);
}
AsmPrinter*
AMDIL7XXDevice::getAsmPrinter(TargetMachine& TM, MCStreamer &Streamer) const
{
@@ -39,8 +39,6 @@ public:
virtual uint32_t getGeneration() const;
virtual uint32_t getResourceID(uint32_t DeviceID) const;
virtual uint32_t getMaxNumUAVs() const;
FunctionPass*
getIOExpansion(TargetMachine& AMDIL_OPT_LEVEL_DECL) const;
AsmPrinter*
getAsmPrinter(TargetMachine& TM, MCStreamer &Streamer) const;
@@ -1,548 +0,0 @@
//===-- AMDIL7XXIOExpansion.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.
//
//==-----------------------------------------------------------------------===//
// @file AMDIL7XXIOExpansion.cpp
// @details Implementation of the IO Printing class for 7XX devices
//
#include "AMDILCompilerErrors.h"
#include "AMDILCompilerWarnings.h"
#include "AMDILDevices.h"
#include "AMDILGlobalManager.h"
#include "AMDILIOExpansion.h"
#include "AMDILKernelManager.h"
#include "AMDILMachineFunctionInfo.h"
#include "AMDILTargetMachine.h"
#include "AMDILUtilityFunctions.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Value.h"
using namespace llvm;
AMDIL7XXIOExpansion::AMDIL7XXIOExpansion(TargetMachine &tm
AMDIL_OPT_LEVEL_DECL) : AMDIL789IOExpansion(tm AMDIL_OPT_LEVEL_VAR)
{
}
AMDIL7XXIOExpansion::~AMDIL7XXIOExpansion() {
}
const char *AMDIL7XXIOExpansion::getPassName() const
{
return "AMDIL 7XX IO Expansion Pass";
}
void
AMDIL7XXIOExpansion::expandGlobalLoad(MachineInstr *MI)
{
DebugLoc DL;
// These instructions go before the current MI.
expandLoadStartCode(MI);
uint32_t ID = getPointerID(MI);
mKM->setOutputInst();
switch(getMemorySize(MI)) {
default:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWLOAD_v4i32), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(ID);
break;
case 4:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWLOAD_i32), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(ID);
break;
case 8:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWLOAD_v2i32), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(ID);
break;
case 1:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(0xFFFFFFFC));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi128Literal(0xFFFFFFFFULL << 32,
(0xFFFFFFFEULL | (0xFFFFFFFDULL << 32))));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::IEQ_v4i32), AMDIL::R1012)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(0));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1008)
.addReg(AMDIL::R1012)
.addImm(mMFI->addi32Literal(0))
.addImm(mMFI->addi32Literal(24));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_Y_i32), AMDIL::R1008)
.addReg(AMDIL::R1012)
.addImm(mMFI->addi32Literal(8))
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_Z_i32), AMDIL::R1008)
.addReg(AMDIL::R1012)
.addImm(mMFI->addi32Literal(16))
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWLOAD_i32), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(ID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i8), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
break;
case 2:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(1));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(0xFFFFFFFC));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(16))
.addImm(mMFI->addi32Literal(0));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWLOAD_i32), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(ID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i16), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
break;
}
// These instructions go after the current MI.
expandPackedData(MI);
expandExtendLoad(MI);
BuildMI(*mBB, MI, MI->getDebugLoc(),
mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)))
.addOperand(MI->getOperand(0))
.addReg(AMDIL::R1011);
MI->getOperand(0).setReg(AMDIL::R1011);
}
void
AMDIL7XXIOExpansion::expandRegionLoad(MachineInstr *MI)
{
bool HWRegion = mSTM->device()->usesHardware(AMDILDeviceInfo::RegionMem);
if (!mSTM->device()->isSupported(AMDILDeviceInfo::RegionMem)) {
mMFI->addErrorMsg(
amd::CompilerErrorMessage[REGION_MEMORY_ERROR]);
return;
}
if (!HWRegion || !isHardwareRegion(MI)) {
return expandGlobalLoad(MI);
}
if (!mMFI->usesMem(AMDILDevice::GDS_ID)
&& mKM->isKernel()) {
mMFI->addErrorMsg(amd::CompilerErrorMessage[MEMOP_NO_ALLOCATION]);
}
uint32_t gID = getPointerID(MI);
assert(gID && "Found a GDS load that was incorrectly marked as zero ID!\n");
if (!gID) {
gID = mSTM->device()->getResourceID(AMDILDevice::GDS_ID);
mMFI->addErrorMsg(amd::CompilerWarningMessage[RECOVERABLE_ERROR]);
}
DebugLoc DL;
// These instructions go before the current MI.
expandLoadStartCode(MI);
switch (getMemorySize(MI)) {
default:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1010)
.addReg(AMDIL::R1010);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi128Literal(1ULL << 32, 2ULL | (3ULL << 32)));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD_Y), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD_Z), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD_W), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
break;
case 1:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UMUL_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(8));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(0xFFFFFFFC));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
// The instruction would normally fit in right here so everything created
// after this point needs to go into the afterInst vector.
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(24));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(24));
break;
case 2:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UMUL_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(8));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(0xFFFFFFFC));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
// The instruction would normally fit in right here so everything created
// after this point needs to go into the afterInst vector.
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
break;
case 4:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
break;
case 8:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VCREATE_v2i32), AMDIL::R1010)
.addReg(AMDIL::R1010);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi64Literal(1ULL << 32));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSLOAD_Y), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(gID);
break;
}
// These instructions go after the current MI.
expandPackedData(MI);
expandExtendLoad(MI);
BuildMI(*mBB, MI, MI->getDebugLoc(),
mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)))
.addOperand(MI->getOperand(0))
.addReg(AMDIL::R1011);
MI->getOperand(0).setReg(AMDIL::R1011);
}
void
AMDIL7XXIOExpansion::expandLocalLoad(MachineInstr *MI)
{
bool HWLocal = mSTM->device()->usesHardware(AMDILDeviceInfo::LocalMem);
if (!HWLocal || !isHardwareLocal(MI)) {
return expandGlobalLoad(MI);
}
if (!mMFI->usesMem(AMDILDevice::LDS_ID)
&& mKM->isKernel()) {
mMFI->addErrorMsg(amd::CompilerErrorMessage[MEMOP_NO_ALLOCATION]);
}
uint32_t lID = getPointerID(MI);
assert(lID && "Found a LDS load that was incorrectly marked as zero ID!\n");
if (!lID) {
lID = mSTM->device()->getResourceID(AMDILDevice::LDS_ID);
mMFI->addErrorMsg(amd::CompilerWarningMessage[RECOVERABLE_ERROR]);
}
DebugLoc DL;
// These instructions go before the current MI.
expandLoadStartCode(MI);
switch (getMemorySize(MI)) {
default:
case 8:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LDSLOADVEC), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(lID);
break;
case 4:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(lID);
break;
case 1:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UMUL_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(8));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(0xFFFFFFFC));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(lID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(24));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(24));
break;
case 2:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UMUL_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(8));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(0xFFFFFFFC));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LDSLOAD), AMDIL::R1011)
.addReg(AMDIL::R1010)
.addImm(lID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(16));
break;
}
// These instructions go after the current MI.
expandPackedData(MI);
expandExtendLoad(MI);
BuildMI(*mBB, MI, MI->getDebugLoc(),
mTII->get(getMoveInstFromID(
MI->getDesc().OpInfo[0].RegClass)))
.addOperand(MI->getOperand(0))
.addReg(AMDIL::R1011);
MI->getOperand(0).setReg(AMDIL::R1011);
}
void
AMDIL7XXIOExpansion::expandGlobalStore(MachineInstr *MI)
{
uint32_t ID = getPointerID(MI);
mKM->setOutputInst();
DebugLoc DL = MI->getDebugLoc();
// These instructions go before the current MI.
expandStoreSetupCode(MI);
switch (getMemorySize(MI)) {
default:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWSTORE_v4i32), AMDIL::MEM)
.addReg(AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(ID);
break;
case 1:
mMFI->addErrorMsg(
amd::CompilerErrorMessage[BYTE_STORE_ERROR]);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWSTORE_i32), AMDIL::MEM)
.addReg(AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(ID);
break;
case 2:
mMFI->addErrorMsg(
amd::CompilerErrorMessage[BYTE_STORE_ERROR]);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWSTORE_i32), AMDIL::MEM)
.addReg(AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(ID);
break;
case 4:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWSTORE_i32), AMDIL::MEM)
.addReg(AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(ID);
break;
case 8:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UAVRAWSTORE_v2i32), AMDIL::MEM)
.addReg(AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(ID);
break;
};
}
void
AMDIL7XXIOExpansion::expandRegionStore(MachineInstr *MI)
{
bool HWRegion = mSTM->device()->usesHardware(AMDILDeviceInfo::RegionMem);
if (!mSTM->device()->isSupported(AMDILDeviceInfo::RegionMem)) {
mMFI->addErrorMsg(
amd::CompilerErrorMessage[REGION_MEMORY_ERROR]);
return;
}
if (!HWRegion || !isHardwareRegion(MI)) {
return expandGlobalStore(MI);
}
DebugLoc DL = MI->getDebugLoc();
mKM->setOutputInst();
if (!mMFI->usesMem(AMDILDevice::GDS_ID)
&& mKM->isKernel()) {
mMFI->addErrorMsg(amd::CompilerErrorMessage[MEMOP_NO_ALLOCATION]);
}
uint32_t gID = getPointerID(MI);
assert(gID && "Found a GDS store that was incorrectly marked as zero ID!\n");
if (!gID) {
gID = mSTM->device()->getResourceID(AMDILDevice::GDS_ID);
mMFI->addErrorMsg(amd::CompilerWarningMessage[RECOVERABLE_ERROR]);
}
// These instructions go before the current MI.
expandStoreSetupCode(MI);
switch (getMemorySize(MI)) {
default:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1010)
.addReg(AMDIL::R1010);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi128Literal(1ULL << 32, 2ULL | (3ULL << 32)));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE_Y), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE_Z), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE_W), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
break;
case 1:
mMFI->addErrorMsg(
amd::CompilerErrorMessage[BYTE_STORE_ERROR]);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(0xFF));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1012)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VCREATE_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi128Literal(0xFFFFFFFFULL << 32,
(0xFFFFFFFEULL | (0xFFFFFFFDULL << 32))));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::UMUL_i32), AMDIL::R1006)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(8));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1007)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(0xFFFFFF00))
.addImm(mMFI->addi32Literal(0x00FFFFFF));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_Y_i32), AMDIL::R1007)
.addReg(AMDIL::R1008)
.addReg(AMDIL::R1007)
.addImm(mMFI->addi32Literal(0xFF00FFFF));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_Z_i32), AMDIL::R1012)
.addReg(AMDIL::R1008)
.addReg(AMDIL::R1007)
.addImm(mMFI->addi32Literal(0xFFFF00FF));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1007);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
break;
case 2:
mMFI->addErrorMsg(
amd::CompilerErrorMessage[BYTE_STORE_ERROR]);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addImm(mMFI->addi32Literal(0x0000FFFF));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::BINARY_AND_i32), AMDIL::R1008)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi32Literal(3));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHR_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(1));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1012)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(0x0000FFFF))
.addImm(mMFI->addi32Literal(0xFFFF0000));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::CMOVLOG_i32), AMDIL::R1008)
.addReg(AMDIL::R1008)
.addImm(mMFI->addi32Literal(16))
.addImm(mMFI->addi32Literal(0));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHL_i32), AMDIL::R1011)
.addReg(AMDIL::R1011)
.addReg(AMDIL::R1008);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
break;
case 4:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
break;
case 8:
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VCREATE_v2i32), AMDIL::R1010)
.addReg(AMDIL::R1010);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_v4i32), AMDIL::R1010)
.addReg(AMDIL::R1010)
.addImm(mMFI->addi64Literal(1ULL << 32));
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::GDSSTORE_Y), AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(gID);
break;
};
}
void
AMDIL7XXIOExpansion::expandLocalStore(MachineInstr *MI)
{
bool HWLocal = mSTM->device()->usesHardware(AMDILDeviceInfo::LocalMem);
if (!HWLocal || !isHardwareLocal(MI)) {
return expandGlobalStore(MI);
}
uint32_t lID = getPointerID(MI);
assert(lID && "Found a LDS store that was incorrectly marked as zero ID!\n");
if (!lID) {
lID = mSTM->device()->getResourceID(AMDILDevice::LDS_ID);
mMFI->addErrorMsg(amd::CompilerWarningMessage[RECOVERABLE_ERROR]);
}
DebugLoc DL = MI->getDebugLoc();
// These instructions go before the current MI.
expandStoreSetupCode(MI);
BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LDSSTOREVEC), AMDIL::MEM)
.addReg(AMDIL::R1010)
.addReg(AMDIL::R1011)
.addImm(lID);
}
-5
View File
@@ -22,7 +22,6 @@
namespace llvm {
class AMDILSubtarget;
class AMDILAsmPrinter;
class AMDILIOExpansion;
class AMDILPointerManager;
class AsmPrinter;
class MCStreamer;
@@ -85,10 +84,6 @@ public:
// Get the max number of UAV's for this device.
virtual uint32_t getMaxNumUAVs() const = 0;
// Interface to get the IO Expansion pass for each device.
virtual FunctionPass*
getIOExpansion(TargetMachine& AMDIL_OPT_LEVEL_DECL) const = 0;
// Interface to get the Asm printer for each device.
virtual AsmPrinter*
getAsmPrinter(TargetMachine& TM, MCStreamer &Streamer) const = 0;
File diff suppressed because it is too large Load Diff
@@ -10,7 +10,6 @@
#ifdef UPSTREAM_LLVM
#include "AMDILEGAsmPrinter.h"
#endif
#include "AMDILIOExpansion.h"
using namespace llvm;
@@ -136,12 +135,6 @@ void AMDILEvergreenDevice::setCaps() {
}
mHWBits.set(AMDILDeviceInfo::TmrReg);
}
FunctionPass*
AMDILEvergreenDevice::getIOExpansion(
TargetMachine& TM AMDIL_OPT_LEVEL_DECL) const
{
return new AMDILEGIOExpansion(TM AMDIL_OPT_LEVEL_VAR);
}
AsmPrinter*
AMDILEvergreenDevice::getAsmPrinter(TargetMachine& TM, MCStreamer &Streamer) const
@@ -40,8 +40,6 @@ public:
virtual uint32_t getGeneration() const;
virtual uint32_t getMaxNumUAVs() const;
virtual uint32_t getResourceID(uint32_t) const;
virtual FunctionPass*
getIOExpansion(TargetMachine& AMDIL_OPT_LEVEL_DECL) const;
virtual AsmPrinter*
getAsmPrinter(TargetMachine& TM, MCStreamer &Streamer) const;
protected:
File diff suppressed because it is too large Load Diff
@@ -1,320 +0,0 @@
//===----------- AMDILIOExpansion.h - IO Expansion Pass -------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//==-----------------------------------------------------------------------===//
// The AMDIL IO Expansion class expands pseudo IO instructions into a sequence
// of instructions that produces the correct results. These instructions are
// not expanded earlier in the backend because any pass before this can assume to
// be able to generate a load/store instruction. So this pass can only have
// passes that execute after it if no load/store instructions can be generated
// in those passes.
//===----------------------------------------------------------------------===//
#ifndef _AMDILIOEXPANSION_H_
#define _AMDILIOEXPANSION_H_
#undef DEBUG_TYPE
#undef DEBUGME
#define DEBUG_TYPE "IOExpansion"
#if !defined(NDEBUG)
#define DEBUGME (DebugFlag && isCurrentDebugType(DEBUG_TYPE))
#else
#define DEBUGME (false)
#endif
#include "AMDIL.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MachineFunction;
class AMDILKernelManager;
class AMDILMachineFunctionInfo;
class AMDILSubtarget;
class MachineInstr;
class Constant;
class TargetInstrInfo;
class Type;
typedef enum {
NO_PACKING = 0,
PACK_V2I8,
PACK_V4I8,
PACK_V2I16,
PACK_V4I16,
UNPACK_V2I8,
UNPACK_V4I8,
UNPACK_V2I16,
UNPACK_V4I16,
UNPACK_LAST
} REG_PACKED_TYPE;
class AMDILIOExpansion : public MachineFunctionPass
{
public:
virtual ~AMDILIOExpansion();
virtual const char* getPassName() const;
bool runOnMachineFunction(MachineFunction &MF);
static char ID;
protected:
AMDILIOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
TargetMachine &TM;
//
// @param MI Machine instruction to check.
// @brief checks to see if the machine instruction
// is an I/O instruction or not.
//
// @return true if I/O, false otherwise.
//
virtual bool
isIOInstruction(MachineInstr *MI);
// Wrapper function that calls the appropriate I/O
// expansion function based on the instruction type.
virtual void
expandIOInstruction(MachineInstr *MI);
virtual void
expandGlobalStore(MachineInstr *MI) = 0;
virtual void
expandLocalStore(MachineInstr *MI) = 0;
virtual void
expandRegionStore(MachineInstr *MI) = 0;
virtual void
expandPrivateStore(MachineInstr *MI) = 0;
virtual void
expandGlobalLoad(MachineInstr *MI) = 0;
virtual void
expandRegionLoad(MachineInstr *MI) = 0;
virtual void
expandLocalLoad(MachineInstr *MI) = 0;
virtual void
expandPrivateLoad(MachineInstr *MI) = 0;
virtual void
expandConstantLoad(MachineInstr *MI) = 0;
virtual void
expandConstantPoolLoad(MachineInstr *MI) = 0;
bool
isAddrCalcInstr(MachineInstr *MI);
bool
isExtendLoad(MachineInstr *MI);
bool
isHardwareRegion(MachineInstr *MI);
bool
isHardwareLocal(MachineInstr *MI);
bool
isPackedData(MachineInstr *MI);
bool
isStaticCPLoad(MachineInstr *MI);
bool
isNbitType(Type *MI, uint32_t nBits, bool isScalar = true);
bool
isHardwareInst(MachineInstr *MI);
uint32_t
getMemorySize(MachineInstr *MI);
REG_PACKED_TYPE
getPackedID(MachineInstr *MI);
uint32_t
getShiftSize(MachineInstr *MI);
uint32_t
getPointerID(MachineInstr *MI);
void
expandTruncData(MachineInstr *MI);
void
expandLoadStartCode(MachineInstr *MI);
virtual void
expandStoreSetupCode(MachineInstr *MI) = 0;
void
expandAddressCalc(MachineInstr *MI);
void
expandLongExtend(MachineInstr *MI,
uint32_t numComponents, uint32_t size, bool signedShift);
void
expandLongExtendSub32(MachineInstr *MI,
unsigned SHLop, unsigned SHRop, unsigned USHRop,
unsigned SHLimm, uint64_t SHRimm, unsigned USHRimm,
unsigned LCRop, bool signedShift);
void
expandIntegerExtend(MachineInstr *MI, unsigned, unsigned, unsigned);
void
expandExtendLoad(MachineInstr *MI);
virtual void
expandPackedData(MachineInstr *MI) = 0;
void
emitCPInst(MachineInstr* MI, const Constant* C,
AMDILKernelManager* KM, int swizzle, bool ExtFPLoad);
bool mDebug;
const AMDILSubtarget *mSTM;
AMDILKernelManager *mKM;
MachineBasicBlock *mBB;
AMDILMachineFunctionInfo *mMFI;
const TargetInstrInfo *mTII;
bool saveInst;
private:
void
emitStaticCPLoad(MachineInstr* MI, int swizzle, int id,
bool ExtFPLoad);
}; // class AMDILIOExpansion
// Intermediate class that holds I/O code expansion that is common to the
// 7XX, Evergreen and Northern Island family of chips.
class AMDIL789IOExpansion : public AMDILIOExpansion {
public:
virtual ~AMDIL789IOExpansion();
virtual const char* getPassName() const;
protected:
AMDIL789IOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
virtual void
expandGlobalStore(MachineInstr *MI) = 0;
virtual void
expandLocalStore(MachineInstr *MI) = 0;
virtual void
expandRegionStore(MachineInstr *MI) = 0;
virtual void
expandGlobalLoad(MachineInstr *MI) = 0;
virtual void
expandRegionLoad(MachineInstr *MI) = 0;
virtual void
expandLocalLoad(MachineInstr *MI) = 0;
virtual void
expandPrivateStore(MachineInstr *MI);
virtual void
expandConstantLoad(MachineInstr *MI);
virtual void
expandPrivateLoad(MachineInstr *MI) ;
virtual void
expandConstantPoolLoad(MachineInstr *MI);
void
expandStoreSetupCode(MachineInstr *MI);
virtual void
expandPackedData(MachineInstr *MI);
private:
void emitVectorAddressCalc(MachineInstr *MI, bool is32bit,
bool needsSelect);
void emitVectorSwitchWrite(MachineInstr *MI, bool is32bit);
void emitComponentExtract(MachineInstr *MI, unsigned flag, unsigned src,
unsigned dst, bool beforeInst);
void emitDataLoadSelect(MachineInstr *MI);
}; // class AMDIL789IOExpansion
// Class that handles I/O emission for the 7XX family of devices.
class AMDIL7XXIOExpansion : public AMDIL789IOExpansion {
public:
AMDIL7XXIOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
~AMDIL7XXIOExpansion();
const char* getPassName() const;
protected:
void
expandGlobalStore(MachineInstr *MI);
void
expandLocalStore(MachineInstr *MI);
void
expandRegionStore(MachineInstr *MI);
void
expandGlobalLoad(MachineInstr *MI);
void
expandRegionLoad(MachineInstr *MI);
void
expandLocalLoad(MachineInstr *MI);
}; // class AMDIL7XXIOExpansion
// Class that handles image functions to expand them into the
// correct set of I/O instructions.
class AMDILImageExpansion : public AMDIL789IOExpansion {
public:
AMDILImageExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
virtual ~AMDILImageExpansion();
protected:
//
// @param MI Instruction iterator that has the sample instruction
// that needs to be taken care of.
// @brief transforms the __amdil_sample_data function call into a
// sample instruction in IL.
//
// @warning This function only works correctly if all functions get
// inlined
//
virtual void
expandImageLoad(MachineBasicBlock *BB, MachineInstr *MI);
//
// @param MI Instruction iterator that has the write instruction that
// needs to be taken care of.
// @brief transforms the __amdil_write_data function call into a
// simple UAV write instruction in IL.
//
// @warning This function only works correctly if all functions get
// inlined
//
virtual void
expandImageStore(MachineBasicBlock *BB, MachineInstr *MI);
//
// @param MI Instruction interator that has the image parameter
// instruction
// @brief transforms the __amdil_get_image_params function call into
// a copy of data from a specific constant buffer to the register
//
// @warning This function only works correctly if all functions get
// inlined
//
virtual void
expandImageParam(MachineBasicBlock *BB, MachineInstr *MI);
//
// @param MI Insturction that points to the image
// @brief transforms __amdil_sample_data into a sequence of
// if/else that selects the correct sample instruction.
//
// @warning This function is inefficient and works with no
// inlining.
//
virtual void
expandInefficientImageLoad(MachineBasicBlock *BB, MachineInstr *MI);
private:
AMDILImageExpansion(); // Do not implement.
}; // class AMDILImageExpansion
// Class that expands IO instructions for Evergreen and Northern
// Island family of devices.
class AMDILEGIOExpansion : public AMDILImageExpansion {
public:
AMDILEGIOExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL);
virtual ~AMDILEGIOExpansion();
const char* getPassName() const;
protected:
virtual bool
isIOInstruction(MachineInstr *MI);
virtual void
expandIOInstruction(MachineInstr *MI);
bool
isImageIO(MachineInstr *MI);
virtual void
expandGlobalStore(MachineInstr *MI);
void
expandLocalStore(MachineInstr *MI);
void
expandRegionStore(MachineInstr *MI);
virtual void
expandGlobalLoad(MachineInstr *MI);
void
expandRegionLoad(MachineInstr *MI);
void
expandLocalLoad(MachineInstr *MI);
virtual bool
isCacheableOp(MachineInstr *MI);
void
expandStoreSetupCode(MachineInstr *MI);
void
expandPackedData(MachineInstr *MI);
private:
bool
isArenaOp(MachineInstr *MI);
void
expandArenaSetup(MachineInstr *MI);
}; // class AMDILEGIOExpansion
} // namespace llvm
#endif // _AMDILIOEXPANSION_H_
@@ -1,171 +0,0 @@
//===-- AMDILImageExpansion.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.
//
//==-----------------------------------------------------------------------===//
// @file AMDILImageExpansion.cpp
// @details Implementatino of the Image expansion class for image capable devices
//
#include "AMDILIOExpansion.h"
#include "AMDILKernelManager.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Value.h"
using namespace llvm;
AMDILImageExpansion::AMDILImageExpansion(TargetMachine &tm AMDIL_OPT_LEVEL_DECL)
: AMDIL789IOExpansion(tm AMDIL_OPT_LEVEL_VAR)
{
}
AMDILImageExpansion::~AMDILImageExpansion()
{
}
void AMDILImageExpansion::expandInefficientImageLoad(
MachineBasicBlock *mBB, MachineInstr *MI)
{
#if 0
const llvm::StringRef &name = MI->getOperand(0).getGlobal()->getName();
const char *tReg1, *tReg2, *tReg3, *tReg4;
tReg1 = mASM->getRegisterName(MI->getOperand(1).getReg());
if (MI->getOperand(2).isReg()) {
tReg2 = mASM->getRegisterName(MI->getOperand(2).getReg());
} else {
tReg2 = mASM->getRegisterName(AMDIL::R1);
O << "\tmov " << tReg2 << ", l" << MI->getOperand(2).getImm() << "\n";
}
if (MI->getOperand(3).isReg()) {
tReg3 = mASM->getRegisterName(MI->getOperand(3).getReg());
} else {
tReg3 = mASM->getRegisterName(AMDIL::R2);
O << "\tmov " << tReg3 << ", l" << MI->getOperand(3).getImm() << "\n";
}
if (MI->getOperand(4).isReg()) {
tReg4 = mASM->getRegisterName(MI->getOperand(4).getReg());
} else {
tReg4 = mASM->getRegisterName(AMDIL::R3);
O << "\tmov " << tReg2 << ", l" << MI->getOperand(4).getImm() << "\n";
}
bool internalSampler = false;
//bool linear = true;
unsigned ImageCount = 3; // OPENCL_MAX_READ_IMAGES
unsigned SamplerCount = 3; // OPENCL_MAX_SAMPLERS
if (ImageCount - 1) {
O << "\tswitch " << mASM->getRegisterName(MI->getOperand(1).getReg())
<< "\n";
}
for (unsigned rID = 0; rID < ImageCount; ++rID) {
if (ImageCount - 1) {
if (!rID) {
O << "\tdefault\n";
} else {
O << "\tcase " << rID << "\n" ;
}
O << "\tswitch " << mASM->getRegisterName(MI->getOperand(2).getReg())
<< "\n";
}
for (unsigned sID = 0; sID < SamplerCount; ++sID) {
if (SamplerCount - 1) {
if (!sID) {
O << "\tdefault\n";
} else {
O << "\tcase " << sID << "\n" ;
}
}
if (internalSampler) {
// Check if sampler has normalized setting.
O << "\tand r0.x, " << tReg2 << ".x, l0.y\n"
<< "\tif_logicalz r0.x\n"
<< "\tflr " << tReg3 << ", " << tReg3 << "\n"
<< "\tsample_resource(" << rID << ")_sampler("
<< sID << ")_coordtype(unnormalized) "
<< tReg1 << ", " << tReg3 << " ; " << name.data() << "\n"
<< "\telse\n"
<< "\tiadd " << tReg1 << ".y, " << tReg1 << ".x, l0.y\n"
<< "\titof " << tReg2 << ", cb1[" << tReg1 << ".x].xyz\n"
<< "\tmul " << tReg3 << ", " << tReg3 << ", " << tReg2 << "\n"
<< "\tflr " << tReg3 << ", " << tReg3 << "\n"
<< "\tmul " << tReg3 << ", " << tReg3 << ", cb1["
<< tReg1 << ".y].xyz\n"
<< "\tsample_resource(" << rID << ")_sampler("
<< sID << ")_coordtype(normalized) "
<< tReg1 << ", " << tReg3 << " ; " << name.data() << "\n"
<< "\tendif\n";
} else {
O << "\tiadd " << tReg1 << ".y, " << tReg1 << ".x, l0.y\n"
// Check if sampler has normalized setting.
<< "\tand r0, " << tReg2 << ".x, l0.y\n"
// Convert image dimensions to float.
<< "\titof " << tReg4 << ", cb1[" << tReg1 << ".x].xyz\n"
// Move into R0 1 if unnormalized or dimensions if normalized.
<< "\tcmov_logical r0, r0, " << tReg4 << ", r1.1111\n"
// Make coordinates unnormalized.
<< "\tmul " << tReg3 << ", r0, " << tReg3 << "\n"
// Get linear filtering if set.
<< "\tand " << tReg4 << ", " << tReg2 << ".x, l6.x\n"
// Save unnormalized coordinates in R0.
<< "\tmov r0, " << tReg3 << "\n"
// Floor the coordinates due to HW incompatibility with precision
// requirements.
<< "\tflr " << tReg3 << ", " << tReg3 << "\n"
// get Origianl coordinates (without floor) if linear filtering
<< "\tcmov_logical " << tReg3 << ", " << tReg4
<< ".xxxx, r0, " << tReg3 << "\n"
// Normalize the coordinates with multiplying by 1/dimensions
<< "\tmul " << tReg3 << ", " << tReg3 << ", cb1["
<< tReg1 << ".y].xyz\n"
<< "\tsample_resource(" << rID << ")_sampler("
<< sID << ")_coordtype(normalized) "
<< tReg1 << ", " << tReg3 << " ; " << name.data() << "\n";
}
if (SamplerCount - 1) {
O << "\tbreak\n";
}
}
if (SamplerCount - 1) {
O << "\tendswitch\n";
}
if (ImageCount - 1) {
O << "\tbreak\n";
}
}
if (ImageCount - 1) {
O << "\tendswitch\n";
}
#endif
}
void
AMDILImageExpansion::expandImageLoad(MachineBasicBlock *mBB, MachineInstr *MI)
{
uint32_t imageID = getPointerID(MI);
MI->getOperand(1).ChangeToImmediate(imageID);
saveInst = true;
}
void
AMDILImageExpansion::expandImageStore(MachineBasicBlock *mBB, MachineInstr *MI)
{
uint32_t imageID = getPointerID(MI);
mKM->setOutputInst();
MI->getOperand(0).ChangeToImmediate(imageID);
saveInst = true;
}
void
AMDILImageExpansion::expandImageParam(MachineBasicBlock *mBB, MachineInstr *MI)
{
MachineBasicBlock::iterator I = *MI;
uint32_t ID = getPointerID(MI);
DebugLoc DL = MI->getDebugLoc();
BuildMI(*mBB, I, DL, mTII->get(AMDIL::CBLOAD),
MI->getOperand(0).getReg())
.addImm(ID)
.addImm(1);
}
@@ -188,7 +188,6 @@ bool AMDILPassConfig::addPreEmitPass()
PM.add(createAMDILCFGPreparationPass(*TM));
PM.add(createAMDILCFGStructurizerPass(*TM));
PM.add(createAMDILLiteralManager(*TM));
PM.add(createAMDILIOExpansion(*TM));
return true;
}
@@ -19,23 +19,18 @@ GENERATED_SOURCES := \
CPP_SOURCES := \
AMDIL7XXDevice.cpp \
AMDIL7XXIOExpansion.cpp \
AMDIL789IOExpansion.cpp \
AMDILAsmBackend.cpp \
AMDILBarrierDetect.cpp \
AMDILCFGStructurizer.cpp \
AMDILDevice.cpp \
AMDILDeviceInfo.cpp \
AMDILEGIOExpansion.cpp \
AMDILEvergreenDevice.cpp \
AMDILELFWriterInfo.cpp \
AMDILFrameLowering.cpp \
AMDILGlobalManager.cpp \
AMDILImageExpansion.cpp \
AMDILInliner.cpp \
AMDILInstrInfo.cpp \
AMDILIntrinsicInfo.cpp \
AMDILIOExpansion.cpp \
AMDILISelDAGToDAG.cpp \
AMDILISelLowering.cpp \
AMDILKernelManager.cpp \