[CSKY] Lower ISD::ConstantPool node to support getting the address of ConstantPool entry

When there is not GRS or MOVIH/ORI instruction, we can not get the address of
ConstantPool entry directly. So we need put the address into ConstantPool to leverage CSKY::LRW instruction.
This commit is contained in:
Zi Xuan Wu (Zeson) 2022-11-21 09:33:09 +08:00 committed by Zi Xuan Wu
parent c2ec455f18
commit f4d61cdf9c
9 changed files with 114 additions and 11 deletions

View File

@ -208,6 +208,9 @@ void CSKYAsmPrinter::emitMachineConstantPoolValue(
} else if (CCPV->isJT()) {
signed JTI = cast<CSKYConstantPoolJT>(CCPV)->getJTI();
MCSym = GetJTISymbol(JTI);
} else if (CCPV->isConstPool()) {
const Constant *C = cast<CSKYConstantPoolConstant>(CCPV)->getConstantPool();
MCSym = GetCPISymbol(MCP->getConstantPoolIndex(C, Align(4)));
} else {
assert(CCPV->isExtSymbol() && "unrecognized constant pool value");
StringRef Sym = cast<CSKYConstantPoolSymbol>(CCPV)->getSymbol();

View File

@ -573,10 +573,6 @@ void CSKYConstantIslands::initializeFunctionInfo(
CPEntry *CPE = findConstPoolEntry(CPI, CPEMI);
assert(CPE && "Cannot find a corresponding CPEntry!");
CPE->RefCount++;
// Instructions can only use one CP entry, don't bother scanning the
// rest of the operands.
break;
}
}
}

View File

@ -77,16 +77,23 @@ void CSKYConstantPoolValue::print(raw_ostream &O) const {
//===----------------------------------------------------------------------===//
CSKYConstantPoolConstant::CSKYConstantPoolConstant(
const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, unsigned ID)
: CSKYConstantPoolValue(C->getType(), Kind, PCAdjust, Modifier,
AddCurrentAddress, ID),
: CSKYConstantPoolValue(Ty, Kind, PCAdjust, Modifier, AddCurrentAddress,
ID),
CVal(C) {}
CSKYConstantPoolConstant *CSKYConstantPoolConstant::Create(
const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, unsigned ID) {
return new CSKYConstantPoolConstant(C, Kind, PCAdjust, Modifier,
return new CSKYConstantPoolConstant(C, C->getType(), Kind, PCAdjust, Modifier,
AddCurrentAddress, ID);
}
CSKYConstantPoolConstant *CSKYConstantPoolConstant::Create(
const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress, unsigned ID) {
return new CSKYConstantPoolConstant(C, Ty, Kind, PCAdjust, Modifier,
AddCurrentAddress, ID);
}
@ -100,6 +107,10 @@ const BlockAddress *CSKYConstantPoolConstant::getBlockAddress() const {
return cast<BlockAddress>(CVal);
}
const Constant *CSKYConstantPoolConstant::getConstantPool() const {
return CVal;
}
int CSKYConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) {
return getExistingMachineCPValueImpl<CSKYConstantPoolConstant>(CP, Alignment);

View File

@ -33,7 +33,8 @@ enum CSKYCPKind {
CPExtSymbol,
CPBlockAddress,
CPMachineBasicBlock,
CPJT
CPJT,
CPConstPool
};
enum CSKYCPModifier { NO_MOD, ADDR, GOT, GOTOFF, PLT, TLSLE, TLSIE, TLSGD };
@ -69,6 +70,7 @@ public:
return Kind == CSKYCP::CPMachineBasicBlock;
}
bool isJT() const { return Kind == CSKYCP::CPJT; }
bool isConstPool() const { return Kind == CSKYCP::CPConstPool; }
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
@ -105,7 +107,7 @@ public:
class CSKYConstantPoolConstant : public CSKYConstantPoolValue {
const Constant *CVal; // Constant being loaded.
CSKYConstantPoolConstant(const Constant *C, CSKYCP::CSKYCPKind Kind,
CSKYConstantPoolConstant(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind,
unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier,
bool AddCurrentAddress, unsigned ID);
@ -114,8 +116,13 @@ public:
Create(const Constant *C, CSKYCP::CSKYCPKind Kind, unsigned PCAdjust,
CSKYCP::CSKYCPModifier Modifier, bool AddCurrentAddress,
unsigned ID = 0);
static CSKYConstantPoolConstant *
Create(const Constant *C, Type *Ty, CSKYCP::CSKYCPKind Kind,
unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier,
bool AddCurrentAddress, unsigned ID = 0);
const GlobalValue *getGV() const;
const BlockAddress *getBlockAddress() const;
const Constant *getConstantPool() const;
int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;
@ -127,7 +134,7 @@ public:
}
static bool classof(const CSKYConstantPoolValue *APV) {
return APV->isGlobalValue() || APV->isBlockAddress();
return APV->isGlobalValue() || APV->isBlockAddress() || APV->isConstPool();
}
};

View File

@ -87,6 +87,9 @@ CSKYTargetLowering::CSKYTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::ExternalSymbol, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
if (!Subtarget.hasE2()) {
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
}
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::VASTART, MVT::Other, Custom);
@ -170,6 +173,8 @@ SDValue CSKYTargetLowering::LowerOperation(SDValue Op,
return LowerJumpTable(Op, DAG);
case ISD::BlockAddress:
return LowerBlockAddress(Op, DAG);
case ISD::ConstantPool:
return LowerConstantPool(Op, DAG);
case ISD::VASTART:
return LowerVASTART(Op, DAG);
case ISD::FRAMEADDR:
@ -1058,12 +1063,24 @@ SDValue CSKYTargetLowering::getTargetConstantPoolValue(BlockAddressSDNode *N,
EVT Ty,
SelectionDAG &DAG,
unsigned Flags) const {
assert(N->getOffset() == 0);
CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
N->getBlockAddress(), CSKYCP::CPBlockAddress, 0, getModifier(Flags),
false);
return DAG.getTargetConstantPool(CPV, Ty);
}
SDValue CSKYTargetLowering::getTargetConstantPoolValue(ConstantPoolSDNode *N,
EVT Ty,
SelectionDAG &DAG,
unsigned Flags) const {
assert(N->getOffset() == 0);
CSKYConstantPoolValue *CPV = CSKYConstantPoolConstant::Create(
N->getConstVal(), Type::getInt32Ty(*DAG.getContext()),
CSKYCP::CPConstPool, 0, getModifier(Flags), false);
return DAG.getTargetConstantPool(CPV, Ty);
}
SDValue CSKYTargetLowering::getTargetNode(GlobalAddressSDNode *N, SDLoc DL,
EVT Ty, SelectionDAG &DAG,
unsigned Flags) const {
@ -1089,6 +1106,14 @@ SDValue CSKYTargetLowering::getTargetNode(BlockAddressSDNode *N, SDLoc DL,
Flags);
}
SDValue CSKYTargetLowering::getTargetNode(ConstantPoolSDNode *N, SDLoc DL,
EVT Ty, SelectionDAG &DAG,
unsigned Flags) const {
return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),
N->getOffset(), Flags);
}
const char *CSKYTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default:
@ -1158,6 +1183,14 @@ SDValue CSKYTargetLowering::LowerBlockAddress(SDValue Op,
return getAddr(N, DAG);
}
SDValue CSKYTargetLowering::LowerConstantPool(SDValue Op,
SelectionDAG &DAG) const {
assert(!Subtarget.hasE2());
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
return getAddr(N, DAG);
}
SDValue CSKYTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
CSKYMachineFunctionInfo *FuncInfo = MF.getInfo<CSKYMachineFunctionInfo>();

View File

