[llvm] r256025 - [Hexagon] Add PIC support
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 18 12:19:31 PST 2015
Author: kparzysz
Date: Fri Dec 18 14:19:30 2015
New Revision: 256025
URL: http://llvm.org/viewvc/llvm-project?rev=256025&view=rev
Log:
[Hexagon] Add PIC support
Added:
llvm/trunk/test/CodeGen/Hexagon/pic-jumptables.ll
llvm/trunk/test/CodeGen/Hexagon/pic-simple.ll
llvm/trunk/test/CodeGen/Hexagon/pic-static.ll
llvm/trunk/test/MC/Hexagon/got.s
llvm/trunk/test/MC/Hexagon/pcrel.s
Modified:
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td
llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td
llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp
llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.h
llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Fri Dec 18 14:19:30 2015
@@ -41,8 +41,8 @@ using namespace llvm;
#define DEBUG_TYPE "hexagon-lowering"
-static cl::opt<bool>
-EmitJumpTables("hexagon-emit-jump-tables", cl::init(true), cl::Hidden,
+static cl::opt<bool> EmitJumpTables("hexagon-emit-jump-tables",
+ cl::init(true), cl::Hidden,
cl::desc("Control jump table emission on Hexagon target"));
static cl::opt<bool> EnableHexSDNodeSched("enable-hexagon-sdnode-sched",
@@ -505,6 +505,18 @@ static bool RetCC_HexagonVector(unsigned
return false;
}
+void HexagonTargetLowering::promoteLdStType(EVT VT, EVT PromotedLdStVT) {
+ if (VT != PromotedLdStVT) {
+ setOperationAction(ISD::LOAD, VT.getSimpleVT(), Promote);
+ AddPromotedToType(ISD::LOAD, VT.getSimpleVT(),
+ PromotedLdStVT.getSimpleVT());
+
+ setOperationAction(ISD::STORE, VT.getSimpleVT(), Promote);
+ AddPromotedToType(ISD::STORE, VT.getSimpleVT(),
+ PromotedLdStVT.getSimpleVT());
+ }
+}
+
SDValue
HexagonTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG)
const {
@@ -649,19 +661,15 @@ HexagonTargetLowering::LowerCall(TargetL
// Check for varargs.
int NumNamedVarArgParams = -1;
- if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Callee))
- {
- const Function* CalleeFn = nullptr;
- Callee = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, MVT::i32);
- if ((CalleeFn = dyn_cast<Function>(GA->getGlobal())))
- {
+ if (GlobalAddressSDNode *GAN = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ const GlobalValue *GV = GAN->getGlobal();
+ Callee = DAG.getTargetGlobalAddress(GV, dl, MVT::i32);
+ if (const Function* F = dyn_cast<Function>(GV)) {
// If a function has zero args and is a vararg function, that's
// disallowed so it must be an undeclared function. Do not assume
// varargs if the callee is undefined.
- if (CalleeFn->isVarArg() &&
- CalleeFn->getFunctionType()->getNumParams() != 0) {
- NumNamedVarArgParams = CalleeFn->getFunctionType()->getNumParams();
- }
+ if (F->isVarArg() && F->getFunctionType()->getNumParams() != 0)
+ NumNamedVarArgParams = F->getFunctionType()->getNumParams();
}
}
@@ -932,8 +940,8 @@ bool HexagonTargetLowering::getPostIndex
return false;
}
-SDValue HexagonTargetLowering::LowerINLINEASM(SDValue Op,
- SelectionDAG &DAG) const {
+SDValue
+HexagonTargetLowering::LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const {
SDNode *Node = Op.getNode();
MachineFunction &MF = DAG.getMachineFunction();
auto &FuncInfo = *MF.getInfo<HexagonMachineFunctionInfo>();
@@ -982,47 +990,6 @@ SDValue HexagonTargetLowering::LowerINLI
return Op;
}
-
-//
-// Taken from the XCore backend.
-//
-SDValue HexagonTargetLowering::
-LowerBR_JT(SDValue Op, SelectionDAG &DAG) const
-{
- SDValue Chain = Op.getOperand(0);
- SDValue Table = Op.getOperand(1);
- SDValue Index = Op.getOperand(2);
- SDLoc dl(Op);
- JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
- unsigned JTI = JT->getIndex();
- MachineFunction &MF = DAG.getMachineFunction();
- const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
- SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
-
- // Mark all jump table targets as address taken.
- const std::vector<MachineJumpTableEntry> &JTE = MJTI->getJumpTables();
- const std::vector<MachineBasicBlock*> &JTBBs = JTE[JTI].MBBs;
- for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
- MachineBasicBlock *MBB = JTBBs[i];
- MBB->setHasAddressTaken();
- // This line is needed to set the hasAddressTaken flag on the BasicBlock
- // object.
- BlockAddress::get(const_cast<BasicBlock *>(MBB->getBasicBlock()));
- }
-
- SDValue JumpTableBase = DAG.getNode(
- HexagonISD::JT, dl, getPointerTy(DAG.getDataLayout()), TargetJT);
- SDValue ShiftIndex = DAG.getNode(ISD::SHL, dl, MVT::i32, Index,
- DAG.getConstant(2, dl, MVT::i32));
- SDValue JTAddress = DAG.getNode(ISD::ADD, dl, MVT::i32, JumpTableBase,
- ShiftIndex);
- SDValue LoadTarget = DAG.getLoad(MVT::i32, dl, Chain, JTAddress,
- MachinePointerInfo(), false, false, false,
- 0);
- return DAG.getNode(HexagonISD::BR_JT, dl, MVT::Other, Chain, LoadTarget);
-}
-
-
SDValue
HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SelectionDAG &DAG) const {
@@ -1294,8 +1261,8 @@ SDValue HexagonTargetLowering::LowerSETC
return SDValue();
}
-SDValue HexagonTargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG)
- const {
+SDValue
+HexagonTargetLowering::LowerVSELECT(SDValue Op, SelectionDAG &DAG) const {
SDValue PredOp = Op.getOperand(0);
SDValue Op1 = Op.getOperand(1), Op2 = Op.getOperand(2);
EVT OpVT = Op1.getValueType();
@@ -1401,16 +1368,33 @@ SDValue HexagonTargetLowering::LowerLOAD
SDValue
HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
EVT ValTy = Op.getValueType();
- SDLoc dl(Op);
- ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
- SDValue Res;
- if (CP->isMachineConstantPoolEntry())
- Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), ValTy,
- CP->getAlignment());
+ ConstantPoolSDNode *CPN = cast<ConstantPoolSDNode>(Op);
+ unsigned Align = CPN->getAlignment();
+ Reloc::Model RM = HTM.getRelocationModel();
+ unsigned char TF = (RM == Reloc::PIC_) ? HexagonII::MO_PCREL : 0;
+
+ SDValue T;
+ if (CPN->isMachineConstantPoolEntry())
+ T = DAG.getTargetConstantPool(CPN->getMachineCPVal(), ValTy, Align, TF);
else
- Res = DAG.getTargetConstantPool(CP->getConstVal(), ValTy,
- CP->getAlignment());
- return DAG.getNode(HexagonISD::CP, dl, ValTy, Res);
+ T = DAG.getTargetConstantPool(CPN->getConstVal(), ValTy, Align, TF);
+ if (RM == Reloc::PIC_)
+ return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), ValTy, T);
+ return DAG.getNode(HexagonISD::CP, SDLoc(Op), ValTy, T);
+}
+
+SDValue
+HexagonTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
+ EVT VT = Op.getValueType();
+ int Idx = cast<JumpTableSDNode>(Op)->getIndex();
+ Reloc::Model RM = HTM.getRelocationModel();
+ if (RM == Reloc::PIC_) {
+ SDValue T = DAG.getTargetJumpTable(Idx, VT, HexagonII::MO_PCREL);
+ return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), VT, T);
+ }
+
+ SDValue T = DAG.getTargetJumpTable(Idx, VT);
+ return DAG.getNode(HexagonISD::JT, SDLoc(Op), VT, T);
}
SDValue
@@ -1457,52 +1441,70 @@ HexagonTargetLowering::LowerFRAMEADDR(SD
return FrameAddr;
}
-SDValue HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op,
- SelectionDAG& DAG) const {
+SDValue
+HexagonTargetLowering::LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const {
SDLoc dl(Op);
return DAG.getNode(HexagonISD::BARRIER, dl, MVT::Other, Op.getOperand(0));
}
-SDValue HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op,
- SelectionDAG &DAG) const {
- SDValue Result;
- const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
- int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
+SDValue
+HexagonTargetLowering::LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const {
SDLoc dl(Op);
+ auto *GAN = cast<GlobalAddressSDNode>(Op);
auto PtrVT = getPointerTy(DAG.getDataLayout());
- Result = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset);
+ auto *GV = GAN->getGlobal();
+ int64_t Offset = GAN->getOffset();
- const HexagonTargetObjectFile *TLOF =
- static_cast<const HexagonTargetObjectFile *>(
- getTargetMachine().getObjFileLowering());
- if (TLOF->IsGlobalInSmallSection(GV, getTargetMachine())) {
- return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, Result);
- }
+ auto &HLOF = *HTM.getObjFileLowering();
+ Reloc::Model RM = HTM.getRelocationModel();
- return DAG.getNode(HexagonISD::CONST32, dl, PtrVT, Result);
+ if (RM == Reloc::Static) {
+ SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset);
+ if (HLOF.IsGlobalInSmallSection(GV, HTM))
+ return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, GA);
+ return DAG.getNode(HexagonISD::CONST32, dl, PtrVT, GA);
+ }
+
+ bool UsePCRel = GV->hasInternalLinkage() || GV->hasHiddenVisibility() ||
+ (GV->hasLocalLinkage() && !isa<Function>(GV));
+ if (UsePCRel) {
+ SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, Offset,
+ HexagonII::MO_PCREL);
+ return DAG.getNode(HexagonISD::AT_PCREL, dl, PtrVT, GA);
+ }
+
+ // Use GOT index.
+ SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT);
+ SDValue GA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, HexagonII::MO_GOT);
+ SDValue Off = DAG.getConstant(Offset, dl, MVT::i32);
+ return DAG.getNode(HexagonISD::AT_GOT, dl, PtrVT, GOT, GA, Off);
}
// Specifies that for loads and stores VT can be promoted to PromotedLdStVT.
-void HexagonTargetLowering::promoteLdStType(EVT VT, EVT PromotedLdStVT) {
- if (VT != PromotedLdStVT) {
- setOperationAction(ISD::LOAD, VT.getSimpleVT(), Promote);
- AddPromotedToType(ISD::LOAD, VT.getSimpleVT(),
- PromotedLdStVT.getSimpleVT());
+SDValue
+HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
+ const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
+ SDLoc dl(Op);
+ EVT PtrVT = getPointerTy(DAG.getDataLayout());
- setOperationAction(ISD::STORE, VT.getSimpleVT(), Promote);
- AddPromotedToType(ISD::STORE, VT.getSimpleVT(),
- PromotedLdStVT.getSimpleVT());
+ Reloc::Model RM = HTM.getRelocationModel();
+ if (RM == Reloc::Static) {
+ SDValue A = DAG.getTargetBlockAddress(BA, PtrVT);
+ return DAG.getNode(HexagonISD::CONST32_GP, dl, PtrVT, A);
}
+
+ SDValue A = DAG.getTargetBlockAddress(BA, PtrVT, 0, HexagonII::MO_PCREL);
+ return DAG.getNode(HexagonISD::AT_PCREL, dl, PtrVT, A);
}
SDValue
-HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
- const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
- SDValue BA_SD = DAG.getTargetBlockAddress(BA, MVT::i32);
- SDLoc dl(Op);
- return DAG.getNode(HexagonISD::CONST32_GP, dl,
- getPointerTy(DAG.getDataLayout()), BA_SD);
+HexagonTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG)
+ const {
+ EVT PtrVT = getPointerTy(DAG.getDataLayout());
+ SDValue GOTSym = DAG.getTargetExternalSymbol(HEXAGON_GOT_SYM_NAME, PtrVT,
+ HexagonII::MO_PCREL);
+ return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Op), PtrVT, GOTSym);
}
//===----------------------------------------------------------------------===//
@@ -1600,10 +1602,12 @@ HexagonTargetLowering::HexagonTargetLowe
setOperationAction(ISD::ConstantFP, MVT::f64, Legal); // Default: expand
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+ setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
setOperationAction(ISD::INLINEASM, MVT::Other, Custom);
setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);
+ setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
// Custom legalize GlobalAddress nodes into CONST32.
@@ -1625,11 +1629,10 @@ HexagonTargetLowering::HexagonTargetLowe
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
if (EmitJumpTables)
- setOperationAction(ISD::BR_JT, MVT::Other, Custom);
+ setMinimumJumpTableEntries(2);
else
- setOperationAction(ISD::BR_JT, MVT::Other, Expand);
- // Increase jump tables cutover to 5, was 4.
- setMinimumJumpTableEntries(MinimumJumpTables);
+ setMinimumJumpTableEntries(MinimumJumpTables);
+ setOperationAction(ISD::BR_JT, MVT::Other, Expand);
// Hexagon has instructions for add/sub with carry. The problem with
// modeling these instructions is that they produce 2 results: Rdd and Px.
@@ -2006,7 +2009,6 @@ const char* HexagonTargetLowering::getTa
case HexagonISD::AT_GOT: return "HexagonISD::AT_GOT";
case HexagonISD::AT_PCREL: return "HexagonISD::AT_PCREL";
case HexagonISD::BARRIER: return "HexagonISD::BARRIER";
- case HexagonISD::BR_JT: return "HexagonISD::BR_JT";
case HexagonISD::CALLR: return "HexagonISD::CALLR";
case HexagonISD::CALLv3nr: return "HexagonISD::CALLv3nr";
case HexagonISD::CALLv3: return "HexagonISD::CALLv3";
@@ -2023,7 +2025,6 @@ const char* HexagonTargetLowering::getTa
case HexagonISD::INSERTRP: return "HexagonISD::INSERTRP";
case HexagonISD::JT: return "HexagonISD::JT";
case HexagonISD::PACKHL: return "HexagonISD::PACKHL";
- case HexagonISD::PIC_ADD: return "HexagonISD::PIC_ADD";
case HexagonISD::POPCOUNT: return "HexagonISD::POPCOUNT";
case HexagonISD::RET_FLAG: return "HexagonISD::RET_FLAG";
case HexagonISD::SHUFFEB: return "HexagonISD::SHUFFEB";
@@ -2590,6 +2591,7 @@ HexagonTargetLowering::LowerOperation(SD
case ISD::SHL:
case ISD::SRL: return LowerVECTOR_SHIFT(Op, DAG);
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
+ case ISD::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
// Frame & Return address. Currently unimplemented.
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
@@ -2597,8 +2599,8 @@ HexagonTargetLowering::LowerOperation(SD
case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG);
case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG);
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);
- case ISD::BR_JT: return LowerBR_JT(Op, DAG);
// Custom lower some vector loads.
case ISD::LOAD: return LowerLOAD(Op, DAG);
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
@@ -2610,6 +2612,16 @@ HexagonTargetLowering::LowerOperation(SD
}
}
+/// Returns relocation base for the given PIC jumptable.
+SDValue
+HexagonTargetLowering::getPICJumpTableRelocBase(SDValue Table,
+ SelectionDAG &DAG) const {
+ int Idx = cast<JumpTableSDNode>(Table)->getIndex();
+ EVT VT = Table.getValueType();
+ SDValue T = DAG.getTargetJumpTable(Idx, VT, HexagonII::MO_PCREL);
+ return DAG.getNode(HexagonISD::AT_PCREL, SDLoc(Table), VT, T);
+}
+
MachineBasicBlock *
HexagonTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
MachineBasicBlock *BB)
@@ -2724,6 +2736,14 @@ bool HexagonTargetLowering::isLegalAddre
return true;
}
+/// Return true if folding a constant offset with the given GlobalAddress is
+/// legal. It is frequently not legal in PIC relocation models.
+bool HexagonTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA)
+ const {
+ return HTM.getRelocationModel() == Reloc::Static;
+}
+
+
/// isLegalICmpImmediate - Return true if the specified immediate is legal
/// icmp immediate, that is the target has icmp instructions which can compare
/// a register against the immediate without having to materialize the
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h Fri Dec 18 14:19:30 2015
@@ -35,16 +35,14 @@ bool isPositiveHalfWord(SDNode *N);
ALLOCA,
ARGEXTEND,
- PIC_ADD,
- AT_GOT,
- AT_PCREL,
+ AT_GOT, // Index in GOT.
+ AT_PCREL, // Offset relative to PC.
CALLv3, // A V3+ call instruction.
CALLv3nr, // A V3+ call instruction that doesn't return.
CALLR,
RET_FLAG, // Return with a flag operand.
- BR_JT, // Branch through jump table.
BARRIER, // Memory barrier.
JT, // Jump table.
CP, // Constant pool.
@@ -128,7 +126,6 @@ bool isPositiveHalfWord(SDNode *N);
SDValue LowerEXTRACT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINSERT_VECTOR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const;
@@ -138,6 +135,7 @@ bool isPositiveHalfWord(SDNode *N);
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
@@ -180,6 +178,7 @@ bool isPositiveHalfWord(SDNode *N);
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
EVT getSetCCResultType(const DataLayout &, LLVMContext &C,
EVT VT) const override {
if (!VT.isVector())
@@ -215,6 +214,10 @@ bool isPositiveHalfWord(SDNode *N);
/// TODO: Handle pre/postinc as well.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
Type *Ty, unsigned AS) const override;
+ /// Return true if folding a constant offset with the given GlobalAddress
+ /// is legal. It is frequently not legal in PIC relocation models.
+ bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
+
bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
/// isLegalICmpImmediate - Return true if the specified immediate is legal
@@ -223,6 +226,10 @@ bool isPositiveHalfWord(SDNode *N);
/// the immediate into a register.
bool isLegalICmpImmediate(int64_t Imm) const override;
+ /// Returns relocation base for the given PIC jumptable.
+ SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG)
+ const override;
+
// Handling of atomic RMW instructions.
Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr,
AtomicOrdering Ord) const override;
Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td Fri Dec 18 14:19:30 2015
@@ -1426,9 +1426,6 @@ def retflag : SDNode<"HexagonISD::RET_FL
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
-def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
-def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
-
class CondStr<string CReg, bit True, bit New> {
string S = "if (" # !if(True,"","!") # CReg # !if(New,".new","") # ") ";
}
@@ -1606,8 +1603,6 @@ def EH_RETURN_JMPR : T_JMPr;
def: Pat<(eh_return),
(EH_RETURN_JMPR (i32 R31))>;
-def: Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
- (J2_jumpr IntRegs:$dst)>;
def: Pat<(brind (i32 IntRegs:$dst)),
(J2_jumpr IntRegs:$dst)>;
Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td Fri Dec 18 14:19:30 2015
@@ -1838,43 +1838,22 @@ def: LogLogNot_pat<or, or, C4_or_orn>;
// below are needed to support code generation for PIC
//===----------------------------------------------------------------------===//
-def SDT_HexagonPICAdd
+def SDT_HexagonAtGot
+ : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>;
+def SDT_HexagonAtPcrel
: SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
-def SDT_HexagonGOTAdd
- : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
-def SDT_HexagonGOTAddInternal : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>;
-def SDT_HexagonGOTAddInternalJT : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>;
-def SDT_HexagonGOTAddInternalBA : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>;
-
-def Hexagonpic_add : SDNode<"HexagonISD::PIC_ADD", SDT_HexagonPICAdd>;
-def Hexagonat_got : SDNode<"HexagonISD::AT_GOT", SDT_HexagonGOTAdd>;
-def Hexagongat_pcrel : SDNode<"HexagonISD::AT_PCREL",
- SDT_HexagonGOTAddInternal>;
-def Hexagongat_pcrel_jt : SDNode<"HexagonISD::AT_PCREL",
- SDT_HexagonGOTAddInternalJT>;
-def Hexagongat_pcrel_ba : SDNode<"HexagonISD::AT_PCREL",
- SDT_HexagonGOTAddInternalBA>;
-
-// PIC: Map from a block address computation to a PC-relative add
-def: Pat<(Hexagongat_pcrel_ba tblockaddress:$src1),
- (C4_addipc u32ImmPred:$src1)>;
-
-// PIC: Map from the computation to generate a GOT pointer to a PC-relative add
-def: Pat<(Hexagonpic_add texternalsym:$src1),
- (C4_addipc u32ImmPred:$src1)>;
-
-// PIC: Map from a jump table address computation to a PC-relative add
-def: Pat<(Hexagongat_pcrel_jt tjumptable:$src1),
- (C4_addipc u32ImmPred:$src1)>;
-
-// PIC: Map from a GOT-relative symbol reference to a load
-def: Pat<(Hexagonat_got (i32 IntRegs:$src1), tglobaladdr:$src2),
- (L2_loadri_io IntRegs:$src1, s30_2ImmPred:$src2)>;
-
-// PIC: Map from a static symbol reference to a PC-relative add
-def: Pat<(Hexagongat_pcrel tglobaladdr:$src1),
- (C4_addipc u32ImmPred:$src1)>;
+// AT_GOT address-of-GOT, address-of-global, offset-in-global
+def HexagonAtGot : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>;
+// AT_PCREL address-of-global
+def HexagonAtPcrel : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>;
+
+def: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)),
+ (L2_loadri_io I32:$got, imm:$addr)>;
+def: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off),
+ (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>;
+def: Pat<(HexagonAtPcrel I32:$addr),
+ (C4_addipc imm:$addr)>;
//===----------------------------------------------------------------------===//
// CR -
Modified: llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp Fri Dec 18 14:19:30 2015
@@ -102,7 +102,7 @@ BitVector HexagonRegisterInfo::getReserv
Reserved.set(Hexagon::R29);
Reserved.set(Hexagon::R30);
Reserved.set(Hexagon::R31);
- Reserved.set(Hexagon::D14);
+ Reserved.set(Hexagon::PC);
Reserved.set(Hexagon::D15);
Reserved.set(Hexagon::LC0);
Reserved.set(Hexagon::LC1);
Modified: llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.h?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.h Fri Dec 18 14:19:30 2015
@@ -16,6 +16,7 @@
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
+#include "HexagonTargetObjectFile.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
@@ -39,8 +40,8 @@ public:
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
TargetIRAnalysis getTargetIRAnalysis() override;
- TargetLoweringObjectFile *getObjFileLowering() const override {
- return TLOF.get();
+ HexagonTargetObjectFile *getObjFileLowering() const override {
+ return static_cast<HexagonTargetObjectFile*>(TLOF.get());
}
};
Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp?rev=256025&r1=256024&r2=256025&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp Fri Dec 18 14:19:30 2015
@@ -164,9 +164,9 @@ static MCCodeGenInfo *createHexagonMCCod
CodeModel::Model CM,
CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
- // For the time being, use static relocations, since there's really no
- // support for PIC yet.
- X->initMCCodeGenInfo(Reloc::Static, CM, OL);
+ if (RM == Reloc::Default)
+ RM = Reloc::Static;
+ X->initMCCodeGenInfo(RM, CM, OL);
return X;
}
Added: llvm/trunk/test/CodeGen/Hexagon/pic-jumptables.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/pic-jumptables.ll?rev=256025&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/pic-jumptables.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/pic-jumptables.ll Fri Dec 18 14:19:30 2015
@@ -0,0 +1,48 @@
+; RUN: llc -march=hexagon -relocation-model=pic < %s | FileCheck %s
+
+; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add({{pc|PC}}{{ *}},{{ *}}##
+; CHECK: r{{[0-9]+}}{{ *}}={{ *}}memw(r{{[0-9]+}}{{ *}}+{{ *}}r{{[0-9]+}}{{ *}}<<{{ *}}#2)
+; CHECK: r{{[0-9]+}}{{ *}}={{ *}}add(r{{[0-9]+}}{{ *}},{{ *}}r{{[0-9]+}})
+
+
+define i32 @test(i32 %y) nounwind {
+entry:
+ switch i32 %y, label %sw.epilog [
+ i32 1, label %sw.bb
+ i32 2, label %sw.bb1
+ i32 3, label %sw.bb2
+ i32 4, label %sw.bb3
+ i32 5, label %sw.bb4
+ ]
+
+sw.bb: ; preds = %entry
+ tail call void bitcast (void (...)* @baz1 to void ()*)() nounwind
+ br label %sw.epilog
+
+sw.bb1: ; preds = %entry
+ tail call void @baz2(i32 2, i32 78) nounwind
+ br label %sw.epilog
+
+sw.bb2: ; preds = %entry
+ tail call void @baz3(i32 59) nounwind
+ br label %sw.epilog
+
+sw.bb3: ; preds = %entry
+ tail call void @baz4(i32 4, i32 14) nounwind
+ br label %sw.epilog
+
+sw.bb4: ; preds = %entry
+ br label %sw.epilog
+
+sw.epilog: ; preds = %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb, %entry
+ %y.addr.0 = phi i32 [ %y, %entry ], [ 14, %sw.bb4 ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, %sw.bb1 ], [ 1, %sw.bb ]
+ ret i32 %y.addr.0
+}
+
+declare void @baz1(...)
+
+declare void @baz2(i32, i32)
+
+declare void @baz3(i32)
+
+declare void @baz4(i32, i32)
Added: llvm/trunk/test/CodeGen/Hexagon/pic-simple.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/pic-simple.ll?rev=256025&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/pic-simple.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/pic-simple.ll Fri Dec 18 14:19:30 2015
@@ -0,0 +1,22 @@
+; RUN: llc -march=hexagon -mcpu=hexagonv5 -relocation-model=pic < %s | FileCheck %s
+
+; CHECK: r{{[0-9]+}} = add({{pc|PC}}, ##_GLOBAL_OFFSET_TABLE_ at PCREL)
+; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}{{.*}}+{{.*}}##src at GOT)
+; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}{{.*}}+{{.*}}##dst at GOT)
+
+ at dst = external global i32
+ at src = external global i32
+
+define i32 @foo() nounwind {
+entry:
+ %0 = load i32, i32* @src, align 4, !tbaa !0
+ store i32 %0, i32* @dst, align 4, !tbaa !0
+ %call = tail call i32 @baz(i32 %0) nounwind
+ ret i32 0
+}
+
+declare i32 @baz(i32)
+
+!0 = !{!"int", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
Added: llvm/trunk/test/CodeGen/Hexagon/pic-static.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/pic-static.ll?rev=256025&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/pic-static.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/pic-static.ll Fri Dec 18 14:19:30 2015
@@ -0,0 +1,21 @@
+; RUN: llc -march=hexagon -mcpu=hexagonv5 -relocation-model=pic < %s | FileCheck %s
+
+; CHECK-DAG: r{{[0-9]+}} = add({{pc|PC}}, ##_GLOBAL_OFFSET_TABLE_ at PCREL)
+; CHECK-DAG: r{{[0-9]+}} = add({{pc|PC}}, ##x at PCREL)
+; CHECK: r{{[0-9]+}} = memw(r{{[0-9]+}}{{.*}}+{{.*}}##bar at GOT)
+
+ at x = internal global i32 9, align 4
+ at bar = external global i32*
+
+define i32 @foo(i32 %y) nounwind {
+entry:
+ store i32* @x, i32** @bar, align 4, !tbaa !0
+ %0 = load i32, i32* @x, align 4, !tbaa !3
+ %add = add nsw i32 %0, %y
+ ret i32 %add
+}
+
+!0 = !{!"any pointer", !1}
+!1 = !{!"omnipotent char", !2}
+!2 = !{!"Simple C/C++ TBAA"}
+!3 = !{!"int", !1}
Added: llvm/trunk/test/MC/Hexagon/got.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/got.s?rev=256025&view=auto
==============================================================================
--- llvm/trunk/test/MC/Hexagon/got.s (added)
+++ llvm/trunk/test/MC/Hexagon/got.s Fri Dec 18 14:19:30 2015
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -arch=hexagon -filetype=obj %s | llvm-objdump -r - | FileCheck %s
+#
+
+# make sure the fixups emitted match what is
+# expected.
+.Lgot:
+ r0 = memw (r1 + ##foo at GOT)
+
+# CHECK: R_HEX_GOT_32_6_X foo
+# CHECK: R_HEX_GOT_11_X foo
+
Added: llvm/trunk/test/MC/Hexagon/pcrel.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/pcrel.s?rev=256025&view=auto
==============================================================================
--- llvm/trunk/test/MC/Hexagon/pcrel.s (added)
+++ llvm/trunk/test/MC/Hexagon/pcrel.s Fri Dec 18 14:19:30 2015
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -arch=hexagon -filetype=obj %s | llvm-objdump -r - | FileCheck %s
+#
+
+# make sure the fixups emitted match what is
+# expected.
+.Lpc:
+ r0 = add (pc, ##foo at PCREL)
+
+# CHECK: R_HEX_B32_PCREL_X
+# CHECK: R_HEX_6_PCREL_X
+
More information about the llvm-commits
mailing list