summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp')
-rw-r--r--contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp160
1 files changed, 94 insertions, 66 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index 9123057..a0da945 100644
--- a/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -50,16 +50,21 @@ namespace {
class HexagonDAGToDAGISel : public SelectionDAGISel {
const HexagonTargetMachine& HTM;
const HexagonSubtarget *HST;
+ const HexagonInstrInfo *HII;
+ const HexagonRegisterInfo *HRI;
public:
explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm,
CodeGenOpt::Level OptLevel)
- : SelectionDAGISel(tm, OptLevel), HTM(tm) {
+ : SelectionDAGISel(tm, OptLevel), HTM(tm), HST(nullptr), HII(nullptr),
+ HRI(nullptr) {
initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
}
bool runOnMachineFunction(MachineFunction &MF) override {
// Reset the subtarget each time through.
HST = &MF.getSubtarget<HexagonSubtarget>();
+ HII = HST->getInstrInfo();
+ HRI = HST->getRegisterInfo();
SelectionDAGISel::runOnMachineFunction(MF);
return true;
}
@@ -104,7 +109,6 @@ public:
SDNode *SelectConstantFP(SDNode *N);
SDNode *SelectAdd(SDNode *N);
SDNode *SelectBitOp(SDNode *N);
- bool isConstExtProfitable(SDNode *N) const;
// XformMskToBitPosU5Imm - Returns the bit position which
// the single bit 32 bit mask represents.
@@ -139,8 +143,8 @@ public:
// type i32 where the negative literal is transformed into a positive literal
// for use in -= memops.
inline SDValue XformM5ToU5Imm(signed Imm, SDLoc DL) {
- assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
- return CurDAG->getTargetConstant( - Imm, DL, MVT::i32);
+ assert((Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
+ return CurDAG->getTargetConstant(-Imm, DL, MVT::i32);
}
// XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
@@ -203,11 +207,10 @@ void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
// Intrinsics that return a a predicate.
-static unsigned doesIntrinsicReturnPredicate(unsigned ID)
-{
+static bool doesIntrinsicReturnPredicate(unsigned ID) {
switch (ID) {
default:
- return 0;
+ return false;
case Intrinsic::hexagon_C2_cmpeq:
case Intrinsic::hexagon_C2_cmpgt:
case Intrinsic::hexagon_C2_cmpgtu:
@@ -244,7 +247,7 @@ static unsigned doesIntrinsicReturnPredicate(unsigned ID)
case Intrinsic::hexagon_C2_tfrrp:
case Intrinsic::hexagon_S2_tstbit_i:
case Intrinsic::hexagon_S2_tstbit_r:
- return 1;
+ return true;
}
}
@@ -258,8 +261,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
SDNode *OffsetNode = Offset.getNode();
int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
- const HexagonInstrInfo &TII = *HST->getInstrInfo();
- if (TII.isValidAutoIncImm(LoadedVT, Val)) {
+ if (HII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConst = CurDAG->getTargetConstant(Val, dl, MVT::i32);
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
MVT::Other, Base, TargetConst,
@@ -312,8 +314,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
SDNode *OffsetNode = Offset.getNode();
int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
- const HexagonInstrInfo &TII = *HST->getInstrInfo();
- if (TII.isValidAutoIncImm(LoadedVT, Val)) {
+ if (HII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, dl, MVT::i32);
SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
@@ -378,29 +379,46 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
// loads.
ISD::LoadExtType ExtType = LD->getExtensionType();
bool IsZeroExt = (ExtType == ISD::ZEXTLOAD || ExtType == ISD::EXTLOAD);
+ bool HasVecOffset = false;
// Figure out the opcode.
- const HexagonInstrInfo &TII = *HST->getInstrInfo();
if (LoadedVT == MVT::i64) {
- if (TII.isValidAutoIncImm(LoadedVT, Val))
+ if (HII->isValidAutoIncImm(LoadedVT, Val))
Opcode = Hexagon::L2_loadrd_pi;
else
Opcode = Hexagon::L2_loadrd_io;
} else if (LoadedVT == MVT::i32) {
- if (TII.isValidAutoIncImm(LoadedVT, Val))
+ if (HII->isValidAutoIncImm(LoadedVT, Val))
Opcode = Hexagon::L2_loadri_pi;
else
Opcode = Hexagon::L2_loadri_io;
} else if (LoadedVT == MVT::i16) {
- if (TII.isValidAutoIncImm(LoadedVT, Val))
+ if (HII->isValidAutoIncImm(LoadedVT, Val))
Opcode = IsZeroExt ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
else
Opcode = IsZeroExt ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
} else if (LoadedVT == MVT::i8) {
- if (TII.isValidAutoIncImm(LoadedVT, Val))
+ if (HII->isValidAutoIncImm(LoadedVT, Val))
Opcode = IsZeroExt ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
else
Opcode = IsZeroExt ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
+ } else if (LoadedVT == MVT::v16i32 || LoadedVT == MVT::v8i64 ||
+ LoadedVT == MVT::v32i16 || LoadedVT == MVT::v64i8) {
+ HasVecOffset = true;
+ if (HII->isValidAutoIncImm(LoadedVT, Val)) {
+ Opcode = Hexagon::V6_vL32b_pi;
+ }
+ else
+ Opcode = Hexagon::V6_vL32b_ai;
+ // 128B
+ } else if (LoadedVT == MVT::v32i32 || LoadedVT == MVT::v16i64 ||
+ LoadedVT == MVT::v64i16 || LoadedVT == MVT::v128i8) {
+ HasVecOffset = true;
+ if (HII->isValidAutoIncImm(LoadedVT, Val)) {
+ Opcode = Hexagon::V6_vL32b_pi_128B;
+ }
+ else
+ Opcode = Hexagon::V6_vL32b_ai_128B;
} else
llvm_unreachable("unknown memory type");
@@ -411,7 +429,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
if (LD->getValueType(0) == MVT::i64 && ExtType == ISD::SEXTLOAD)
return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
- if (TII.isValidAutoIncImm(LoadedVT, Val)) {
+ if (HII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, dl, MVT::i32);
SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
LD->getValueType(0),
@@ -420,15 +438,25 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = LD->getMemOperand();
cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
- const SDValue Froms[] = { SDValue(LD, 0),
- SDValue(LD, 1),
- SDValue(LD, 2)
- };
- const SDValue Tos[] = { SDValue(Result, 0),
- SDValue(Result, 1),
- SDValue(Result, 2)
- };
- ReplaceUses(Froms, Tos, 3);
+ if (HasVecOffset) {
+ const SDValue Froms[] = { SDValue(LD, 0),
+ SDValue(LD, 2)
+ };
+ const SDValue Tos[] = { SDValue(Result, 0),
+ SDValue(Result, 2)
+ };
+ ReplaceUses(Froms, Tos, 2);
+ } else {
+ const SDValue Froms[] = { SDValue(LD, 0),
+ SDValue(LD, 1),
+ SDValue(LD, 2)
+ };
+ const SDValue Tos[] = { SDValue(Result, 0),
+ SDValue(Result, 1),
+ SDValue(Result, 2)
+ };
+ ReplaceUses(Froms, Tos, 3);
+ }
return Result;
} else {
SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
@@ -487,8 +515,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
// Offset value must be within representable range
// and must have correct alignment properties.
- const HexagonInstrInfo &TII = *HST->getInstrInfo();
- if (TII.isValidAutoIncImm(StoredVT, Val)) {
+ if (HII->isValidAutoIncImm(StoredVT, Val)) {
unsigned Opcode = 0;
// Figure out the post inc version of opcode.
@@ -496,7 +523,15 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
- else llvm_unreachable("unknown memory type");
+ else if (StoredVT == MVT::v16i32 || StoredVT == MVT::v8i64 ||
+ StoredVT == MVT::v32i16 || StoredVT == MVT::v64i8) {
+ Opcode = Hexagon::V6_vS32b_pi;
+ }
+ // 128B
+ else if (StoredVT == MVT::v32i32 || StoredVT == MVT::v16i64 ||
+ StoredVT == MVT::v64i16 || StoredVT == MVT::v128i8) {
+ Opcode = Hexagon::V6_vS32b_pi_128B;
+ } else llvm_unreachable("unknown memory type");
if (ST->isTruncatingStore() && ValueVT.getSizeInBits() == 64) {
assert(StoredVT.getSizeInBits() < 64 && "Not a truncating store");
@@ -530,6 +565,13 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
+ else if (StoredVT == MVT::v16i32 || StoredVT == MVT::v8i64 ||
+ StoredVT == MVT::v32i16 || StoredVT == MVT::v64i8)
+ Opcode = Hexagon::V6_vS32b_ai;
+ // 128B
+ else if (StoredVT == MVT::v32i32 || StoredVT == MVT::v16i64 ||
+ StoredVT == MVT::v64i16 || StoredVT == MVT::v128i8)
+ Opcode = Hexagon::V6_vS32b_ai_128B;
else llvm_unreachable("unknown memory type");
// Build regular store.
@@ -1113,14 +1155,12 @@ SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
}
if (Opc == ISD::AND) {
- if (((ValueVT == MVT::i32) &&
- (!((Val & 0x80000000) || (Val & 0x7fffffff)))) ||
- ((ValueVT == MVT::i64) &&
- (!((Val & 0x8000000000000000) || (Val & 0x7fffffff)))))
- // If it's simple AND, do the normal op.
- return SelectCode(N);
- else
+ // Check if this is a bit-clearing AND, if not select code the usual way.
+ if ((ValueVT == MVT::i32 && isPowerOf2_32(~Val)) ||
+ (ValueVT == MVT::i64 && isPowerOf2_64(~Val)))
Val = ~Val;
+ else
+ return SelectCode(N);
}
// If OR or AND is being fed by shl, srl and, sra don't do this change,
@@ -1128,7 +1168,8 @@ SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
// Traverse the DAG to see if there is shl, srl and sra.
if (Opc == ISD::OR || Opc == ISD::AND) {
switch (N->getOperand(0)->getOpcode()) {
- default: break;
+ default:
+ break;
case ISD::SRA:
case ISD::SRL:
case ISD::SHL:
@@ -1137,23 +1178,24 @@ SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
}
// Make sure it's power of 2.
- unsigned bitpos = 0;
+ unsigned BitPos = 0;
if (Opc != ISD::FABS && Opc != ISD::FNEG) {
- if (((ValueVT == MVT::i32) && !isPowerOf2_32(Val)) ||
- ((ValueVT == MVT::i64) && !isPowerOf2_64(Val)))
+ if ((ValueVT == MVT::i32 && !isPowerOf2_32(Val)) ||
+ (ValueVT == MVT::i64 && !isPowerOf2_64(Val)))
return SelectCode(N);
// Get the bit position.
- bitpos = countTrailingZeros(uint64_t(Val));
+ BitPos = countTrailingZeros(uint64_t(Val));
} else {
// For fabs and fneg, it's always the 31st bit.
- bitpos = 31;
+ BitPos = 31;
}
unsigned BitOpc = 0;
// Set the right opcode for bitwise operations.
- switch(Opc) {
- default: llvm_unreachable("Only bit-wise/abs/neg operations are allowed.");
+ switch (Opc) {
+ default:
+ llvm_unreachable("Only bit-wise/abs/neg operations are allowed.");
case ISD::AND:
case ISD::FABS:
BitOpc = Hexagon::S2_clrbit_i;
@@ -1169,7 +1211,7 @@ SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
SDNode *Result;
// Get the right SDVal for the opcode.
- SDValue SDVal = CurDAG->getTargetConstant(bitpos, dl, MVT::i32);
+ SDValue SDVal = CurDAG->getTargetConstant(BitPos, dl, MVT::i32);
if (ValueVT == MVT::i32 || ValueVT == MVT::f32) {
Result = CurDAG->getMachineNode(BitOpc, dl, ValueVT,
@@ -1198,7 +1240,7 @@ SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
MVT::i32, SDValue(Reg, 0));
// Clear/set/toggle hi or lo registers depending on the bit position.
- if (SubValueVT != MVT::f32 && bitpos < 32) {
+ if (SubValueVT != MVT::f32 && BitPos < 32) {
SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT,
SubregLO, SDVal);
const SDValue Ops[] = { RegClass, SubregHI, SubregHiIdx,
@@ -1207,7 +1249,7 @@ SDNode *HexagonDAGToDAGISel::SelectBitOp(SDNode *N) {
dl, ValueVT, Ops);
} else {
if (Opc != ISD::FABS && Opc != ISD::FNEG)
- SDVal = CurDAG->getTargetConstant(bitpos - 32, dl, MVT::i32);
+ SDVal = CurDAG->getTargetConstant(BitPos-32, dl, MVT::i32);
SDNode *Result0 = CurDAG->getMachineNode(BitOpc, dl, SubValueVT,
SubregHI, SDVal);
const SDValue Ops[] = { RegClass, SDValue(Result0, 0), SubregHiIdx,
@@ -1328,25 +1370,12 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
return false;
}
-bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
- unsigned UseCount = 0;
- unsigned CallCount = 0;
- for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
- // Ignore call instructions.
- if (I->getOpcode() == ISD::CopyToReg)
- ++CallCount;
- UseCount++;
- }
-
- return (UseCount <= 1) || (CallCount > 1);
-
-}
void HexagonDAGToDAGISel::PreprocessISelDAG() {
SelectionDAG &DAG = *CurDAG;
std::vector<SDNode*> Nodes;
- for (auto I = DAG.allnodes_begin(), E = DAG.allnodes_end(); I != E; ++I)
- Nodes.push_back(I);
+ for (SDNode &Node : DAG.allnodes())
+ Nodes.push_back(&Node);
// Simplify: (or (select c x 0) z) -> (select c (or x z) z)
// (or (select c 0 y) z) -> (select c z (or y z))
@@ -1397,11 +1426,10 @@ void HexagonDAGToDAGISel::EmitFunctionEntryCode() {
return;
MachineFrameInfo *MFI = MF->getFrameInfo();
- MachineBasicBlock *EntryBB = MF->begin();
+ MachineBasicBlock *EntryBB = &MF->front();
unsigned AR = FuncInfo->CreateReg(MVT::i32);
unsigned MaxA = MFI->getMaxAlignment();
- auto &HII = *HST.getInstrInfo();
- BuildMI(EntryBB, DebugLoc(), HII.get(Hexagon::ALIGNA), AR)
+ BuildMI(EntryBB, DebugLoc(), HII->get(Hexagon::ALIGNA), AR)
.addImm(MaxA);
MF->getInfo<HexagonMachineFunctionInfo>()->setStackAlignBaseVReg(AR);
}
OpenPOWER on IntegriCloud