radeon/llvm: Remove AMDILUtilityFunctions.cpp
This commit is contained in:
parent
21ab46eae8
commit
5aaaa6a426
|
@ -176,26 +176,6 @@ typedef union ResourceRec {
|
||||||
|
|
||||||
} // namespace AMDILAS
|
} // namespace AMDILAS
|
||||||
|
|
||||||
// The OpSwizzle encodes a subset of all possible
|
|
||||||
// swizzle combinations into a number of bits using
|
|
||||||
// only the combinations utilized by the backend.
|
|
||||||
// The lower 128 are for source swizzles and the
|
|
||||||
// upper 128 or for destination swizzles.
|
|
||||||
// The valid mappings can be found in the
|
|
||||||
// getSrcSwizzle and getDstSwizzle functions of
|
|
||||||
// AMDILUtilityFunctions.cpp.
|
|
||||||
typedef union SwizzleRec {
|
|
||||||
struct {
|
|
||||||
#ifdef __BIG_ENDIAN__
|
|
||||||
unsigned char dst : 1;
|
|
||||||
unsigned char swizzle : 7;
|
|
||||||
#else
|
|
||||||
unsigned char swizzle : 7;
|
|
||||||
unsigned char dst : 1;
|
|
||||||
#endif
|
|
||||||
} bits;
|
|
||||||
unsigned char u8all;
|
|
||||||
} OpSwizzle;
|
|
||||||
// Enums corresponding to AMDIL condition codes for IL. These
|
// Enums corresponding to AMDIL condition codes for IL. These
|
||||||
// values must be kept in sync with the ones in the .td file.
|
// values must be kept in sync with the ones in the .td file.
|
||||||
namespace AMDILCC {
|
namespace AMDILCC {
|
||||||
|
|
|
@ -3152,10 +3152,6 @@ struct CFGStructTraits<AMDILCFGStructurizer>
|
||||||
iterEnd = srcBlk->end();
|
iterEnd = srcBlk->end();
|
||||||
iter != iterEnd; ++iter) {
|
iter != iterEnd; ++iter) {
|
||||||
MachineInstr *instr = func->CloneMachineInstr(iter);
|
MachineInstr *instr = func->CloneMachineInstr(iter);
|
||||||
// This is a workaround for LLVM bugzilla 8420 because CloneMachineInstr
|
|
||||||
// does not clone the AsmPrinterFlags.
|
|
||||||
instr->setAsmPrinterFlag(
|
|
||||||
(llvm::MachineInstr::CommentFlag)iter->getAsmPrinterFlags());
|
|
||||||
newBlk->push_back(instr);
|
newBlk->push_back(instr);
|
||||||
}
|
}
|
||||||
return newBlk;
|
return newBlk;
|
||||||
|
|
|
@ -13,9 +13,12 @@
|
||||||
#include "AMDILDevices.h"
|
#include "AMDILDevices.h"
|
||||||
#include "AMDILTargetMachine.h"
|
#include "AMDILTargetMachine.h"
|
||||||
#include "AMDILUtilityFunctions.h"
|
#include "AMDILUtilityFunctions.h"
|
||||||
|
#include "llvm/ADT/ValueMap.h"
|
||||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
#include <list>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -35,13 +38,21 @@ class AMDILDAGToDAGISel : public SelectionDAGISel {
|
||||||
public:
|
public:
|
||||||
AMDILDAGToDAGISel(AMDILTargetMachine &TM AMDIL_OPT_LEVEL_DECL);
|
AMDILDAGToDAGISel(AMDILTargetMachine &TM AMDIL_OPT_LEVEL_DECL);
|
||||||
virtual ~AMDILDAGToDAGISel();
|
virtual ~AMDILDAGToDAGISel();
|
||||||
inline SDValue getSmallIPtrImm(unsigned Imm);
|
|
||||||
|
|
||||||
SDNode *Select(SDNode *N);
|
SDNode *Select(SDNode *N);
|
||||||
|
virtual const char *getPassName() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline SDValue getSmallIPtrImm(unsigned Imm);
|
||||||
|
|
||||||
// Complex pattern selectors
|
// Complex pattern selectors
|
||||||
bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2);
|
bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2);
|
||||||
bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2);
|
bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2);
|
||||||
bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2);
|
bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2);
|
||||||
|
|
||||||
|
static bool checkType(const Value *ptr, unsigned int addrspace);
|
||||||
|
static const Value *getBasePointerValue(const Value *V);
|
||||||
|
|
||||||
static bool isGlobalStore(const StoreSDNode *N);
|
static bool isGlobalStore(const StoreSDNode *N);
|
||||||
static bool isPrivateStore(const StoreSDNode *N);
|
static bool isPrivateStore(const StoreSDNode *N);
|
||||||
static bool isLocalStore(const StoreSDNode *N);
|
static bool isLocalStore(const StoreSDNode *N);
|
||||||
|
@ -54,8 +65,6 @@ public:
|
||||||
static bool isLocalLoad(const LoadSDNode *N);
|
static bool isLocalLoad(const LoadSDNode *N);
|
||||||
static bool isRegionLoad(const LoadSDNode *N);
|
static bool isRegionLoad(const LoadSDNode *N);
|
||||||
|
|
||||||
virtual const char *getPassName() const;
|
|
||||||
private:
|
|
||||||
SDNode *xformAtomicInst(SDNode *N);
|
SDNode *xformAtomicInst(SDNode *N);
|
||||||
|
|
||||||
// Include the pieces autogenerated from the target description.
|
// Include the pieces autogenerated from the target description.
|
||||||
|
@ -165,26 +174,75 @@ SDNode *AMDILDAGToDAGISel::Select(SDNode *N) {
|
||||||
return SelectCode(N);
|
return SelectCode(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AMDILDAGToDAGISel::checkType(const Value *ptr, unsigned int addrspace) {
|
||||||
|
if (!ptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Type *ptrType = ptr->getType();
|
||||||
|
return dyn_cast<PointerType>(ptrType)->getAddressSpace() == addrspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Value * AMDILDAGToDAGISel::getBasePointerValue(const Value *V)
|
||||||
|
{
|
||||||
|
if (!V) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const Value *ret = NULL;
|
||||||
|
ValueMap<const Value *, bool> ValueBitMap;
|
||||||
|
std::queue<const Value *, std::list<const Value *> > ValueQueue;
|
||||||
|
ValueQueue.push(V);
|
||||||
|
while (!ValueQueue.empty()) {
|
||||||
|
V = ValueQueue.front();
|
||||||
|
if (ValueBitMap.find(V) == ValueBitMap.end()) {
|
||||||
|
ValueBitMap[V] = true;
|
||||||
|
if (dyn_cast<Argument>(V) && dyn_cast<PointerType>(V->getType())) {
|
||||||
|
ret = V;
|
||||||
|
break;
|
||||||
|
} else if (dyn_cast<GlobalVariable>(V)) {
|
||||||
|
ret = V;
|
||||||
|
break;
|
||||||
|
} else if (dyn_cast<Constant>(V)) {
|
||||||
|
const ConstantExpr *CE = dyn_cast<ConstantExpr>(V);
|
||||||
|
if (CE) {
|
||||||
|
ValueQueue.push(CE->getOperand(0));
|
||||||
|
}
|
||||||
|
} else if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
|
||||||
|
ret = AI;
|
||||||
|
break;
|
||||||
|
} else if (const Instruction *I = dyn_cast<Instruction>(V)) {
|
||||||
|
uint32_t numOps = I->getNumOperands();
|
||||||
|
for (uint32_t x = 0; x < numOps; ++x) {
|
||||||
|
ValueQueue.push(I->getOperand(x));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// assert(0 && "Found a Value that we didn't know how to handle!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ValueQueue.pop();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isGlobalStore(const StoreSDNode *N) {
|
bool AMDILDAGToDAGISel::isGlobalStore(const StoreSDNode *N) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isPrivateStore(const StoreSDNode *N) {
|
bool AMDILDAGToDAGISel::isPrivateStore(const StoreSDNode *N) {
|
||||||
return (!check_type(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS)
|
return (!checkType(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS)
|
&& !checkType(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::REGION_ADDRESS));
|
&& !checkType(N->getSrcValue(), AMDILAS::REGION_ADDRESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isLocalStore(const StoreSDNode *N) {
|
bool AMDILDAGToDAGISel::isLocalStore(const StoreSDNode *N) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isRegionStore(const StoreSDNode *N) {
|
bool AMDILDAGToDAGISel::isRegionStore(const StoreSDNode *N) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::REGION_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::REGION_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int cbID) {
|
bool AMDILDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int cbID) {
|
||||||
if (check_type(N->getSrcValue(), AMDILAS::CONSTANT_ADDRESS)) {
|
if (checkType(N->getSrcValue(), AMDILAS::CONSTANT_ADDRESS)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
MachineMemOperand *MMO = N->getMemOperand();
|
MachineMemOperand *MMO = N->getMemOperand();
|
||||||
|
@ -195,27 +253,27 @@ bool AMDILDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int cbID) {
|
||||||
&& ((V && dyn_cast<GlobalValue>(V))
|
&& ((V && dyn_cast<GlobalValue>(V))
|
||||||
|| (BV && dyn_cast<GlobalValue>(
|
|| (BV && dyn_cast<GlobalValue>(
|
||||||
getBasePointerValue(MMO->getValue()))))) {
|
getBasePointerValue(MMO->getValue()))))) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::PRIVATE_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::PRIVATE_ADDRESS);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) {
|
bool AMDILDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isLocalLoad(const LoadSDNode *N) {
|
bool AMDILDAGToDAGISel::isLocalLoad(const LoadSDNode *N) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isRegionLoad(const LoadSDNode *N) {
|
bool AMDILDAGToDAGISel::isRegionLoad(const LoadSDNode *N) {
|
||||||
return check_type(N->getSrcValue(), AMDILAS::REGION_ADDRESS);
|
return checkType(N->getSrcValue(), AMDILAS::REGION_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isCPLoad(const LoadSDNode *N) {
|
bool AMDILDAGToDAGISel::isCPLoad(const LoadSDNode *N) {
|
||||||
MachineMemOperand *MMO = N->getMemOperand();
|
MachineMemOperand *MMO = N->getMemOperand();
|
||||||
if (check_type(N->getSrcValue(), AMDILAS::PRIVATE_ADDRESS)) {
|
if (checkType(N->getSrcValue(), AMDILAS::PRIVATE_ADDRESS)) {
|
||||||
if (MMO) {
|
if (MMO) {
|
||||||
const Value *V = MMO->getValue();
|
const Value *V = MMO->getValue();
|
||||||
const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V);
|
const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V);
|
||||||
|
@ -228,19 +286,19 @@ bool AMDILDAGToDAGISel::isCPLoad(const LoadSDNode *N) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AMDILDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) {
|
bool AMDILDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) {
|
||||||
if (check_type(N->getSrcValue(), AMDILAS::PRIVATE_ADDRESS)) {
|
if (checkType(N->getSrcValue(), AMDILAS::PRIVATE_ADDRESS)) {
|
||||||
// Check to make sure we are not a constant pool load or a constant load
|
// Check to make sure we are not a constant pool load or a constant load
|
||||||
// that is marked as a private load
|
// that is marked as a private load
|
||||||
if (isCPLoad(N) || isConstantLoad(N, -1)) {
|
if (isCPLoad(N) || isConstantLoad(N, -1)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!check_type(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS)
|
if (!checkType(N->getSrcValue(), AMDILAS::LOCAL_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS)
|
&& !checkType(N->getSrcValue(), AMDILAS::GLOBAL_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::REGION_ADDRESS)
|
&& !checkType(N->getSrcValue(), AMDILAS::REGION_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::CONSTANT_ADDRESS)
|
&& !checkType(N->getSrcValue(), AMDILAS::CONSTANT_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::PARAM_D_ADDRESS)
|
&& !checkType(N->getSrcValue(), AMDILAS::PARAM_D_ADDRESS)
|
||||||
&& !check_type(N->getSrcValue(), AMDILAS::PARAM_I_ADDRESS))
|
&& !checkType(N->getSrcValue(), AMDILAS::PARAM_I_ADDRESS))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,6 +623,48 @@ translateToOpcode(uint64_t CCCode, unsigned int regClass)
|
||||||
assert(0 && "Unknown opcode retrieved");
|
assert(0 && "Unknown opcode retrieved");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function used by LowerFormalArguments
|
||||||
|
static const TargetRegisterClass*
|
||||||
|
getRegClassFromType(unsigned int type) {
|
||||||
|
switch (type) {
|
||||||
|
default:
|
||||||
|
assert(0 && "Passed in type does not match any register classes.");
|
||||||
|
case MVT::i8:
|
||||||
|
return &AMDIL::GPRI8RegClass;
|
||||||
|
case MVT::i16:
|
||||||
|
return &AMDIL::GPRI16RegClass;
|
||||||
|
case MVT::i32:
|
||||||
|
return &AMDIL::GPRI32RegClass;
|
||||||
|
case MVT::f32:
|
||||||
|
return &AMDIL::GPRF32RegClass;
|
||||||
|
case MVT::i64:
|
||||||
|
return &AMDIL::GPRI64RegClass;
|
||||||
|
case MVT::f64:
|
||||||
|
return &AMDIL::GPRF64RegClass;
|
||||||
|
case MVT::v4f32:
|
||||||
|
return &AMDIL::GPRV4F32RegClass;
|
||||||
|
case MVT::v4i8:
|
||||||
|
return &AMDIL::GPRV4I8RegClass;
|
||||||
|
case MVT::v4i16:
|
||||||
|
return &AMDIL::GPRV4I16RegClass;
|
||||||
|
case MVT::v4i32:
|
||||||
|
return &AMDIL::GPRV4I32RegClass;
|
||||||
|
case MVT::v2f32:
|
||||||
|
return &AMDIL::GPRV2F32RegClass;
|
||||||
|
case MVT::v2i8:
|
||||||
|
return &AMDIL::GPRV2I8RegClass;
|
||||||
|
case MVT::v2i16:
|
||||||
|
return &AMDIL::GPRV2I16RegClass;
|
||||||
|
case MVT::v2i32:
|
||||||
|
return &AMDIL::GPRV2I32RegClass;
|
||||||
|
case MVT::v2f64:
|
||||||
|
return &AMDIL::GPRV2F64RegClass;
|
||||||
|
case MVT::v2i64:
|
||||||
|
return &AMDIL::GPRV2I64RegClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDValue
|
SDValue
|
||||||
AMDILTargetLowering::LowerMemArgument(
|
AMDILTargetLowering::LowerMemArgument(
|
||||||
SDValue Chain,
|
SDValue Chain,
|
||||||
|
@ -2189,6 +2231,7 @@ AMDILTargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const
|
||||||
SDValue Result = DAG.getTargetExternalSymbol(Sym, MVT::i32);
|
SDValue Result = DAG.getTargetExternalSymbol(Sym, MVT::i32);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LowerFORMAL_ARGUMENTS - transform physical registers into
|
/// LowerFORMAL_ARGUMENTS - transform physical registers into
|
||||||
/// virtual registers and generate load operations for
|
/// virtual registers and generate load operations for
|
||||||
/// arguments places on the stack.
|
/// arguments places on the stack.
|
||||||
|
@ -3843,7 +3886,6 @@ SDValue
|
||||||
AMDILTargetLowering::LowerBUILD_VECTOR( SDValue Op, SelectionDAG &DAG ) const
|
AMDILTargetLowering::LowerBUILD_VECTOR( SDValue Op, SelectionDAG &DAG ) const
|
||||||
{
|
{
|
||||||
EVT VT = Op.getValueType();
|
EVT VT = Op.getValueType();
|
||||||
//printSDValue(Op, 1);
|
|
||||||
SDValue Nodes1;
|
SDValue Nodes1;
|
||||||
SDValue second;
|
SDValue second;
|
||||||
SDValue third;
|
SDValue third;
|
||||||
|
@ -3965,7 +4007,6 @@ AMDILTargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op,
|
||||||
SelectionDAG &DAG) const
|
SelectionDAG &DAG) const
|
||||||
{
|
{
|
||||||
EVT VT = Op.getValueType();
|
EVT VT = Op.getValueType();
|
||||||
//printSDValue(Op, 1);
|
|
||||||
const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Op.getOperand(1));
|
const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Op.getOperand(1));
|
||||||
uint64_t swizzleNum = 0;
|
uint64_t swizzleNum = 0;
|
||||||
DebugLoc DL = Op.getDebugLoc();
|
DebugLoc DL = Op.getDebugLoc();
|
||||||
|
@ -4782,7 +4823,7 @@ uint32_t
|
||||||
AMDILTargetLowering::genVReg(uint32_t regType) const
|
AMDILTargetLowering::genVReg(uint32_t regType) const
|
||||||
{
|
{
|
||||||
return mBB->getParent()->getRegInfo().createVirtualRegister(
|
return mBB->getParent()->getRegInfo().createVirtualRegister(
|
||||||
getRegClassFromID(regType));
|
getTargetMachine().getRegisterInfo()->getRegClass(regType));
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstrBuilder
|
MachineInstrBuilder
|
||||||
|
|
|
@ -10,13 +10,10 @@
|
||||||
// This file contains the AMDIL implementation of the TargetInstrInfo class.
|
// This file contains the AMDIL implementation of the TargetInstrInfo class.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
#include "AMDILInstrInfo.h"
|
|
||||||
#include "AMDILUtilityFunctions.h"
|
|
||||||
|
|
||||||
#define GET_INSTRINFO_CTOR
|
|
||||||
#include "AMDILGenInstrInfo.inc"
|
|
||||||
|
|
||||||
#include "AMDILInstrInfo.h"
|
#include "AMDILInstrInfo.h"
|
||||||
|
#include "AMDIL.h"
|
||||||
|
#include "AMDILISelLowering.h"
|
||||||
#include "AMDILUtilityFunctions.h"
|
#include "AMDILUtilityFunctions.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
|
@ -24,6 +21,9 @@
|
||||||
#include "llvm/CodeGen/PseudoSourceValue.h"
|
#include "llvm/CodeGen/PseudoSourceValue.h"
|
||||||
#include "llvm/Instructions.h"
|
#include "llvm/Instructions.h"
|
||||||
|
|
||||||
|
#define GET_INSTRINFO_CTOR
|
||||||
|
#include "AMDILGenInstrInfo.inc"
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
AMDILInstrInfo::AMDILInstrInfo(AMDILTargetMachine &tm)
|
AMDILInstrInfo::AMDILInstrInfo(AMDILTargetMachine &tm)
|
||||||
|
@ -334,15 +334,11 @@ AMDILInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
||||||
if (MI != MBB.end()) {
|
if (MI != MBB.end()) {
|
||||||
DL = MI->getDebugLoc();
|
DL = MI->getDebugLoc();
|
||||||
}
|
}
|
||||||
MachineInstr *nMI = BuildMI(MBB, MI, DL, get(Opc))
|
BuildMI(MBB, MI, DL, get(Opc))
|
||||||
.addReg(SrcReg, getKillRegState(isKill))
|
.addReg(SrcReg, getKillRegState(isKill))
|
||||||
.addFrameIndex(FrameIndex)
|
.addFrameIndex(FrameIndex)
|
||||||
.addMemOperand(MMO)
|
.addMemOperand(MMO)
|
||||||
.addImm(0);
|
.addImm(0);
|
||||||
AMDILAS::InstrResEnc curRes;
|
|
||||||
curRes.bits.ResourceID
|
|
||||||
= TM.getSubtargetImpl()->device()->getResourceID(AMDILDevice::SCRATCH_ID);
|
|
||||||
setAsmPrinterFlags(nMI, curRes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -418,16 +414,11 @@ AMDILInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||||
if (MI != MBB.end()) {
|
if (MI != MBB.end()) {
|
||||||
DL = MI->getDebugLoc();
|
DL = MI->getDebugLoc();
|
||||||
}
|
}
|
||||||
MachineInstr* nMI = BuildMI(MBB, MI, DL, get(Opc))
|
BuildMI(MBB, MI, DL, get(Opc))
|
||||||
.addReg(DestReg, RegState::Define)
|
.addReg(DestReg, RegState::Define)
|
||||||
.addFrameIndex(FrameIndex)
|
.addFrameIndex(FrameIndex)
|
||||||
.addMemOperand(MMO)
|
.addMemOperand(MMO)
|
||||||
.addImm(0);
|
.addImm(0);
|
||||||
AMDILAS::InstrResEnc curRes;
|
|
||||||
curRes.bits.ResourceID
|
|
||||||
= TM.getSubtargetImpl()->device()->getResourceID(AMDILDevice::SCRATCH_ID);
|
|
||||||
setAsmPrinterFlags(nMI, curRes);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
MachineInstr *
|
MachineInstr *
|
||||||
AMDILInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
AMDILInstrInfo::foldMemoryOperandImpl(MachineFunction &MF,
|
||||||
|
@ -476,65 +467,6 @@ AMDILInstrInfo::getOpcodeAfterMemoryUnfold(unsigned Opc,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
AMDILInstrInfo::areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
|
|
||||||
int64_t &Offset1,
|
|
||||||
int64_t &Offset2) const {
|
|
||||||
return false;
|
|
||||||
if (!Load1->isMachineOpcode() || !Load2->isMachineOpcode()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const MachineSDNode *mload1 = dyn_cast<MachineSDNode>(Load1);
|
|
||||||
const MachineSDNode *mload2 = dyn_cast<MachineSDNode>(Load2);
|
|
||||||
if (!mload1 || !mload2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (mload1->memoperands_empty() ||
|
|
||||||
mload2->memoperands_empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
MachineMemOperand *memOp1 = (*mload1->memoperands_begin());
|
|
||||||
MachineMemOperand *memOp2 = (*mload2->memoperands_begin());
|
|
||||||
const Value *mv1 = memOp1->getValue();
|
|
||||||
const Value *mv2 = memOp2->getValue();
|
|
||||||
if (!memOp1->isLoad() || !memOp2->isLoad()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (getBasePointerValue(mv1) == getBasePointerValue(mv2)) {
|
|
||||||
if (isa<GetElementPtrInst>(mv1) && isa<GetElementPtrInst>(mv2)) {
|
|
||||||
const GetElementPtrInst *gep1 = dyn_cast<GetElementPtrInst>(mv1);
|
|
||||||
const GetElementPtrInst *gep2 = dyn_cast<GetElementPtrInst>(mv2);
|
|
||||||
if (!gep1 || !gep2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (gep1->getNumOperands() != gep2->getNumOperands()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (unsigned i = 0, e = gep1->getNumOperands() - 1; i < e; ++i) {
|
|
||||||
const Value *op1 = gep1->getOperand(i);
|
|
||||||
const Value *op2 = gep2->getOperand(i);
|
|
||||||
if (op1 != op2) {
|
|
||||||
// If any value except the last one is different, return false.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsigned size = gep1->getNumOperands()-1;
|
|
||||||
if (!isa<ConstantInt>(gep1->getOperand(size))
|
|
||||||
|| !isa<ConstantInt>(gep2->getOperand(size))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Offset1 = dyn_cast<ConstantInt>(gep1->getOperand(size))->getSExtValue();
|
|
||||||
Offset2 = dyn_cast<ConstantInt>(gep2->getOperand(size))->getSExtValue();
|
|
||||||
return true;
|
|
||||||
} else if (isa<Argument>(mv1) && isa<Argument>(mv2)) {
|
|
||||||
return false;
|
|
||||||
} else if (isa<GlobalValue>(mv1) && isa<GlobalValue>(mv2)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AMDILInstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
|
bool AMDILInstrInfo::shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
|
||||||
int64_t Offset1, int64_t Offset2,
|
int64_t Offset1, int64_t Offset2,
|
||||||
unsigned NumLoads) const {
|
unsigned NumLoads) const {
|
||||||
|
@ -585,3 +517,113 @@ AMDILInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
|
||||||
// TODO: Implement this function
|
// TODO: Implement this function
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isLoadInst(MachineInstr *MI) const {
|
||||||
|
if (strstr(getName(MI->getOpcode()), "LOADCONST")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return strstr(getName(MI->getOpcode()), "LOAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isSWSExtLoadInst(MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
switch (MI->getOpcode()) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
ExpandCaseToByteShortTypes(AMDIL::LOCALLOAD);
|
||||||
|
ExpandCaseToByteShortTypes(AMDIL::GLOBALLOAD);
|
||||||
|
ExpandCaseToByteShortTypes(AMDIL::REGIONLOAD);
|
||||||
|
ExpandCaseToByteShortTypes(AMDIL::PRIVATELOAD);
|
||||||
|
ExpandCaseToByteShortTypes(AMDIL::CPOOLLOAD);
|
||||||
|
ExpandCaseToByteShortTypes(AMDIL::CONSTANTLOAD);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isExtLoadInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "EXTLOAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isSExtLoadInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "SEXTLOAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isAExtLoadInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "AEXTLOAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isZExtLoadInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "ZEXTLOAD");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isStoreInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "STORE");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isTruncStoreInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "TRUNCSTORE");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isAtomicInst(MachineInstr *MI) const {
|
||||||
|
return strstr(getName(MI->getOpcode()), "ATOM");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMDILInstrInfo::isVolatileInst(MachineInstr *MI) const {
|
||||||
|
if (!MI->memoperands_empty()) {
|
||||||
|
for (MachineInstr::mmo_iterator mob = MI->memoperands_begin(),
|
||||||
|
moe = MI->memoperands_end(); mob != moe; ++mob) {
|
||||||
|
// If there is a volatile mem operand, this is a volatile instruction.
|
||||||
|
if ((*mob)->isVolatile()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isGlobalInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "GLOBAL");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isPrivateInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "PRIVATE");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isConstantInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "CONSTANT")
|
||||||
|
|| strstr(getName(MI->getOpcode()), "CPOOL");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isRegionInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "REGION");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isLocalInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "LOCAL");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isImageInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "IMAGE");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isAppendInst(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "APPEND");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isRegionAtomic(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "ATOM_R");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isLocalAtomic(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "ATOM_L");
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isGlobalAtomic(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "ATOM_G")
|
||||||
|
|| isArenaAtomic(MI);
|
||||||
|
}
|
||||||
|
bool AMDILInstrInfo::isArenaAtomic(llvm::MachineInstr *MI) const
|
||||||
|
{
|
||||||
|
return strstr(getName(MI->getOpcode()), "ATOM_A");
|
||||||
|
}
|
||||||
|
|
|
@ -110,8 +110,6 @@ public:
|
||||||
unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
|
unsigned getOpcodeAfterMemoryUnfold(unsigned Opc,
|
||||||
bool UnfoldLoad, bool UnfoldStore,
|
bool UnfoldLoad, bool UnfoldStore,
|
||||||
unsigned *LoadRegIndex = 0) const;
|
unsigned *LoadRegIndex = 0) const;
|
||||||
bool areLoadsFromSameBasePtr(SDNode *Load1, SDNode *Load2,
|
|
||||||
int64_t &Offset1, int64_t &Offset2) const;
|
|
||||||
bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
|
bool shouldScheduleLoadsNear(SDNode *Load1, SDNode *Load2,
|
||||||
int64_t Offset1, int64_t Offset2,
|
int64_t Offset1, int64_t Offset2,
|
||||||
unsigned NumLoads) const;
|
unsigned NumLoads) const;
|
||||||
|
@ -126,7 +124,30 @@ public:
|
||||||
std::vector<MachineOperand> &Pred) const;
|
std::vector<MachineOperand> &Pred) const;
|
||||||
bool isPredicable(MachineInstr *MI) const;
|
bool isPredicable(MachineInstr *MI) const;
|
||||||
bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
|
bool isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const;
|
||||||
};
|
|
||||||
|
// Helper functions that check the opcode for status information
|
||||||
|
bool isLoadInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isExtLoadInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isSWSExtLoadInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isSExtLoadInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isZExtLoadInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isAExtLoadInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isStoreInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isTruncStoreInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isAtomicInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isVolatileInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isGlobalInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isPrivateInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isConstantInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isRegionInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isLocalInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isImageInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isAppendInst(llvm::MachineInstr *MI) const;
|
||||||
|
bool isRegionAtomic(llvm::MachineInstr *MI) const;
|
||||||
|
bool isLocalAtomic(llvm::MachineInstr *MI) const;
|
||||||
|
bool isGlobalAtomic(llvm::MachineInstr *MI) const;
|
||||||
|
bool isArenaAtomic(llvm::MachineInstr *MI) const;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,10 @@
|
||||||
|
|
||||||
|
|
||||||
#include "AMDIL.h"
|
#include "AMDIL.h"
|
||||||
|
#include "AMDILInstrInfo.h"
|
||||||
#include "AMDILSubtarget.h"
|
#include "AMDILSubtarget.h"
|
||||||
#include "AMDILUtilityFunctions.h"
|
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
|
@ -57,6 +58,8 @@ AMDILMachinePeephole::runOnMachineFunction(MachineFunction &MF)
|
||||||
{
|
{
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
const AMDILSubtarget *STM = &TM.getSubtarget<AMDILSubtarget>();
|
const AMDILSubtarget *STM = &TM.getSubtarget<AMDILSubtarget>();
|
||||||
|
const AMDILInstrInfo * AMDILII =
|
||||||
|
static_cast<const AMDILInstrInfo *>(TM.getInstrInfo());
|
||||||
for (MachineFunction::iterator MBB = MF.begin(), MBE = MF.end();
|
for (MachineFunction::iterator MBB = MF.begin(), MBE = MF.end();
|
||||||
MBB != MBE; ++MBB) {
|
MBB != MBE; ++MBB) {
|
||||||
MachineBasicBlock *mb = MBB;
|
MachineBasicBlock *mb = MBB;
|
||||||
|
@ -67,7 +70,7 @@ AMDILMachinePeephole::runOnMachineFunction(MachineFunction &MF)
|
||||||
name = TM.getInstrInfo()->getName(mi->getOpcode());
|
name = TM.getInstrInfo()->getName(mi->getOpcode());
|
||||||
switch (mi->getOpcode()) {
|
switch (mi->getOpcode()) {
|
||||||
default:
|
default:
|
||||||
if (isAtomicInst(TM.getInstrInfo(), mi)) {
|
if (AMDILII->isAtomicInst(mi)) {
|
||||||
// If we don't support the hardware accellerated address spaces,
|
// If we don't support the hardware accellerated address spaces,
|
||||||
// then the atomic needs to be transformed to the global atomic.
|
// then the atomic needs to be transformed to the global atomic.
|
||||||
if (strstr(name, "_L_")
|
if (strstr(name, "_L_")
|
||||||
|
@ -87,7 +90,8 @@ AMDILMachinePeephole::runOnMachineFunction(MachineFunction &MF)
|
||||||
TM.getInstrInfo()->get(
|
TM.getInstrInfo()->get(
|
||||||
(mi->getOpcode() - AMDIL::ATOM_R_ADD) + AMDIL::ATOM_G_ADD));
|
(mi->getOpcode() - AMDIL::ATOM_R_ADD) + AMDIL::ATOM_G_ADD));
|
||||||
}
|
}
|
||||||
} else if ((isLoadInst(TM.getInstrInfo(), mi) || isStoreInst(TM.getInstrInfo(), mi)) && isVolatileInst(TM.getInstrInfo(), mi)) {
|
} else if ((AMDILII->isLoadInst(mi) || AMDILII->isStoreInst(mi))
|
||||||
|
&& AMDILII->isVolatileInst(mi)) {
|
||||||
insertFence(MIB);
|
insertFence(MIB);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -9,11 +9,12 @@
|
||||||
|
|
||||||
#include "AMDILAlgorithms.tpp"
|
#include "AMDILAlgorithms.tpp"
|
||||||
#include "AMDILDevices.h"
|
#include "AMDILDevices.h"
|
||||||
#include "AMDILUtilityFunctions.h"
|
#include "AMDILInstrInfo.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
||||||
#include "llvm/Function.h"
|
#include "llvm/Function.h"
|
||||||
|
@ -34,6 +35,9 @@ using namespace llvm;
|
||||||
// The Peephole optimization pass is used to do simple last minute optimizations
|
// The Peephole optimization pass is used to do simple last minute optimizations
|
||||||
// that are required for correct code or to remove redundant functions
|
// that are required for correct code or to remove redundant functions
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
class OpaqueType;
|
||||||
|
|
||||||
class LLVM_LIBRARY_VISIBILITY AMDILPeepholeOpt : public FunctionPass {
|
class LLVM_LIBRARY_VISIBILITY AMDILPeepholeOpt : public FunctionPass {
|
||||||
public:
|
public:
|
||||||
TargetMachine &TM;
|
TargetMachine &TM;
|
||||||
|
@ -107,6 +111,19 @@ private:
|
||||||
// samplers at compile time.
|
// samplers at compile time.
|
||||||
bool propagateSamplerInst(CallInst *CI);
|
bool propagateSamplerInst(CallInst *CI);
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
|
||||||
|
// Group of functions that recursively calculate the size of a structure based
|
||||||
|
// on it's sub-types.
|
||||||
|
size_t getTypeSize(Type * const T, bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(StructType * const ST, bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(IntegerType * const IT, bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(FunctionType * const FT,bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(ArrayType * const AT, bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(VectorType * const VT, bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(PointerType * const PT, bool dereferencePtr = false);
|
||||||
|
size_t getTypeSize(OpaqueType * const OT, bool dereferencePtr = false);
|
||||||
|
|
||||||
LLVMContext *mCTX;
|
LLVMContext *mCTX;
|
||||||
Function *mF;
|
Function *mF;
|
||||||
const AMDILSubtarget *mSTM;
|
const AMDILSubtarget *mSTM;
|
||||||
|
@ -1129,3 +1146,106 @@ AMDILPeepholeOpt::getAnalysisUsage(AnalysisUsage &AU) const
|
||||||
FunctionPass::getAnalysisUsage(AU);
|
FunctionPass::getAnalysisUsage(AU);
|
||||||
AU.setPreservesAll();
|
AU.setPreservesAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(Type * const T, bool dereferencePtr) {
|
||||||
|
size_t size = 0;
|
||||||
|
if (!T) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
switch (T->getTypeID()) {
|
||||||
|
case Type::X86_FP80TyID:
|
||||||
|
case Type::FP128TyID:
|
||||||
|
case Type::PPC_FP128TyID:
|
||||||
|
case Type::LabelTyID:
|
||||||
|
assert(0 && "These types are not supported by this backend");
|
||||||
|
default:
|
||||||
|
case Type::FloatTyID:
|
||||||
|
case Type::DoubleTyID:
|
||||||
|
size = T->getPrimitiveSizeInBits() >> 3;
|
||||||
|
break;
|
||||||
|
case Type::PointerTyID:
|
||||||
|
size = getTypeSize(dyn_cast<PointerType>(T), dereferencePtr);
|
||||||
|
break;
|
||||||
|
case Type::IntegerTyID:
|
||||||
|
size = getTypeSize(dyn_cast<IntegerType>(T), dereferencePtr);
|
||||||
|
break;
|
||||||
|
case Type::StructTyID:
|
||||||
|
size = getTypeSize(dyn_cast<StructType>(T), dereferencePtr);
|
||||||
|
break;
|
||||||
|
case Type::ArrayTyID:
|
||||||
|
size = getTypeSize(dyn_cast<ArrayType>(T), dereferencePtr);
|
||||||
|
break;
|
||||||
|
case Type::FunctionTyID:
|
||||||
|
size = getTypeSize(dyn_cast<FunctionType>(T), dereferencePtr);
|
||||||
|
break;
|
||||||
|
case Type::VectorTyID:
|
||||||
|
size = getTypeSize(dyn_cast<VectorType>(T), dereferencePtr);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(StructType * const ST,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
size_t size = 0;
|
||||||
|
if (!ST) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
Type *curType;
|
||||||
|
StructType::element_iterator eib;
|
||||||
|
StructType::element_iterator eie;
|
||||||
|
for (eib = ST->element_begin(), eie = ST->element_end(); eib != eie; ++eib) {
|
||||||
|
curType = *eib;
|
||||||
|
size += getTypeSize(curType, dereferencePtr);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(IntegerType * const IT,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
return IT ? (IT->getBitWidth() >> 3) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(FunctionType * const FT,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
assert(0 && "Should not be able to calculate the size of an function type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(ArrayType * const AT,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
return (size_t)(AT ? (getTypeSize(AT->getElementType(),
|
||||||
|
dereferencePtr) * AT->getNumElements())
|
||||||
|
: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(VectorType * const VT,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
return VT ? (VT->getBitWidth() >> 3) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(PointerType * const PT,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
if (!PT) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Type *CT = PT->getElementType();
|
||||||
|
if (CT->getTypeID() == Type::StructTyID &&
|
||||||
|
PT->getAddressSpace() == AMDILAS::PRIVATE_ADDRESS) {
|
||||||
|
return getTypeSize(dyn_cast<StructType>(CT));
|
||||||
|
} else if (dereferencePtr) {
|
||||||
|
size_t size = 0;
|
||||||
|
for (size_t x = 0, y = PT->getNumContainedTypes(); x < y; ++x) {
|
||||||
|
size += getTypeSize(PT->getContainedType(x), dereferencePtr);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
} else {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMDILPeepholeOpt::getTypeSize(OpaqueType * const OT,
|
||||||
|
bool dereferencePtr) {
|
||||||
|
//assert(0 && "Should not be able to calculate the size of an opaque type");
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
#include "AMDILRegisterInfo.h"
|
#include "AMDILRegisterInfo.h"
|
||||||
#include "AMDIL.h"
|
#include "AMDIL.h"
|
||||||
#include "AMDILUtilityFunctions.h"
|
#include "AMDILInstrInfo.h"
|
||||||
|
#include "AMDILTargetMachine.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
@ -109,7 +110,9 @@ AMDILRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||||
if (!MI.getOperand(x).isFI()) {
|
if (!MI.getOperand(x).isFI()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool def = isStoreInst(TM.getInstrInfo(), &MI);
|
const AMDILInstrInfo * AMDILII =
|
||||||
|
static_cast<const AMDILInstrInfo *>(TM.getInstrInfo());
|
||||||
|
bool def = AMDILII->isStoreInst(&MI);
|
||||||
int FrameIndex = MI.getOperand(x).getIndex();
|
int FrameIndex = MI.getOperand(x).getIndex();
|
||||||
int64_t Offset = MFI->getObjectOffset(FrameIndex);
|
int64_t Offset = MFI->getObjectOffset(FrameIndex);
|
||||||
//int64_t Size = MF.getFrameInfo()->getObjectSize(FrameIndex);
|
//int64_t Size = MF.getFrameInfo()->getObjectSize(FrameIndex);
|
||||||
|
|
|
@ -1,683 +0,0 @@
|
||||||
//===-- AMDILUtilityFunctions.cpp - AMDIL Utility Functions ---------===//
|
|
||||||
//
|
|
||||||
// The LLVM Compiler Infrastructure
|
|
||||||
//
|
|
||||||
// This file is distributed under the University of Illinois Open Source
|
|
||||||
// License. See LICENSE.TXT for details.
|
|
||||||
//
|
|
||||||
//==-----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// This file provides the implementations of functions that are declared in the
|
|
||||||
// AMDILUtilityFUnctions.h file.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
#include "AMDILUtilityFunctions.h"
|
|
||||||
#include "AMDILISelLowering.h"
|
|
||||||
#include "llvm/ADT/ValueMap.h"
|
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
|
||||||
#include "llvm/Constants.h"
|
|
||||||
#include "llvm/DerivedTypes.h"
|
|
||||||
#include "llvm/Instruction.h"
|
|
||||||
#include "llvm/Instructions.h"
|
|
||||||
#include "llvm/Support/Debug.h"
|
|
||||||
#include "llvm/Support/FormattedStream.h"
|
|
||||||
#include "llvm/Type.h"
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <list>
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
#define GET_OPCODE_NAME(TII, MI) \
|
|
||||||
TII->getName(MI->getOpcode())
|
|
||||||
|
|
||||||
|
|
||||||
using namespace llvm;
|
|
||||||
int64_t GET_SCALAR_SIZE(llvm::Type *A) {
|
|
||||||
return A->getScalarSizeInBits();
|
|
||||||
}
|
|
||||||
|
|
||||||
const TargetRegisterClass * getRegClassFromID(unsigned int ID) {
|
|
||||||
switch (ID) {
|
|
||||||
default:
|
|
||||||
assert(0 && "Passed in ID does not match any register classes.");
|
|
||||||
return NULL;
|
|
||||||
case AMDIL::GPRI8RegClassID:
|
|
||||||
return &AMDIL::GPRI8RegClass;
|
|
||||||
case AMDIL::GPRI16RegClassID:
|
|
||||||
return &AMDIL::GPRI16RegClass;
|
|
||||||
case AMDIL::GPRI32RegClassID:
|
|
||||||
return &AMDIL::GPRI32RegClass;
|
|
||||||
case AMDIL::GPRF32RegClassID:
|
|
||||||
return &AMDIL::GPRF32RegClass;
|
|
||||||
case AMDIL::GPRI64RegClassID:
|
|
||||||
return &AMDIL::GPRI64RegClass;
|
|
||||||
case AMDIL::GPRF64RegClassID:
|
|
||||||
return &AMDIL::GPRF64RegClass;
|
|
||||||
case AMDIL::GPRV4F32RegClassID:
|
|
||||||
return &AMDIL::GPRV4F32RegClass;
|
|
||||||
case AMDIL::GPRV4I8RegClassID:
|
|
||||||
return &AMDIL::GPRV4I8RegClass;
|
|
||||||
case AMDIL::GPRV4I16RegClassID:
|
|
||||||
return &AMDIL::GPRV4I16RegClass;
|
|
||||||
case AMDIL::GPRV4I32RegClassID:
|
|
||||||
return &AMDIL::GPRV4I32RegClass;
|
|
||||||
case AMDIL::GPRV2F32RegClassID:
|
|
||||||
return &AMDIL::GPRV2F32RegClass;
|
|
||||||
case AMDIL::GPRV2I8RegClassID:
|
|
||||||
return &AMDIL::GPRV2I8RegClass;
|
|
||||||
case AMDIL::GPRV2I16RegClassID:
|
|
||||||
return &AMDIL::GPRV2I16RegClass;
|
|
||||||
case AMDIL::GPRV2I32RegClassID:
|
|
||||||
return &AMDIL::GPRV2I32RegClass;
|
|
||||||
case AMDIL::GPRV2F64RegClassID:
|
|
||||||
return &AMDIL::GPRV2F64RegClass;
|
|
||||||
case AMDIL::GPRV2I64RegClassID:
|
|
||||||
return &AMDIL::GPRV2I64RegClass;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int getMoveInstFromID(unsigned int ID) {
|
|
||||||
switch (ID) {
|
|
||||||
default:
|
|
||||||
assert(0 && "Passed in ID does not match any move instructions.");
|
|
||||||
case AMDIL::GPRI8RegClassID:
|
|
||||||
return AMDIL::MOVE_i8;
|
|
||||||
case AMDIL::GPRI16RegClassID:
|
|
||||||
return AMDIL::MOVE_i16;
|
|
||||||
case AMDIL::GPRI32RegClassID:
|
|
||||||
return AMDIL::MOVE_i32;
|
|
||||||
case AMDIL::GPRF32RegClassID:
|
|
||||||
return AMDIL::MOVE_f32;
|
|
||||||
case AMDIL::GPRI64RegClassID:
|
|
||||||
return AMDIL::MOVE_i64;
|
|
||||||
case AMDIL::GPRF64RegClassID:
|
|
||||||
return AMDIL::MOVE_f64;
|
|
||||||
case AMDIL::GPRV4F32RegClassID:
|
|
||||||
return AMDIL::MOVE_v4f32;
|
|
||||||
case AMDIL::GPRV4I8RegClassID:
|
|
||||||
return AMDIL::MOVE_v4i8;
|
|
||||||
case AMDIL::GPRV4I16RegClassID:
|
|
||||||
return AMDIL::MOVE_v4i16;
|
|
||||||
case AMDIL::GPRV4I32RegClassID:
|
|
||||||
return AMDIL::MOVE_v4i32;
|
|
||||||
case AMDIL::GPRV2F32RegClassID:
|
|
||||||
return AMDIL::MOVE_v2f32;
|
|
||||||
case AMDIL::GPRV2I8RegClassID:
|
|
||||||
return AMDIL::MOVE_v2i8;
|
|
||||||
case AMDIL::GPRV2I16RegClassID:
|
|
||||||
return AMDIL::MOVE_v2i16;
|
|
||||||
case AMDIL::GPRV2I32RegClassID:
|
|
||||||
return AMDIL::MOVE_v2i32;
|
|
||||||
case AMDIL::GPRV2F64RegClassID:
|
|
||||||
return AMDIL::MOVE_v2f64;
|
|
||||||
case AMDIL::GPRV2I64RegClassID:
|
|
||||||
return AMDIL::MOVE_v2i64;
|
|
||||||
};
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int getPHIMoveInstFromID(unsigned int ID) {
|
|
||||||
switch (ID) {
|
|
||||||
default:
|
|
||||||
assert(0 && "Passed in ID does not match any move instructions.");
|
|
||||||
case AMDIL::GPRI8RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_i8;
|
|
||||||
case AMDIL::GPRI16RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_i16;
|
|
||||||
case AMDIL::GPRI32RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_i32;
|
|
||||||
case AMDIL::GPRF32RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_f32;
|
|
||||||
case AMDIL::GPRI64RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_i64;
|
|
||||||
case AMDIL::GPRF64RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_f64;
|
|
||||||
case AMDIL::GPRV4F32RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v4f32;
|
|
||||||
case AMDIL::GPRV4I8RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v4i8;
|
|
||||||
case AMDIL::GPRV4I16RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v4i16;
|
|
||||||
case AMDIL::GPRV4I32RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v4i32;
|
|
||||||
case AMDIL::GPRV2F32RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v2f32;
|
|
||||||
case AMDIL::GPRV2I8RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v2i8;
|
|
||||||
case AMDIL::GPRV2I16RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v2i16;
|
|
||||||
case AMDIL::GPRV2I32RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v2i32;
|
|
||||||
case AMDIL::GPRV2F64RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v2f64;
|
|
||||||
case AMDIL::GPRV2I64RegClassID:
|
|
||||||
return AMDIL::PHIMOVE_v2i64;
|
|
||||||
};
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TargetRegisterClass* getRegClassFromType(unsigned int type) {
|
|
||||||
switch (type) {
|
|
||||||
default:
|
|
||||||
assert(0 && "Passed in type does not match any register classes.");
|
|
||||||
case MVT::i8:
|
|
||||||
return &AMDIL::GPRI8RegClass;
|
|
||||||
case MVT::i16:
|
|
||||||
return &AMDIL::GPRI16RegClass;
|
|
||||||
case MVT::i32:
|
|
||||||
return &AMDIL::GPRI32RegClass;
|
|
||||||
case MVT::f32:
|
|
||||||
return &AMDIL::GPRF32RegClass;
|
|
||||||
case MVT::i64:
|
|
||||||
return &AMDIL::GPRI64RegClass;
|
|
||||||
case MVT::f64:
|
|
||||||
return &AMDIL::GPRF64RegClass;
|
|
||||||
case MVT::v4f32:
|
|
||||||
return &AMDIL::GPRV4F32RegClass;
|
|
||||||
case MVT::v4i8:
|
|
||||||
return &AMDIL::GPRV4I8RegClass;
|
|
||||||
case MVT::v4i16:
|
|
||||||
return &AMDIL::GPRV4I16RegClass;
|
|
||||||
case MVT::v4i32:
|
|
||||||
return &AMDIL::GPRV4I32RegClass;
|
|
||||||
case MVT::v2f32:
|
|
||||||
return &AMDIL::GPRV2F32RegClass;
|
|
||||||
case MVT::v2i8:
|
|
||||||
return &AMDIL::GPRV2I8RegClass;
|
|
||||||
case MVT::v2i16:
|
|
||||||
return &AMDIL::GPRV2I16RegClass;
|
|
||||||
case MVT::v2i32:
|
|
||||||
return &AMDIL::GPRV2I32RegClass;
|
|
||||||
case MVT::v2f64:
|
|
||||||
return &AMDIL::GPRV2F64RegClass;
|
|
||||||
case MVT::v2i64:
|
|
||||||
return &AMDIL::GPRV2I64RegClass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printSDNode(const SDNode *N) {
|
|
||||||
printf("Opcode: %d isTargetOpcode: %d isMachineOpcode: %d\n",
|
|
||||||
N->getOpcode(), N->isTargetOpcode(), N->isMachineOpcode());
|
|
||||||
printf("Empty: %d OneUse: %d Size: %d NodeID: %d\n",
|
|
||||||
N->use_empty(), N->hasOneUse(), (int)N->use_size(), N->getNodeId());
|
|
||||||
for (unsigned int i = 0; i < N->getNumOperands(); ++i) {
|
|
||||||
printf("OperandNum: %d ValueCount: %d ValueType: %d\n",
|
|
||||||
i, N->getNumValues(), N->getValueType(0) .getSimpleVT().SimpleTy);
|
|
||||||
printSDValue(N->getOperand(i), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printSDValue(const SDValue &Op, int level) {
|
|
||||||
printf("\nOp: %p OpCode: %d NumOperands: %d ", (void*)&Op, Op.getOpcode(),
|
|
||||||
Op.getNumOperands());
|
|
||||||
printf("IsTarget: %d IsMachine: %d ", Op.isTargetOpcode(),
|
|
||||||
Op.isMachineOpcode());
|
|
||||||
if (Op.isMachineOpcode()) {
|
|
||||||
printf("MachineOpcode: %d\n", Op.getMachineOpcode());
|
|
||||||
} else {
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
EVT vt = Op.getValueType();
|
|
||||||
printf("ValueType: %d \n", vt.getSimpleVT().SimpleTy);
|
|
||||||
printf("UseEmpty: %d OneUse: %d\n", Op.use_empty(), Op.hasOneUse());
|
|
||||||
if (level) {
|
|
||||||
printf("Children for %d:\n", level);
|
|
||||||
for (unsigned int i = 0; i < Op.getNumOperands(); ++i) {
|
|
||||||
printf("Child %d->%d:", level, i);
|
|
||||||
printSDValue(Op.getOperand(i), level - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isPHIMove(unsigned int opcode) {
|
|
||||||
switch (opcode) {
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
ExpandCaseToAllTypes(AMDIL::PHIMOVE);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isMove(unsigned int opcode) {
|
|
||||||
switch (opcode) {
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
ExpandCaseToAllTypes(AMDIL::MOVE);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isMoveOrEquivalent(unsigned int opcode) {
|
|
||||||
switch (opcode) {
|
|
||||||
default:
|
|
||||||
return isMove(opcode) || isPHIMove(opcode);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASCHAR);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASSHORT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASINT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASLONG);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASDOUBLE);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASFLOAT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV2CHAR);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV2SHORT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV2INT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV2FLOAT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV2LONG);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV2DOUBLE);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV4CHAR);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV4SHORT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV4INT);
|
|
||||||
ExpandCaseToAllScalarTypes(AMDIL::IL_ASV4FLOAT);
|
|
||||||
case AMDIL::INTTOANY_i8:
|
|
||||||
case AMDIL::INTTOANY_i16:
|
|
||||||
case AMDIL::INTTOANY_i32:
|
|
||||||
case AMDIL::INTTOANY_f32:
|
|
||||||
case AMDIL::DLO:
|
|
||||||
case AMDIL::LLO:
|
|
||||||
case AMDIL::LLO_v2i64:
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool check_type(const Value *ptr, unsigned int addrspace) {
|
|
||||||
if (!ptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Type *ptrType = ptr->getType();
|
|
||||||
return dyn_cast<PointerType>(ptrType)->getAddressSpace() == addrspace;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(Type * const T, bool dereferencePtr) {
|
|
||||||
size_t size = 0;
|
|
||||||
if (!T) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
switch (T->getTypeID()) {
|
|
||||||
case Type::X86_FP80TyID:
|
|
||||||
case Type::FP128TyID:
|
|
||||||
case Type::PPC_FP128TyID:
|
|
||||||
case Type::LabelTyID:
|
|
||||||
assert(0 && "These types are not supported by this backend");
|
|
||||||
default:
|
|
||||||
case Type::FloatTyID:
|
|
||||||
case Type::DoubleTyID:
|
|
||||||
size = T->getPrimitiveSizeInBits() >> 3;
|
|
||||||
break;
|
|
||||||
case Type::PointerTyID:
|
|
||||||
size = getTypeSize(dyn_cast<PointerType>(T), dereferencePtr);
|
|
||||||
break;
|
|
||||||
case Type::IntegerTyID:
|
|
||||||
size = getTypeSize(dyn_cast<IntegerType>(T), dereferencePtr);
|
|
||||||
break;
|
|
||||||
case Type::StructTyID:
|
|
||||||
size = getTypeSize(dyn_cast<StructType>(T), dereferencePtr);
|
|
||||||
break;
|
|
||||||
case Type::ArrayTyID:
|
|
||||||
size = getTypeSize(dyn_cast<ArrayType>(T), dereferencePtr);
|
|
||||||
break;
|
|
||||||
case Type::FunctionTyID:
|
|
||||||
size = getTypeSize(dyn_cast<FunctionType>(T), dereferencePtr);
|
|
||||||
break;
|
|
||||||
case Type::VectorTyID:
|
|
||||||
size = getTypeSize(dyn_cast<VectorType>(T), dereferencePtr);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(StructType * const ST, bool dereferencePtr) {
|
|
||||||
size_t size = 0;
|
|
||||||
if (!ST) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
Type *curType;
|
|
||||||
StructType::element_iterator eib;
|
|
||||||
StructType::element_iterator eie;
|
|
||||||
for (eib = ST->element_begin(), eie = ST->element_end(); eib != eie; ++eib) {
|
|
||||||
curType = *eib;
|
|
||||||
size += getTypeSize(curType, dereferencePtr);
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(IntegerType * const IT, bool dereferencePtr) {
|
|
||||||
return IT ? (IT->getBitWidth() >> 3) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(FunctionType * const FT, bool dereferencePtr) {
|
|
||||||
assert(0 && "Should not be able to calculate the size of an function type");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(ArrayType * const AT, bool dereferencePtr) {
|
|
||||||
return (size_t)(AT ? (getTypeSize(AT->getElementType(),
|
|
||||||
dereferencePtr) * AT->getNumElements())
|
|
||||||
: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(VectorType * const VT, bool dereferencePtr) {
|
|
||||||
return VT ? (VT->getBitWidth() >> 3) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(PointerType * const PT, bool dereferencePtr) {
|
|
||||||
if (!PT) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Type *CT = PT->getElementType();
|
|
||||||
if (CT->getTypeID() == Type::StructTyID &&
|
|
||||||
PT->getAddressSpace() == AMDILAS::PRIVATE_ADDRESS) {
|
|
||||||
return getTypeSize(dyn_cast<StructType>(CT));
|
|
||||||
} else if (dereferencePtr) {
|
|
||||||
size_t size = 0;
|
|
||||||
for (size_t x = 0, y = PT->getNumContainedTypes(); x < y; ++x) {
|
|
||||||
size += getTypeSize(PT->getContainedType(x), dereferencePtr);
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
} else {
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getTypeSize(OpaqueType * const OT, bool dereferencePtr) {
|
|
||||||
//assert(0 && "Should not be able to calculate the size of an opaque type");
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(Type * const T) {
|
|
||||||
size_t size = 0;
|
|
||||||
if (!T) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
switch (T->getTypeID()) {
|
|
||||||
case Type::X86_FP80TyID:
|
|
||||||
case Type::FP128TyID:
|
|
||||||
case Type::PPC_FP128TyID:
|
|
||||||
case Type::LabelTyID:
|
|
||||||
assert(0 && "These types are not supported by this backend");
|
|
||||||
default:
|
|
||||||
case Type::FloatTyID:
|
|
||||||
case Type::DoubleTyID:
|
|
||||||
size = 1;
|
|
||||||
break;
|
|
||||||
case Type::PointerTyID:
|
|
||||||
size = getNumElements(dyn_cast<PointerType>(T));
|
|
||||||
break;
|
|
||||||
case Type::IntegerTyID:
|
|
||||||
size = getNumElements(dyn_cast<IntegerType>(T));
|
|
||||||
break;
|
|
||||||
case Type::StructTyID:
|
|
||||||
size = getNumElements(dyn_cast<StructType>(T));
|
|
||||||
break;
|
|
||||||
case Type::ArrayTyID:
|
|
||||||
size = getNumElements(dyn_cast<ArrayType>(T));
|
|
||||||
break;
|
|
||||||
case Type::FunctionTyID:
|
|
||||||
size = getNumElements(dyn_cast<FunctionType>(T));
|
|
||||||
break;
|
|
||||||
case Type::VectorTyID:
|
|
||||||
size = getNumElements(dyn_cast<VectorType>(T));
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(StructType * const ST) {
|
|
||||||
size_t size = 0;
|
|
||||||
if (!ST) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
Type *curType;
|
|
||||||
StructType::element_iterator eib;
|
|
||||||
StructType::element_iterator eie;
|
|
||||||
for (eib = ST->element_begin(), eie = ST->element_end();
|
|
||||||
eib != eie; ++eib) {
|
|
||||||
curType = *eib;
|
|
||||||
size += getNumElements(curType);
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(IntegerType * const IT) {
|
|
||||||
return (!IT) ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(FunctionType * const FT) {
|
|
||||||
assert(0 && "Should not be able to calculate the number of "
|
|
||||||
"elements of a function type");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(ArrayType * const AT) {
|
|
||||||
return (!AT) ? 0
|
|
||||||
: (size_t)(getNumElements(AT->getElementType()) *
|
|
||||||
AT->getNumElements());
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(VectorType * const VT) {
|
|
||||||
return (!VT) ? 0
|
|
||||||
: VT->getNumElements() * getNumElements(VT->getElementType());
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getNumElements(PointerType * const PT) {
|
|
||||||
size_t size = 0;
|
|
||||||
if (!PT) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
for (size_t x = 0, y = PT->getNumContainedTypes(); x < y; ++x) {
|
|
||||||
size += getNumElements(PT->getContainedType(x));
|
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm::Value *getBasePointerValue(const llvm::Value *V)
|
|
||||||
{
|
|
||||||
if (!V) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
const Value *ret = NULL;
|
|
||||||
ValueMap<const Value *, bool> ValueBitMap;
|
|
||||||
std::queue<const Value *, std::list<const Value *> > ValueQueue;
|
|
||||||
ValueQueue.push(V);
|
|
||||||
while (!ValueQueue.empty()) {
|
|
||||||
V = ValueQueue.front();
|
|
||||||
if (ValueBitMap.find(V) == ValueBitMap.end()) {
|
|
||||||
ValueBitMap[V] = true;
|
|
||||||
if (dyn_cast<Argument>(V) && dyn_cast<PointerType>(V->getType())) {
|
|
||||||
ret = V;
|
|
||||||
break;
|
|
||||||
} else if (dyn_cast<GlobalVariable>(V)) {
|
|
||||||
ret = V;
|
|
||||||
break;
|
|
||||||
} else if (dyn_cast<Constant>(V)) {
|
|
||||||
const ConstantExpr *CE = dyn_cast<ConstantExpr>(V);
|
|
||||||
if (CE) {
|
|
||||||
ValueQueue.push(CE->getOperand(0));
|
|
||||||
}
|
|
||||||
} else if (const AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
|
|
||||||
ret = AI;
|
|
||||||
break;
|
|
||||||
} else if (const Instruction *I = dyn_cast<Instruction>(V)) {
|
|
||||||
uint32_t numOps = I->getNumOperands();
|
|
||||||
for (uint32_t x = 0; x < numOps; ++x) {
|
|
||||||
ValueQueue.push(I->getOperand(x));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// assert(0 && "Found a Value that we didn't know how to handle!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ValueQueue.pop();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const llvm::Value *getBasePointerValue(const llvm::MachineInstr *MI) {
|
|
||||||
const Value *moVal = NULL;
|
|
||||||
if (!MI->memoperands_empty()) {
|
|
||||||
const MachineMemOperand *memOp = (*MI->memoperands_begin());
|
|
||||||
moVal = memOp ? memOp->getValue() : NULL;
|
|
||||||
moVal = getBasePointerValue(moVal);
|
|
||||||
}
|
|
||||||
return moVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool commaPrint(int i, llvm::raw_ostream &O) {
|
|
||||||
O << ":" << i;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLoadInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
if (strstr(GET_OPCODE_NAME(TII, MI), "LOADCONST")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "LOAD");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSWSExtLoadInst(MachineInstr *MI)
|
|
||||||
{
|
|
||||||
switch (MI->getOpcode()) {
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
ExpandCaseToByteShortTypes(AMDIL::LOCALLOAD);
|
|
||||||
ExpandCaseToByteShortTypes(AMDIL::GLOBALLOAD);
|
|
||||||
ExpandCaseToByteShortTypes(AMDIL::REGIONLOAD);
|
|
||||||
ExpandCaseToByteShortTypes(AMDIL::PRIVATELOAD);
|
|
||||||
ExpandCaseToByteShortTypes(AMDIL::CPOOLLOAD);
|
|
||||||
ExpandCaseToByteShortTypes(AMDIL::CONSTANTLOAD);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isExtLoadInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "EXTLOAD");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isSExtLoadInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "SEXTLOAD");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isAExtLoadInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "AEXTLOAD");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isZExtLoadInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "ZEXTLOAD");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isStoreInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "STORE");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isTruncStoreInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "TRUNCSTORE");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isAtomicInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "ATOM");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isVolatileInst(const llvm::TargetInstrInfo * TII, MachineInstr *MI) {
|
|
||||||
if (!MI->memoperands_empty()) {
|
|
||||||
for (MachineInstr::mmo_iterator mob = MI->memoperands_begin(),
|
|
||||||
moe = MI->memoperands_end(); mob != moe; ++mob) {
|
|
||||||
// If there is a volatile mem operand, this is a volatile instruction.
|
|
||||||
if ((*mob)->isVolatile()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool isGlobalInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "GLOBAL");
|
|
||||||
}
|
|
||||||
bool isPrivateInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "PRIVATE");
|
|
||||||
}
|
|
||||||
bool isConstantInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "CONSTANT")
|
|
||||||
|| strstr(GET_OPCODE_NAME(TII, MI), "CPOOL");
|
|
||||||
}
|
|
||||||
bool isRegionInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "REGION");
|
|
||||||
}
|
|
||||||
bool isLocalInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "LOCAL");
|
|
||||||
}
|
|
||||||
bool isImageInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "IMAGE");
|
|
||||||
}
|
|
||||||
bool isAppendInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "APPEND");
|
|
||||||
}
|
|
||||||
bool isRegionAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "ATOM_R");
|
|
||||||
}
|
|
||||||
bool isLocalAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "ATOM_L");
|
|
||||||
}
|
|
||||||
bool isGlobalAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "ATOM_G")
|
|
||||||
|| isArenaAtomic(TII, MI);
|
|
||||||
}
|
|
||||||
bool isArenaAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI)
|
|
||||||
{
|
|
||||||
return strstr(GET_OPCODE_NAME(TII, MI), "ATOM_A");
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* getSrcSwizzle(unsigned idx) {
|
|
||||||
const char *srcSwizzles[] = {
|
|
||||||
"", ".x000", ".0x00", ".00x0", ".000x", ".y000", ".0y00", ".00y0", ".000y",
|
|
||||||
".z000", ".0z00", ".00z0", ".000z", ".w000", ".0w00", ".00w0", ".000w",
|
|
||||||
".xy00", ".00xy", ".zw00", ".00zw", ".xyz0", ".0xyz", ".xyzw", ".0000",
|
|
||||||
".xxxx", ".yyyy", ".zzzz", ".wwww", ".xyxy", ".zwzw", ".xzxz", ".ywyw",
|
|
||||||
".x0y0", ".0x0y", ".xy_neg(y)", "_neg(yw)", "_neg(x)", ".xy_neg(xy)",
|
|
||||||
"_neg(xyzw)", ".0yzw", ".x0zw", ".xy0w", ".x", ".y", ".z", ".w", ".xy",
|
|
||||||
".zw"
|
|
||||||
};
|
|
||||||
assert(idx < sizeof(srcSwizzles)/sizeof(srcSwizzles[0])
|
|
||||||
&& "Idx passed in is invalid!");
|
|
||||||
return srcSwizzles[idx];
|
|
||||||
}
|
|
||||||
const char* getDstSwizzle(unsigned idx) {
|
|
||||||
const char *dstSwizzles[] = {
|
|
||||||
"", ".x___", ".xy__", ".xyz_", ".xyzw", "._y__", "._yz_", "._yzw", ".__z_",
|
|
||||||
".__zw", ".___w", ".x_zw", ".xy_w", ".x_z_", ".x__w", "._y_w",
|
|
||||||
};
|
|
||||||
assert(idx < sizeof(dstSwizzles)/sizeof(dstSwizzles[0])
|
|
||||||
&& "Idx passed in is invalid!");
|
|
||||||
return dstSwizzles[idx];
|
|
||||||
}
|
|
||||||
/// Helper function to get the currently set flags
|
|
||||||
void getAsmPrinterFlags(MachineInstr *MI, AMDILAS::InstrResEnc &curRes)
|
|
||||||
{
|
|
||||||
// We need 16 bits of information, but LLVMr127097 cut the field in half.
|
|
||||||
// So we have to use two different fields to store all of our information.
|
|
||||||
uint16_t upper = MI->getFlags() << 8;
|
|
||||||
uint16_t lower = MI->getAsmPrinterFlags();
|
|
||||||
curRes.u16all = upper | lower;
|
|
||||||
}
|
|
||||||
/// Helper function to clear the currently set flags and add the new flags.
|
|
||||||
void setAsmPrinterFlags(MachineInstr *MI, AMDILAS::InstrResEnc &curRes)
|
|
||||||
{
|
|
||||||
// We need 16 bits of information, but LLVMr127097 cut the field in half.
|
|
||||||
// So we have to use two different fields to store all of our information.
|
|
||||||
MI->clearAsmPrinterFlags();
|
|
||||||
MI->setFlags(0);
|
|
||||||
uint8_t lower = curRes.u16all & 0xFF;
|
|
||||||
uint8_t upper = (curRes.u16all >> 8) & 0xFF;
|
|
||||||
MI->setFlags(upper);
|
|
||||||
MI->setAsmPrinterFlag((llvm::MachineInstr::CommentFlag)lower);
|
|
||||||
}
|
|
|
@ -7,191 +7,12 @@
|
||||||
//
|
//
|
||||||
//==-----------------------------------------------------------------------===//
|
//==-----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file provides declarations for functions that are used across different
|
// This file provides helper macros for expanding case statements.
|
||||||
// classes and provide various conversions or utility to shorten the code
|
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
#ifndef AMDILUTILITYFUNCTIONS_H_
|
#ifndef AMDILUTILITYFUNCTIONS_H_
|
||||||
#define AMDILUTILITYFUNCTIONS_H_
|
#define AMDILUTILITYFUNCTIONS_H_
|
||||||
|
|
||||||
#include "AMDIL.h"
|
|
||||||
#include "AMDILTargetMachine.h"
|
|
||||||
#include "llvm/ADT/SmallVector.h"
|
|
||||||
|
|
||||||
// Utility functions from ID
|
|
||||||
//
|
|
||||||
namespace llvm {
|
|
||||||
class TargetRegisterClass;
|
|
||||||
class SDValue;
|
|
||||||
class SDNode;
|
|
||||||
class Value;
|
|
||||||
class Type;
|
|
||||||
class StructType;
|
|
||||||
class IntegerType;
|
|
||||||
class FunctionType;
|
|
||||||
class VectorType;
|
|
||||||
class ArrayType;
|
|
||||||
class PointerType;
|
|
||||||
class OpaqueType;
|
|
||||||
class MachineInstr;
|
|
||||||
|
|
||||||
}
|
|
||||||
enum SrcSwizzles {
|
|
||||||
AMDIL_SRC_SWIZZLE_DEFAULT = 0,
|
|
||||||
AMDIL_SRC_SWIZZLE_X000,
|
|
||||||
AMDIL_SRC_SWIZZLE_0X00,
|
|
||||||
AMDIL_SRC_SWIZZLE_00X0,
|
|
||||||
AMDIL_SRC_SWIZZLE_000X,
|
|
||||||
AMDIL_SRC_SWIZZLE_Y000,
|
|
||||||
AMDIL_SRC_SWIZZLE_0Y00,
|
|
||||||
AMDIL_SRC_SWIZZLE_00Y0,
|
|
||||||
AMDIL_SRC_SWIZZLE_000Y,
|
|
||||||
AMDIL_SRC_SWIZZLE_Z000,
|
|
||||||
AMDIL_SRC_SWIZZLE_0Z00,
|
|
||||||
AMDIL_SRC_SWIZZLE_00Z0,
|
|
||||||
AMDIL_SRC_SWIZZLE_000Z,
|
|
||||||
AMDIL_SRC_SWIZZLE_W000,
|
|
||||||
AMDIL_SRC_SWIZZLE_0W00,
|
|
||||||
AMDIL_SRC_SWIZZLE_00W0,
|
|
||||||
AMDIL_SRC_SWIZZLE_000W,
|
|
||||||
AMDIL_SRC_SWIZZLE_XY00,
|
|
||||||
AMDIL_SRC_SWIZZLE_00XY,
|
|
||||||
AMDIL_SRC_SWIZZLE_ZW00,
|
|
||||||
AMDIL_SRC_SWIZZLE_00ZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_XYZ0,
|
|
||||||
AMDIL_SRC_SWIZZLE_0XYZ,
|
|
||||||
AMDIL_SRC_SWIZZLE_XYZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_0000,
|
|
||||||
AMDIL_SRC_SWIZZLE_XXXX,
|
|
||||||
AMDIL_SRC_SWIZZLE_YYYY,
|
|
||||||
AMDIL_SRC_SWIZZLE_ZZZZ,
|
|
||||||
AMDIL_SRC_SWIZZLE_WWWW,
|
|
||||||
AMDIL_SRC_SWIZZLE_XYXY,
|
|
||||||
AMDIL_SRC_SWIZZLE_ZWZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_XZXZ,
|
|
||||||
AMDIL_SRC_SWIZZLE_YWYW,
|
|
||||||
AMDIL_SRC_SWIZZLE_X0Y0,
|
|
||||||
AMDIL_SRC_SWIZZLE_0X0Y,
|
|
||||||
AMDIL_SRC_SWIZZLE_XY_NEGY,
|
|
||||||
AMDIL_SRC_SWIZZLE_NEGYW,
|
|
||||||
AMDIL_SRC_SWIZZLE_NEGX,
|
|
||||||
AMDIL_SRC_SWIZZLE_XY_NEGXY,
|
|
||||||
AMDIL_SRC_SWIZZLE_NEG_XYZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_0YZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_X0ZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_XY0W,
|
|
||||||
AMDIL_SRC_SWIZZLE_X,
|
|
||||||
AMDIL_SRC_SWIZZLE_Y,
|
|
||||||
AMDIL_SRC_SWIZZLE_Z,
|
|
||||||
AMDIL_SRC_SWIZZLE_W,
|
|
||||||
AMDIL_SRC_SWIZZLE_XY,
|
|
||||||
AMDIL_SRC_SWIZZLE_ZW,
|
|
||||||
AMDIL_SRC_SWIZZLE_LAST
|
|
||||||
};
|
|
||||||
enum DstSwizzles {
|
|
||||||
AMDIL_DST_SWIZZLE_DEFAULT = 0,
|
|
||||||
AMDIL_DST_SWIZZLE_X___,
|
|
||||||
AMDIL_DST_SWIZZLE_XY__,
|
|
||||||
AMDIL_DST_SWIZZLE_XYZ_,
|
|
||||||
AMDIL_DST_SWIZZLE_XYZW,
|
|
||||||
AMDIL_DST_SWIZZLE__Y__,
|
|
||||||
AMDIL_DST_SWIZZLE__YZ_,
|
|
||||||
AMDIL_DST_SWIZZLE__YZW,
|
|
||||||
AMDIL_DST_SWIZZLE___Z_,
|
|
||||||
AMDIL_DST_SWIZZLE___ZW,
|
|
||||||
AMDIL_DST_SWIZZLE____W,
|
|
||||||
AMDIL_DST_SWIZZLE_X_ZW,
|
|
||||||
AMDIL_DST_SWIZZLE_XY_W,
|
|
||||||
AMDIL_DST_SWIZZLE_X_Z_,
|
|
||||||
AMDIL_DST_SWIZZLE_X__W,
|
|
||||||
AMDIL_DST_SWIZZLE__Y_W,
|
|
||||||
AMDIL_DST_SWIZZLE_LAST
|
|
||||||
};
|
|
||||||
// Function to get the correct src swizzle string from ID
|
|
||||||
const char *getSrcSwizzle(unsigned);
|
|
||||||
|
|
||||||
// Function to get the correct dst swizzle string from ID
|
|
||||||
const char *getDstSwizzle(unsigned);
|
|
||||||
|
|
||||||
const llvm::TargetRegisterClass *getRegClassFromID(unsigned int ID);
|
|
||||||
|
|
||||||
unsigned int getMoveInstFromID(unsigned int ID);
|
|
||||||
unsigned int getPHIMoveInstFromID(unsigned int ID);
|
|
||||||
|
|
||||||
// Utility functions from Type.
|
|
||||||
const llvm::TargetRegisterClass *getRegClassFromType(unsigned int type);
|
|
||||||
unsigned int getTargetIndependentMoveFromType(unsigned int type);
|
|
||||||
|
|
||||||
// Debug functions for SDNode and SDValue.
|
|
||||||
void printSDValue(const llvm::SDValue &Op, int level);
|
|
||||||
void printSDNode(const llvm::SDNode *N);
|
|
||||||
|
|
||||||
// Functions to check if an opcode is a specific type.
|
|
||||||
bool isMove(unsigned int opcode);
|
|
||||||
bool isPHIMove(unsigned int opcode);
|
|
||||||
bool isMoveOrEquivalent(unsigned int opcode);
|
|
||||||
|
|
||||||
// Function to check address space
|
|
||||||
bool check_type(const llvm::Value *ptr, unsigned int addrspace);
|
|
||||||
|
|
||||||
// Group of functions that recursively calculate the size of a structure based
|
|
||||||
// on it's sub-types.
|
|
||||||
size_t getTypeSize(llvm::Type * const T, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::StructType * const ST, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::IntegerType * const IT, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::FunctionType * const FT, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::ArrayType * const AT, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::VectorType * const VT, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::PointerType * const PT, bool dereferencePtr = false);
|
|
||||||
size_t
|
|
||||||
getTypeSize(llvm::OpaqueType * const OT, bool dereferencePtr = false);
|
|
||||||
|
|
||||||
// Group of functions that recursively calculate the number of elements of a
|
|
||||||
// structure based on it's sub-types.
|
|
||||||
size_t getNumElements(llvm::Type * const T);
|
|
||||||
size_t getNumElements(llvm::StructType * const ST);
|
|
||||||
size_t getNumElements(llvm::IntegerType * const IT);
|
|
||||||
size_t getNumElements(llvm::FunctionType * const FT);
|
|
||||||
size_t getNumElements(llvm::ArrayType * const AT);
|
|
||||||
size_t getNumElements(llvm::VectorType * const VT);
|
|
||||||
size_t getNumElements(llvm::PointerType * const PT);
|
|
||||||
size_t getNumElements(llvm::OpaqueType * const OT);
|
|
||||||
const llvm::Value *getBasePointerValue(const llvm::Value *V);
|
|
||||||
const llvm::Value *getBasePointerValue(const llvm::MachineInstr *MI);
|
|
||||||
|
|
||||||
|
|
||||||
int64_t GET_SCALAR_SIZE(llvm::Type* A);
|
|
||||||
|
|
||||||
// Helper functions that check the opcode for status information
|
|
||||||
bool isLoadInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isExtLoadInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isSWSExtLoadInst(llvm::MachineInstr *MI);
|
|
||||||
bool isSExtLoadInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isZExtLoadInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isAExtLoadInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isStoreInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isTruncStoreInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isAtomicInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isVolatileInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isGlobalInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isPrivateInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isConstantInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isRegionInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isLocalInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isImageInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isAppendInst(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isRegionAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isLocalAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isGlobalAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
bool isArenaAtomic(const llvm::TargetInstrInfo * TII, llvm::MachineInstr *MI);
|
|
||||||
|
|
||||||
|
|
||||||
// Macros that are used to help with switch statements for various data types
|
// Macros that are used to help with switch statements for various data types
|
||||||
// However, these macro's do not return anything unlike the second set below.
|
// However, these macro's do not return anything unlike the second set below.
|
||||||
#define ExpandCaseTo32bitIntTypes(Instr) \
|
#define ExpandCaseTo32bitIntTypes(Instr) \
|
||||||
|
@ -354,9 +175,4 @@ case Instr##_v4f32: \
|
||||||
case Instr##_v2i64: \
|
case Instr##_v2i64: \
|
||||||
case Instr##_v2f64:
|
case Instr##_v2f64:
|
||||||
|
|
||||||
bool commaPrint(int i, llvm::raw_ostream &O);
|
|
||||||
/// Helper function to get the currently get/set flags.
|
|
||||||
void getAsmPrinterFlags(llvm::MachineInstr *MI, llvm::AMDILAS::InstrResEnc &curRes);
|
|
||||||
void setAsmPrinterFlags(llvm::MachineInstr *MI, llvm::AMDILAS::InstrResEnc &curRes);
|
|
||||||
|
|
||||||
#endif // AMDILUTILITYFUNCTIONS_H_
|
#endif // AMDILUTILITYFUNCTIONS_H_
|
||||||
|
|
|
@ -37,7 +37,6 @@ CPP_SOURCES := \
|
||||||
AMDILSIDevice.cpp \
|
AMDILSIDevice.cpp \
|
||||||
AMDILSubtarget.cpp \
|
AMDILSubtarget.cpp \
|
||||||
AMDILTargetMachine.cpp \
|
AMDILTargetMachine.cpp \
|
||||||
AMDILUtilityFunctions.cpp \
|
|
||||||
AMDGPUTargetMachine.cpp \
|
AMDGPUTargetMachine.cpp \
|
||||||
AMDGPUISelLowering.cpp \
|
AMDGPUISelLowering.cpp \
|
||||||
AMDGPUConvertToISA.cpp \
|
AMDGPUConvertToISA.cpp \
|
||||||
|
|
|
@ -724,44 +724,5 @@ RegElement maskBitToElement(unsigned int maskBit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int dstSwizzleToWriteMask(unsigned swizzle)
|
|
||||||
{
|
|
||||||
switch(swizzle) {
|
|
||||||
default:
|
|
||||||
case AMDIL_DST_SWIZZLE_DEFAULT:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Y | WRITE_MASK_Z | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE_X___:
|
|
||||||
return WRITE_MASK_X;
|
|
||||||
case AMDIL_DST_SWIZZLE_XY__:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Y;
|
|
||||||
case AMDIL_DST_SWIZZLE_XYZ_:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Y | WRITE_MASK_Z;
|
|
||||||
case AMDIL_DST_SWIZZLE_XYZW:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Y | WRITE_MASK_Z | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE__Y__:
|
|
||||||
return WRITE_MASK_Y;
|
|
||||||
case AMDIL_DST_SWIZZLE__YZ_:
|
|
||||||
return WRITE_MASK_Y | WRITE_MASK_Z;
|
|
||||||
case AMDIL_DST_SWIZZLE__YZW:
|
|
||||||
return WRITE_MASK_Y | WRITE_MASK_Z | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE___Z_:
|
|
||||||
return WRITE_MASK_Z;
|
|
||||||
case AMDIL_DST_SWIZZLE___ZW:
|
|
||||||
return WRITE_MASK_Z | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE____W:
|
|
||||||
return WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE_X_ZW:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Z | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE_XY_W:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Y | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE_X_Z_:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_Z;
|
|
||||||
case AMDIL_DST_SWIZZLE_X__W:
|
|
||||||
return WRITE_MASK_X | WRITE_MASK_W;
|
|
||||||
case AMDIL_DST_SWIZZLE__Y_W:
|
|
||||||
return WRITE_MASK_Y | WRITE_MASK_W;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "AMDILGenCodeEmitter.inc"
|
#include "AMDILGenCodeEmitter.inc"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue