mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-24 04:45:00 +00:00
Lower BR_JT on the XCore to a jump into a series of jump instructions.
llvm-svn: 96942
This commit is contained in:
parent
64810b7bc6
commit
7387249531
@ -27,6 +27,7 @@
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineConstantPool.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
@ -62,6 +63,11 @@ namespace {
|
||||
}
|
||||
|
||||
void printMemOperand(const MachineInstr *MI, int opNum);
|
||||
void printInlineJT(const MachineInstr *MI, int opNum,
|
||||
const std::string &directive = ".jmptable");
|
||||
void printInlineJT32(const MachineInstr *MI, int opNum) {
|
||||
printInlineJT(MI, opNum, ".jmptable32");
|
||||
}
|
||||
void printOperand(const MachineInstr *MI, int opNum);
|
||||
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
unsigned AsmVariant, const char *ExtraCode);
|
||||
@ -257,6 +263,23 @@ void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum)
|
||||
printOperand(MI, opNum+1);
|
||||
}
|
||||
|
||||
void XCoreAsmPrinter::
|
||||
printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
|
||||
{
|
||||
unsigned JTI = MI->getOperand(opNum).getIndex();
|
||||
const MachineFunction *MF = MI->getParent()->getParent();
|
||||
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
|
||||
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
|
||||
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
|
||||
O << "\t" << directive << " ";
|
||||
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
|
||||
MachineBasicBlock *MBB = JTBBs[i];
|
||||
if (i > 0)
|
||||
O << ",";
|
||||
O << *MBB->getSymbol(OutContext);
|
||||
}
|
||||
}
|
||||
|
||||
void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
|
||||
const MachineOperand &MO = MI->getOperand(opNum);
|
||||
switch (MO.getType()) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineJumpTableInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
@ -53,6 +54,8 @@ getTargetNodeName(unsigned Opcode) const
|
||||
case XCoreISD::RETSP : return "XCoreISD::RETSP";
|
||||
case XCoreISD::LADD : return "XCoreISD::LADD";
|
||||
case XCoreISD::LSUB : return "XCoreISD::LSUB";
|
||||
case XCoreISD::BR_JT : return "XCoreISD::BR_JT";
|
||||
case XCoreISD::BR_JT32 : return "XCoreISD::BR_JT32";
|
||||
default : return NULL;
|
||||
}
|
||||
}
|
||||
@ -106,9 +109,8 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM)
|
||||
|
||||
setOperationAction(ISD::TRAP, MVT::Other, Legal);
|
||||
|
||||
// Expand jump tables for now
|
||||
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
|
||||
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
|
||||
// Jump tables.
|
||||
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
|
||||
|
||||
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
|
||||
setOperationAction(ISD::BlockAddress, MVT::i32 , Custom);
|
||||
@ -158,6 +160,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
|
||||
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
|
||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||
case ISD::BR_JT: return LowerBR_JT(Op, DAG);
|
||||
case ISD::LOAD: return LowerLOAD(Op, DAG);
|
||||
case ISD::STORE: return LowerSTORE(Op, DAG);
|
||||
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
|
||||
@ -325,6 +328,30 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG)
|
||||
return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, JTI);
|
||||
}
|
||||
|
||||
SDValue XCoreTargetLowering::
|
||||
LowerBR_JT(SDValue Op, SelectionDAG &DAG)
|
||||
{
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
SDValue Table = Op.getOperand(1);
|
||||
SDValue Index = Op.getOperand(2);
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
|
||||
unsigned JTI = JT->getIndex();
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
|
||||
SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
|
||||
|
||||
unsigned NumEntries = MJTI->getJumpTables()[JTI].MBBs.size();
|
||||
if (NumEntries <= 32) {
|
||||
return DAG.getNode(XCoreISD::BR_JT, dl, MVT::Other, Chain, TargetJT, Index);
|
||||
}
|
||||
assert((NumEntries >> 31) == 0);
|
||||
SDValue ScaledIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index,
|
||||
DAG.getConstant(1, MVT::i32));
|
||||
return DAG.getNode(XCoreISD::BR_JT32, dl, MVT::Other, Chain, TargetJT,
|
||||
ScaledIndex);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsWordAlignedBasePlusConstantOffset(SDValue Addr, SDValue &AlignedBase,
|
||||
int64_t &Offset)
|
||||
|
@ -52,7 +52,13 @@ namespace llvm {
|
||||
LADD,
|
||||
|
||||
// Corresponds to LSUB instruction
|
||||
LSUB
|
||||
LSUB,
|
||||
|
||||
// Jumptable branch.
|
||||
BR_JT,
|
||||
|
||||
// Jumptable branch using long branches for each entry.
|
||||
BR_JT32
|
||||
};
|
||||
}
|
||||
|
||||
@ -123,6 +129,7 @@ namespace llvm {
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG);
|
||||
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG);
|
||||
|
@ -145,6 +145,11 @@ static inline bool IsCondBranch(unsigned BrOpc) {
|
||||
return IsBRF(BrOpc) || IsBRT(BrOpc);
|
||||
}
|
||||
|
||||
static inline bool IsBR_JT(unsigned BrOpc) {
|
||||
return BrOpc == XCore::BR_JT
|
||||
|| BrOpc == XCore::BR_JT32;
|
||||
}
|
||||
|
||||
/// GetCondFromBranchOpc - Return the XCore CC that matches
|
||||
/// the correspondent Branch instruction opcode.
|
||||
static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc)
|
||||
@ -271,6 +276,14 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Likewise if it ends with a branch table followed by an unconditional branch.
|
||||
if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) {
|
||||
I = LastInst;
|
||||
if (AllowModify)
|
||||
I->eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise, can't handle this.
|
||||
return true;
|
||||
}
|
||||
|
@ -34,6 +34,15 @@ def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink,
|
||||
def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTNone,
|
||||
[SDNPHasChain, SDNPOptInFlag]>;
|
||||
|
||||
def SDT_XCoreBR_JT : SDTypeProfile<0, 2,
|
||||
[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
|
||||
|
||||
def XCoreBR_JT : SDNode<"XCoreISD::BR_JT", SDT_XCoreBR_JT,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
def XCoreBR_JT32 : SDNode<"XCoreISD::BR_JT32", SDT_XCoreBR_JT,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
def SDT_XCoreAddress : SDTypeProfile<1, 1,
|
||||
[SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
|
||||
|
||||
@ -185,6 +194,15 @@ def MEMii : Operand<i32> {
|
||||
let MIOperandInfo = (ops i32imm, i32imm);
|
||||
}
|
||||
|
||||
// Jump tables.
|
||||
def InlineJT : Operand<i32> {
|
||||
let PrintMethod = "printInlineJT";
|
||||
}
|
||||
|
||||
def InlineJT32 : Operand<i32> {
|
||||
let PrintMethod = "printInlineJT32";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction Class Templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -756,13 +774,23 @@ def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src),
|
||||
|
||||
// One operand short
|
||||
// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp
|
||||
// bru, setdp, setcp, setv, setev, kcall
|
||||
// setdp, setcp, setv, setev, kcall
|
||||
// dgetreg
|
||||
let isBranch=1, isIndirectBranch=1, isTerminator=1 in
|
||||
def BAU_1r : _F1R<(outs), (ins GRRegs:$addr),
|
||||
"bau $addr",
|
||||
[(brind GRRegs:$addr)]>;
|
||||
|
||||
let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
|
||||
def BR_JT : PseudoInstXCore<(outs), (ins InlineJT:$t, GRRegs:$i),
|
||||
"bru $i\n$t",
|
||||
[(XCoreBR_JT tjumptable:$t, GRRegs:$i)]>;
|
||||
|
||||
let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in
|
||||
def BR_JT32 : PseudoInstXCore<(outs), (ins InlineJT32:$t, GRRegs:$i),
|
||||
"bru $i\n$t",
|
||||
[(XCoreBR_JT32 tjumptable:$t, GRRegs:$i)]>;
|
||||
|
||||
let Defs=[SP], neverHasSideEffects=1 in
|
||||
def SETSP_1r : _F1R<(outs), (ins GRRegs:$src),
|
||||
"set sp, $src",
|
||||
|
24
test/CodeGen/XCore/switch.ll
Normal file
24
test/CodeGen/XCore/switch.ll
Normal file
@ -0,0 +1,24 @@
|
||||
; RUN: llc -march=xcore < %s | FileCheck %s
|
||||
|
||||
define i32 @switch(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %default [
|
||||
i32 0, label %bb0
|
||||
i32 1, label %bb1
|
||||
i32 2, label %bb2
|
||||
i32 3, label %bb3
|
||||
]
|
||||
; CHECK-NOT: shl
|
||||
; CHECK: bru
|
||||
; CHECK: .jmptable
|
||||
bb0:
|
||||
ret i32 0
|
||||
bb1:
|
||||
ret i32 1
|
||||
bb2:
|
||||
ret i32 2
|
||||
bb3:
|
||||
ret i32 3
|
||||
default:
|
||||
ret i32 4
|
||||
}
|
132
test/CodeGen/XCore/switch_long.ll
Normal file
132
test/CodeGen/XCore/switch_long.ll
Normal file
@ -0,0 +1,132 @@
|
||||
; RUN: llc -march=xcore < %s | FileCheck %s
|
||||
|
||||
define i32 @switch(i32 %i) {
|
||||
entry:
|
||||
switch i32 %i, label %default [
|
||||
i32 0, label %bb0
|
||||
i32 1, label %bb1
|
||||
i32 2, label %bb2
|
||||
i32 3, label %bb3
|
||||
i32 4, label %bb4
|
||||
i32 5, label %bb5
|
||||
i32 6, label %bb6
|
||||
i32 7, label %bb7
|
||||
i32 8, label %bb8
|
||||
i32 9, label %bb9
|
||||
i32 10, label %bb10
|
||||
i32 11, label %bb11
|
||||
i32 12, label %bb12
|
||||
i32 13, label %bb13
|
||||
i32 14, label %bb14
|
||||
i32 15, label %bb15
|
||||
i32 16, label %bb16
|
||||
i32 17, label %bb17
|
||||
i32 18, label %bb18
|
||||
i32 19, label %bb19
|
||||
i32 20, label %bb20
|
||||
i32 21, label %bb21
|
||||
i32 22, label %bb22
|
||||
i32 23, label %bb23
|
||||
i32 24, label %bb24
|
||||
i32 25, label %bb25
|
||||
i32 26, label %bb26
|
||||
i32 27, label %bb27
|
||||
i32 28, label %bb28
|
||||
i32 29, label %bb29
|
||||
i32 30, label %bb30
|
||||
i32 31, label %bb31
|
||||
i32 32, label %bb32
|
||||
i32 33, label %bb33
|
||||
i32 34, label %bb34
|
||||
i32 35, label %bb35
|
||||
i32 36, label %bb36
|
||||
i32 37, label %bb37
|
||||
i32 38, label %bb38
|
||||
i32 39, label %bb39
|
||||
]
|
||||
; CHECK: shl
|
||||
; CHECK: bru
|
||||
; CHECK: .jmptable
|
||||
bb0:
|
||||
ret i32 0
|
||||
bb1:
|
||||
ret i32 1
|
||||
bb2:
|
||||
ret i32 2
|
||||
bb3:
|
||||
ret i32 3
|
||||
bb4:
|
||||
ret i32 4
|
||||
bb5:
|
||||
ret i32 5
|
||||
bb6:
|
||||
ret i32 6
|
||||
bb7:
|
||||
ret i32 7
|
||||
bb8:
|
||||
ret i32 8
|
||||
bb9:
|
||||
ret i32 9
|
||||
bb10:
|
||||
ret i32 0
|
||||
bb11:
|
||||
ret i32 1
|
||||
bb12:
|
||||
ret i32 2
|
||||
bb13:
|
||||
ret i32 3
|
||||
bb14:
|
||||
ret i32 4
|
||||
bb15:
|
||||
ret i32 5
|
||||
bb16:
|
||||
ret i32 6
|
||||
bb17:
|
||||
ret i32 7
|
||||
bb18:
|
||||
ret i32 8
|
||||
bb19:
|
||||
ret i32 9
|
||||
bb20:
|
||||
ret i32 0
|
||||
bb21:
|
||||
ret i32 1
|
||||
bb22:
|
||||
ret i32 2
|
||||
bb23:
|
||||
ret i32 3
|
||||
bb24:
|
||||
ret i32 4
|
||||
bb25:
|
||||
ret i32 5
|
||||
bb26:
|
||||
ret i32 6
|
||||
bb27:
|
||||
ret i32 7
|
||||
bb28:
|
||||
ret i32 8
|
||||
bb29:
|
||||
ret i32 9
|
||||
bb30:
|
||||
ret i32 0
|
||||
bb31:
|
||||
ret i32 1
|
||||
bb32:
|
||||
ret i32 2
|
||||
bb33:
|
||||
ret i32 3
|
||||
bb34:
|
||||
ret i32 4
|
||||
bb35:
|
||||
ret i32 5
|
||||
bb36:
|
||||
ret i32 6
|
||||
bb37:
|
||||
ret i32 7
|
||||
bb38:
|
||||
ret i32 8
|
||||
bb39:
|
||||
ret i32 9
|
||||
default:
|
||||
ret i32 0
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user