#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELDAGTODAG_H
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/CodeGen.h"
#include <vector>
namespace llvm {
class MachineFunction;
class HexagonInstrInfo;
class HexagonRegisterInfo;
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 {
HST = &MF.getSubtarget<HexagonSubtarget>();
HII = HST->getInstrInfo();
HRI = HST->getRegisterInfo();
SelectionDAGISel::runOnMachineFunction(MF);
updateAligna();
return true;
}
bool ComplexPatternFuncMutatesDAG() const override {
return true;
}
void PreprocessISelDAG() override;
void emitFunctionEntryCode() override;
void Select(SDNode *N) override;
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, Align Alignment);
bool SelectGlobalAddress(SDValue &N, SDValue &R, bool UseGP, Align Alignment);
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";
}
MachineSDNode *LoadInstrForLoadIntrinsic(SDNode *IntN);
SDNode *StoreInstrForLoadIntrinsic(MachineSDNode *LoadN, SDNode *IntN);
void SelectFrameIndex(SDNode *N);
bool SelectInlineAsmMemoryOperand(const SDValue &Op,
unsigned ConstraintID,
std::vector<SDValue> &OutOps) override;
bool tryLoadOfLoadIntrinsic(LoadSDNode *N);
bool SelectBrevLdIntrinsic(SDNode *IntN);
bool SelectNewCircIntrinsic(SDNode *IntN);
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 SelectIntrinsicWChain(SDNode *N);
void SelectIntrinsicWOChain(SDNode *N);
void SelectConstant(SDNode *N);
void SelectConstantFP(SDNode *N);
void SelectV65Gather(SDNode *N);
void SelectV65GatherPred(SDNode *N);
void SelectHVXDualOutput(SDNode *N);
void SelectAddSubCarry(SDNode *N);
void SelectVAlign(SDNode *N);
void SelectVAlignAddr(SDNode *N);
void SelectTypecast(SDNode *N);
void SelectP2D(SDNode *N);
void SelectD2P(SDNode *N);
void SelectQ2V(SDNode *N);
void SelectV2Q(SDNode *N);
#define GET_DAGISEL_DECL
#include "HexagonGenDAGISel.inc"
private:
friend struct HvxSelector;
SDValue selectUndef(const SDLoc &dl, MVT ResTy) {
SDNode *U = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, ResTy);
return SDValue(U, 0);
}
void SelectHvxShuffle(SDNode *N);
void SelectHvxRor(SDNode *N);
void SelectHvxVAlign(SDNode *N);
bool keepsLowBits(const SDValue &Val, unsigned NumBits, SDValue &Src);
bool isAlignedMemNode(const MemSDNode *N) const;
bool isSmallStackStore(const StoreSDNode *N) const;
bool isPositiveHalfWord(const SDNode *N) const;
bool hasOneUse(const SDNode *N) const;
void ppSimplifyOrSelect0(std::vector<SDNode*> &&Nodes);
void ppAddrReorderAddShl(std::vector<SDNode*> &&Nodes);
void ppAddrRewriteAndSrl(std::vector<SDNode*> &&Nodes);
void ppHoistZextI1(std::vector<SDNode*> &&Nodes);
void updateAligna();
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();
}; }
#endif