aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-07-19 07:02:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-07-19 07:02:10 +0000
commit93c91e39b29142dec1d03a30df9f6e757f56c193 (patch)
tree33a9b014a327e64450b3c9ed46d8c5bdb78ad345 /lib/Target/Hexagon
parentca089b24d48ef6fa8da2d0bb8c25bb802c4a95c0 (diff)
downloadsrc-93c91e39b29142dec1d03a30df9f6e757f56c193.tar.gz
src-93c91e39b29142dec1d03a30df9f6e757f56c193.zip
Notes
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r--lib/Target/Hexagon/HexagonBitSimplify.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonDepInstrInfo.td4
-rw-r--r--lib/Target/Hexagon/HexagonEarlyIfConv.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonExpandCondsets.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonGenInsert.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonGenPredicate.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp147
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h4
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsics.td12
-rw-r--r--lib/Target/Hexagon/HexagonOptAddrMode.cpp4
-rw-r--r--lib/Target/Hexagon/HexagonPatterns.td92
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.cpp47
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.h6
14 files changed, 163 insertions, 177 deletions
diff --git a/lib/Target/Hexagon/HexagonBitSimplify.cpp b/lib/Target/Hexagon/HexagonBitSimplify.cpp
index b064778c4bbd..d75d95a6baea 100644
--- a/lib/Target/Hexagon/HexagonBitSimplify.cpp
+++ b/lib/Target/Hexagon/HexagonBitSimplify.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "hexbit"
-
#include "HexagonBitTracker.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/BitVector.h"
@@ -42,6 +40,8 @@
#include <utility>
#include <vector>
+#define DEBUG_TYPE "hexbit"
+
using namespace llvm;
static cl::opt<bool> PreserveTiedOps("hexbit-keep-tied", cl::Hidden,
diff --git a/lib/Target/Hexagon/HexagonDepInstrInfo.td b/lib/Target/Hexagon/HexagonDepInstrInfo.td
index 2dc74632e9be..30ebf89c9808 100644
--- a/lib/Target/Hexagon/HexagonDepInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonDepInstrInfo.td
@@ -45863,6 +45863,7 @@ tc_30665cb0, TypeST>, Enc_ecbcc8 {
let Inst{13-0} = 0b00000000000000;
let Inst{31-21} = 0b10100000000;
let isSoloAin1 = 1;
+let hasSideEffects = 1;
}
def Y2_dccleaninva : HInst<
(outs),
@@ -45872,6 +45873,7 @@ tc_30665cb0, TypeST>, Enc_ecbcc8 {
let Inst{13-0} = 0b00000000000000;
let Inst{31-21} = 0b10100000010;
let isSoloAin1 = 1;
+let hasSideEffects = 1;
}
def Y2_dcfetch : HInst<
(outs),
@@ -45900,6 +45902,7 @@ tc_30665cb0, TypeST>, Enc_ecbcc8 {
let Inst{13-0} = 0b00000000000000;
let Inst{31-21} = 0b10100000001;
let isSoloAin1 = 1;
+let hasSideEffects = 1;
}
def Y2_dczeroa : HInst<
(outs),
@@ -45909,6 +45912,7 @@ tc_30665cb0, TypeST>, Enc_ecbcc8 {
let Inst{13-0} = 0b00000000000000;
let Inst{31-21} = 0b10100000110;
let isSoloAin1 = 1;
+let hasSideEffects = 1;
let mayStore = 1;
}
def Y2_icinva : HInst<
diff --git a/lib/Target/Hexagon/HexagonEarlyIfConv.cpp b/lib/Target/Hexagon/HexagonEarlyIfConv.cpp
index 03c4a83594b3..80361015e649 100644
--- a/lib/Target/Hexagon/HexagonEarlyIfConv.cpp
+++ b/lib/Target/Hexagon/HexagonEarlyIfConv.cpp
@@ -59,8 +59,6 @@
// J2_jump <BB#6>, %PC<imp-def,dead>
// Successors according to CFG: BB#6 BB#3
-#define DEBUG_TYPE "hexagon-eif"
-
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
@@ -90,6 +88,8 @@
#include <cassert>
#include <iterator>
+#define DEBUG_TYPE "hexagon-eif"
+
using namespace llvm;
namespace llvm {
diff --git a/lib/Target/Hexagon/HexagonExpandCondsets.cpp b/lib/Target/Hexagon/HexagonExpandCondsets.cpp
index 734f3c6658d9..a2f6dd68c1a1 100644
--- a/lib/Target/Hexagon/HexagonExpandCondsets.cpp
+++ b/lib/Target/Hexagon/HexagonExpandCondsets.cpp
@@ -86,8 +86,6 @@
// however, is that finding the locations where the implicit uses need
// to be added, and updating the live ranges will be more involved.
-#define DEBUG_TYPE "expand-condsets"
-
#include "HexagonInstrInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
@@ -116,6 +114,8 @@
#include <set>
#include <utility>
+#define DEBUG_TYPE "expand-condsets"
+
using namespace llvm;
static cl::opt<unsigned> OptTfrLimit("expand-condsets-tfr-limit",
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp
index c790579ccebc..e5e75198b2d1 100644
--- a/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -8,8 +8,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "hexagon-pei"
-
#include "HexagonFrameLowering.h"
#include "HexagonBlockRanges.h"
#include "HexagonInstrInfo.h"
@@ -63,6 +61,8 @@
#include <utility>
#include <vector>
+#define DEBUG_TYPE "hexagon-pei"
+
// Hexagon stack frame layout as defined by the ABI:
//
// Incoming arguments
diff --git a/lib/Target/Hexagon/HexagonGenInsert.cpp b/lib/Target/Hexagon/HexagonGenInsert.cpp
index bf31e1699284..0a955aedaf1a 100644
--- a/lib/Target/Hexagon/HexagonGenInsert.cpp
+++ b/lib/Target/Hexagon/HexagonGenInsert.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "hexinsert"
-
#include "BitTracker.h"
#include "HexagonBitTracker.h"
#include "HexagonInstrInfo.h"
@@ -44,6 +42,8 @@
#include <utility>
#include <vector>
+#define DEBUG_TYPE "hexinsert"
+
using namespace llvm;
static cl::opt<unsigned> VRegIndexCutoff("insert-vreg-cutoff", cl::init(~0U),
diff --git a/lib/Target/Hexagon/HexagonGenPredicate.cpp b/lib/Target/Hexagon/HexagonGenPredicate.cpp
index 3470480d607d..2da211563e0a 100644
--- a/lib/Target/Hexagon/HexagonGenPredicate.cpp
+++ b/lib/Target/Hexagon/HexagonGenPredicate.cpp
@@ -7,8 +7,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "gen-pred"
-
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/ADT/SetVector.h"
@@ -35,6 +33,8 @@
#include <set>
#include <utility>
+#define DEBUG_TYPE "gen-pred"
+
using namespace llvm;
namespace llvm {
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index 67242764d453..3997702bc962 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1286,16 +1286,6 @@ HexagonTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
MachinePointerInfo(SV));
}
-// Creates a SPLAT instruction for a constant value VAL.
-static SDValue createSplat(SelectionDAG &DAG, const SDLoc &dl, EVT VT,
- SDValue Val) {
- EVT T = VT.getVectorElementType();
- if (T == MVT::i8 || T == MVT::i16)
- return DAG.getNode(HexagonISD::VSPLAT, dl, VT, Val);
-
- return SDValue();
-}
-
static bool isSExtFree(SDValue N) {
// A sign-extend of a truncate of a sign-extend is free.
if (N.getOpcode() == ISD::TRUNCATE &&
@@ -1374,79 +1364,6 @@ HexagonTargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
return SDValue();
}
-// Handle only specific vector loads.
-SDValue HexagonTargetLowering::LowerLOAD(SDValue Op, SelectionDAG &DAG) const {
- EVT VT = Op.getValueType();
- SDLoc DL(Op);
- LoadSDNode *LoadNode = cast<LoadSDNode>(Op);
- SDValue Chain = LoadNode->getChain();
- SDValue Ptr = Op.getOperand(1);
- SDValue LoweredLoad;
- SDValue Result;
- SDValue Base = LoadNode->getBasePtr();
- ISD::LoadExtType Ext = LoadNode->getExtensionType();
- unsigned Alignment = LoadNode->getAlignment();
- SDValue LoadChain;
-
- if(Ext == ISD::NON_EXTLOAD)
- Ext = ISD::ZEXTLOAD;
-
- if (VT == MVT::v4i16) {
- if (Alignment == 2) {
- SDValue Loads[4];
- // Base load.
- Loads[0] = DAG.getExtLoad(Ext, DL, MVT::i32, Chain, Base,
- LoadNode->getPointerInfo(), MVT::i16, Alignment,
- LoadNode->getMemOperand()->getFlags());
- // Base+2 load.
- SDValue Increment = DAG.getConstant(2, DL, MVT::i32);
- Ptr = DAG.getNode(ISD::ADD, DL, Base.getValueType(), Base, Increment);
- Loads[1] = DAG.getExtLoad(Ext, DL, MVT::i32, Chain, Ptr,
- LoadNode->getPointerInfo(), MVT::i16, Alignment,
- LoadNode->getMemOperand()->getFlags());
- // SHL 16, then OR base and base+2.
- SDValue ShiftAmount = DAG.getConstant(16, DL, MVT::i32);
- SDValue Tmp1 = DAG.getNode(ISD::SHL, DL, MVT::i32, Loads[1], ShiftAmount);
- SDValue Tmp2 = DAG.getNode(ISD::OR, DL, MVT::i32, Tmp1, Loads[0]);
- // Base + 4.
- Increment = DAG.getConstant(4, DL, MVT::i32);
- Ptr = DAG.getNode(ISD::ADD, DL, Base.getValueType(), Base, Increment);
- Loads[2] = DAG.getExtLoad(Ext, DL, MVT::i32, Chain, Ptr,
- LoadNode->getPointerInfo(), MVT::i16, Alignment,
- LoadNode->getMemOperand()->getFlags());
- // Base + 6.
- Increment = DAG.getConstant(6, DL, MVT::i32);
- Ptr = DAG.getNode(ISD::ADD, DL, Base.getValueType(), Base, Increment);
- Loads[3] = DAG.getExtLoad(Ext, DL, MVT::i32, Chain, Ptr,
- LoadNode->getPointerInfo(), MVT::i16, Alignment,
- LoadNode->getMemOperand()->getFlags());
- // SHL 16, then OR base+4 and base+6.
- Tmp1 = DAG.getNode(ISD::SHL, DL, MVT::i32, Loads[3], ShiftAmount);
- SDValue Tmp4 = DAG.getNode(ISD::OR, DL, MVT::i32, Tmp1, Loads[2]);
- // Combine to i64. This could be optimised out later if we can
- // affect reg allocation of this code.
- Result = DAG.getNode(HexagonISD::COMBINE, DL, MVT::i64, Tmp4, Tmp2);
- LoadChain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
- Loads[0].getValue(1), Loads[1].getValue(1),
- Loads[2].getValue(1), Loads[3].getValue(1));
- } else {
- // Perform default type expansion.
- Result = DAG.getLoad(MVT::i64, DL, Chain, Ptr, LoadNode->getPointerInfo(),
- LoadNode->getAlignment(),
- LoadNode->getMemOperand()->getFlags());
- LoadChain = Result.getValue(1);
- }
- } else
- llvm_unreachable("Custom lowering unsupported load");
-
- Result = DAG.getNode(ISD::BITCAST, DL, VT, Result);
- // Since we pretend to lower a load, we need the original chain
- // info attached to the result.
- SDValue Ops[] = { Result, LoadChain };
-
- return DAG.getMergeValues(Ops, DL);
-}
-
SDValue
HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
EVT ValTy = Op.getValueType();
@@ -1971,18 +1888,12 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
// Handling of vector operations.
//
- // Custom lower v4i16 load only. Let v4i16 store to be
- // promoted for now.
promoteLdStType(MVT::v4i8, MVT::i32);
promoteLdStType(MVT::v2i16, MVT::i32);
promoteLdStType(MVT::v8i8, MVT::i64);
+ promoteLdStType(MVT::v4i16, MVT::i64);
promoteLdStType(MVT::v2i32, MVT::i64);
- setOperationAction(ISD::LOAD, MVT::v4i16, Custom);
- setOperationAction(ISD::STORE, MVT::v4i16, Promote);
- AddPromotedToType(ISD::LOAD, MVT::v4i16, MVT::i64);
- AddPromotedToType(ISD::STORE, MVT::v4i16, MVT::i64);
-
// Set the action for vector operations to "expand", then override it with
// either "custom" or "legal" for specific cases.
static const unsigned VectExpOps[] = {
@@ -2301,7 +2212,8 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
case HexagonISD::RET_FLAG: return "HexagonISD::RET_FLAG";
case HexagonISD::TC_RETURN: return "HexagonISD::TC_RETURN";
case HexagonISD::VCOMBINE: return "HexagonISD::VCOMBINE";
- case HexagonISD::VPACK: return "HexagonISD::VPACK";
+ case HexagonISD::VPACKE: return "HexagonISD::VPACKE";
+ case HexagonISD::VPACKO: return "HexagonISD::VPACKO";
case HexagonISD::VASL: return "HexagonISD::VASL";
case HexagonISD::VASR: return "HexagonISD::VASR";
case HexagonISD::VLSR: return "HexagonISD::VLSR";
@@ -2394,7 +2306,7 @@ HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
// Test if V1 is a SCALAR_TO_VECTOR.
if (Lane == 0 && V1.getOpcode() == ISD::SCALAR_TO_VECTOR)
- return createSplat(DAG, dl, VT, V1.getOperand(0));
+ return DAG.getNode(HexagonISD::VSPLAT, dl, VT, V1.getOperand(0));
// Test if V1 is a BUILD_VECTOR which is equivalent to a SCALAR_TO_VECTOR
// (and probably will turn into a SCALAR_TO_VECTOR once legalization
@@ -2409,28 +2321,26 @@ HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
}
}
if (IsScalarToVector)
- return createSplat(DAG, dl, VT, V1.getOperand(0));
+ return DAG.getNode(HexagonISD::VSPLAT, dl, VT, V1.getOperand(0));
}
- return createSplat(DAG, dl, VT, DAG.getConstant(Lane, dl, MVT::i32));
+ return DAG.getNode(HexagonISD::VSPLAT, dl, VT,
+ DAG.getConstant(Lane, dl, MVT::i32));
}
if (UseHVX) {
ArrayRef<int> Mask = SVN->getMask();
size_t MaskLen = Mask.size();
- int ElemSizeInBits = VT.getScalarSizeInBits();
- if ((Subtarget.useHVXSglOps() && (ElemSizeInBits * MaskLen) == 64 * 8) ||
- (Subtarget.useHVXDblOps() && (ElemSizeInBits * MaskLen) == 128 * 8)) {
- // Return 1 for odd and 2 of even
- StridedLoadKind Pattern = isStridedLoad(Mask);
+ unsigned SizeInBits = VT.getScalarSizeInBits() * MaskLen;
+ if ((Subtarget.useHVXSglOps() && SizeInBits == 64 * 8) ||
+ (Subtarget.useHVXDblOps() && SizeInBits == 128 * 8)) {
+ StridedLoadKind Pattern = isStridedLoad(Mask);
if (Pattern == StridedLoadKind::NoPattern)
return SDValue();
- SDValue Vec0 = Op.getOperand(0);
- SDValue Vec1 = Op.getOperand(1);
- SDValue StridePattern = DAG.getConstant(Pattern, dl, MVT::i32);
- SDValue Ops[] = { Vec1, Vec0, StridePattern };
- return DAG.getNode(HexagonISD::VPACK, dl, VT, Ops);
+ unsigned Opc = Pattern == StridedLoadKind::Even ? HexagonISD::VPACKE
+ : HexagonISD::VPACKO;
+ return DAG.getNode(Opc, dl, VT, {Op.getOperand(1), Op.getOperand(0)});
}
// We used to assert in the "else" part here, but that is bad for Halide
// Halide creates intermediate double registers by interleaving two
@@ -2531,19 +2441,26 @@ HexagonTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const {
if (Size > 64)
return SDValue();
- APInt APSplatBits, APSplatUndef;
- unsigned SplatBitSize;
- bool HasAnyUndefs;
unsigned NElts = BVN->getNumOperands();
// Try to generate a SPLAT instruction.
- if ((VT.getSimpleVT() == MVT::v4i8 || VT.getSimpleVT() == MVT::v4i16) &&
- (BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
- HasAnyUndefs, 0, true) && SplatBitSize <= 16)) {
- unsigned SplatBits = APSplatBits.getZExtValue();
- int32_t SextVal = ((int32_t) (SplatBits << (32 - SplatBitSize)) >>
- (32 - SplatBitSize));
- return createSplat(DAG, dl, VT, DAG.getConstant(SextVal, dl, MVT::i32));
+ if (VT == MVT::v4i8 || VT == MVT::v4i16 || VT == MVT::v2i32) {
+ APInt APSplatBits, APSplatUndef;
+ unsigned SplatBitSize;
+ bool HasAnyUndefs;
+ if (BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
+ HasAnyUndefs, 0, false)) {
+ if (SplatBitSize == VT.getVectorElementType().getSizeInBits()) {
+ unsigned ZV = APSplatBits.getZExtValue();
+ assert(SplatBitSize <= 32 && "Can only handle up to i32");
+ // Sign-extend the splat value from SplatBitSize to 32.
+ int32_t SV = SplatBitSize < 32
+ ? int32_t(ZV << (32-SplatBitSize)) >> (32-SplatBitSize)
+ : int32_t(ZV);
+ return DAG.getNode(HexagonISD::VSPLAT, dl, VT,
+ DAG.getConstant(SV, dl, MVT::i32));
+ }
+ }
}
// Try to generate COMBINE to build v2i32 vectors.
@@ -2974,8 +2891,6 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG);
- // Custom lower some vector loads.
- case ISD::LOAD: return LowerLOAD(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
case ISD::SETCC: return LowerSETCC(Op, DAG);
case ISD::VSELECT: return LowerVSELECT(Op, DAG);
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index bfd2c94eeaba..d66cbc95e918 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -62,7 +62,8 @@ namespace HexagonISD {
EXTRACTU,
EXTRACTURP,
VCOMBINE,
- VPACK,
+ VPACKE,
+ VPACKO,
TC_RETURN,
EH_RETURN,
DCFETCH,
@@ -164,7 +165,6 @@ namespace HexagonISD {
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const;
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
bool CanLowerReturn(CallingConv::ID CallConv,
MachineFunction &MF, bool isVarArg,
diff --git a/lib/Target/Hexagon/HexagonIntrinsics.td b/lib/Target/Hexagon/HexagonIntrinsics.td
index c611857ec26a..104a28654dd5 100644
--- a/lib/Target/Hexagon/HexagonIntrinsics.td
+++ b/lib/Target/Hexagon/HexagonIntrinsics.td
@@ -1366,6 +1366,18 @@ defm : MaskedStore <V6_vS32b_nqpred_ai, int_hexagon_V6_vmaskedstorenq>;
defm : MaskedStore <V6_vS32b_nt_qpred_ai, int_hexagon_V6_vmaskedstorentq>;
defm : MaskedStore <V6_vS32b_nt_nqpred_ai, int_hexagon_V6_vmaskedstorentnq>;
+//*******************************************************************
+// SYSTEM
+//*******************************************************************
+
+def: T_R_pat<Y2_dccleana, int_hexagon_Y2_dccleana>;
+def: T_R_pat<Y2_dccleaninva, int_hexagon_Y2_dccleaninva>;
+def: T_R_pat<Y2_dcinva, int_hexagon_Y2_dcinva>;
+def: T_R_pat<Y2_dczeroa, int_hexagon_Y2_dczeroa>;
+
+def: T_RR_pat<Y4_l2fetch, int_hexagon_Y4_l2fetch>;
+def: T_RP_pat<Y5_l2fetch, int_hexagon_Y5_l2fetch>;
+
include "HexagonIntrinsicsV3.td"
include "HexagonIntrinsicsV4.td"
include "HexagonIntrinsicsV5.td"
diff --git a/lib/Target/Hexagon/HexagonOptAddrMode.cpp b/lib/Target/Hexagon/HexagonOptAddrMode.cpp
index a331c978f59d..374ffa3799b0 100644
--- a/lib/Target/Hexagon/HexagonOptAddrMode.cpp
+++ b/lib/Target/Hexagon/HexagonOptAddrMode.cpp
@@ -10,8 +10,6 @@
// load/store instructions.
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "opt-addr-mode"
-
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
@@ -36,6 +34,8 @@
#include <cassert>
#include <cstdint>
+#define DEBUG_TYPE "opt-addr-mode"
+
static cl::opt<int> CodeGrowthLimit("hexagon-amode-growth-limit",
cl::Hidden, cl::init(0), cl::desc("Code growth limit for address mode "
"optimization"));
diff --git a/lib/Target/Hexagon/HexagonPatterns.td b/lib/Target/Hexagon/HexagonPatterns.td
index ba98b8994937..804a547d5b33 100644
--- a/lib/Target/Hexagon/HexagonPatterns.td
+++ b/lib/Target/Hexagon/HexagonPatterns.td
@@ -2250,6 +2250,12 @@ def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, PS_storerhabs>;
def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, PS_storeriabs>;
def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, PS_storerdabs>;
+// Prefer this pattern to S2_asl_i_p_or for the special case of joining
+// two 32-bit words into a 64-bit word.
+let AddedComplexity = 200 in
+def: Pat<(or (shl (Aext64 I32:$a), (i32 32)), (Zext64 I32:$b)),
+ (A2_combinew I32:$a, I32:$b)>;
+
def: Pat<(or (or (or (shl (i64 (zext (and I32:$b, (i32 65535)))), (i32 16)),
(i64 (zext (i32 (and I32:$a, (i32 65535)))))),
(shl (i64 (anyext (and I32:$c, (i32 65535)))), (i32 32))),
@@ -2971,45 +2977,40 @@ def: Pat<(v64i32 (HexagonVCOMBINE (v32i32 VecDblRegs:$Vs),
(V6_vcombine_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
Requires<[UseHVXDbl]>;
-def SDTHexagonVPACK: SDTypeProfile<1, 3, [SDTCisSameAs<1, 2>,
- SDTCisInt<3>]>;
-
-def HexagonVPACK: SDNode<"HexagonISD::VPACK", SDTHexagonVPACK>;
-
-// 0 as the last argument denotes vpacke. 1 denotes vpacko
-def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs),
- (v64i8 VectorRegs:$Vt), (i32 0))),
- (V6_vpackeb VectorRegs:$Vs, VectorRegs:$Vt)>,
- Requires<[UseHVXSgl]>;
-def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs),
- (v64i8 VectorRegs:$Vt), (i32 1))),
- (V6_vpackob VectorRegs:$Vs, VectorRegs:$Vt)>,
- Requires<[UseHVXSgl]>;
-def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs),
- (v32i16 VectorRegs:$Vt), (i32 0))),
- (V6_vpackeh VectorRegs:$Vs, VectorRegs:$Vt)>,
- Requires<[UseHVXSgl]>;
-def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs),
- (v32i16 VectorRegs:$Vt), (i32 1))),
- (V6_vpackoh VectorRegs:$Vs, VectorRegs:$Vt)>,
- Requires<[UseHVXSgl]>;
-
-def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs),
- (v128i8 VecDblRegs:$Vt), (i32 0))),
- (V6_vpackeb_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
- Requires<[UseHVXDbl]>;
-def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs),
- (v128i8 VecDblRegs:$Vt), (i32 1))),
- (V6_vpackob_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
- Requires<[UseHVXDbl]>;
-def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs),
- (v64i16 VecDblRegs:$Vt), (i32 0))),
- (V6_vpackeh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
- Requires<[UseHVXDbl]>;
-def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs),
- (v64i16 VecDblRegs:$Vt), (i32 1))),
- (V6_vpackoh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>,
- Requires<[UseHVXDbl]>;
+def SDTHexagonVPACK: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>, SDTCisVec<1>]>;
+
+def HexagonVPACKE: SDNode<"HexagonISD::VPACKE", SDTHexagonVPACK>;
+def HexagonVPACKO: SDNode<"HexagonISD::VPACKO", SDTHexagonVPACK>;
+
+let Predicates = [UseHVXSgl] in {
+ def: Pat<(v64i8 (HexagonVPACKE (v64i8 VectorRegs:$Vs),
+ (v64i8 VectorRegs:$Vt))),
+ (V6_vpackeb VectorRegs:$Vs, VectorRegs:$Vt)>;
+ def: Pat<(v64i8 (HexagonVPACKO (v64i8 VectorRegs:$Vs),
+ (v64i8 VectorRegs:$Vt))),
+ (V6_vpackob VectorRegs:$Vs, VectorRegs:$Vt)>;
+ def: Pat<(v32i16 (HexagonVPACKE (v32i16 VectorRegs:$Vs),
+ (v32i16 VectorRegs:$Vt))),
+ (V6_vpackeh VectorRegs:$Vs, VectorRegs:$Vt)>;
+ def: Pat<(v32i16 (HexagonVPACKO (v32i16 VectorRegs:$Vs),
+ (v32i16 VectorRegs:$Vt))),
+ (V6_vpackoh VectorRegs:$Vs, VectorRegs:$Vt)>;
+}
+
+let Predicates = [UseHVXDbl] in {
+ def: Pat<(v128i8 (HexagonVPACKE (v128i8 VecDblRegs:$Vs),
+ (v128i8 VecDblRegs:$Vt))),
+ (V6_vpackeb_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
+ def: Pat<(v128i8 (HexagonVPACKO (v128i8 VecDblRegs:$Vs),
+ (v128i8 VecDblRegs:$Vt))),
+ (V6_vpackob_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
+ def: Pat<(v64i16 (HexagonVPACKE (v64i16 VecDblRegs:$Vs),
+ (v64i16 VecDblRegs:$Vt))),
+ (V6_vpackeh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
+ def: Pat<(v64i16 (HexagonVPACKO (v64i16 VecDblRegs:$Vs),
+ (v64i16 VecDblRegs:$Vt))),
+ (V6_vpackoh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>;
+}
def V2I1: PatLeaf<(v2i1 PredRegs:$R)>;
def V4I1: PatLeaf<(v4i1 PredRegs:$R)>;
@@ -3073,6 +3074,10 @@ def: Pat<(v4i8 (HexagonVSPLAT I32:$Rs)), (S2_vsplatrb I32:$Rs)>;
// four halfwords of 64-bits destination register.
def: Pat<(v4i16 (HexagonVSPLAT I32:$Rs)), (S2_vsplatrh I32:$Rs)>;
+def: Pat<(v2i32 (HexagonVSPLAT s8_0ImmPred:$s8)),
+ (A2_combineii imm:$s8, imm:$s8)>;
+def: Pat<(v2i32 (HexagonVSPLAT I32:$Rs)), (A2_combinew I32:$Rs, I32:$Rs)>;
+
class VArith_pat <InstHexagon MI, SDNode Op, PatFrag Type>
: Pat <(Op Type:$Rss, Type:$Rtt),
@@ -3099,14 +3104,11 @@ def: VArith_pat <A2_xorp, xor, V8I8>;
def: VArith_pat <A2_xorp, xor, V4I16>;
def: VArith_pat <A2_xorp, xor, V2I32>;
-def: Pat<(v2i32 (sra V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
- (i32 u5_0ImmPred:$c))))),
+def: Pat<(v2i32 (sra V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c)))),
(S2_asr_i_vw V2I32:$b, imm:$c)>;
-def: Pat<(v2i32 (srl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
- (i32 u5_0ImmPred:$c))))),
+def: Pat<(v2i32 (srl V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c)))),
(S2_lsr_i_vw V2I32:$b, imm:$c)>;
-def: Pat<(v2i32 (shl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c),
- (i32 u5_0ImmPred:$c))))),
+def: Pat<(v2i32 (shl V2I32:$b, (v2i32 (HexagonVSPLAT u5_0ImmPred:$c)))),
(S2_asl_i_vw V2I32:$b, imm:$c)>;
def: Pat<(v4i16 (sra V4I16:$b, (v4i16 (HexagonVSPLAT u4_0ImmPred:$c)))),
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
index 34df2ebcc520..ea86c9c42f47 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
@@ -53,6 +53,10 @@ static cl::opt<bool>
EmitJtInText("hexagon-emit-jt-text", cl::Hidden, cl::init(false),
cl::desc("Emit hexagon jump tables in function section"));
+static cl::opt<bool>
+ EmitLutInText("hexagon-emit-lut-text", cl::Hidden, cl::init(false),
+ cl::desc("Emit hexagon lookup tables in function section"));
+
// TraceGVPlacement controls messages for all builds. For builds with assertions
// (debug or release), messages are also controlled by the usual debug flags
// (e.g. -debug and -debug-only=globallayout)
@@ -136,6 +140,13 @@ MCSection *HexagonTargetObjectFile::SelectSectionForGlobal(
<< (Kind.isBSS() ? "kind_bss " : "" )
<< (Kind.isBSSLocal() ? "kind_bss_local " : "" ));
+ // If the lookup table is used by more than one function, do not place
+ // it in text section.
+ if (EmitLutInText && GO->getName().startswith("switch.table")) {
+ if (const Function *Fn = getLutUsedFunction(GO))
+ return selectSectionForLookupTable(GO, TM, Fn);
+ }
+
if (isGlobalInSmallSection(GO, TM))
return selectSmallSectionForGlobal(GO, Kind, TM);
@@ -402,3 +413,39 @@ MCSection *HexagonTargetObjectFile::selectSmallSectionForGlobal(
// Otherwise, we work the same as ELF.
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
}
+
+// Return the function that uses the lookup table. If there are more
+// than one live function that uses this look table, bail out and place
+// the lookup table in default section.
+const Function *
+HexagonTargetObjectFile::getLutUsedFunction(const GlobalObject *GO) const {
+ const Function *ReturnFn = nullptr;
+ for (auto U : GO->users()) {
+ // validate each instance of user to be a live function.
+ auto *I = dyn_cast<Instruction>(U);
+ if (!I)
+ continue;
+ auto *Bb = I->getParent();
+ if (!Bb)
+ continue;
+ auto *UserFn = Bb->getParent();
+ if (!ReturnFn)
+ ReturnFn = UserFn;
+ else if (ReturnFn != UserFn)
+ return nullptr;
+ }
+ return ReturnFn;
+}
+
+MCSection *HexagonTargetObjectFile::selectSectionForLookupTable(
+ const GlobalObject *GO, const TargetMachine &TM, const Function *Fn) const {
+
+ SectionKind Kind = SectionKind::getText();
+ // If the function has explicit section, place the lookup table in this
+ // explicit section.
+ if (Fn->hasSection())
+ return getExplicitSectionGlobal(Fn, Kind, TM);
+
+ const auto *FuncObj = dyn_cast<GlobalObject>(Fn);
+ return SelectSectionForGlobal(FuncObj, Kind, TM);
+}
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.h b/lib/Target/Hexagon/HexagonTargetObjectFile.h
index 373d850b53be..eff44f097e03 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.h
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.h
@@ -36,6 +36,8 @@ namespace llvm {
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
const Function &F) const override;
+ const Function *getLutUsedFunction(const GlobalObject *GO) const;
+
private:
MCSectionELF *SmallDataSection;
MCSectionELF *SmallBSSSection;
@@ -46,6 +48,10 @@ namespace llvm {
MCSection *selectSmallSectionForGlobal(const GlobalObject *GO,
SectionKind Kind,
const TargetMachine &TM) const;
+
+ MCSection *selectSectionForLookupTable(const GlobalObject *GO,
+ const TargetMachine &TM,
+ const Function *Fn) const;
};
} // namespace llvm