@ -110,6 +110,9 @@ private:
SDValue getTargetNode(BlockAddressSDNode *N, SDLoc DL, EVT Ty,
SelectionDAG &DAG, unsigned Flags) const;
SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty,
SelectionDAG &DAG, unsigned Flags) const;
SDValue getTargetConstantPoolValue(GlobalAddressSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flags) const;
@ -122,6 +125,9 @@ private:
SDValue getTargetConstantPoolValue(BlockAddressSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flags) const;
SDValue getTargetConstantPoolValue(ConstantPoolSDNode *N, EVT Ty,
SelectionDAG &DAG, unsigned Flags) const;
template <class NodeTy, bool IsCall = false>
SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const {
SDLoc DL(N);
@ -155,6 +161,7 @@ private:
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;

View File

@ -1117,6 +1117,7 @@ def : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW32 tconstpool:$src
def : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
def : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW32_Gen tjumptable:$src1, tconstpool:$src2)>;
def : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW32 tconstpool:$src2)>;
def : Pat<(CSKY_LOAD_ADDR tconstpool:$src1, tconstpool:$src2), (LRW32_Gen tconstpool:$src1, tconstpool:$src2)>;
let Predicates = [iHas2E3] in
def : Pat<(i32 constpool:$src), (GRS32 (to_tconstpool tconstpool:$src))>;

View File

@ -472,6 +472,7 @@ def : Pat<(CSKY_LOAD_ADDR tglobaladdr, tconstpool:$src2), (LRW16 tconstpool:$src
def : Pat<(CSKY_LOAD_ADDR tblockaddress, tconstpool:$src2), (LRW16 tconstpool:$src2)>;
def : Pat<(CSKY_LOAD_ADDR tjumptable:$src1, tconstpool:$src2), (LRW16_Gen tjumptable:$src1, tconstpool:$src2)>;
def : Pat<(CSKY_LOAD_ADDR texternalsym, tconstpool:$src2), (LRW16 tconstpool:$src2)>;
def : Pat<(CSKY_LOAD_ADDR tconstpool:$src1, tconstpool:$src2), (LRW16_Gen tconstpool:$src1, tconstpool:$src2)>;
def : Pat<(i32 (load constpool:$src)), (LRW16 (to_tconstpool tconstpool:$src))>;

View File

@ -0,0 +1,44 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; Test get the address of constant pool without grs instruction
; RUN: llc -verify-machineinstrs -csky-no-aliases < %s -mtriple=csky | FileCheck %s --check-prefix=GENERIC
declare i32 @llvm.cttz.i32(i32, i1)
define void @cttztest(i32 %C, i32* %CP) {
; GENERIC-LABEL: cttztest:
; GENERIC: # %bb.0:
; GENERIC-NEXT: .cfi_def_cfa_offset 0
; GENERIC-NEXT: subi16 sp, sp, 4
; GENERIC-NEXT: .cfi_def_cfa_offset 4
; GENERIC-NEXT: movi16 a2, 0
; GENERIC-NEXT: subu16 a2, a2, a0
; GENERIC-NEXT: and16 a2, a0
; GENERIC-NEXT: movi16 a0, 7
; GENERIC-NEXT: lsli16 a0, a0, 24
; GENERIC-NEXT: movi16 a3, 124
; GENERIC-NEXT: lsli16 a3, a3, 16
; GENERIC-NEXT: or16 a3, a0
; GENERIC-NEXT: movi16 a0, 181
; GENERIC-NEXT: lsli16 a0, a0, 8
; GENERIC-NEXT: or16 a0, a3
; GENERIC-NEXT: movi16 a3, 49
; GENERIC-NEXT: or16 a3, a0
; GENERIC-NEXT: mult16 a3, a2
; GENERIC-NEXT: lsri16 a0, a3, 27
; GENERIC-NEXT: lrw32 a2, [.LCPI0_1]
; GENERIC-NEXT: addu16 a0, a2, a0
; GENERIC-NEXT: ld16.b a0, (a0, 0)
; GENERIC-NEXT: st16.w a0, (a1, 0)
; GENERIC-NEXT: addi16 sp, sp, 4
; GENERIC-NEXT: rts16
; GENERIC-NEXT: .p2align 1
; GENERIC-NEXT: # %bb.1:
; GENERIC-NEXT: .p2align 2, 0x0
; GENERIC-NEXT: .LCPI0_1:
; GENERIC-NEXT: .long .LCPI0_0
; GENERIC-NEXT: .LCPI0_0:
; GENERIC-NEXT: .ascii "\000\001\034\002\035\016\030\003\036\026\024\017\031\021\004\b\037\033\r\027\025\023\020\007\032\f\022\006\013\005\n\t"
%c = call i32 @llvm.cttz.i32( i32 %C, i1 true )
store i32 %c, i32* %CP
ret void
}