diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 112 |
1 files changed, 109 insertions, 3 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 2551fe5a140..b23da692498 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "Hexagon.h" -#include "HexagonISelDAGToDAG.h" #include "HexagonISelLowering.h" #include "HexagonMachineFunctionInfo.h" #include "HexagonTargetMachine.h" @@ -51,8 +50,115 @@ static cl::opt<bool> CheckSingleUse("hexagon-isel-su", cl::Hidden, // Instruction Selector Implementation //===----------------------------------------------------------------------===// -#define GET_DAGISEL_BODY HexagonDAGToDAGISel -#include "HexagonGenDAGISel.inc" +//===--------------------------------------------------------------------===// +/// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine +/// instructions for SelectionDAG operations. +/// +namespace { +class HexagonDAGToDAGISel : public SelectionDAGISel { + const HexagonSubtarget *HST; + const HexagonInstrInfo *HII; + const HexagonRegisterInfo *HRI; +public: + explicit HexagonDAGToDAGISel(HexagonTargetMachine &tm, + CodeGenOpt::Level OptLevel) + : SelectionDAGISel(tm, OptLevel), HST(nullptr), HII(nullptr), + HRI(nullptr) {} + + 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; + } + + bool ComplexPatternFuncMutatesDAG() const override { + return true; + } + void PreprocessISelDAG() override; + void EmitFunctionEntryCode() override; + + void Select(SDNode *N) override; + + // Complex Pattern Selectors. + inline bool SelectAddrGA(SDValue &N, SDValue &R); + inline bool SelectAddrGP(SDValue &N, SDValue &R); + inline bool SelectAnyImm(SDValue &N, SDValue &R); + inline bool SelectAnyInt(SDValue &N, SDValue &R); + bool SelectAnyImmediate(SDValue &N, SDValue &R, uint32_t LogAlign); + bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP, + uint32_t LogAlign); + bool SelectAddrFI(SDValue &N, SDValue &R); + bool DetectUseSxtw(SDValue &N, SDValue &R); + + inline bool SelectAnyImm0(SDValue &N, SDValue &R); + inline bool SelectAnyImm1(SDValue &N, SDValue &R); + inline bool SelectAnyImm2(SDValue &N, SDValue &R); + inline bool SelectAnyImm3(SDValue &N, SDValue &R); + + StringRef getPassName() const override { + return "Hexagon DAG->DAG Pattern Instruction Selection"; + } + + // Generate a machine instruction node corresponding to the circ/brev + // load intrinsic. + MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN); + // Given the circ/brev load intrinsic and the already generated machine + // instruction, generate the appropriate store (that is a part of the + // intrinsic's functionality). + SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN); + + void SelectFrameIndex(SDNode *N); + /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for + /// inline asm expressions. + bool SelectInlineAsmMemoryOperand(const SDValue &Op, + unsigned ConstraintID, + std::vector<SDValue> &OutOps) override; + bool tryLoadOfLoadIntrinsic(LoadSDNode *N); + void SelectLoad(SDNode *N); + void SelectIndexedLoad(LoadSDNode *LD, const SDLoc &dl); + void SelectIndexedStore(StoreSDNode *ST, const SDLoc &dl); + void SelectStore(SDNode *N); + void SelectSHL(SDNode *N); + void SelectZeroExtend(SDNode *N); + void SelectIntrinsicWChain(SDNode *N); + void SelectIntrinsicWOChain(SDNode *N); + void SelectConstant(SDNode *N); + void SelectConstantFP(SDNode *N); + void SelectBitcast(SDNode *N); + + // Include the pieces autogenerated from the target description. + #include "HexagonGenDAGISel.inc" + +private: + bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src); + bool isOrEquivalentToAdd(const SDNode *N) const; + bool isAlignedMemNode(const MemSDNode *N) const; + bool isSmallStackStore(const StoreSDNode *N) const; + bool isPositiveHalfWord(const SDNode *N) const; + bool hasOneUse(const SDNode *N) const; + + // DAG preprocessing functions. + void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes); + void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes); + void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes); + void ppHoistZextI1(std::vector<SDNode*> &&Nodes); + + SmallDenseMap<SDNode *,int> RootWeights; + SmallDenseMap<SDNode *,int> RootHeights; + SmallDenseMap<const Value *,int> GAUsesInFunction; + int getWeight(SDNode *N); + int getHeight(SDNode *N); + SDValue getMultiplierForSHL(SDNode *N); + SDValue factorOutPowerOf2(SDValue V, unsigned Power); + unsigned getUsesInFunction(const Value *V); + SDValue balanceSubTree(SDNode *N, bool Factorize = false); + void rebalanceAddressTrees(); +}; // end HexagonDAGToDAGISel +} // end anonymous namespace + /// createHexagonISelDag - This pass converts a legalized DAG into a /// Hexagon-specific DAG, ready for instruction scheduling. |