mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[Hexagon] Tidy up some code, NFC: reapply r277372 with a fix
llvm-svn: 277383
This commit is contained in:
parent
79800f1511
commit
6f6fbffa9f
@ -78,8 +78,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void PreprocessISelDAG() override;
|
||||
virtual void EmitFunctionEntryCode() override;
|
||||
void PreprocessISelDAG() override;
|
||||
void EmitFunctionEntryCode() override;
|
||||
|
||||
void Select(SDNode *N) override;
|
||||
|
||||
@ -127,11 +127,9 @@ public:
|
||||
// the single bit 32 bit mask represents.
|
||||
// Used in Clr and Set bit immediate memops.
|
||||
SDValue XformMskToBitPosU5Imm(uint32_t Imm, const SDLoc &DL) {
|
||||
int32_t bitPos;
|
||||
bitPos = Log2_32(Imm);
|
||||
assert(bitPos >= 0 && bitPos < 32 &&
|
||||
"Constant out of range for 32 BitPos Memops");
|
||||
return CurDAG->getTargetConstant(bitPos, DL, MVT::i32);
|
||||
unsigned BitPos = Log2_32(Imm);
|
||||
assert(BitPos < 32 && "Constant out of range for 32 BitPos Memops");
|
||||
return CurDAG->getTargetConstant(BitPos, DL, MVT::i32);
|
||||
}
|
||||
|
||||
// XformMskToBitPosU4Imm - Returns the bit position which the single-bit
|
||||
@ -667,7 +665,6 @@ void HexagonDAGToDAGISel::SelectStore(SDNode *N) {
|
||||
void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
SDLoc dl(N);
|
||||
|
||||
//
|
||||
// %conv.i = sext i32 %tmp1 to i64
|
||||
// %conv2.i = sext i32 %add to i64
|
||||
// %mul.i = mul nsw i64 %conv2.i, %conv.i
|
||||
@ -692,7 +689,6 @@ void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
SelectCode(N);
|
||||
return;
|
||||
}
|
||||
|
||||
OP0 = Sext0;
|
||||
} else if (MulOp0.getOpcode() == ISD::LOAD) {
|
||||
LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
|
||||
@ -702,7 +698,6 @@ void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
SelectCode(N);
|
||||
return;
|
||||
}
|
||||
|
||||
SDValue Chain = LD->getChain();
|
||||
SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
|
||||
OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
|
||||
@ -721,7 +716,6 @@ void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
SelectCode(N);
|
||||
return;
|
||||
}
|
||||
|
||||
OP1 = Sext1;
|
||||
} else if (MulOp1.getOpcode() == ISD::LOAD) {
|
||||
LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
|
||||
@ -731,7 +725,6 @@ void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
SelectCode(N);
|
||||
return;
|
||||
}
|
||||
|
||||
SDValue Chain = LD->getChain();
|
||||
SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
|
||||
OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
|
||||
@ -744,8 +737,8 @@ void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
}
|
||||
|
||||
// Generate a mpy instruction.
|
||||
SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
|
||||
OP0, OP1);
|
||||
SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl,
|
||||
MVT::i64, OP0, OP1);
|
||||
ReplaceNode(N, Result);
|
||||
return;
|
||||
}
|
||||
@ -755,68 +748,56 @@ void HexagonDAGToDAGISel::SelectMul(SDNode *N) {
|
||||
|
||||
void HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
|
||||
SDLoc dl(N);
|
||||
if (N->getValueType(0) == MVT::i32) {
|
||||
SDValue Shl_0 = N->getOperand(0);
|
||||
SDValue Shl_1 = N->getOperand(1);
|
||||
|
||||
auto Default = [this,N] () -> void { SelectCode(N); };
|
||||
|
||||
if (N->getValueType(0) != MVT::i32 || Shl_1.getOpcode() != ISD::Constant)
|
||||
return Default();
|
||||
|
||||
// RHS is const.
|
||||
if (Shl_1.getOpcode() == ISD::Constant) {
|
||||
int32_t ShlConst = cast<ConstantSDNode>(Shl_1)->getSExtValue();
|
||||
|
||||
if (Shl_0.getOpcode() == ISD::MUL) {
|
||||
SDValue Mul_0 = Shl_0.getOperand(0); // Val
|
||||
SDValue Mul_1 = Shl_0.getOperand(1); // Const
|
||||
// RHS of mul is const.
|
||||
if (Mul_1.getOpcode() == ISD::Constant) {
|
||||
int32_t ShlConst =
|
||||
cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
|
||||
int32_t MulConst =
|
||||
cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
|
||||
int32_t ValConst = MulConst << ShlConst;
|
||||
SDValue Val = CurDAG->getTargetConstant(ValConst, dl,
|
||||
MVT::i32);
|
||||
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
|
||||
if (isInt<9>(CN->getSExtValue())) {
|
||||
SDNode* Result =
|
||||
CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Mul_1)) {
|
||||
int32_t ValConst = C->getSExtValue() << ShlConst;
|
||||
if (isInt<9>(ValConst)) {
|
||||
SDValue Val = CurDAG->getTargetConstant(ValConst, dl, MVT::i32);
|
||||
SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
|
||||
MVT::i32, Mul_0, Val);
|
||||
ReplaceNode(N, Result);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
} else if (Shl_0.getOpcode() == ISD::SUB) {
|
||||
return Default();
|
||||
}
|
||||
|
||||
if (Shl_0.getOpcode() == ISD::SUB) {
|
||||
SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
|
||||
SDValue Sub_1 = Shl_0.getOperand(1); // Val
|
||||
if (Sub_0.getOpcode() == ISD::Constant) {
|
||||
int32_t SubConst =
|
||||
cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
|
||||
if (SubConst == 0) {
|
||||
if (Sub_1.getOpcode() == ISD::SHL) {
|
||||
if (ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(Sub_0)) {
|
||||
if (C1->getSExtValue() != 0 || Sub_1.getOpcode() != ISD::SHL)
|
||||
return Default();
|
||||
SDValue Shl2_0 = Sub_1.getOperand(0); // Val
|
||||
SDValue Shl2_1 = Sub_1.getOperand(1); // Const
|
||||
if (Shl2_1.getOpcode() == ISD::Constant) {
|
||||
int32_t ShlConst =
|
||||
cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
|
||||
int32_t Shl2Const =
|
||||
cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
|
||||
int32_t ValConst = 1 << (ShlConst+Shl2Const);
|
||||
SDValue Val = CurDAG->getTargetConstant(-ValConst, dl,
|
||||
MVT::i32);
|
||||
if (ConstantSDNode *CN =
|
||||
dyn_cast<ConstantSDNode>(Val.getNode()))
|
||||
if (isInt<9>(CN->getSExtValue())) {
|
||||
SDNode* Result =
|
||||
CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
|
||||
Shl2_0, Val);
|
||||
if (ConstantSDNode *C2 = dyn_cast<ConstantSDNode>(Shl2_1)) {
|
||||
int32_t ValConst = 1 << (ShlConst + C2->getSExtValue());
|
||||
if (isInt<9>(-ValConst)) {
|
||||
SDValue Val = CurDAG->getTargetConstant(-ValConst, dl, MVT::i32);
|
||||
SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
|
||||
MVT::i32, Shl2_0, Val);
|
||||
ReplaceNode(N, Result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SelectCode(N);
|
||||
|
||||
return Default();
|
||||
}
|
||||
|
||||
|
||||
@ -866,21 +847,18 @@ void HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDNode *IsIntrinsic = N->getOperand(0).getNode();
|
||||
if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
|
||||
unsigned ID =
|
||||
cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
|
||||
SDNode *Int = N->getOperand(0).getNode();
|
||||
if ((Int->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
|
||||
unsigned ID = cast<ConstantSDNode>(Int->getOperand(0))->getZExtValue();
|
||||
if (doesIntrinsicReturnPredicate(ID)) {
|
||||
// Now we need to differentiate target data types.
|
||||
if (N->getValueType(0) == MVT::i64) {
|
||||
// Convert the zero_extend to Rs = Pd followed by A2_combinew(0,Rs).
|
||||
SDValue TargetConst0 = CurDAG->getTargetConstant(0, dl, MVT::i32);
|
||||
SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
|
||||
MVT::i32,
|
||||
SDValue(IsIntrinsic, 0));
|
||||
MVT::i32, SDValue(Int, 0));
|
||||
SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
|
||||
MVT::i32,
|
||||
TargetConst0);
|
||||
MVT::i32, TargetConst0);
|
||||
SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
|
||||
MVT::i64, MVT::Other,
|
||||
SDValue(Result_2, 0),
|
||||
@ -891,8 +869,7 @@ void HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
|
||||
if (N->getValueType(0) == MVT::i32) {
|
||||
// Convert the zero_extend to Rs = Pd
|
||||
SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
|
||||
MVT::i32,
|
||||
SDValue(IsIntrinsic, 0));
|
||||
MVT::i32, SDValue(Int, 0));
|
||||
ReplaceNode(N, RsPd);
|
||||
return;
|
||||
}
|
||||
@ -956,7 +933,7 @@ void HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
|
||||
APF.convertToFloat(), dl, MVT::f32)));
|
||||
return;
|
||||
}
|
||||
else if (N->getValueType(0) == MVT::f64) {
|
||||
if (N->getValueType(0) == MVT::f64) {
|
||||
ReplaceNode(
|
||||
N, CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
|
||||
CurDAG->getTargetConstantFP(
|
||||
@ -1001,8 +978,8 @@ void HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
|
||||
}
|
||||
// Identify nodes of the form: add(asr(...)).
|
||||
SDNode* Src1 = N->getOperand(0).getNode();
|
||||
if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
|
||||
|| Src1->getValueType(0) != MVT::i32) {
|
||||
if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse() ||
|
||||
Src1->getValueType(0) != MVT::i32) {
|
||||
SelectCode(N);
|
||||
return;
|
||||
}
|
||||
@ -1173,7 +1150,7 @@ void HexagonDAGToDAGISel::SelectFrameIndex(SDNode *N) {
|
||||
SDValue FI = CurDAG->getTargetFrameIndex(FX, MVT::i32);
|
||||
SDLoc DL(N);
|
||||
SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32);
|
||||
SDNode *R = 0;
|
||||
SDNode *R = nullptr;
|
||||
|
||||
// Use TFR_FI when:
|
||||
// - the object is fixed, or
|
||||
@ -1793,7 +1770,7 @@ static bool willShiftRightEliminate(SDValue V, unsigned Amount) {
|
||||
SDValue Ops[] = { V.getOperand(0), V.getOperand(1) };
|
||||
for (int i = 0; i < 2; ++i)
|
||||
if (isa<ConstantSDNode>(Ops[i].getNode()) &&
|
||||
V.getConstantOperandVal(i) % ((uint64_t)1 << Amount) == 0) {
|
||||
V.getConstantOperandVal(i) % (1ULL << Amount) == 0) {
|
||||
uint64_t NewConst = V.getConstantOperandVal(i) >> Amount;
|
||||
return (NewConst == 1);
|
||||
}
|
||||
@ -2111,6 +2088,9 @@ SDValue HexagonDAGToDAGISel::balanceSubTree(SDNode *N, bool TopLevel) {
|
||||
Leaves.pushToBottom(Leaves.pop());
|
||||
}
|
||||
|
||||
const DataLayout &DL = CurDAG->getDataLayout();
|
||||
const TargetLowering &TLI = *getTargetLowering();
|
||||
|
||||
// Rebuild the tree using Huffman's algorithm
|
||||
while (Leaves.size() > 1) {
|
||||
WeightedLeaf L0 = Leaves.pop();
|
||||
@ -2156,7 +2136,7 @@ SDValue HexagonDAGToDAGISel::balanceSubTree(SDNode *N, bool TopLevel) {
|
||||
ISD::SHL, SDLoc(V0), VT, V0,
|
||||
CurDAG->getConstant(
|
||||
V1C->getAPIntValue().logBase2(), SDLoc(N),
|
||||
getTargetLowering()->getScalarShiftAmountTy(CurDAG->getDataLayout(), V0.getValueType())));
|
||||
TLI.getScalarShiftAmountTy(DL, V0.getValueType())));
|
||||
else
|
||||
NewNode = CurDAG->getNode(NOpcode, SDLoc(N), VT, V0, V1);
|
||||
|
||||
@ -2184,9 +2164,9 @@ SDValue HexagonDAGToDAGISel::balanceSubTree(SDNode *N, bool TopLevel) {
|
||||
SDValue V0 = NewRoot.getOperand(0);
|
||||
NewRoot = CurDAG->getNode(
|
||||
ISD::SHL, SDLoc(NewRoot), VT, V0,
|
||||
CurDAG->getConstant(V1C->getAPIntValue().logBase2(), SDLoc(NewRoot),
|
||||
getTargetLowering()->getScalarShiftAmountTy(
|
||||
CurDAG->getDataLayout(), V0.getValueType())));
|
||||
CurDAG->getConstant(
|
||||
V1C->getAPIntValue().logBase2(), SDLoc(NewRoot),
|
||||
TLI.getScalarShiftAmountTy(DL, V0.getValueType())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2209,8 +2189,7 @@ SDValue HexagonDAGToDAGISel::balanceSubTree(SDNode *N, bool TopLevel) {
|
||||
}
|
||||
|
||||
void HexagonDAGToDAGISel::rebalanceAddressTrees() {
|
||||
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
|
||||
E = CurDAG->allnodes_end(); I != E;) {
|
||||
for (auto I = CurDAG->allnodes_begin(), E = CurDAG->allnodes_end(); I != E;) {
|
||||
SDNode *N = &*I++;
|
||||
if (N->getOpcode() != ISD::LOAD && N->getOpcode() != ISD::STORE)
|
||||
continue;
|
||||
@ -2274,4 +2253,3 @@ void HexagonDAGToDAGISel::rebalanceAddressTrees() {
|
||||
RootWeights.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,7 +105,7 @@ namespace {
|
||||
|
||||
// Implement calling convention for Hexagon.
|
||||
|
||||
static bool IsHvxVectorType(MVT ty);
|
||||
static bool isHvxVectorType(MVT ty);
|
||||
|
||||
static bool
|
||||
CC_Hexagon(unsigned ValNo, MVT ValVT,
|
||||
@ -159,13 +159,13 @@ CC_Hexagon_VarArg (unsigned ValNo, MVT ValVT,
|
||||
}
|
||||
|
||||
// Deal with un-named arguments.
|
||||
unsigned ofst;
|
||||
unsigned Offset;
|
||||
if (ArgFlags.isByVal()) {
|
||||
// If pass-by-value, the size allocated on stack is decided
|
||||
// by ArgFlags.getByValSize(), not by the size of LocVT.
|
||||
ofst = State.AllocateStack(ArgFlags.getByValSize(),
|
||||
Offset = State.AllocateStack(ArgFlags.getByValSize(),
|
||||
ArgFlags.getByValAlign());
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::i1 || LocVT == MVT::i8 || LocVT == MVT::i16) {
|
||||
@ -179,43 +179,43 @@ CC_Hexagon_VarArg (unsigned ValNo, MVT ValVT,
|
||||
LocInfo = CCValAssign::AExt;
|
||||
}
|
||||
if (LocVT == MVT::i32 || LocVT == MVT::f32) {
|
||||
ofst = State.AllocateStack(4, 4);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(4, 4);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::i64 || LocVT == MVT::f64) {
|
||||
ofst = State.AllocateStack(8, 8);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(8, 8);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::v2i64 || LocVT == MVT::v4i32 || LocVT == MVT::v8i16 ||
|
||||
LocVT == MVT::v16i8) {
|
||||
ofst = State.AllocateStack(16, 16);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(16, 16);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::v4i64 || LocVT == MVT::v8i32 || LocVT == MVT::v16i16 ||
|
||||
LocVT == MVT::v32i8) {
|
||||
ofst = State.AllocateStack(32, 32);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(32, 32);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::v8i64 || LocVT == MVT::v16i32 || LocVT == MVT::v32i16 ||
|
||||
LocVT == MVT::v64i8 || LocVT == MVT::v512i1) {
|
||||
ofst = State.AllocateStack(64, 64);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(64, 64);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::v16i64 || LocVT == MVT::v32i32 || LocVT == MVT::v64i16 ||
|
||||
LocVT == MVT::v128i8 || LocVT == MVT::v1024i1) {
|
||||
ofst = State.AllocateStack(128, 128);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(128, 128);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
if (LocVT == MVT::v32i64 || LocVT == MVT::v64i32 || LocVT == MVT::v128i16 ||
|
||||
LocVT == MVT::v256i8) {
|
||||
ofst = State.AllocateStack(256, 256);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, ofst, LocVT, LocInfo));
|
||||
Offset = State.AllocateStack(256, 256);
|
||||
State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -266,7 +266,7 @@ static bool CC_Hexagon (unsigned ValNo, MVT ValVT, MVT LocVT,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsHvxVectorType(LocVT)) {
|
||||
if (isHvxVectorType(LocVT)) {
|
||||
if (!CC_HexagonVector(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))
|
||||
return false;
|
||||
}
|
||||
@ -322,18 +322,16 @@ static bool CC_HexagonVector(unsigned ValNo, MVT ValVT,
|
||||
MVT LocVT, CCValAssign::LocInfo LocInfo,
|
||||
ISD::ArgFlagsTy ArgFlags, CCState &State) {
|
||||
|
||||
static const MCPhysReg VecLstS[] = { Hexagon::V0, Hexagon::V1,
|
||||
Hexagon::V2, Hexagon::V3,
|
||||
Hexagon::V4, Hexagon::V5,
|
||||
Hexagon::V6, Hexagon::V7,
|
||||
Hexagon::V8, Hexagon::V9,
|
||||
Hexagon::V10, Hexagon::V11,
|
||||
Hexagon::V12, Hexagon::V13,
|
||||
Hexagon::V14, Hexagon::V15};
|
||||
static const MCPhysReg VecLstD[] = { Hexagon::W0, Hexagon::W1,
|
||||
Hexagon::W2, Hexagon::W3,
|
||||
Hexagon::W4, Hexagon::W5,
|
||||
Hexagon::W6, Hexagon::W7};
|
||||
static const MCPhysReg VecLstS[] = {
|
||||
Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4,
|
||||
Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9,
|
||||
Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
|
||||
Hexagon::V15
|
||||
};
|
||||
static const MCPhysReg VecLstD[] = {
|
||||
Hexagon::W0, Hexagon::W1, Hexagon::W2, Hexagon::W3, Hexagon::W4,
|
||||
Hexagon::W5, Hexagon::W6, Hexagon::W7
|
||||
};
|
||||
auto &MF = State.getMachineFunction();
|
||||
auto &HST = MF.getSubtarget<HexagonSubtarget>();
|
||||
bool UseHVX = HST.useHVXOps();
|
||||
@ -543,7 +541,6 @@ const {
|
||||
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst,
|
||||
SDValue Chain, ISD::ArgFlagsTy Flags,
|
||||
SelectionDAG &DAG, const SDLoc &dl) {
|
||||
|
||||
SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i32);
|
||||
return DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(),
|
||||
/*isVolatile=*/false, /*AlwaysInline=*/false,
|
||||
@ -551,14 +548,26 @@ static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst,
|
||||
MachinePointerInfo(), MachinePointerInfo());
|
||||
}
|
||||
|
||||
static bool IsHvxVectorType(MVT ty) {
|
||||
return (ty == MVT::v8i64 || ty == MVT::v16i32 || ty == MVT::v32i16 ||
|
||||
ty == MVT::v64i8 ||
|
||||
ty == MVT::v16i64 || ty == MVT::v32i32 || ty == MVT::v64i16 ||
|
||||
ty == MVT::v128i8 ||
|
||||
ty == MVT::v32i64 || ty == MVT::v64i32 || ty == MVT::v128i16 ||
|
||||
ty == MVT::v256i8 ||
|
||||
ty == MVT::v512i1 || ty == MVT::v1024i1);
|
||||
static bool isHvxVectorType(MVT Ty) {
|
||||
switch (Ty.SimpleTy) {
|
||||
case MVT::v8i64:
|
||||
case MVT::v16i32:
|
||||
case MVT::v32i16:
|
||||
case MVT::v64i8:
|
||||
case MVT::v16i64:
|
||||
case MVT::v32i32:
|
||||
case MVT::v64i16:
|
||||
case MVT::v128i8:
|
||||
case MVT::v32i64:
|
||||
case MVT::v64i32:
|
||||
case MVT::v128i16:
|
||||
case MVT::v256i8:
|
||||
case MVT::v512i1:
|
||||
case MVT::v1024i1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// LowerReturn - Lower ISD::RET. If a struct is larger than 8 bytes and is
|
||||
@ -675,17 +684,17 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
|
||||
SDValue Chain = CLI.Chain;
|
||||
SDValue Callee = CLI.Callee;
|
||||
bool &isTailCall = CLI.IsTailCall;
|
||||
bool &IsTailCall = CLI.IsTailCall;
|
||||
CallingConv::ID CallConv = CLI.CallConv;
|
||||
bool isVarArg = CLI.IsVarArg;
|
||||
bool doesNotReturn = CLI.DoesNotReturn;
|
||||
bool IsVarArg = CLI.IsVarArg;
|
||||
bool DoesNotReturn = CLI.DoesNotReturn;
|
||||
|
||||
bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
auto PtrVT = getPointerTy(MF.getDataLayout());
|
||||
|
||||
// Check for varargs.
|
||||
int NumNamedVarArgParams = -1;
|
||||
unsigned NumNamedVarArgParams = -1U;
|
||||
if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Callee)) {
|
||||
const GlobalValue *GV = GAN->getGlobal();
|
||||
Callee = DAG.getTargetGlobalAddress(GV, dl, MVT::i32);
|
||||
@ -700,32 +709,32 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
|
||||
// Analyze operands of the call, assigning locations to each operand.
|
||||
SmallVector<CCValAssign, 16> ArgLocs;
|
||||
HexagonCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
|
||||
HexagonCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
|
||||
*DAG.getContext(), NumNamedVarArgParams);
|
||||
|
||||
if (isVarArg)
|
||||
if (IsVarArg)
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_VarArg);
|
||||
else
|
||||
CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon);
|
||||
|
||||
auto Attr = MF.getFunction()->getFnAttribute("disable-tail-calls");
|
||||
if (Attr.getValueAsString() == "true")
|
||||
isTailCall = false;
|
||||
IsTailCall = false;
|
||||
|
||||
if (isTailCall) {
|
||||
if (IsTailCall) {
|
||||
bool StructAttrFlag = MF.getFunction()->hasStructRetAttr();
|
||||
isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
|
||||
isVarArg, IsStructRet,
|
||||
IsTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
|
||||
IsVarArg, IsStructRet,
|
||||
StructAttrFlag,
|
||||
Outs, OutVals, Ins, DAG);
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
CCValAssign &VA = ArgLocs[i];
|
||||
if (VA.isMemLoc()) {
|
||||
isTailCall = false;
|
||||
IsTailCall = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUG(dbgs() << (isTailCall ? "Eligible for Tail Call\n"
|
||||
DEBUG(dbgs() << (IsTailCall ? "Eligible for Tail Call\n"
|
||||
: "Argument must be passed on stack. "
|
||||
"Not eligible for Tail Call\n"));
|
||||
}
|
||||
@ -746,7 +755,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
SDValue Arg = OutVals[i];
|
||||
ISD::ArgFlagsTy Flags = Outs[i].Flags;
|
||||
// Record if we need > 8 byte alignment on an argument.
|
||||
bool ArgAlign = IsHvxVectorType(VA.getValVT());
|
||||
bool ArgAlign = isHvxVectorType(VA.getValVT());
|
||||
NeedsArgAlign |= ArgAlign;
|
||||
|
||||
// Promote the value if needed.
|
||||
@ -812,21 +821,21 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
if (!MemOpChains.empty())
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
|
||||
|
||||
if (!isTailCall) {
|
||||
if (!IsTailCall) {
|
||||
SDValue C = DAG.getConstant(NumBytes, dl, PtrVT, true);
|
||||
Chain = DAG.getCALLSEQ_START(Chain, C, dl);
|
||||
}
|
||||
|
||||
// Build a sequence of copy-to-reg nodes chained together with token
|
||||
// chain and flag operands which copy the outgoing args into registers.
|
||||
// The InFlag in necessary since all emitted instructions must be
|
||||
// The Glue is necessary since all emitted instructions must be
|
||||
// stuck together.
|
||||
SDValue InFlag;
|
||||
if (!isTailCall) {
|
||||
SDValue Glue;
|
||||
if (!IsTailCall) {
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
RegsToPass[i].second, Glue);
|
||||
Glue = Chain.getValue(1);
|
||||
}
|
||||
} else {
|
||||
// For tail calls lower the arguments to the 'real' stack slot.
|
||||
@ -839,13 +848,13 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
// on every argument instead of just those arguments it would clobber.
|
||||
//
|
||||
// Do not flag preceding copytoreg stuff together with the following stuff.
|
||||
InFlag = SDValue();
|
||||
Glue = SDValue();
|
||||
for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
|
||||
Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
|
||||
RegsToPass[i].second, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
RegsToPass[i].second, Glue);
|
||||
Glue = Chain.getValue(1);
|
||||
}
|
||||
InFlag = SDValue();
|
||||
Glue = SDValue();
|
||||
}
|
||||
|
||||
bool LongCalls = MF.getSubtarget<HexagonSubtarget>().useLongCalls();
|
||||
@ -874,33 +883,32 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
RegsToPass[i].second.getValueType()));
|
||||
}
|
||||
|
||||
if (InFlag.getNode())
|
||||
Ops.push_back(InFlag);
|
||||
if (Glue.getNode())
|
||||
Ops.push_back(Glue);
|
||||
|
||||
if (isTailCall) {
|
||||
if (IsTailCall) {
|
||||
MF.getFrameInfo().setHasTailCall();
|
||||
return DAG.getNode(HexagonISD::TC_RETURN, dl, NodeTys, Ops);
|
||||
}
|
||||
|
||||
int OpCode = doesNotReturn ? HexagonISD::CALLv3nr : HexagonISD::CALLv3;
|
||||
unsigned OpCode = DoesNotReturn ? HexagonISD::CALLv3nr : HexagonISD::CALLv3;
|
||||
Chain = DAG.getNode(OpCode, dl, NodeTys, Ops);
|
||||
InFlag = Chain.getValue(1);
|
||||
Glue = Chain.getValue(1);
|
||||
|
||||
// Create the CALLSEQ_END node.
|
||||
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, dl, true),
|
||||
DAG.getIntPtrConstant(0, dl, true), InFlag, dl);
|
||||
InFlag = Chain.getValue(1);
|
||||
DAG.getIntPtrConstant(0, dl, true), Glue, dl);
|
||||
Glue = Chain.getValue(1);
|
||||
|
||||
// Handle result values, copying them out of physregs into vregs that we
|
||||
// return.
|
||||
return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, DAG,
|
||||
return LowerCallResult(Chain, Glue, CallConv, IsVarArg, Ins, dl, DAG,
|
||||
InVals, OutVals, Callee);
|
||||
}
|
||||
|
||||
static bool getIndexedAddressParts(SDNode *Ptr, EVT VT,
|
||||
bool isSEXTLoad, SDValue &Base,
|
||||
SDValue &Offset, bool &isInc,
|
||||
SelectionDAG &DAG) {
|
||||
SDValue &Base, SDValue &Offset,
|
||||
bool &IsInc, SelectionDAG &DAG) {
|
||||
if (Ptr->getOpcode() != ISD::ADD)
|
||||
return false;
|
||||
|
||||
@ -917,11 +925,11 @@ static bool getIndexedAddressParts(SDNode *Ptr, EVT VT,
|
||||
|
||||
if (ValidHVXDblType || ValidHVXType ||
|
||||
VT == MVT::i64 || VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) {
|
||||
isInc = (Ptr->getOpcode() == ISD::ADD);
|
||||
IsInc = (Ptr->getOpcode() == ISD::ADD);
|
||||
Base = Ptr->getOperand(0);
|
||||
Offset = Ptr->getOperand(1);
|
||||
// Ensure that Offset is a constant.
|
||||
return (isa<ConstantSDNode>(Offset));
|
||||
return isa<ConstantSDNode>(Offset);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -938,28 +946,24 @@ bool HexagonTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
|
||||
{
|
||||
EVT VT;
|
||||
SDValue Ptr;
|
||||
bool isSEXTLoad = false;
|
||||
|
||||
if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
|
||||
VT = LD->getMemoryVT();
|
||||
isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
|
||||
} else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
|
||||
VT = ST->getMemoryVT();
|
||||
if (ST->getValue().getValueType() == MVT::i64 && ST->isTruncatingStore()) {
|
||||
if (ST->getValue().getValueType() == MVT::i64 && ST->isTruncatingStore())
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isInc = false;
|
||||
bool isLegal = getIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
|
||||
isInc, DAG);
|
||||
bool IsInc = false;
|
||||
bool isLegal = getIndexedAddressParts(Op, VT, Base, Offset, IsInc, DAG);
|
||||
if (isLegal) {
|
||||
auto &HII = *Subtarget.getInstrInfo();
|
||||
int32_t OffsetVal = cast<ConstantSDNode>(Offset.getNode())->getSExtValue();
|
||||
if (HII.isValidAutoIncImm(VT, OffsetVal)) {
|
||||
AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
|
||||
AM = IsInc ? ISD::POST_INC : ISD::POST_DEC;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2283,7 +2287,6 @@ bool HexagonTargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
|
||||
bool
|
||||
HexagonTargetLowering::shouldExpandBuildVectorWithShuffles(EVT VT,
|
||||
unsigned DefinedValues) const {
|
||||
|
||||
// Hexagon vector shuffle operates on element sizes of bytes or halfwords
|
||||
EVT EltVT = VT.getVectorElementType();
|
||||
int EltBits = EltVT.getSizeInBits();
|
||||
@ -2346,11 +2349,12 @@ HexagonTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG)
|
||||
if (Lane == 0 && V1.getOpcode() == ISD::BUILD_VECTOR &&
|
||||
!isa<ConstantSDNode>(V1.getOperand(0))) {
|
||||
bool IsScalarToVector = true;
|
||||
for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i)
|
||||
for (unsigned i = 1, e = V1.getNumOperands(); i != e; ++i) {
|
||||
if (!V1.getOperand(i).isUndef()) {
|
||||
IsScalarToVector = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsScalarToVector)
|
||||
return createSplat(DAG, dl, VT, V1.getOperand(0));
|
||||
}
|
||||
@ -2716,7 +2720,7 @@ HexagonTargetLowering::LowerEXTRACT_VECTOR(SDValue Op,
|
||||
// If we are dealing with EXTRACT_SUBVECTOR on a HVX type, we may
|
||||
// be able to simplify it to an EXTRACT_SUBREG.
|
||||
if (Op.getOpcode() == ISD::EXTRACT_SUBVECTOR && Subtarget.useHVXOps() &&
|
||||
IsHvxVectorType(Op.getValueType().getSimpleVT()))
|
||||
isHvxVectorType(Op.getValueType().getSimpleVT()))
|
||||
return LowerEXTRACT_SUBVECTOR_HVX(Op, DAG);
|
||||
|
||||
EVT VT = Op.getValueType();
|
||||
@ -3060,7 +3064,8 @@ bool HexagonTargetLowering::isLegalAddressingMode(const DataLayout &DL,
|
||||
return false;
|
||||
|
||||
int Scale = AM.Scale;
|
||||
if (Scale < 0) Scale = -Scale;
|
||||
if (Scale < 0)
|
||||
Scale = -Scale;
|
||||
switch (Scale) {
|
||||
case 0: // No scale reg, "r+i", "r", or just "i".
|
||||
break;
|
||||
@ -3109,8 +3114,8 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
|
||||
// ***************************************************************************
|
||||
|
||||
// If this is a tail call via a function pointer, then don't do it!
|
||||
if (!(isa<GlobalAddressSDNode>(Callee)) &&
|
||||
!(isa<ExternalSymbolSDNode>(Callee))) {
|
||||
if (!isa<GlobalAddressSDNode>(Callee) &&
|
||||
!isa<ExternalSymbolSDNode>(Callee)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user