Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/lib/Target/Hexagon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler)
tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM HexagonGenSDNodeInfo.inc -gen-sd-node-info)
tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)

add_public_tablegen_target(HexagonCommonTableGen)
Expand Down
62 changes: 0 additions & 62 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1914,66 +1914,6 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
computeRegisterProperties(&HRI);
}

const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch ((HexagonISD::NodeType)Opcode) {
case HexagonISD::ADDC: return "HexagonISD::ADDC";
case HexagonISD::SUBC: return "HexagonISD::SUBC";
case HexagonISD::ALLOCA: return "HexagonISD::ALLOCA";
case HexagonISD::AT_GOT: return "HexagonISD::AT_GOT";
case HexagonISD::AT_PCREL: return "HexagonISD::AT_PCREL";
case HexagonISD::BARRIER: return "HexagonISD::BARRIER";
case HexagonISD::CALL: return "HexagonISD::CALL";
case HexagonISD::CALLnr: return "HexagonISD::CALLnr";
case HexagonISD::CALLR: return "HexagonISD::CALLR";
case HexagonISD::COMBINE: return "HexagonISD::COMBINE";
case HexagonISD::CONST32_GP: return "HexagonISD::CONST32_GP";
case HexagonISD::CONST32: return "HexagonISD::CONST32";
case HexagonISD::CP: return "HexagonISD::CP";
case HexagonISD::DCFETCH: return "HexagonISD::DCFETCH";
case HexagonISD::EH_RETURN: return "HexagonISD::EH_RETURN";
case HexagonISD::TSTBIT: return "HexagonISD::TSTBIT";
case HexagonISD::EXTRACTU: return "HexagonISD::EXTRACTU";
case HexagonISD::INSERT: return "HexagonISD::INSERT";
case HexagonISD::JT: return "HexagonISD::JT";
case HexagonISD::RET_GLUE: return "HexagonISD::RET_GLUE";
case HexagonISD::TC_RETURN: return "HexagonISD::TC_RETURN";
case HexagonISD::VASL: return "HexagonISD::VASL";
case HexagonISD::VASR: return "HexagonISD::VASR";
case HexagonISD::VLSR: return "HexagonISD::VLSR";
case HexagonISD::MFSHL: return "HexagonISD::MFSHL";
case HexagonISD::MFSHR: return "HexagonISD::MFSHR";
case HexagonISD::SSAT: return "HexagonISD::SSAT";
case HexagonISD::USAT: return "HexagonISD::USAT";
case HexagonISD::SMUL_LOHI: return "HexagonISD::SMUL_LOHI";
case HexagonISD::UMUL_LOHI: return "HexagonISD::UMUL_LOHI";
case HexagonISD::USMUL_LOHI: return "HexagonISD::USMUL_LOHI";
case HexagonISD::VEXTRACTW: return "HexagonISD::VEXTRACTW";
case HexagonISD::VINSERTW0: return "HexagonISD::VINSERTW0";
case HexagonISD::VROR: return "HexagonISD::VROR";
case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE";
case HexagonISD::READTIMER: return "HexagonISD::READTIMER";
case HexagonISD::THREAD_POINTER:
return "HexagonISD::THREAD_POINTER";
case HexagonISD::PTRUE: return "HexagonISD::PTRUE";
case HexagonISD::PFALSE: return "HexagonISD::PFALSE";
case HexagonISD::D2P: return "HexagonISD::D2P";
case HexagonISD::P2D: return "HexagonISD::P2D";
case HexagonISD::V2Q: return "HexagonISD::V2Q";
case HexagonISD::Q2V: return "HexagonISD::Q2V";
case HexagonISD::QCAT: return "HexagonISD::QCAT";
case HexagonISD::QTRUE: return "HexagonISD::QTRUE";
case HexagonISD::QFALSE: return "HexagonISD::QFALSE";
case HexagonISD::TL_EXTEND: return "HexagonISD::TL_EXTEND";
case HexagonISD::TL_TRUNCATE: return "HexagonISD::TL_TRUNCATE";
case HexagonISD::TYPECAST: return "HexagonISD::TYPECAST";
case HexagonISD::VALIGN: return "HexagonISD::VALIGN";
case HexagonISD::VALIGNADDR: return "HexagonISD::VALIGNADDR";
case HexagonISD::ISEL: return "HexagonISD::ISEL";
case HexagonISD::OP_END: break;
}
return nullptr;
}

