summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelLowering.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.cpp158
1 files changed, 64 insertions, 94 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index 63900e02042..0a17abc6f64 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -420,6 +420,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
bool doesNotReturn = CLI.DoesNotReturn;
bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet();
+ MachineFunction &MF = DAG.getMachineFunction();
// Check for varargs.
int NumNamedVarArgParams = -1;
@@ -444,41 +445,40 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
HexagonCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
*DAG.getContext(), NumNamedVarArgParams);
- if (NumNamedVarArgParams > 0)
+ if (isVarArg)
CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_VarArg);
else
CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon);
+ if (DAG.getTarget().Options.DisableTailCalls)
+ isTailCall = false;
- if(isTailCall) {
- bool StructAttrFlag =
- DAG.getMachineFunction().getFunction()->hasStructRetAttr();
+ if (isTailCall) {
+ bool StructAttrFlag = MF.getFunction()->hasStructRetAttr();
isTailCall = IsEligibleForTailCallOptimization(Callee, CallConv,
isVarArg, IsStructRet,
StructAttrFlag,
Outs, OutVals, Ins, DAG);
- for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i){
+ for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
CCValAssign &VA = ArgLocs[i];
if (VA.isMemLoc()) {
isTailCall = false;
break;
}
}
- if (isTailCall) {
- DEBUG(dbgs () << "Eligible for Tail Call\n");
- } else {
- DEBUG(dbgs () <<
- "Argument must be passed on stack. Not 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"));
}
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = CCInfo.getNextStackOffset();
SmallVector<std::pair<unsigned, SDValue>, 16> RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
- const HexagonRegisterInfo *QRI = Subtarget->getRegisterInfo();
- SDValue StackPtr =
- DAG.getCopyFromReg(Chain, dl, QRI->getStackRegister(), getPointerTy());
+ auto &HRI =
+ static_cast<const HexagonRegisterInfo&>(*Subtarget->getRegisterInfo());
+ SDValue StackPtr = DAG.getCopyFromReg(Chain, dl, HRI.getStackRegister(),
+ getPointerTy());
// Walk the register/memloc assignments, inserting copies/loads.
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@@ -491,6 +491,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
default:
// Loc info must be one of Full, SExt, ZExt, or AExt.
llvm_unreachable("Unknown loc info!");
+ case CCValAssign::BCvt:
case CCValAssign::Full:
break;
case CCValAssign::SExt:
@@ -506,41 +507,37 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (VA.isMemLoc()) {
unsigned LocMemOffset = VA.getLocMemOffset();
- SDValue PtrOff = DAG.getConstant(LocMemOffset, StackPtr.getValueType());
- PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, PtrOff);
-
+ SDValue MemAddr = DAG.getConstant(LocMemOffset, StackPtr.getValueType());
+ MemAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr, MemAddr);
if (Flags.isByVal()) {
// The argument is a struct passed by value. According to LLVM, "Arg"
// is is pointer.
- MemOpChains.push_back(CreateCopyOfByValArgument(Arg, PtrOff, Chain,
+ MemOpChains.push_back(CreateCopyOfByValArgument(Arg, MemAddr, Chain,
Flags, DAG, dl));
} else {
- // The argument is not passed by value. "Arg" is a buildin type. It is
- // not a pointer.
- MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
- MachinePointerInfo(),false, false,
- 0));
+ MachinePointerInfo LocPI = MachinePointerInfo::getStack(LocMemOffset);
+ SDValue S = DAG.getStore(Chain, dl, Arg, MemAddr, LocPI, false,
+ false, 0);
+ MemOpChains.push_back(S);
}
continue;
}
// Arguments that can be passed on register must be kept at RegsToPass
// vector.
- if (VA.isRegLoc()) {
+ if (VA.isRegLoc())
RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
- }
}
// Transform all store nodes into one single node because all store
// nodes are independent of each other.
- if (!MemOpChains.empty()) {
+ if (!MemOpChains.empty())
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
- }
- if (!isTailCall)
- Chain = DAG.getCALLSEQ_START(Chain, DAG.getConstant(NumBytes,
- getPointerTy(), true),
- dl);
+ if (!isTailCall) {
+ SDValue C = DAG.getConstant(NumBytes, getPointerTy(), 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.
@@ -553,10 +550,9 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
RegsToPass[i].second, InFlag);
InFlag = Chain.getValue(1);
}
- }
-
- // For tail calls lower the arguments to the 'real' stack slot.
- if (isTailCall) {
+ } else {
+ // For tail calls lower the arguments to the 'real' stack slot.
+ //
// Force all the incoming stack arguments to be loaded from the stack
// before any new outgoing arguments are stored to the stack, because the
// outgoing stack slots may alias the incoming argument stack slots, and
@@ -571,7 +567,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
RegsToPass[i].second, InFlag);
InFlag = Chain.getValue(1);
}
- InFlag =SDValue();
+ InFlag = SDValue();
}
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
@@ -580,8 +576,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
if (flag_aligned_memcpy) {
const char *MemcpyName =
"__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes";
- Callee =
- DAG.getTargetExternalSymbol(MemcpyName, getPointerTy());
+ Callee = DAG.getTargetExternalSymbol(MemcpyName, getPointerTy());
flag_aligned_memcpy = false;
} else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, getPointerTy());
@@ -603,9 +598,8 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
RegsToPass[i].second.getValueType()));
}
- if (InFlag.getNode()) {
+ if (InFlag.getNode())
Ops.push_back(InFlag);
- }
if (isTailCall)
return DAG.getNode(HexagonISD::TC_RETURN, dl, NodeTys, Ops);
@@ -630,7 +624,7 @@ static bool getIndexedAddressParts(SDNode *Ptr, EVT VT,
SDValue &Offset, bool &isInc,
SelectionDAG &DAG) {
if (Ptr->getOpcode() != ISD::ADD)
- return false;
+ return false;
if (VT == MVT::i64 || VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8) {
isInc = (Ptr->getOpcode() == ISD::ADD);
@@ -702,8 +696,7 @@ SDValue HexagonTargetLowering::LowerINLINEASM(SDValue Op,
SelectionDAG &DAG) const {
SDNode *Node = Op.getNode();
MachineFunction &MF = DAG.getMachineFunction();
- HexagonMachineFunctionInfo *FuncInfo =
- MF.getInfo<HexagonMachineFunctionInfo>();
+ auto &FuncInfo = *MF.getInfo<HexagonMachineFunctionInfo>();
switch (Node->getOpcode()) {
case ISD::INLINEASM: {
unsigned NumOps = Node->getNumOperands();
@@ -711,7 +704,7 @@ SDValue HexagonTargetLowering::LowerINLINEASM(SDValue Op,
--NumOps; // Ignore the flag operand.
for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
- if (FuncInfo->hasClobberLR())
+ if (FuncInfo.hasClobberLR())
break;
unsigned Flags =
cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
@@ -736,7 +729,7 @@ SDValue HexagonTargetLowering::LowerINLINEASM(SDValue Op,
// Check it to be lr
const HexagonRegisterInfo *QRI = Subtarget->getRegisterInfo();
if (Reg == QRI->getRARegister()) {
- FuncInfo->setHasClobberLR(true);
+ FuncInfo.setHasClobberLR(true);
break;
}
}
@@ -795,43 +788,28 @@ HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
SDValue Size = Op.getOperand(1);
+ SDValue Align = Op.getOperand(2);
SDLoc dl(Op);
- unsigned SPReg = getStackPointerRegisterToSaveRestore();
-
- // Get a reference to the stack pointer.
- SDValue StackPointer = DAG.getCopyFromReg(Chain, dl, SPReg, MVT::i32);
-
- // Subtract the dynamic size from the actual stack size to
- // obtain the new stack size.
- SDValue Sub = DAG.getNode(ISD::SUB, dl, MVT::i32, StackPointer, Size);
-
- //
- // For Hexagon, the outgoing memory arguments area should be on top of the
- // alloca area on the stack i.e., the outgoing memory arguments should be
- // at a lower address than the alloca area. Move the alloca area down the
- // stack by adding back the space reserved for outgoing arguments to SP
- // here.
- //
- // We do not know what the size of the outgoing args is at this point.
- // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
- // stack pointer. We patch this instruction with the correct, known
- // offset in emitPrologue().
- //
- // Use a placeholder immediate (zero) for now. This will be patched up
- // by emitPrologue().
- SDValue ArgAdjust = DAG.getNode(HexagonISD::ADJDYNALLOC, dl,
- MVT::i32,
- Sub,
- DAG.getConstant(0, MVT::i32));
-
- // The Sub result contains the new stack start address, so it
- // must be placed in the stack pointer register.
- const HexagonRegisterInfo *QRI = Subtarget->getRegisterInfo();
- SDValue CopyChain = DAG.getCopyToReg(Chain, dl, QRI->getStackRegister(), Sub);
-
- SDValue Ops[2] = { ArgAdjust, CopyChain };
- return DAG.getMergeValues(Ops, dl);
+ ConstantSDNode *AlignConst = dyn_cast<ConstantSDNode>(Align);
+ assert(AlignConst && "Non-constant Align in LowerDYNAMIC_STACKALLOC");
+
+ unsigned A = AlignConst->getSExtValue();
+ auto &HST = static_cast<const HexagonSubtarget&>(DAG.getSubtarget());
+ auto &HFI = *HST.getFrameLowering();
+ // "Zero" means natural stack alignment.
+ if (A == 0)
+ A = HFI.getStackAlignment();
+
+ DEBUG({
+ dbgs () << __func__ << " Align: " << A << " Size: ";
+ Size.getNode()->dump(&DAG);
+ dbgs() << "\n";
+ });
+
+ SDValue AC = DAG.getConstant(A, MVT::i32);
+ SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
+ return DAG.getNode(HexagonISD::ALLOCA, dl, VTs, Chain, Size, AC);
}
SDValue
@@ -847,9 +825,7 @@ const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineRegisterInfo &RegInfo = MF.getRegInfo();
- HexagonMachineFunctionInfo *FuncInfo =
- MF.getInfo<HexagonMachineFunctionInfo>();
-
+ auto &FuncInfo = *MF.getInfo<HexagonMachineFunctionInfo>();
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
@@ -938,7 +914,7 @@ const {
HEXAGON_LRFP_SIZE +
CCInfo.getNextStackOffset(),
true);
- FuncInfo->setVarArgsFrameIndex(FrameIndex);
+ FuncInfo.setVarArgsFrameIndex(FrameIndex);
}
return Chain;
@@ -1795,7 +1771,7 @@ HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
case HexagonISD::CONST32: return "HexagonISD::CONST32";
case HexagonISD::CONST32_GP: return "HexagonISD::CONST32_GP";
case HexagonISD::CONST32_Int_Real: return "HexagonISD::CONST32_Int_Real";
- case HexagonISD::ADJDYNALLOC: return "HexagonISD::ADJDYNALLOC";
+ case HexagonISD::ALLOCA: return "HexagonISD::ALLOCA";
case HexagonISD::CMPICC: return "HexagonISD::CMPICC";
case HexagonISD::CMPFCC: return "HexagonISD::CMPFCC";
case HexagonISD::BRICC: return "HexagonISD::BRICC";
@@ -2419,20 +2395,14 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
}
}
-
-
-//===----------------------------------------------------------------------===//
-// Hexagon Scheduler Hooks
-//===----------------------------------------------------------------------===//
MachineBasicBlock *
HexagonTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB)
-const {
+ const {
switch (MI->getOpcode()) {
- case Hexagon::ADJDYNALLOC: {
+ case Hexagon::ALLOCA: {
MachineFunction *MF = BB->getParent();
- HexagonMachineFunctionInfo *FuncInfo =
- MF->getInfo<HexagonMachineFunctionInfo>();
+ auto *FuncInfo = MF->getInfo<HexagonMachineFunctionInfo>();
FuncInfo->addAllocaAdjustInst(MI);
return BB;
}
OpenPOWER on IntegriCloud