radeon/llvm: Coding style fixes

This commit is contained in:
Tom Stellard 2012-07-13 15:52:37 +00:00
parent 39d82a1b20
commit f323c6260d
2 changed files with 322 additions and 406 deletions

View File

@ -49,19 +49,19 @@ private:
const MachineRegisterInfo * MRI;
const R600RegisterInfo * TRI;
bool isCube;
bool isReduction;
bool isVector;
bool IsCube;
bool IsReduction;
bool IsVector;
unsigned currentElement;
bool isLast;
bool IsLast;
unsigned section_start;
public:
R600CodeEmitter(formatted_raw_ostream &OS) : MachineFunctionPass(ID),
_OS(OS), TM(NULL), isCube(false), isReduction(false), isVector(false),
isLast(true) { }
_OS(OS), TM(NULL), IsCube(false), IsReduction(false), IsVector(false),
IsLast(true) { }
const char *getPassName() const { return "AMDGPU Machine Code Emitter"; }
@ -71,21 +71,21 @@ public:
private:
void emitALUInstr(MachineInstr &MI);
void emitSrc(const MachineOperand & MO, int chan_override = -1);
void emitDst(const MachineOperand & MO);
void emitALU(MachineInstr &MI, unsigned numSrc);
void emitTexInstr(MachineInstr &MI);
void emitFCInstr(MachineInstr &MI);
void EmitALUInstr(MachineInstr &MI);
void EmitSrc(const MachineOperand & MO, int chan_override = -1);
void EmitDst(const MachineOperand & MO);
void EmitALU(MachineInstr &MI, unsigned numSrc);
void EmitTexInstr(MachineInstr &MI);
void EmitFCInstr(MachineInstr &MI);
void emitNullBytes(unsigned int byteCount);
void EmitNullBytes(unsigned int byteCount);
void emitByte(unsigned int byte);
void EmitByte(unsigned int byte);
void emitTwoBytes(uint32_t bytes);
void EmitTwoBytes(uint32_t bytes);
void emit(uint32_t value);
void emit(uint64_t value);
void Emit(uint32_t value);
void Emit(uint64_t value);
unsigned getHWReg(unsigned regNo) const;
@ -160,27 +160,27 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) {
MachineInstr &MI = *I;
isReduction = AMDGPU::isReductionOp(MI.getOpcode());
isVector = TII->isVector(MI);
isCube = AMDGPU::isCubeOp(MI.getOpcode());
IsReduction = AMDGPU::isReductionOp(MI.getOpcode());
IsVector = TII->isVector(MI);
IsCube = AMDGPU::isCubeOp(MI.getOpcode());
if (MI.getNumOperands() > 1 && MI.getOperand(0).isReg() && MI.getOperand(0).isDead()) {
continue;
}
if (AMDGPU::isTexOp(MI.getOpcode())) {
emitTexInstr(MI);
EmitTexInstr(MI);
} else if (AMDGPU::isFCOp(MI.getOpcode())){
emitFCInstr(MI);
} else if (isReduction || isVector || isCube) {
isLast = false;
EmitFCInstr(MI);
} else if (IsReduction || IsVector || IsCube) {
IsLast = false;
// XXX: On Cayman, some (all?) of the vector instructions only need
// to fill the first three slots.
for (currentElement = 0; currentElement < 4; currentElement++) {
isLast = (currentElement == 3);
emitALUInstr(MI);
IsLast = (currentElement == 3);
EmitALUInstr(MI);
}
isReduction = false;
isVector = false;
isCube = false;
IsReduction = false;
IsVector = false;
IsCube = false;
} else if (MI.getOpcode() == AMDGPU::RETURN ||
MI.getOpcode() == AMDGPU::BUNDLE ||
MI.getOpcode() == AMDGPU::KILL) {
@ -199,8 +199,8 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
if (NextMI.getOpcode() == AMDGPU::RETURN) {
inst |= (((uint64_t)1) << 53);
}
emitByte(INSTR_NATIVE);
emit(inst);
EmitByte(INSTR_NATIVE);
Emit(inst);
break;
}
case AMDGPU::VTX_READ_PARAM_i32_eg:
@ -213,14 +213,14 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
uint64_t InstWord01 = getBinaryCodeForInstr(MI);
uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
emitByte(INSTR_VTX);
emit(InstWord01);
emit(InstWord2);
EmitByte(INSTR_VTX);
Emit(InstWord01);
Emit(InstWord2);
break;
}
default:
emitALUInstr(MI);
EmitALUInstr(MI);
break;
}
}
@ -229,7 +229,7 @@ bool R600CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
return false;
}
void R600CodeEmitter::emitALUInstr(MachineInstr &MI)
void R600CodeEmitter::EmitALUInstr(MachineInstr &MI)
{
unsigned numOperands = MI.getNumExplicitOperands();
@ -247,13 +247,13 @@ void R600CodeEmitter::emitALUInstr(MachineInstr &MI)
const MachineOperand dstOp = MI.getOperand(0);
// Emit instruction type
emitByte(0);
EmitByte(0);
if (isCube) {
if (IsCube) {
static const int cube_src_swz[] = {2, 2, 0, 1};
emitSrc(MI.getOperand(1), cube_src_swz[currentElement]);
emitSrc(MI.getOperand(1), cube_src_swz[3-currentElement]);
emitNullBytes(SRC_BYTE_COUNT);
EmitSrc(MI.getOperand(1), cube_src_swz[currentElement]);
EmitSrc(MI.getOperand(1), cube_src_swz[3-currentElement]);
EmitNullBytes(SRC_BYTE_COUNT);
} else {
unsigned int opIndex;
for (opIndex = 1; opIndex < numOperands; opIndex++) {
@ -261,21 +261,21 @@ void R600CodeEmitter::emitALUInstr(MachineInstr &MI)
if (MI.getOperand(opIndex).isImm() || MI.getOperand(opIndex).isFPImm()) {
break;
}
emitSrc(MI.getOperand(opIndex));
EmitSrc(MI.getOperand(opIndex));
}
// Emit zeros for unused sources
for ( ; opIndex < 4; opIndex++) {
emitNullBytes(SRC_BYTE_COUNT);
EmitNullBytes(SRC_BYTE_COUNT);
}
}
emitDst(dstOp);
EmitDst(dstOp);
emitALU(MI, numOperands - 1);
EmitALU(MI, numOperands - 1);
}
void R600CodeEmitter::emitSrc(const MachineOperand & MO, int chan_override)
void R600CodeEmitter::EmitSrc(const MachineOperand & MO, int chan_override)
{
uint32_t value = 0;
// Emit the source select (2 bytes). For GPRs, this is the register index.
@ -283,7 +283,7 @@ void R600CodeEmitter::emitSrc(const MachineOperand & MO, int chan_override)
// value of the source select is defined in the r600isa docs.
if (MO.isReg()) {
unsigned reg = MO.getReg();
emitTwoBytes(getHWReg(reg));
EmitTwoBytes(getHWReg(reg));
if (reg == AMDGPU::ALU_LITERAL_X) {
const MachineInstr * parent = MO.getParent();
unsigned immOpIndex = parent->getNumExplicitOperands() - 1;
@ -297,18 +297,18 @@ void R600CodeEmitter::emitSrc(const MachineOperand & MO, int chan_override)
}
} else {
// XXX: Handle other operand types.
emitTwoBytes(0);
EmitTwoBytes(0);
}
// Emit the source channel (1 byte)
if (chan_override != -1) {
emitByte(chan_override);
} else if (isReduction) {
emitByte(currentElement);
EmitByte(chan_override);
} else if (IsReduction) {
EmitByte(currentElement);
} else if (MO.isReg()) {
emitByte(TRI->getHWRegChan(MO.getReg()));
EmitByte(TRI->getHWRegChan(MO.getReg()));
} else {
emitByte(0);
EmitByte(0);
}
// XXX: Emit isNegated (1 byte)
@ -316,103 +316,103 @@ void R600CodeEmitter::emitSrc(const MachineOperand & MO, int chan_override)
&& (MO.getTargetFlags() & MO_FLAG_NEG ||
(MO.isReg() &&
(MO.getReg() == AMDGPU::NEG_ONE || MO.getReg() == AMDGPU::NEG_HALF)))){
emitByte(1);
EmitByte(1);
} else {
emitByte(0);
EmitByte(0);
}
// Emit isAbsolute (1 byte)
if (MO.getTargetFlags() & MO_FLAG_ABS) {
emitByte(1);
EmitByte(1);
} else {
emitByte(0);
EmitByte(0);
}
// XXX: Emit relative addressing mode (1 byte)
emitByte(0);
EmitByte(0);
// Emit kc_bank, This will be adjusted later by r600_asm
emitByte(0);
EmitByte(0);
// Emit the literal value, if applicable (4 bytes).
emit(value);
Emit(value);
}
void R600CodeEmitter::emitDst(const MachineOperand & MO)
void R600CodeEmitter::EmitDst(const MachineOperand & MO)
{
if (MO.isReg()) {
// Emit the destination register index (1 byte)
emitByte(getHWReg(MO.getReg()));
EmitByte(getHWReg(MO.getReg()));
// Emit the element of the destination register (1 byte)
if (isReduction || isCube || isVector) {
emitByte(currentElement);
if (IsReduction || IsCube || IsVector) {
EmitByte(currentElement);
} else {
emitByte(TRI->getHWRegChan(MO.getReg()));
EmitByte(TRI->getHWRegChan(MO.getReg()));
}
// Emit isClamped (1 byte)
if (MO.getTargetFlags() & MO_FLAG_CLAMP) {
emitByte(1);
EmitByte(1);
} else {
emitByte(0);
EmitByte(0);
}
// Emit writemask (1 byte).
if (((isReduction || isVector) &&
if (((IsReduction || IsVector) &&
currentElement != TRI->getHWRegChan(MO.getReg()))
|| MO.getTargetFlags() & MO_FLAG_MASK) {
emitByte(0);
EmitByte(0);
} else {
emitByte(1);
EmitByte(1);
}
// XXX: Emit relative addressing mode
emitByte(0);
EmitByte(0);
} else {
// XXX: Handle other operand types. Are there any for destination regs?
emitNullBytes(DST_BYTE_COUNT);
EmitNullBytes(DST_BYTE_COUNT);
}
}
void R600CodeEmitter::emitALU(MachineInstr &MI, unsigned numSrc)
void R600CodeEmitter::EmitALU(MachineInstr &MI, unsigned numSrc)
{
// Emit the instruction (2 bytes)
emitTwoBytes(getBinaryCodeForInstr(MI));
EmitTwoBytes(getBinaryCodeForInstr(MI));
// Emit isLast (for this instruction group) (1 byte)
if (isLast) {
emitByte(1);
// Emit IsLast (for this instruction group) (1 byte)
if (IsLast) {
EmitByte(1);
} else {
emitByte(0);
EmitByte(0);
}
// Emit isOp3 (1 byte)
if (numSrc == 3) {
emitByte(1);
EmitByte(1);
} else {
emitByte(0);
EmitByte(0);
}
// XXX: Emit predicate (1 byte)
emitByte(0);
EmitByte(0);
// XXX: Emit bank swizzle. (1 byte) Do we need this? It looks like
// r600_asm.c sets it.
emitByte(0);
EmitByte(0);
// XXX: Emit bank_swizzle_force (1 byte) Not sure what this is for.
emitByte(0);
EmitByte(0);
// XXX: Emit OMOD (1 byte) Not implemented.
emitByte(0);
EmitByte(0);
// XXX: Emit index_mode. I think this is for indirect addressing, so we
// don't need to worry about it.
emitByte(0);
EmitByte(0);
}
void R600CodeEmitter::emitTexInstr(MachineInstr &MI)
void R600CodeEmitter::EmitTexInstr(MachineInstr &MI)
{
unsigned opcode = MI.getOpcode();
@ -423,34 +423,34 @@ void R600CodeEmitter::emitTexInstr(MachineInstr &MI)
unsigned srcSelect[4] = {0, 1, 2, 3};
// Emit instruction type
emitByte(1);
EmitByte(1);
// Emit instruction
emitByte(getBinaryCodeForInstr(MI));
EmitByte(getBinaryCodeForInstr(MI));
// XXX: Emit resource id r600_shader.c uses sampler + 1. Why?
emitByte(sampler + 1 + 1);
EmitByte(sampler + 1 + 1);
// Emit source register
emitByte(getHWReg(MI.getOperand(1).getReg()));
EmitByte(getHWReg(MI.getOperand(1).getReg()));
// XXX: Emit src isRelativeAddress
emitByte(0);
EmitByte(0);
// Emit destination register
emitByte(getHWReg(MI.getOperand(0).getReg()));
EmitByte(getHWReg(MI.getOperand(0).getReg()));
// XXX: Emit dst isRealtiveAddress
emitByte(0);
EmitByte(0);
// XXX: Emit dst select
emitByte(0); // X
emitByte(1); // Y
emitByte(2); // Z
emitByte(3); // W
EmitByte(0); // X
EmitByte(1); // Y
EmitByte(2); // Z
EmitByte(3); // W
// XXX: Emit lod bias
emitByte(0);
EmitByte(0);
// XXX: Emit coord types
unsigned coordType[4] = {1, 1, 1, 1};
@ -475,18 +475,18 @@ void R600CodeEmitter::emitTexInstr(MachineInstr &MI)
}
for (unsigned i = 0; i < 4; i++) {
emitByte(coordType[i]);
EmitByte(coordType[i]);
}
// XXX: Emit offsets
if (hasOffsets)
for (unsigned i = 2; i < 5; i++)
emitByte(MI.getOperand(i).getImm()<<1);
EmitByte(MI.getOperand(i).getImm()<<1);
else
emitNullBytes(3);
EmitNullBytes(3);
// Emit sampler id
emitByte(sampler);
EmitByte(sampler);
// XXX:Emit source select
if ((textureType == TEXTURE_SHADOW1D
@ -499,22 +499,22 @@ void R600CodeEmitter::emitTexInstr(MachineInstr &MI)
}
for (unsigned i = 0; i < 4; i++) {
emitByte(srcSelect[i]);
EmitByte(srcSelect[i]);
}
}
void R600CodeEmitter::emitFCInstr(MachineInstr &MI)
void R600CodeEmitter::EmitFCInstr(MachineInstr &MI)
{
// Emit instruction type
emitByte(INSTR_FC);
EmitByte(INSTR_FC);
// Emit SRC
unsigned numOperands = MI.getNumOperands();
if (numOperands > 0) {
assert(numOperands == 1);
emitSrc(MI.getOperand(0));
EmitSrc(MI.getOperand(0));
} else {
emitNullBytes(SRC_BYTE_COUNT);
EmitNullBytes(SRC_BYTE_COUNT);
}
// Emit FC Instruction
@ -557,49 +557,49 @@ void R600CodeEmitter::emitFCInstr(MachineInstr &MI)
abort();
break;
}
emitByte(instr);
EmitByte(instr);
}
void R600CodeEmitter::emitNullBytes(unsigned int byteCount)
void R600CodeEmitter::EmitNullBytes(unsigned int byteCount)
{
for (unsigned int i = 0; i < byteCount; i++) {
emitByte(0);
EmitByte(0);
}
}
void R600CodeEmitter::emitByte(unsigned int byte)
void R600CodeEmitter::EmitByte(unsigned int byte)
{
_OS.write((uint8_t) byte & 0xff);
}
void R600CodeEmitter::emitTwoBytes(unsigned int bytes)
void R600CodeEmitter::EmitTwoBytes(unsigned int bytes)
{
_OS.write((uint8_t) (bytes & 0xff));
_OS.write((uint8_t) ((bytes >> 8) & 0xff));
}
void R600CodeEmitter::emit(uint32_t value)
void R600CodeEmitter::Emit(uint32_t value)
{
for (unsigned i = 0; i < 4; i++) {
_OS.write((uint8_t) ((value >> (8 * i)) & 0xff));
}
}
void R600CodeEmitter::emit(uint64_t value)
void R600CodeEmitter::Emit(uint64_t value)
{
for (unsigned i = 0; i < 8; i++) {
emitByte((value >> (8 * i)) & 0xff);
EmitByte((value >> (8 * i)) & 0xff);
}
}
unsigned R600CodeEmitter::getHWReg(unsigned regNo) const
{
unsigned hwReg;
unsigned HWReg;
hwReg = TRI->getHWRegIndex(regNo);
HWReg = TRI->getHWRegIndex(regNo);
if (AMDGPU::R600_CReg32RegClass.contains(regNo)) {
hwReg += 512;
HWReg += 512;
}
return hwReg;
return HWReg;
}
uint64_t R600CodeEmitter::getMachineOpValue(const MachineInstr &MI,

View File

@ -36,49 +36,47 @@ namespace {
#define CONSTANT_CACHE_SIZE_DW 127
class R600KernelParameters : public FunctionPass
{
const TargetData * TD;
class R600KernelParameters : public FunctionPass {
const TargetData *TD;
LLVMContext* Context;
Module *mod;
Module *Mod;
struct param
{
param() : val(NULL), ptr_val(NULL), offset_in_dw(0), size_in_dw(0),
indirect(true), specialID(0) {}
struct Param {
Param() : Val(NULL), PtrVal(NULL), OffsetInDW(0), SizeInDW(0),
IsIndirect(true), SpecialID(0) {}
Value* val;
Value* ptr_val;
int offset_in_dw;
int size_in_dw;
Value* Val;
Value* PtrVal;
int OffsetInDW;
int SizeInDW;
bool indirect;
bool IsIndirect;
std::string specialType;
int specialID;
std::string SpecialType;
int SpecialID;
int end() { return offset_in_dw + size_in_dw; }
int End() { return OffsetInDW + SizeInDW; }
// The first 9 dwords are reserved for the grid sizes.
int get_rat_offset() { return 9 + offset_in_dw; }
int getRatOffset() { return 9 + OffsetInDW; }
};
std::vector<param> params;
std::vector<Param> Params;
bool isOpenCLKernel(const Function* fun);
bool IsOpenCLKernel(const Function *Fun);
int getLastSpecialID(const std::string& TypeName);
int getListSize();
void AddParam(Argument* arg);
int calculateArgumentSize(Argument* arg);
void RunAna(Function* fun);
void Replace(Function* fun);
bool isIndirect(Value* val, std::set<Value*>& visited);
void Propagate(Function* fun);
void Propagate(Value* v, const Twine& name, bool indirect = true);
Value* ConstantRead(Function* fun, param& p);
Value* handleSpecial(Function* fun, param& p);
bool isSpecialType(Type*);
std::string getSpecialTypeName(Type*);
void AddParam(Argument *Arg);
int CalculateArgumentSize(Argument *Arg);
void RunAna(Function *Fun);
void Replace(Function *Fun);
bool IsIndirect(Value *Val, std::set<Value*> &Visited);
void Propagate(Function* Fun);
void Propagate(Value *V, const Twine &Name, bool IsIndirect = true);
Value* ConstantRead(Function *Fun, Param &P);
Value* handleSpecial(Function *Fun, Param &P);
bool IsSpecialType(Type *T);
std::string getSpecialTypeName(Type *T);
public:
static char ID;
R600KernelParameters() : FunctionPass(ID) {};
@ -95,27 +93,22 @@ char R600KernelParameters::ID = 0;
static RegisterPass<R600KernelParameters> X("kerparam",
"OpenCL Kernel Parameter conversion", false, false);
bool R600KernelParameters::isOpenCLKernel(const Function* fun)
{
Module *mod = const_cast<Function*>(fun)->getParent();
NamedMDNode * md = mod->getOrInsertNamedMetadata("opencl.kernels");
bool R600KernelParameters::IsOpenCLKernel(const Function* Fun) {
Module *Mod = const_cast<Function*>(Fun)->getParent();
NamedMDNode * MD = Mod->getOrInsertNamedMetadata("opencl.kernels");
if (!md or !md->getNumOperands())
{
if (!MD or !MD->getNumOperands()) {
return false;
}
for (int i = 0; i < int(md->getNumOperands()); i++)
{
if (!md->getOperand(i) or !md->getOperand(i)->getOperand(0))
{
for (int i = 0; i < int(MD->getNumOperands()); i++) {
if (!MD->getOperand(i) or !MD->getOperand(i)->getOperand(0)) {
continue;
}
assert(md->getOperand(i)->getNumOperands() == 1);
if (md->getOperand(i)->getOperand(0)->getName() == fun->getName())
{
assert(MD->getOperand(i)->getNumOperands() == 1);
if (MD->getOperand(i)->getOperand(0)->getName() == Fun->getName()) {
return true;
}
}
@ -123,76 +116,61 @@ bool R600KernelParameters::isOpenCLKernel(const Function* fun)
return false;
}
int R600KernelParameters::getLastSpecialID(const std::string& TypeName)
{
int lastID = -1;
int R600KernelParameters::getLastSpecialID(const std::string &TypeName) {
int LastID = -1;
for (std::vector<param>::iterator i = params.begin(); i != params.end(); i++)
{
if (i->specialType == TypeName)
{
lastID = i->specialID;
for (std::vector<Param>::iterator i = Params.begin(); i != Params.end(); i++) {
if (i->SpecialType == TypeName) {
LastID = i->SpecialID;
}
}
return lastID;
return LastID;
}
int R600KernelParameters::getListSize()
{
if (params.size() == 0)
{
int R600KernelParameters::getListSize() {
if (Params.size() == 0) {
return 0;
}
return params.back().end();
return Params.back().End();
}
bool R600KernelParameters::isIndirect(Value* val, std::set<Value*>& visited)
{
bool R600KernelParameters::IsIndirect(Value *Val, std::set<Value*> &Visited) {
//XXX Direct parameters are not supported yet, so return true here.
return true;
#if 0
if (isa<LoadInst>(val))
{
if (isa<LoadInst>(Val)) {
return false;
}
if (isa<IntegerType>(val->getType()))
{
if (isa<IntegerType>(Val->getType())) {
assert(0 and "Internal error");
return false;
}
if (visited.count(val))
{
if (Visited.count(Val)) {
return false;
}
visited.insert(val);
Visited.insert(Val);
if (isa<GetElementPtrInst>(val))
{
GetElementPtrInst* GEP = dyn_cast<GetElementPtrInst>(val);
GetElementPtrInst::op_iterator i = GEP->op_begin();
if (isa<getElementPtrInst>(Val)) {
getElementPtrInst* GEP = dyn_cast<getElementPtrInst>(Val);
getElementPtrInst::op_iterator I = GEP->op_begin();
for (i++; i != GEP->op_end(); i++)
{
if (!isa<Constant>(*i))
{
for (++I; I != GEP->op_end(); ++I) {
if (!isa<Constant>(*I)) {
return true;
}
}
}
for (Value::use_iterator i = val->use_begin(); i != val->use_end(); i++)
{
Value* v2 = dyn_cast<Value>(*i);
for (Value::use_iterator I = Val->use_begin(); i != Val->use_end(); ++I) {
Value* V2 = dyn_cast<Value>(*I);
if (v2)
{
if (isIndirect(v2, visited))
{
if (V2) {
if (IsIndirect(V2, Visited)) {
return true;
}
}
@ -202,293 +180,242 @@ bool R600KernelParameters::isIndirect(Value* val, std::set<Value*>& visited)
#endif
}
void R600KernelParameters::AddParam(Argument* arg)
{
param p;
void R600KernelParameters::AddParam(Argument *Arg) {
Param P;
p.val = dyn_cast<Value>(arg);
p.offset_in_dw = getListSize();
p.size_in_dw = calculateArgumentSize(arg);
P.Val = dyn_cast<Value>(Arg);
P.OffsetInDW = getListSize();
P.SizeInDW = CalculateArgumentSize(Arg);
if (isa<PointerType>(arg->getType()) and arg->hasByValAttr())
{
std::set<Value*> visited;
p.indirect = isIndirect(p.val, visited);
if (isa<PointerType>(Arg->getType()) and Arg->hasByValAttr()) {
std::set<Value*> Visited;
P.IsIndirect = IsIndirect(P.Val, Visited);
}
params.push_back(p);
Params.push_back(P);
}
int R600KernelParameters::calculateArgumentSize(Argument* arg)
{
Type* t = arg->getType();
int R600KernelParameters::CalculateArgumentSize(Argument *Arg) {
Type* T = Arg->getType();
if (arg->hasByValAttr() and dyn_cast<PointerType>(t))
{
t = dyn_cast<PointerType>(t)->getElementType();
if (Arg->hasByValAttr() and dyn_cast<PointerType>(T)) {
T = dyn_cast<PointerType>(T)->getElementType();
}
int store_size_in_dw = (TD->getTypeStoreSize(t) + 3)/4;
int StoreSizeInDW = (TD->getTypeStoreSize(T) + 3)/4;
assert(store_size_in_dw);
assert(StoreSizeInDW);
return store_size_in_dw;
return StoreSizeInDW;
}
void R600KernelParameters::RunAna(Function* fun)
{
assert(isOpenCLKernel(fun));
void R600KernelParameters::RunAna(Function* Fun) {
assert(IsOpenCLKernel(Fun));
for (Function::arg_iterator i = fun->arg_begin(); i != fun->arg_end(); i++)
{
AddParam(i);
for (Function::arg_iterator I = Fun->arg_begin(); I != Fun->arg_end(); ++I) {
AddParam(I);
}
}
void R600KernelParameters::Replace(Function* fun)
{
for (std::vector<param>::iterator i = params.begin(); i != params.end(); i++)
{
Value *new_val;
void R600KernelParameters::Replace(Function* Fun) {
for (std::vector<Param>::iterator I = Params.begin(); I != Params.end(); ++I) {
Value *NewVal;
if (isSpecialType(i->val->getType()))
{
new_val = handleSpecial(fun, *i);
if (IsSpecialType(I->Val->getType())) {
NewVal = handleSpecial(Fun, *I);
} else {
NewVal = ConstantRead(Fun, *I);
}
else
{
new_val = ConstantRead(fun, *i);
}
if (new_val)
{
i->val->replaceAllUsesWith(new_val);
if (NewVal) {
I->Val->replaceAllUsesWith(NewVal);
}
}
}
void R600KernelParameters::Propagate(Function* fun)
{
for (std::vector<param>::iterator i = params.begin(); i != params.end(); i++)
{
if (i->ptr_val)
{
Propagate(i->ptr_val, i->val->getName(), i->indirect);
}
void R600KernelParameters::Propagate(Function* Fun) {
for (std::vector<Param>::iterator I = Params.begin(); I != Params.end(); ++I) {
if (I->PtrVal) {
Propagate(I->PtrVal, I->Val->getName(), I->IsIndirect);
}
}
}
void R600KernelParameters::Propagate(Value* v, const Twine& name, bool indirect)
{
LoadInst* load = dyn_cast<LoadInst>(v);
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(v);
void R600KernelParameters::Propagate(Value* V, const Twine& Name, bool IsIndirect) {
LoadInst* Load = dyn_cast<LoadInst>(V);
GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V);
unsigned addrspace;
unsigned Addrspace;
if (indirect)
{
addrspace = AMDILAS::PARAM_I_ADDRESS;
}
else
{
addrspace = AMDILAS::PARAM_D_ADDRESS;
if (IsIndirect) {
Addrspace = AMDILAS::PARAM_I_ADDRESS;
} else {
Addrspace = AMDILAS::PARAM_D_ADDRESS;
}
if (GEP and GEP->getType()->getAddressSpace() != addrspace)
{
Value* op = GEP->getPointerOperand();
if (GEP and GEP->getType()->getAddressSpace() != Addrspace) {
Value *Op = GEP->getPointerOperand();
if (dyn_cast<PointerType>(op->getType())->getAddressSpace() != addrspace)
{
op = new BitCastInst(op, PointerType::get(dyn_cast<PointerType>(
op->getType())->getElementType(), addrspace),
name, dyn_cast<Instruction>(v));
if (dyn_cast<PointerType>(Op->getType())->getAddressSpace() != Addrspace) {
Op = new BitCastInst(Op, PointerType::get(dyn_cast<PointerType>(
Op->getType())->getElementType(), Addrspace),
Name, dyn_cast<Instruction>(V));
}
std::vector<Value*> params(GEP->idx_begin(), GEP->idx_end());
std::vector<Value*> Params(GEP->idx_begin(), GEP->idx_end());
GetElementPtrInst* GEP2 = GetElementPtrInst::Create(op, params, name,
dyn_cast<Instruction>(v));
GetElementPtrInst* GEP2 = GetElementPtrInst::Create(Op, Params, Name,
dyn_cast<Instruction>(V));
GEP2->setIsInBounds(GEP->isInBounds());
v = dyn_cast<Value>(GEP2);
V = dyn_cast<Value>(GEP2);
GEP->replaceAllUsesWith(GEP2);
GEP->eraseFromParent();
load = NULL;
Load = NULL;
}
if (load)
{
if (Load) {
///normally at this point we have the right address space
if (load->getPointerAddressSpace() != addrspace)
{
Value *orig_ptr = load->getPointerOperand();
PointerType *orig_ptr_type = dyn_cast<PointerType>(orig_ptr->getType());
if (Load->getPointerAddressSpace() != Addrspace) {
Value *OrigPtr = Load->getPointerOperand();
PointerType *OrigPtrType = dyn_cast<PointerType>(OrigPtr->getType());
Type* new_ptr_type = PointerType::get(orig_ptr_type->getElementType(),
addrspace);
Type* NewPtrType = PointerType::get(OrigPtrType->getElementType(),
Addrspace);
Value* new_ptr = orig_ptr;
Value* NewPtr = OrigPtr;
if (orig_ptr->getType() != new_ptr_type)
{
new_ptr = new BitCastInst(orig_ptr, new_ptr_type, "prop_cast", load);
if (OrigPtr->getType() != NewPtrType) {
NewPtr = new BitCastInst(OrigPtr, NewPtrType, "prop_cast", Load);
}
Value* new_load = new LoadInst(new_ptr, name, load);
load->replaceAllUsesWith(new_load);
load->eraseFromParent();
Value* new_Load = new LoadInst(NewPtr, Name, Load);
Load->replaceAllUsesWith(new_Load);
Load->eraseFromParent();
}
return;
}
std::vector<User*> users(v->use_begin(), v->use_end());
std::vector<User*> Users(V->use_begin(), V->use_end());
for (int i = 0; i < int(users.size()); i++)
{
Value* v2 = dyn_cast<Value>(users[i]);
for (int i = 0; i < int(Users.size()); i++) {
Value* V2 = dyn_cast<Value>(Users[i]);
if (v2)
{
Propagate(v2, name, indirect);
if (V2) {
Propagate(V2, Name, IsIndirect);
}
}
}
Value* R600KernelParameters::ConstantRead(Function* fun, param& p)
{
assert(fun->front().begin() != fun->front().end());
Value* R600KernelParameters::ConstantRead(Function *Fun, Param &P) {
assert(Fun->front().begin() != Fun->front().end());
Instruction *first_inst = fun->front().begin();
IRBuilder <> builder (first_inst);
Instruction *FirstInst = Fun->front().begin();
IRBuilder <> Builder (FirstInst);
/* First 3 dwords are reserved for the dimmension info */
if (!p.val->hasNUsesOrMore(1))
{
if (!P.Val->hasNUsesOrMore(1)) {
return NULL;
}
unsigned addrspace;
unsigned Addrspace;
if (p.indirect)
{
addrspace = AMDILAS::PARAM_I_ADDRESS;
}
else
{
addrspace = AMDILAS::PARAM_D_ADDRESS;
if (P.IsIndirect) {
Addrspace = AMDILAS::PARAM_I_ADDRESS;
} else {
Addrspace = AMDILAS::PARAM_D_ADDRESS;
}
Argument *arg = dyn_cast<Argument>(p.val);
Type * argType = p.val->getType();
PointerType * argPtrType = dyn_cast<PointerType>(p.val->getType());
Argument *Arg = dyn_cast<Argument>(P.Val);
Type * ArgType = P.Val->getType();
PointerType * ArgPtrType = dyn_cast<PointerType>(P.Val->getType());
if (argPtrType and arg->hasByValAttr())
{
Value* param_addr_space_ptr = ConstantPointerNull::get(
if (ArgPtrType and Arg->hasByValAttr()) {
Value* ParamAddrSpacePtr = ConstantPointerNull::get(
PointerType::get(Type::getInt32Ty(*Context),
addrspace));
Value* param_ptr = GetElementPtrInst::Create(param_addr_space_ptr,
Addrspace));
Value* ParamPtr = GetElementPtrInst::Create(ParamAddrSpacePtr,
ConstantInt::get(Type::getInt32Ty(*Context),
p.get_rat_offset()), arg->getName(),
first_inst);
param_ptr = new BitCastInst(param_ptr,
PointerType::get(argPtrType->getElementType(),
addrspace),
arg->getName(), first_inst);
p.ptr_val = param_ptr;
return param_ptr;
}
else
{
Value* param_addr_space_ptr = ConstantPointerNull::get(PointerType::get(
argType, addrspace));
P.getRatOffset()), Arg->getName(),
FirstInst);
ParamPtr = new BitCastInst(ParamPtr,
PointerType::get(ArgPtrType->getElementType(),
Addrspace),
Arg->getName(), FirstInst);
P.PtrVal = ParamPtr;
return ParamPtr;
} else {
Value *ParamAddrSpacePtr = ConstantPointerNull::get(PointerType::get(
ArgType, Addrspace));
Value* param_ptr = builder.CreateGEP(param_addr_space_ptr,
ConstantInt::get(Type::getInt32Ty(*Context), p.get_rat_offset()),
arg->getName());
Value *ParamPtr = Builder.CreateGEP(ParamAddrSpacePtr,
ConstantInt::get(Type::getInt32Ty(*Context), P.getRatOffset()),
Arg->getName());
Value* param_value = builder.CreateLoad(param_ptr, arg->getName());
Value *Param_Value = Builder.CreateLoad(ParamPtr, Arg->getName());
return param_value;
return Param_Value;
}
}
Value* R600KernelParameters::handleSpecial(Function* fun, param& p)
{
std::string name = getSpecialTypeName(p.val->getType());
Value* R600KernelParameters::handleSpecial(Function* Fun, Param& P) {
std::string Name = getSpecialTypeName(P.Val->getType());
int ID;
assert(!name.empty());
assert(!Name.empty());
if (name == "image2d_t" or name == "image3d_t")
{
int lastID = std::max(getLastSpecialID("image2d_t"),
if (Name == "image2d_t" or Name == "image3d_t") {
int LastID = std::max(getLastSpecialID("image2d_t"),
getLastSpecialID("image3d_t"));
if (lastID == -1)
{
if (LastID == -1) {
ID = 2; ///ID0 and ID1 are used internally by the driver
} else {
ID = LastID + 1;
}
else
{
ID = lastID + 1;
}
}
else if (name == "sampler_t")
{
int lastID = getLastSpecialID("sampler_t");
} else if (Name == "sampler_t") {
int LastID = getLastSpecialID("sampler_t");
if (lastID == -1)
{
if (LastID == -1) {
ID = 0;
} else {
ID = LastID + 1;
}
else
{
ID = lastID + 1;
}
}
else
{
} else {
///TODO: give some error message
return NULL;
}
p.specialType = name;
p.specialID = ID;
P.SpecialType = Name;
P.SpecialID = ID;
Instruction *first_inst = fun->front().begin();
Instruction *FirstInst = Fun->front().begin();
return new IntToPtrInst(ConstantInt::get(Type::getInt32Ty(*Context),
p.specialID), p.val->getType(),
"resourceID", first_inst);
P.SpecialID), P.Val->getType(),
"resourceID", FirstInst);
}
bool R600KernelParameters::isSpecialType(Type* t)
{
return !getSpecialTypeName(t).empty();
bool R600KernelParameters::IsSpecialType(Type* T) {
return !getSpecialTypeName(T).empty();
}
std::string R600KernelParameters::getSpecialTypeName(Type* t)
{
PointerType *pt = dyn_cast<PointerType>(t);
StructType *st = NULL;
std::string R600KernelParameters::getSpecialTypeName(Type* T) {
PointerType *PT = dyn_cast<PointerType>(T);
StructType *ST = NULL;
if (pt)
{
st = dyn_cast<StructType>(pt->getElementType());
if (PT) {
ST = dyn_cast<StructType>(PT->getElementType());
}
if (st)
{
std::string prefix = "struct.opencl_builtin_type_";
if (ST) {
std::string Prefix = "struct.opencl_builtin_type_";
std::string name = st->getName().str();
std::string Name = ST->getName().str();
if (name.substr(0, prefix.length()) == prefix)
{
return name.substr(prefix.length(), name.length());
if (Name.substr(0, Prefix.length()) == Prefix) {
return Name.substr(Prefix.length(), Name.length());
}
}
@ -496,10 +423,8 @@ std::string R600KernelParameters::getSpecialTypeName(Type* t)
}
bool R600KernelParameters::runOnFunction (Function &F)
{
if (!isOpenCLKernel(&F))
{
bool R600KernelParameters::runOnFunction (Function &F) {
if (!IsOpenCLKernel(&F)) {
return false;
}
@ -510,37 +435,28 @@ bool R600KernelParameters::runOnFunction (Function &F)
return false;
}
void R600KernelParameters::getAnalysisUsage(AnalysisUsage &AU) const
{
void R600KernelParameters::getAnalysisUsage(AnalysisUsage &AU) const {
FunctionPass::getAnalysisUsage(AU);
AU.setPreservesAll();
}
const char *R600KernelParameters::getPassName() const
{
const char *R600KernelParameters::getPassName() const {
return "OpenCL Kernel parameter conversion to memory";
}
bool R600KernelParameters::doInitialization(Module &M)
{
bool R600KernelParameters::doInitialization(Module &M) {
Context = &M.getContext();
mod = &M;
Mod = &M;
return false;
}
bool R600KernelParameters::doFinalization(Module &M)
{
bool R600KernelParameters::doFinalization(Module &M) {
return false;
}
} // End anonymous namespace
FunctionPass* llvm::createR600KernelParametersPass(const TargetData* TD)
{
FunctionPass *p = new R600KernelParameters(TD);
return p;
FunctionPass* llvm::createR600KernelParametersPass(const TargetData* TD) {
return new R600KernelParameters(TD);
}