bool
HexagonTargetLowering::validateConstPtrAlignment(SDValue Ptr, Align NeedAlign,
const SDLoc &dl, SelectionDAG &DAG) const {
Expand Down Expand Up @@ -3368,8 +3308,6 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
default:
#ifndef NDEBUG
Op.getNode()->dumpr(&DAG);
if (Opc > HexagonISD::OP_BEGIN && Opc < HexagonISD::OP_END)
errs() << "Error: check for a non-legal type in this operation\n";
#endif
llvm_unreachable("Should not custom lower this!");

Expand Down
97 changes: 0 additions & 97 deletions llvm/lib/Target/Hexagon/HexagonISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,102 +29,6 @@

namespace llvm {

namespace HexagonISD {

// clang-format off
enum NodeType : unsigned {
OP_BEGIN = ISD::BUILTIN_OP_END,

CONST32 = OP_BEGIN,
CONST32_GP, // For marking data present in GP.
ADDC, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
SUBC, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
ALLOCA,

AT_GOT, // Index in GOT.
AT_PCREL, // Offset relative to PC.

CALL, // Function call.
CALLnr, // Function call that does not return.
CALLR,

RET_GLUE, // Return with a glue operand.
BARRIER, // Memory barrier.
JT, // Jump table.
CP, // Constant pool.

COMBINE,
VASL, // Vector shifts by a scalar value
VASR,
VLSR,
MFSHL, // Funnel shifts with the shift amount guaranteed to be
MFSHR, // within the range of the bit width of the element.

SSAT, // Signed saturate.
USAT, // Unsigned saturate.
SMUL_LOHI, // Same as ISD::SMUL_LOHI, but opaque to the combiner.
UMUL_LOHI, // Same as ISD::UMUL_LOHI, but opaque to the combiner.
// We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
// combiner will keep rewriting it back to MULH[SU].
USMUL_LOHI, // Like SMUL_LOHI, but unsigned*signed.

TSTBIT,
INSERT,
EXTRACTU,
VEXTRACTW,
VINSERTW0,
VROR,
TC_RETURN,
EH_RETURN,
DCFETCH,
READCYCLE,
READTIMER,
THREAD_POINTER,
PTRUE,
PFALSE,
D2P, // Convert 8-byte value to 8-bit predicate register. [*]
P2D, // Convert 8-bit predicate register to 8-byte value. [*]
V2Q, // Convert HVX vector to a vector predicate reg. [*]
Q2V, // Convert vector predicate to an HVX vector. [*]
// [*] The equivalence is defined as "Q <=> (V != 0)",
// where the != operation compares bytes.
// Note: V != 0 is implemented as V >u 0.
QCAT,
QTRUE,
QFALSE,

TL_EXTEND, // Wrappers for ISD::*_EXTEND and ISD::TRUNCATE to prevent DAG
TL_TRUNCATE, // from auto-folding operations, e.g.
// (i32 ext (i16 ext i8)) would be folded to (i32 ext i8).
// To simplify the type legalization, we want to keep these
// single steps separate during type legalization.
// TL_[EXTEND|TRUNCATE] Inp, i128 _, i32 Opc
// * Inp is the original input to extend/truncate,
// * _ is a dummy operand with an illegal type (can be undef),
// * Opc is the original opcode.
// The legalization process (in Hexagon lowering code) will
// first deal with the "real" types (i.e. Inp and the result),
// and once all of them are processed, the wrapper node will
// be replaced with the original ISD node. The dummy illegal
// operand is there to make sure that the legalization hooks
// are called again after everything else is legal, giving
// us the opportunity to undo the wrapping.

TYPECAST, // No-op that's used to convert between different legal
// types in a register.
VALIGN, // Align two vectors (in Op0, Op1) to one that would have
// been loaded from address in Op2.
VALIGNADDR, // Align vector address: Op0 & -Op1, except when it is
// an address in a vector load, then it's a no-op.
ISEL, // Marker for nodes that were created during ISel, and
// which need explicit selection (would have been left
// unselected otherwise).
OP_END
};

} // end namespace HexagonISD
// clang-format on

class HexagonSubtarget;

class HexagonTargetLowering : public TargetLowering {
Expand Down Expand Up @@ -189,7 +93,6 @@ class HexagonTargetLowering : public TargetLowering {
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const override;

const char *getTargetNodeName(unsigned Opcode) const override;
std::pair<MVT, unsigned>
handleMaskRegisterForCallingConv(const HexagonSubtarget &Subtarget,
EVT VT) const;
Expand Down
46 changes: 46 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonPatterns.td
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,47 @@ def SDTVecLeaf:
def SDTVecVecIntOp:
SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<1,2>,
SDTCisVT<3,i32>]>;
def SDTIntBinOpWithCarryInOut:
SDTypeProfile<2, 3, [SDTCisInt<0>, SDTCisVT<1, i1>, SDTCisSameAs<2, 0>,
SDTCisSameAs<3, 0>, SDTCisVT<4, i1>]>;

// Add with carry: (X, Y, Cin) -> (X+Y, Cout).
def HexagonADDC: SDNode<"HexagonISD::ADDC", SDTIntBinOpWithCarryInOut>;

// Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
def HexagonSUBC: SDNode<"HexagonISD::SUBC", SDTIntBinOpWithCarryInOut>;

// Same as ISD::SMUL_LOHI, but opaque to the combiner.
// We want to legalize MULH[SU] to [SU]MUL_LOHI, but the
// combiner will keep rewriting it back to MULH[SU].
def HexagonSMUL_LOHI: SDNode<"HexagonISD::SMUL_LOHI", SDTIntBinHiLoOp>;

// Same as ISD::UMUL_LOHI, but opaque to the combiner.
def HexagonUMUL_LOHI: SDNode<"HexagonISD::UMUL_LOHI", SDTIntBinHiLoOp>;

// Like SMUL_LOHI, but unsigned*signed.
def HexagonUSMUL_LOHI: SDNode<"HexagonISD::USMUL_LOHI", SDTIntBinHiLoOp>;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few more nodes here so that they can be "imported". These ones were very straightforward to add, I didn't try to add the remaining ones (listed in HexagonSelectionDAGInfo.h).


def HexagonPTRUE: SDNode<"HexagonISD::PTRUE", SDTVecLeaf>;
def HexagonPFALSE: SDNode<"HexagonISD::PFALSE", SDTVecLeaf>;

// Align two vectors (in Op0, Op1) to one that would have
// been loaded from address in Op2.
def HexagonVALIGN: SDNode<"HexagonISD::VALIGN", SDTVecVecIntOp>;

// Align vector address: Op0 & -Op1, except when it is
// an address in a vector load, then it's a no-op.
def HexagonVALIGNADDR: SDNode<"HexagonISD::VALIGNADDR", SDTIntUnaryOp>;

def HexagonMULHUS: SDNode<"HexagonISD::MULHUS", SDTIntBinOp>;

def SDTSaturate:
SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, SDTCisVT<2, OtherVT>]>;

// Signed saturate.
def HexagonSSAT: SDNode<"HexagonISD::SSAT", SDTSaturate>;

// Unsigned saturate.
def HexagonUSAT: SDNode<"HexagonISD::USAT", SDTSaturate>;

def ptrue: PatFrag<(ops), (HexagonPTRUE)>;
Expand Down Expand Up @@ -408,9 +439,15 @@ def Imm64Hi: SDNodeXForm<imm, [{
def SDTHexagonCONST32
: SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisPtrTy<0>]>;

// Jump table.
def HexagonJT: SDNode<"HexagonISD::JT", SDTIntUnaryOp>;

// Constant pool.
def HexagonCP: SDNode<"HexagonISD::CP", SDTIntUnaryOp>;

def HexagonCONST32: SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>;

// For marking data present in GP.
def HexagonCONST32_GP: SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;

def TruncI64ToI32: SDNodeXForm<imm, [{
Expand Down Expand Up @@ -1430,6 +1467,7 @@ let AddedComplexity = 200 in {
def SDTHexagonVShift
: SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisVec<0>, SDTCisVT<2, i32>]>;

// Vector shifts by a scalar value
def HexagonVASL: SDNode<"HexagonISD::VASL", SDTHexagonVShift>;
def HexagonVASR: SDNode<"HexagonISD::VASR", SDTHexagonVShift>;
def HexagonVLSR: SDNode<"HexagonISD::VLSR", SDTHexagonVShift>;
Expand Down Expand Up @@ -3291,8 +3329,12 @@ def SDT_SPCall: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;

def HexagonTCRet: SDNode<"HexagonISD::TC_RETURN", SDT_SPCall,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;

// Function call.
def callv3: SDNode<"HexagonISD::CALL", SDT_SPCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;

// Function call that does not return.
def callv3nr: SDNode<"HexagonISD::CALLnr", SDT_SPCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>;

Expand All @@ -3314,8 +3356,10 @@ def: Pat<(callv3nr I32:$dst), (PS_callr_nr I32:$dst)>;
def: Pat<(callv3nr tglobaladdr:$dst), (PS_call_nr tglobaladdr:$dst)>;
def: Pat<(callv3nr texternalsym:$dst), (PS_call_nr texternalsym:$dst)>;

// Return with a glue operand.
def retglue : SDNode<"HexagonISD::RET_GLUE", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;

def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;

def: Pat<(retglue), (PS_jmpret (i32 R31))>;
Expand Down Expand Up @@ -3395,7 +3439,9 @@ def HexagonALLOCA
def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)),
(PS_alloca IntRegs:$Rs, imm:$A)>;

// Memory barrier.
def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;

def: Pat<(HexagonBARRIER), (Y2_barrier)>;

def: Pat<(trap), (PS_crash)>;
Expand Down
46 changes: 46 additions & 0 deletions llvm/lib/Target/Hexagon/HexagonSelectionDAGInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,58 @@
//
//===----------------------------------------------------------------------===//

#include "HexagonSelectionDAGInfo.h"
#include "HexagonTargetMachine.h"
#include "llvm/CodeGen/SelectionDAG.h"

#define GET_SDNODE_DESC
#include "HexagonGenSDNodeInfo.inc"

using namespace llvm;

#define DEBUG_TYPE "hexagon-selectiondag-info"

HexagonSelectionDAGInfo::HexagonSelectionDAGInfo()
: SelectionDAGGenTargetInfo(HexagonGenSDNodeInfo) {}

const char *HexagonSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
#define CASE(NAME) \
case HexagonISD::NAME: \
return "HexagonISD::" #NAME

// These nodes don't have corresponding entries in *.td files yet.
switch (static_cast<HexagonISD::NodeType>(Opcode)) {
CASE(CALLR);
CASE(VROR);
CASE(D2P);
CASE(P2D);
CASE(V2Q);
CASE(Q2V);
CASE(TL_EXTEND);
CASE(TL_TRUNCATE);
CASE(TYPECAST);
CASE(ISEL);
}
#undef CASE

return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
}

void HexagonSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
const SDNode *N) const {
switch (N->getOpcode()) {
default:
break;
case HexagonISD::VALIGNADDR:
// invalid number of operands; expected 1, got 2
case HexagonISD::VINSERTW0:
// operand #1 must have type i32, but has type v4i8/v2i16
return;
}

SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
}

SDValue HexagonSelectionDAGInfo::EmitTargetCodeForMemcpy(
SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
SDValue Size, Align Alignment, bool isVolatile, bool AlwaysInline,
Expand Down
Loading
Loading