forked from OSchip/llvm-project
[aarch64][globalisel] Define G_ATOMIC_CMPXCHG and G_ATOMICRMW_* and make them legal
The IRTranslator cannot generate these instructions at the moment so there's no issue with not having implemented ISel for them yet. D40092 will add G_ATOMIC_CMPXCHG_WITH_SUCCESS and G_ATOMICRMW_* to the IRTranslator and a further patch will add support for lowering G_ATOMIC_CMPXCHG_WITH_SUCCESS into G_ATOMIC_CMPXCHG with an external success check via the `Lower` action. The separation of G_ATOMIC_CMPXCHG_WITH_SUCCESS and G_ATOMIC_CMPXCHG is to import SelectionDAG rules while still supporting targets that prefer to custom lower the original LLVM-IR-like operation. llvm-svn: 319216
This commit is contained in:
parent
1d4b3023dc
commit
7fe7acc6b1
|
@ -265,6 +265,22 @@ HANDLE_TARGET_OPCODE(G_LOAD)
|
|||
/// Generic store.
|
||||
HANDLE_TARGET_OPCODE(G_STORE)
|
||||
|
||||
/// Generic atomic cmpxchg.
|
||||
HANDLE_TARGET_OPCODE(G_ATOMIC_CMPXCHG)
|
||||
|
||||
/// Generic atomicrmw.
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_XCHG)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_ADD)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_SUB)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_AND)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_NAND)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_OR)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_XOR)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_MAX)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_MIN)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMAX)
|
||||
HANDLE_TARGET_OPCODE(G_ATOMICRMW_UMIN)
|
||||
|
||||
/// Generic conditional branch instruction.
|
||||
HANDLE_TARGET_OPCODE(G_BRCOND)
|
||||
|
||||
|
|
|
@ -482,6 +482,104 @@ def G_STORE : Instruction {
|
|||
let mayStore = 1;
|
||||
}
|
||||
|
||||
// Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
|
||||
// operands.
|
||||
def G_ATOMIC_CMPXCHG : Instruction {
|
||||
let OutOperandList = (outs type0:$oldval);
|
||||
let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
|
||||
let hasSideEffects = 0;
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
// Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
|
||||
// operands.
|
||||
class G_ATOMICRMW_OP : Instruction {
|
||||
let OutOperandList = (outs type0:$oldval);
|
||||
let InOperandList = (ins ptype1:$addr, type0:$val);
|
||||
let hasSideEffects = 0;
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_ADD : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_SUB : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_AND : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_NAND : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_OR : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_XOR : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_MAX : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_MIN : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP {
|
||||
// FIXME: This include is surrounded by a 'let mayLoad = 0, mayStore = 0 in {}'
|
||||
// block which overrides the value inherited from G_ATOMICRMW_OP. Work
|
||||
// around this for now. See http://reviews.llvm.org/D40096
|
||||
let mayLoad = 1;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Variadic ops
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AArch64LegalizerInfo.h"
|
||||
#include "AArch64Subtarget.h"
|
||||
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
|
@ -127,7 +128,7 @@ widen_1_8_16_32(const LegalizerInfo::SizeAndActionsVec &v) {
|
|||
return result;
|
||||
}
|
||||
|
||||
AArch64LegalizerInfo::AArch64LegalizerInfo() {
|
||||
AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
|
||||
using namespace TargetOpcode;
|
||||
const LLT p0 = LLT::pointer(0, 64);
|
||||
const LLT s1 = LLT::scalar(1);
|
||||
|
@ -349,6 +350,22 @@ AArch64LegalizerInfo::AArch64LegalizerInfo() {
|
|||
for (auto Ty : {s8, s16, s32, s64, p0})
|
||||
setAction({G_VAARG, Ty}, Custom);
|
||||
|
||||
if (ST.hasLSE()) {
|
||||
for (auto Ty : {s8, s16, s32, s64})
|
||||
setAction({G_ATOMIC_CMPXCHG, Ty}, Legal);
|
||||
setAction({G_ATOMIC_CMPXCHG, 1, p0}, Legal);
|
||||
|
||||
for (auto Op :
|
||||
{G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND,
|
||||
G_ATOMICRMW_OR, G_ATOMICRMW_XOR, G_ATOMICRMW_MIN, G_ATOMICRMW_MAX,
|
||||
G_ATOMICRMW_UMIN, G_ATOMICRMW_UMAX}) {
|
||||
for (auto Ty : {s8, s16, s32, s64}) {
|
||||
setAction({Op, Ty}, Legal);
|
||||
}
|
||||
setAction({Op, 1, p0}, Legal);
|
||||
}
|
||||
}
|
||||
|
||||
computeTables();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
namespace llvm {
|
||||
|
||||
class LLVMContext;
|
||||
class AArch64Subtarget;
|
||||
|
||||
/// This class provides the information for the target register banks.
|
||||
class AArch64LegalizerInfo : public LegalizerInfo {
|
||||
public:
|
||||
AArch64LegalizerInfo();
|
||||
AArch64LegalizerInfo(const AArch64Subtarget &ST);
|
||||
|
||||
bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
|
||||
MachineIRBuilder &MIRBuilder) const override;
|
||||
|
|
|
@ -154,7 +154,7 @@ AArch64Subtarget::AArch64Subtarget(const Triple &TT, const std::string &CPU,
|
|||
InstrInfo(initializeSubtargetDependencies(FS, CPU)), TSInfo(),
|
||||
TLInfo(TM, *this) {
|
||||
CallLoweringInfo.reset(new AArch64CallLowering(*getTargetLowering()));
|
||||
Legalizer.reset(new AArch64LegalizerInfo());
|
||||
Legalizer.reset(new AArch64LegalizerInfo(*this));
|
||||
|
||||
auto *RBI = new AArch64RegisterBankInfo(*getRegisterInfo());
|
||||
|
||||
|
|
Loading…
Reference in New Issue